Frontend/src/localization/views/LanguageSelector.tsx

90 lines
3.6 KiB
TypeScript

/* -------------------------------------------------------------------------- */
/* Libraries */
/* -------------------------------------------------------------------------- */
import React from "react";
import { Langs } from "localization/i18n";
import { useTranslation } from "react-i18next";
/* -------------------------------------------------------------------------- */
/* Hooks */
/* -------------------------------------------------------------------------- */
import { useLangugeViewModel } from "localization/controller/langugeViewModel";
/* -------------------------------------------------------------------------- */
/* Components */
/* -------------------------------------------------------------------------- */
import Combox from "components/controls/Combox";
import Modal from "components/containers/modal/Modal";
/* -------------------------------------------------------------------------- */
/* Icons */
/* -------------------------------------------------------------------------- */
import classNames from "classnames";
/* -------------------------------------------------------------------------- */
/* Properties */
/* -------------------------------------------------------------------------- */
type Props = {
isShown: boolean;
onClose: VoidFunction;
};
/* -------------------------------------------------------------------------- */
/* Language switcher */
/* -------------------------------------------------------------------------- */
function CheckIcon(props: React.SVGProps<SVGSVGElement>) {
return (
<svg viewBox="0 0 24 24" {...props}>
<circle cx={12} cy={12} r={12} stroke="none" opacity="0.2" />
<path
d="M7 13l3 3 7-7"
fill="none"
strokeWidth={1.5}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
}
export default function LanguageSelector({ isShown, onClose }: Props) {
const { t } = useTranslation();
const { selected, languages, switchLang } = useLangugeViewModel();
return (
<Modal isOpen={isShown} onClose={onClose} className="max-w-lg">
<Modal.Header>{t("selectLanguage")}</Modal.Header>
<Combox
options={Object.keys(languages)}
displayValue={(key) => languages[key as Langs].nativeName}
keyMaper={(key) => key}
setSelected={switchLang}
filterRule={(query, item) => {
if (query === "") {
return true;
}
return languages[item as Langs].nativeName
.toLowerCase()
.replace(/\s+/g, "")
.includes(query.toLowerCase().replace(/\s+/g, ""));
}}
selected={selected}
itemBuilder={({ selected, active }, item) => {
return (
<div className="flex items-center justify-between">
<span
className={`block truncate ${
selected ? "font-medium" : "font-normal"
}`}
>
{languages[item as Langs].nativeName}
</span>
<CheckIcon
className={classNames("w-5 h-5", {
"stroke-blue-400 fill-white": selected,
"stroke-transparent fill-transparent": !selected,
})}
/>
</div>
);
}}
/>
</Modal>
);
}