Other · LocaleProvider

LocaleProvider

Internationalized components to provide multilingual support for Semi components

Languages supported

Minimum supported versionLanguage
v0.0.1Simplified Chinese: zh_CN
v0.7.0English: en_GB, Japanese: ja_JP, Korean: ko_KR
v1.8.0Arabic: ar
v1.11.0Vietnamese: vi_VN、Russian: ru_RU、Indonesian: id_ID、Malay: ms_MY、Thai: th_TH、Turkish: tr_TR
v1.17.0Portuguese: pt_BR
v1.28.0Traditional Chinese: zh_TW
v2.2.0Spanish: es
v2.15.0Italian: it、French:fr、German:de
v2.21.0Romanian: ro
v2.29.0Swedish: sv_SE、 Polish: pl_PL、Dutch: nl_NL
v2.88.0Azerbaijani: az, Bulgarian: bg, Catalan: ca, Czech: cs_CZ, Cebu: ceb_PH, Danish: da, Greek: el_GR, Spanish (Latin America): es_419, Estonian: et, Persian: fa_IR, Filipino: fil_PH, Finnish: fi_FI, French (Canada): fr_CA, Irish: ga, Hebrew: he_IL, Hindi: hi_IN, Croatian: hr, Hungarian: hu_HU, Icelandic: is, Javanese: jv_ID, Kazakh: kk, Khmer: km_KH, Lithuanian: lt, Latvian: lv, Burmese: my_MM, Norwegian: nb, Portuguese: pt, Slovak: sk, Slovenian: sl, Albanian: sq, Swahili: sw, Ukrainian: uk_UA, Urdu: ur, Uzbek: uz

Components supported

Calendar、Cascader、Chat、DatePicker、Form、Image、List、Modal、Navigation、Nav、Pagination、Popconfirm、Select、Table、TimePicker、Transfer、Tree、TreeSelect、Typography、Upload

How to use

LocaleProvider uses the context feature of React, and you only need to wrap the periphery of the application once to take effect globally.
When you need to switch the language, you can directly switch the locale passed in by the props.

import React, { useCallback, useMemo, useState } from 'react';
import zh_CN from '@fibrous/semi-foundation/locale/source/zh_CN';
import en_GB from '@fibrous/semi-foundation/locale/source/en_GB';
import en_US from '@fibrous/semi-foundation/locale/source/en_US';
import ko_KR from '@fibrous/semi-foundation/locale/source/ko_KR';
import ja_JP from '@fibrous/semi-foundation/locale/source/ja_JP';
import vi_VN from '@fibrous/semi-foundation/locale/source/vi_VN';
import ru_RU from '@fibrous/semi-foundation/locale/source/ru_RU';
import id_ID from '@fibrous/semi-foundation/locale/source/id_ID';
import ms_MY from '@fibrous/semi-foundation/locale/source/ms_MY';
import th_TH from '@fibrous/semi-foundation/locale/source/th_TH';
import tr_TR from '@fibrous/semi-foundation/locale/source/tr_TR';
import pt_BR from '@fibrous/semi-foundation/locale/source/pt_BR';
import zh_TW from '@fibrous/semi-foundation/locale/source/zh_TW';
import sv_SE from '@fibrous/semi-foundation/locale/source/sv_SE';
import pl_PL from '@fibrous/semi-foundation/locale/source/pl_PL';
import nl_NL from '@fibrous/semi-foundation/locale/source/nl_NL';
import ar from '@fibrous/semi-foundation/locale/source/ar';
import es from '@fibrous/semi-foundation/locale/source/es';
import it from '@fibrous/semi-foundation/locale/source/it';
import de from '@fibrous/semi-foundation/locale/source/de';
import fr from '@fibrous/semi-foundation/locale/source/fr';
import ro from '@fibrous/semi-foundation/locale/source/ro';

import { LocaleProvider } from '@fibrous/semi-ui-react';

