Translation support for dropdown.tsx component

This commit is contained in:
rift 2023-12-16 14:13:04 -06:00
parent fe85a1c33a
commit 0f7297aa70
6 changed files with 81 additions and 29 deletions

View file

@ -24,6 +24,10 @@
"tab": "Tab", "tab": "Tab",
"custom": "Customization", "custom": "Customization",
"misc": "Misc" "misc": "Misc"
},
"proxy": {
"title": "Proxy",
"automatic": "Automatic"
} }
} }
} }

View file

@ -24,6 +24,10 @@
"tab": "タブ", "tab": "タブ",
"custom": "カスタマイズ", "custom": "カスタマイズ",
"misc": "その他" "misc": "その他"
},
"proxy": {
"title": "プロキシ",
"automatic": "自動"
} }
} }
} }

View file

@ -1,7 +1,6 @@
import { useState } from "preact/hooks"; import { useState } from "preact/hooks";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { HeaderRoute } from "../components/HeaderRoute"; import { HeaderRoute } from "../components/HeaderRoute";
export function Home() { export function Home() {
const [isFocused, setIsFocused] = useState(false); const [isFocused, setIsFocused] = useState(false);
const { t } = useTranslation(); const { t } = useTranslation();

View file

@ -1,10 +1,29 @@
import { useState } from "preact/hooks"; import { useState, useEffect } from "preact/hooks";
const Dropdown = ({ name, options }: { name: string; options: string[] }) => { interface Option {
id: string;
label: string; // Translations CAN be passed
}
const Dropdown = ({
name,
options,
storageKey
}: {
name: string;
storageKey: string;
options: Option[];
}) => {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const [choice, setChoice] = useState(
localStorage.getItem(name) || options[0] const [choice, setChoice] = useState(() => {
); return localStorage.getItem(storageKey) || options[0]?.id || "";
});
// update on localstorage change
useEffect(() => {
setChoice(localStorage.getItem(storageKey) || options[0]?.id || "");
}, [storageKey, options]);
return ( return (
<div className="relative text-center"> <div className="relative text-center">
@ -13,20 +32,22 @@ const Dropdown = ({ name, options }: { name: string; options: string[] }) => {
className="font-roboto flex h-14 w-56 cursor-pointer flex-col items-center justify-center rounded-2xl border border-input-border-color bg-input text-center text-xl" className="font-roboto flex h-14 w-56 cursor-pointer flex-col items-center justify-center rounded-2xl border border-input-border-color bg-input text-center text-xl"
onClick={() => setIsOpen(!isOpen)} onClick={() => setIsOpen(!isOpen)}
> >
<div className="select-none">{choice}</div> <div className="select-none">
{options.find((o) => o.id === choice)?.label}
</div>
{isOpen && ( {isOpen && (
<div className="absolute top-full w-full border"> <div className="absolute top-full w-full border">
{options.map((option: string) => ( {options.map((option) => (
<div <div
key={option} key={option.id}
className="hover:bg-dropdown-option-hover-color" className="hover:bg-dropdown-option-hover-color"
onClick={() => { onClick={() => {
setIsOpen(false); setIsOpen(false);
setChoice(option); setChoice(option.id);
localStorage.setItem(name, option); localStorage.setItem(storageKey, option.id);
}} }}
> >
{option} {option.label}
</div> </div>
))} ))}
</div> </div>
@ -37,4 +58,3 @@ const Dropdown = ({ name, options }: { name: string; options: string[] }) => {
}; };
export default Dropdown; export default Dropdown;

View file

@ -1,7 +1,18 @@
import { motion } from "framer-motion"; import { motion } from "framer-motion";
import { tabContentVariant, settingsPageVariant } from "./Variants"; import { tabContentVariant, settingsPageVariant } from "./Variants";
import Dropdown from "./Dropdown";
import { useTranslation } from "react-i18next";
const Misc = ({ id, active }) => ( const Misc = ({ id, active }) => {
const { t } = useTranslation();
const engines = [
{ id: "automatic", label: t("settings.proxy.automatic") },
{ id: "ultraviolet", label: "Ultraviolet" },
{ id: "rammerhead", label: "Rammerhead" },
{ id: "dynamic", label: "Dynamic" }
];
return (
<motion.div <motion.div
role="tabpanel" role="tabpanel"
id={id} id={id}
@ -10,10 +21,17 @@ const Misc = ({ id, active }) => (
animate={active ? "active" : "inactive"} animate={active ? "active" : "inactive"}
initial="inactive" initial="inactive"
> >
<motion.div variants={settingsPageVariant} className="content-card"> <motion.div
<h1>Misc settings</h1> variants={settingsPageVariant}
className="content-card flex flex-row flex-wrap justify-around"
>
<Dropdown
name={t("settings.proxy.title")}
storageKey="proxy"
options={engines}
/>
</motion.div> </motion.div>
</motion.div> </motion.div>
); );
};
export default Misc; export default Misc;

View file

@ -1,9 +1,16 @@
import { motion } from "framer-motion"; import { motion } from "framer-motion";
import { tabContentVariant, settingsPageVariant } from "./Variants"; import { tabContentVariant, settingsPageVariant } from "./Variants";
import Dropdown from "./Dropdown"; import Dropdown from "./Dropdown";
import { useTranslation } from "react-i18next";
const Proxy = ({ id, active }) => { const Proxy = ({ id, active }) => {
const engines = ["Automatic", "Ultraviolet", "Rammerhead", "Dynamic"]; const { t } = useTranslation();
const engines = [
{ id: "automatic", label: t("settings.proxy.automatic") },
{ id: "ultraviolet", label: "Ultraviolet" },
{ id: "rammerhead", label: "Rammerhead" },
{ id: "dynamic", label: "Dynamic" }
];
return ( return (
<motion.div <motion.div
@ -18,7 +25,7 @@ const Proxy = ({ id, active }) => {
variants={settingsPageVariant} variants={settingsPageVariant}
className="content-card flex flex-row flex-wrap justify-around" className="content-card flex flex-row flex-wrap justify-around"
> >
<Dropdown name="Engine" options={engines} /> <Dropdown name={t("settings.proxy.title")} storageKey="proxy" options={engines} />
</motion.div> </motion.div>
</motion.div> </motion.div>
); );