app-template/app/web/src/components/LocaleSwitch.tsx

56 lines
2.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 顶栏语言下拉:trigger 显示当前语言,菜单项来自 `LOCALES`(后续扩展只需改 `@app/i18n`)。
* 菜单项是带 `data-switch-locale` 的 `<a>`,由 AppLayout 内联脚本写 `app-lang` cookie 后跳转。
*/
import { LOCALES, type Locale, t } from "@app/i18n";
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@app/ui";
export interface LocaleSwitchProps {
locale: Locale;
/** 各语言在当前页的 URL(AppLayout 按 pathname 预先算好) */
hrefs: Record<Locale, string>;
}
export default function LocaleSwitch({ locale, hrefs }: LocaleSwitchProps) {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<button
type="button"
className="u-linelink"
aria-label={t(locale, "locale.switch")}
>
{t(locale, `locale.${locale}`)}
<span aria-hidden="true" className="text-[9px] opacity-70">
▾
</span>
</button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
{LOCALES.map((code) => (
<DropdownMenuItem key={code} asChild>
<a
data-switch-locale={code}
href={hrefs[code]}
aria-current={code === locale ? "true" : undefined}
className={
code === locale
? "flex w-full items-center gap-2 font-medium text-inherit no-underline"
: "flex w-full items-center gap-2 text-inherit no-underline"
}
>
<span>{t(code, `locale.${code}`)}</span>
{code === locale && (
<span aria-hidden="true" className="ml-auto text-[11px]">
✓
</span>
)}
</a>
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
);
}