() => {
    return (
        <LocaleProvider locale={en_GB}>
            {/* eslint-disable-next-line react/jsx-no-undef */}
            <App />
        </LocaleProvider>
    );
};

When locale is omitted, LocaleProvider inherits the language of the outer LocaleProvider; without any outer provider, zh_CN is used. The locale of ConfigProvider takes precedence over LocaleProvider.

Code example

Internationalization

  • Total pages: 10
  • 合計ページ数:10
Code
import en_GB from '@fibrous/semi-foundation/locale/source/en_GB';
import ja_JP from '@fibrous/semi-foundation/locale/source/ja_JP';
import { LocaleProvider, Pagination } from '@fibrous/semi-ui-react';

export default function LocaleDemo() {
    return (
        <>
            <LocaleProvider locale={en_GB}>
                <Pagination total={100} showTotal showSizeChanger style={{ margin: 20 }} />
            </LocaleProvider>
            <LocaleProvider locale={ja_JP}>
                <Pagination total={100} showTotal showSizeChanger style={{ margin: 20 }} />
            </LocaleProvider>
        </>
    );
}

Custom Internationalization Component

When your custom component also wants to consume the localeCode in the Semi LocaleProvider Context or read the i18n text localeData of a specific component, you can use LocaleConsumer to get it

zh-CN : 开始时间
ko-KR : 시작 시간
en-GB : Start Time
semi
design
dsm
Code
import en_GB from '@fibrous/semi-foundation/locale/source/en_GB';
import ko_KR from '@fibrous/semi-foundation/locale/source/ko_KR';
import zh_CN from '@fibrous/semi-foundation/locale/source/zh_CN';
import { LocaleProvider, LocaleConsumer } from '@fibrous/semi-ui-react';

// Custom component text joins the Locale type through declaration merging
declare module '@fibrous/semi-foundation/locale/interface' {
    interface Locale {
        ComponentA: { customKey: string };
    }
}

function GetLocaleFromSemi() {
    return (
        <LocaleConsumer componentName="TimePicker">
            {(localeData, localeCode) => (
                <div>
                    {localeCode} : {localeData.begin}
                </div>
            )}
        </LocaleConsumer>
    );
}

function ExtractComponent() {
    return <LocaleConsumer componentName="ComponentA">{(localeData) => <div>{localeData.customKey}</div>}</LocaleConsumer>;
}

export default function LocaleDemo() {
    const new_zh_CN = { ...zh_CN, ComponentA: { customKey: 'semi' } };
    const new_ko_KR = { ...ko_KR, ComponentA: { customKey: 'design' } };
    const new_en_GB = { ...en_GB, ComponentA: { customKey: 'dsm' } };

    return (
        <>
            <LocaleProvider locale={new_zh_CN}>
                <GetLocaleFromSemi />
            </LocaleProvider>
            <LocaleProvider locale={new_ko_KR}>
                <GetLocaleFromSemi />
            </LocaleProvider>
            <LocaleProvider locale={new_en_GB}>
                <GetLocaleFromSemi />
            </LocaleProvider>
            <LocaleProvider locale={new_zh_CN}>
                <ExtractComponent />
            </LocaleProvider>
            <LocaleProvider locale={new_ko_KR}>
                <ExtractComponent />
            </LocaleProvider>
            <LocaleProvider locale={new_en_GB}>
                <ExtractComponent />
            </LocaleProvider>
        </>
    );
}

Components that support multilingualism

The example gives all the current multilingual components

When your site needs RTL support, use ConfigProvider directly: besides locale, it also configures direction='rtl'/'ltr'.
Without RTL needs, LocaleProvider is enough.

Pagination
  • 总页数:10
  • 跳至
    页
Modal
Select & Cascader
DatePicker
~
~
TimePicker


