56 lines
2.3 KiB
TypeScript
56 lines
2.3 KiB
TypeScript
/**
|
||
* 顶栏语言下拉: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>
|
||
);
|
||
}
|