92 lines
2.5 KiB
TypeScript
92 lines
2.5 KiB
TypeScript
import { Icon } from "@icones/react"
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuLabel,
|
|
DropdownMenuRadioGroup,
|
|
DropdownMenuRadioItem,
|
|
DropdownMenuTrigger,
|
|
} from "@workspace/ui/components/dropdown-menu"
|
|
import { cn } from "@workspace/ui/lib/utils"
|
|
import { HeaderActionButton } from "@workspace/blocks/layout"
|
|
|
|
import { appLocales, isAppLocale, type AppLocaleCountry } from "./app-locales"
|
|
import { useAppLocale } from "./app-i18n-provider"
|
|
|
|
function LocaleFlag({
|
|
country,
|
|
className,
|
|
}: {
|
|
className?: string
|
|
country: AppLocaleCountry
|
|
}) {
|
|
return (
|
|
<span
|
|
aria-hidden="true"
|
|
className={cn(
|
|
"inline-flex shrink-0 overflow-hidden rounded-full ring-1 ring-foreground/15",
|
|
className
|
|
)}
|
|
>
|
|
{country === "CN" ? (
|
|
<Icon name="flag:cn-square" className="size-full" />
|
|
) : (
|
|
<Icon name="flag:us-square" className="size-full" />
|
|
)}
|
|
</span>
|
|
)
|
|
}
|
|
|
|
export function AppLanguageSwitcher() {
|
|
const { locale, setLocale } = useAppLocale()
|
|
const activeLocale =
|
|
appLocales.find((definition) => definition.locale === locale) ??
|
|
appLocales[0]
|
|
const menuLabel = locale === "zh-Hans" ? "语言" : "Language"
|
|
const triggerLabel =
|
|
locale === "zh-Hans"
|
|
? `切换语言,当前为${activeLocale.label}`
|
|
: `Change language, currently ${activeLocale.label}`
|
|
|
|
return (
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger
|
|
render={
|
|
<HeaderActionButton
|
|
aria-label={triggerLabel}
|
|
className="rounded-full"
|
|
/>
|
|
}
|
|
>
|
|
<LocaleFlag country={activeLocale.country} className="size-6" />
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent
|
|
align="end"
|
|
className="w-44"
|
|
showArrow={{ cornerRadius: "lg", tailSize: "sm" }}
|
|
>
|
|
<DropdownMenuRadioGroup
|
|
value={locale}
|
|
onValueChange={(value) => {
|
|
if (isAppLocale(value)) {
|
|
setLocale(value)
|
|
}
|
|
}}
|
|
>
|
|
<DropdownMenuLabel>{menuLabel}</DropdownMenuLabel>
|
|
{appLocales.map((definition) => (
|
|
<DropdownMenuRadioItem
|
|
key={definition.locale}
|
|
className="py-2"
|
|
value={definition.locale}
|
|
>
|
|
<LocaleFlag country={definition.country} className="size-5" />
|
|
<span lang={definition.languageTag}>{definition.label}</span>
|
|
</DropdownMenuRadioItem>
|
|
))}
|
|
</DropdownMenuRadioGroup>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
)
|
|
}
|