TreeSelect
Table
NameAgeAddress
Bytedance 032Beijing, Haidian. Zhichun Road 0
Bytedance 132Beijing, Haidian. Zhichun Road 1
Bytedance 232Beijing, Haidian. Zhichun Road 2
Bytedance 332Beijing, Haidian. Zhichun Road 3
Bytedance 432Beijing, Haidian. Zhichun Road 4
Bytedance 532Beijing, Haidian. Zhichun Road 5
Bytedance 632Beijing, Haidian. Zhichun Road 6
Bytedance 732Beijing, Haidian. Zhichun Road 7
Bytedance 832Beijing, Haidian. Zhichun Road 8
Bytedance 932Beijing, Haidian. Zhichun Road 9
显示第 1 条-第 10 条,共 46 条
Table - Empty
NameAgeAddress
暂无数据
List - Empty
List
暂无数据
Calendar
周日
周一
周二
周三
周四
周五
周六
30
7月 1日
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
8月 1日
2
3
Typography - Copyable

Click to copy text.

Typography - Collapsible

支持展开和折叠:Semi Design 是由抖音前端团队与 UED 团队共同设计开发并维护的设计系统。设计系统包含设计语言以及一整套可复用的前端组件,帮助设计师与开发者更容易地打造高质量的、用户体验一致的、符合设计规范的 Web 应用。

Transfer
总个数:100
选项名称 0
选项名称 1
选项名称 2
选项名称 3
选项名称 4
选项名称 5
选项名称 6
选项名称 7
选项名称 8
选项名称 9
选项名称 10
选项名称 11
选项名称 12
选项名称 13
选项名称 14
选项名称 15
选项名称 16
选项名称 17
选项名称 18
选项名称 19
选项名称 20
选项名称 21
选项名称 22
选项名称 23
选项名称 24
选项名称 25
选项名称 26
选项名称 27
选项名称 28
选项名称 29
选项名称 30
选项名称 31
选项名称 32
选项名称 33
选项名称 34
选项名称 35
选项名称 36
选项名称 37
选项名称 38
选项名称 39
选项名称 40
选项名称 41
选项名称 42
选项名称 43
选项名称 44
选项名称 45
选项名称 46
选项名称 47
选项名称 48
选项名称 49
选项名称 50
选项名称 51
选项名称 52
选项名称 53
选项名称 54
选项名称 55
选项名称 56
选项名称 57
选项名称 58
选项名称 59
选项名称 60
选项名称 61
选项名称 62
选项名称 63
选项名称 64
选项名称 65
选项名称 66
选项名称 67
选项名称 68
选项名称 69
选项名称 70
选项名称 71
选项名称 72
选项名称 73
选项名称 74
选项名称 75
选项名称 76
选项名称 77
选项名称 78
选项名称 79
选项名称 80
选项名称 81
选项名称 82
选项名称 83
选项名称 84
选项名称 85
选项名称 86
选项名称 87
选项名称 88
选项名称 89
选项名称 90
选项名称 91
选项名称 92
选项名称 93
选项名称 94
选项名称 95
选项名称 96
选项名称 97
选项名称 98
选项名称 99
已选个数:0
暂无内容,可从左侧勾选
Image
lamp1
lamp2
lamp3
lamp4
Form
Navigation
Code
import { useState, useMemo, useCallback, useRef } from 'react';
import zh_CN from '@fibrous/semi-foundation/locale/source/zh_CN';
import { IconUser, IconSemiLogo, IconStar } from '@fibrous/semi-icons-react';
import { LocaleProvider, ConfigProvider, Pagination, Modal, Button, Select, Cascader, DatePicker, TreeSelect, Table, TimePicker, List, Calendar, Typography, Transfer, ImagePreview, Image, Form, Nav } from '@fibrous/semi-ui-react';

