115 lines
3.4 KiB
TypeScript
Executable File
115 lines
3.4 KiB
TypeScript
Executable File
'use client';
|
|
|
|
import { useI18n } from '@nice/i18n';
|
|
import { Button } from '@nice/ui/components/button';
|
|
import {
|
|
Select,
|
|
SelectContent,
|
|
SelectItem,
|
|
SelectTrigger,
|
|
SelectValue,
|
|
} from '@nice/ui/components/select';
|
|
import { IconWorld } from '@tabler/icons-react';
|
|
|
|
interface LanguageSwitcherProps {
|
|
variant?: 'button' | 'select';
|
|
showFlag?: boolean;
|
|
showText?: boolean;
|
|
}
|
|
|
|
// 语言显示配置
|
|
const LANGUAGE_CONFIG = {
|
|
'cn': {
|
|
name: '中文',
|
|
nativeName: '中文',
|
|
flag: '🇨🇳',
|
|
},
|
|
} as const;
|
|
|
|
export function LanguageSwitcher({
|
|
variant = 'select',
|
|
showFlag = true,
|
|
showText = true,
|
|
}: LanguageSwitcherProps) {
|
|
const { locale, switchLocale, supportedLocales, t } = useI18n();
|
|
|
|
const currentLang = LANGUAGE_CONFIG[locale as keyof typeof LANGUAGE_CONFIG];
|
|
const availableLanguages = supportedLocales
|
|
.filter(lang => lang in LANGUAGE_CONFIG)
|
|
.map(lang => ({
|
|
value: lang,
|
|
...LANGUAGE_CONFIG[lang as keyof typeof LANGUAGE_CONFIG],
|
|
}));
|
|
|
|
if (variant === 'button') {
|
|
return (
|
|
<div className="flex gap-1">
|
|
{availableLanguages.map((lang) => (
|
|
<Button
|
|
key={lang.value}
|
|
variant={locale === lang.value ? 'default' : 'outline'}
|
|
size="sm"
|
|
onClick={() => switchLocale(lang.value)}
|
|
className="min-w-0"
|
|
>
|
|
{showFlag && <span className="mr-1">{lang.flag}</span>}
|
|
{showText && <span>{lang.nativeName}</span>}
|
|
</Button>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<Select value={locale} onValueChange={switchLocale}>
|
|
<SelectTrigger className="w-auto min-w-[120px]">
|
|
<div className="flex items-center gap-2">
|
|
<IconWorld className="h-4 w-4" />
|
|
<SelectValue>
|
|
<div className="flex items-center gap-1">
|
|
{showFlag && currentLang && (
|
|
<span>{currentLang.flag}</span>
|
|
)}
|
|
{showText && currentLang && (
|
|
<span>{currentLang.nativeName}</span>
|
|
)}
|
|
</div>
|
|
</SelectValue>
|
|
</div>
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
{availableLanguages.map((lang) => (
|
|
<SelectItem key={lang.value} value={lang.value}>
|
|
<div className="flex items-center gap-2">
|
|
{showFlag && <span>{lang.flag}</span>}
|
|
{showText && <span>{lang.nativeName}</span>}
|
|
</div>
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
);
|
|
}
|
|
|
|
// 简化的语言切换器,仅显示图标
|
|
export function LanguageToggle() {
|
|
return (
|
|
<LanguageSwitcher
|
|
variant="select"
|
|
showFlag={false}
|
|
showText={false}
|
|
/>
|
|
);
|
|
}
|
|
|
|
// 简化的按钮版本
|
|
export function LanguageButtons() {
|
|
return (
|
|
<LanguageSwitcher
|
|
variant="button"
|
|
showFlag={true}
|
|
showText={false}
|
|
/>
|
|
);
|
|
}
|