// A pack loads when it is picked, so the page does not bundle every language up front
const loaders = {
    ar: () => import('@fibrous/semi-foundation/locale/source/ar'),
    az: () => import('@fibrous/semi-foundation/locale/source/az'),
    bg: () => import('@fibrous/semi-foundation/locale/source/bg'),
    bn_IN: () => import('@fibrous/semi-foundation/locale/source/bn_IN'),
    ca: () => import('@fibrous/semi-foundation/locale/source/ca'),
    ceb_PH: () => import('@fibrous/semi-foundation/locale/source/ceb_PH'),
    cs_CZ: () => import('@fibrous/semi-foundation/locale/source/cs_CZ'),
    da: () => import('@fibrous/semi-foundation/locale/source/da'),
    de: () => import('@fibrous/semi-foundation/locale/source/de'),
    el_GR: () => import('@fibrous/semi-foundation/locale/source/el_GR'),
    en_GB: () => import('@fibrous/semi-foundation/locale/source/en_GB'),
    en_US: () => import('@fibrous/semi-foundation/locale/source/en_US'),
    es: () => import('@fibrous/semi-foundation/locale/source/es'),
    es_419: () => import('@fibrous/semi-foundation/locale/source/es_419'),
    et: () => import('@fibrous/semi-foundation/locale/source/et'),
    fa_IR: () => import('@fibrous/semi-foundation/locale/source/fa_IR'),
    fi_FI: () => import('@fibrous/semi-foundation/locale/source/fi_FI'),
    fil_PH: () => import('@fibrous/semi-foundation/locale/source/fil_PH'),
    fr: () => import('@fibrous/semi-foundation/locale/source/fr'),
    fr_CA: () => import('@fibrous/semi-foundation/locale/source/fr_CA'),
    ga: () => import('@fibrous/semi-foundation/locale/source/ga'),
    he_IL: () => import('@fibrous/semi-foundation/locale/source/he_IL'),
    hi_IN: () => import('@fibrous/semi-foundation/locale/source/hi_IN'),
    hr: () => import('@fibrous/semi-foundation/locale/source/hr'),
    hu_HU: () => import('@fibrous/semi-foundation/locale/source/hu_HU'),
    id_ID: () => import('@fibrous/semi-foundation/locale/source/id_ID'),
    is: () => import('@fibrous/semi-foundation/locale/source/is'),
    it: () => import('@fibrous/semi-foundation/locale/source/it'),
    ja_JP: () => import('@fibrous/semi-foundation/locale/source/ja_JP'),
    jv_ID: () => import('@fibrous/semi-foundation/locale/source/jv_ID'),
    kk: () => import('@fibrous/semi-foundation/locale/source/kk'),
    km_KH: () => import('@fibrous/semi-foundation/locale/source/km_KH'),
    ko_KR: () => import('@fibrous/semi-foundation/locale/source/ko_KR'),
    lt: () => import('@fibrous/semi-foundation/locale/source/lt'),
    lv: () => import('@fibrous/semi-foundation/locale/source/lv'),
    ms_MY: () => import('@fibrous/semi-foundation/locale/source/ms_MY'),
    my_MM: () => import('@fibrous/semi-foundation/locale/source/my_MM'),
    nb: () => import('@fibrous/semi-foundation/locale/source/nb'),
    nl_NL: () => import('@fibrous/semi-foundation/locale/source/nl_NL'),
    pl_PL: () => import('@fibrous/semi-foundation/locale/source/pl_PL'),
    pt: () => import('@fibrous/semi-foundation/locale/source/pt'),
    pt_BR: () => import('@fibrous/semi-foundation/locale/source/pt_BR'),
    ro: () => import('@fibrous/semi-foundation/locale/source/ro'),
    ru_RU: () => import('@fibrous/semi-foundation/locale/source/ru_RU'),
    sk: () => import('@fibrous/semi-foundation/locale/source/sk'),
    sl: () => import('@fibrous/semi-foundation/locale/source/sl'),
    sq: () => import('@fibrous/semi-foundation/locale/source/sq'),
    sv_SE: () => import('@fibrous/semi-foundation/locale/source/sv_SE'),
    sw: () => import('@fibrous/semi-foundation/locale/source/sw'),
    th_TH: () => import('@fibrous/semi-foundation/locale/source/th_TH'),
    tr_TR: () => import('@fibrous/semi-foundation/locale/source/tr_TR'),
    uk_UA: () => import('@fibrous/semi-foundation/locale/source/uk_UA'),
    ur: () => import('@fibrous/semi-foundation/locale/source/ur'),
    uz: () => import('@fibrous/semi-foundation/locale/source/uz'),
    vi_VN: () => import('@fibrous/semi-foundation/locale/source/vi_VN'),
    zh_TW: () => import('@fibrous/semi-foundation/locale/source/zh_TW'),
};
type LocaleCode = 'zh_CN' | keyof typeof loaders;

const treeData = [
    {
        label: 'Asia',
        value: 'asia',
        key: '1',
        children: [
            {
                label: 'China',
                value: 'china',
                key: '1-0',
                children: [
                    { label: 'Beijing', value: 'beijing', key: '1-0-0' },
                    { label: 'Shanghai', value: 'shanghai', key: '1-0-1' },
                ],
            },
            {
                label: 'Japan',
                value: 'japan',
                key: '1-1',
                children: [{ label: 'Osaka', value: 'osaka', key: '1-1-0' }],
            },
        ],
    },
];
const I18nComponent = () => {
    const [modalVisible, setModalVisible] = useState(false);
    const columns = useMemo(
        () => [
            {
                title: 'Name',
                width: 250,
                dataIndex: 'name',
            },
            {
                title: 'Age',
                width: 150,
                dataIndex: 'age',
            },
            {
                title: 'Address',
                dataIndex: 'address',
            },
        ],
        []
    );
    const dataSource = useMemo(() => {
        const data = [];
        for (let i = 0; i < 46; i++) {
            data.push({
                key: '' + i,
                name: `Bytedance ${i}`,
                age: 32,
                address: `Beijing, Haidian. Zhichun Road ${i}`,
            });
        }
        return data;
    }, []);
    const transferData = useMemo(() => {
        return Array.from({ length: 100 }, (_v, i) => {
            return {
                label: `选项名称 ${i}`,
                value: i,
                disabled: false,
                key: i,
            };
        });
    }, []);
    const srcList = useMemo(() => ['/assets/root-web-sites/abstract.jpg', '/assets/root-web-sites/sky.jpg', '/assets/root-web-sites/greenleaf.jpg', '/assets/root-web-sites/colorful.jpg'], []);
    const style = { margin: 10 };
    return (
        <>
            <h5>Pagination</h5>
            <Pagination total={100} showTotal showSizeChanger style={style} showQuickJumper />
            <h5>Modal</h5>

            <div style={style}>
                <Button onClick={() => setModalVisible(true)}>Show Modal</Button>
                <Modal title="Modal" visible={modalVisible} onOk={() => setModalVisible(false)} onCancel={() => setModalVisible(false)}>
                    <p>This is the content of a basic modal.</p>
                    <p>More content...</p>
                </Modal>
            </div>
            <h5>Select & Cascader</h5>
            <div style={style}>
                <Select aria-label="Select" filter style={{ width: '180px' }}>
                    <Select.Option value="abc">abc</Select.Option>
                    <Select.Option value="vigo" disabled>
                        vigo
                    </Select.Option>
                    <Select.Option value="hotsoon">hotsoon</Select.Option>
                </Select>
                <Cascader style={{ width: 300, margin: 10 }} treeData={treeData} filterTreeNode prefix="Cascader" />
            </div>
            <h5>DatePicker</h5>
            <DatePicker style={{ ...style, width: 250 }} />
            <DatePicker style={{ ...style, width: 300 }} type="dateTime" />
            <DatePicker style={{ ...style, width: 300 }} type="dateRange" />
            <DatePicker style={{ ...style, width: 450 }} type="dateTimeRange" />
            <h5>TimePicker</h5>
            <TimePicker style={style} />
            <TimePicker use12Hours style={style} />
            <br />
            <br />
            <h5>TreeSelect</h5>
            <TreeSelect style={{ ...style, width: 300 }} dropdownStyle={{ maxHeight: 400, overflow: 'auto' }} treeData={treeData} filterTreeNode />
            <h5>Table</h5>
            <Table columns={columns} dataSource={dataSource} scroll={{ y: 320 }} />
            <h5>Table - Empty</h5>
            <Table columns={columns} dataSource={[]} scroll={{ y: 320 }} />
            <h5>List - Empty</h5>
            <List header={<div>List</div>} dataSource={[]} />
            <h5>Calendar</h5>
            <Calendar mode="month" displayValue={new Date(2019, 6, 23)} />
            <h5>Typography - Copyable</h5>
            <Typography.Paragraph copyable>Click to copy text.</Typography.Paragraph>
            <h5>Typography - Collapsible</h5>
            <Typography.Paragraph ellipsis={{ rows: 3, expandable: true, collapsible: true }} style={{ width: 300 }}>
                支持展开和折叠:Semi Design 是由抖音前端团队与 UED 团队共同设计开发并维护的设计系统。设计系统包含设计语言以及一整套可复用的前端组件,帮助设计师与开发者更容易地打造高质量的、用户体验一致的、符合设计规范的 Web 应用。
            </Typography.Paragraph>
            <h5>Transfer</h5>
            <Transfer style={{ width: 568, height: 416 }} dataSource={transferData} />
            <h5>Image</h5>
            <ImagePreview showTooltip>
                {srcList.map((src, index) => {
                    return <Image key={index} src={src} width={200} alt={`lamp${index + 1}`} style={{ marginRight: 5 }} />;
                })}
            </ImagePreview>
            <h5>Form</h5>
            <Form layout="horizontal" onValueChange={(values) => console.log(values)}>
                <Form.Input field="UserName" label={{ text: '角色', optional: true }} style={{ width: 200 }} />
            </Form>
            <h5>Navigation</h5>
            <Nav
                bodyStyle={{ height: 320 }}
                items={[
                    { itemKey: 'user', text: '用户管理', icon: <IconUser /> },
                    { itemKey: 'union', text: '活动管理', icon: <IconStar /> },
                ]}
                header={{
                    logo: <IconSemiLogo style={{ height: '36px', fontSize: 36 }} />,
                    text: 'Semi 数据后台',
                }}
                footer={{
                    collapseButton: true,
                }}
            />
        </>
    );
};

export default function LocaleDemo() {
    const [current, setCurrent] = useState({ code: 'zh_CN', locale: zh_CN });
    const latest = useRef('zh_CN');

    const onLanguageChange = useCallback(async (value = 'zh_CN') => {
        const code = value as LocaleCode;
        latest.current = code;
        const locale = code === 'zh_CN' ? zh_CN : (await loaders[code]()).default;
        // A pick made while this pack was loading wins
        if (latest.current === code) {
            setCurrent({ code, locale });
        }
    }, []);

    return (
        <>
            <div style={{ borderBottom: '1px solid var(--semi-color-border)', paddingBottom: 20 }}>
                <Select aria-label="切换语言" onChange={onLanguageChange} prefix="切换语言" style={{ width: 250 }} defaultValue="zh_CN">
                    <Select.Option value="zh_CN">简体中文</Select.Option>
                    <Select.Option value="en_US">英语(美)</Select.Option>
                    <Select.Option value="en_GB">英语(英)</Select.Option>
                    <Select.Option value="ja_JP">日语</Select.Option>
                    <Select.Option value="ko_KR">韩语</Select.Option>
                    <Select.Option value="ar">阿拉伯语</Select.Option>
                    <Select.Option value="vi_VN">越南语</Select.Option>
                    <Select.Option value="ru_RU">俄罗斯语</Select.Option>
                    <Select.Option value="id_ID">印尼语</Select.Option>
                    <Select.Option value="ms_MY">马来语</Select.Option>
                    <Select.Option value="th_TH">泰语</Select.Option>
                    <Select.Option value="tr_TR">土耳其语</Select.Option>
                    <Select.Option value="pt_BR">葡萄牙语(巴西)</Select.Option>
                    <Select.Option value="zh_TW">繁体中文</Select.Option>
                    <Select.Option value="es">西班牙语</Select.Option>
                    <Select.Option value="de">德语</Select.Option>
                    <Select.Option value="it">意大利语</Select.Option>
                    <Select.Option value="fr">法语</Select.Option>
                    <Select.Option value="ro">罗马尼亚语</Select.Option>
                    <Select.Option value="sv_SE">瑞典语</Select.Option>
                    <Select.Option value="pl_PL">波兰语</Select.Option>
                    <Select.Option value="nl_NL">荷兰语</Select.Option>
                    <Select.Option value="az">阿塞拜疆语</Select.Option>
                    <Select.Option value="bn_IN">孟加拉语</Select.Option>
                    <Select.Option value="bg">保加利亚语</Select.Option>
                    <Select.Option value="ca">加泰罗尼亚语</Select.Option>
                    <Select.Option value="cs_CZ">捷克语</Select.Option>
                    <Select.Option value="ceb_PH">宿务语</Select.Option>
                    <Select.Option value="da">丹麦语</Select.Option>
                    <Select.Option value="el_GR">希腊语</Select.Option>
                    <Select.Option value="es_419">西班牙语(拉美)</Select.Option>
                    <Select.Option value="et">爱沙尼亚语</Select.Option>
                    <Select.Option value="fa_IR">波斯语</Select.Option>
                    <Select.Option value="fil_PH">菲律宾语</Select.Option>
                    <Select.Option value="fi_FI">芬兰语</Select.Option>
                    <Select.Option value="fr_CA">法语(加)</Select.Option>
                    <Select.Option value="ga">爱尔兰语</Select.Option>
                    <Select.Option value="he_IL">希伯来语</Select.Option>
                    <Select.Option value="hi_IN">印地语</Select.Option>
                    <Select.Option value="hr">克罗地亚语</Select.Option>
                    <Select.Option value="hu_HU">匈牙利语</Select.Option>
                    <Select.Option value="is">冰岛语</Select.Option>
                    <Select.Option value="jv_ID">爪哇语</Select.Option>
                    <Select.Option value="kk">哈萨克语</Select.Option>
                    <Select.Option value="km_KH">高棉语</Select.Option>
                    <Select.Option value="lt">立陶宛语</Select.Option>
                    <Select.Option value="lv">拉脱维亚语</Select.Option>
                    <Select.Option value="my_MM">缅甸语</Select.Option>
                    <Select.Option value="nb">挪威语</Select.Option>
                    <Select.Option value="pt">葡萄牙语</Select.Option>
                    <Select.Option value="sk">斯洛伐克语</Select.Option>
                    <Select.Option value="sl">斯洛文尼亚语</Select.Option>
                    <Select.Option value="sq">阿尔巴尼亚语</Select.Option>
                    <Select.Option value="sw">斯瓦希里语</Select.Option>
                    <Select.Option value="uk_UA">乌克兰语</Select.Option>
                    <Select.Option value="ur">乌尔都语</Select.Option>
                    <Select.Option value="uz">乌兹别克语</Select.Option>
                </Select>
            </div>
            <LocaleProvider locale={current.locale}>
                <ConfigProvider direction={current.code === 'ar' ? 'rtl' : 'ltr'} locale={current.locale}>
                    <I18nComponent key={current.code} />
                </ConfigProvider>
            </LocaleProvider>
        </>
    );
}