chore(history): import initial web product snapshot
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
import { createContext, useContext, useEffect, useMemo, useState, type ReactNode } from 'react'
|
||||
import { UI_LOCALES, type UiLocale } from '@/config/languages'
|
||||
import { zh, type LocaleDict } from './locales/zh'
|
||||
import { en } from './locales/en'
|
||||
import { ar } from './locales/ar'
|
||||
|
||||
const DICTS: Record<UiLocale, LocaleDict> = { zh, en, ar }
|
||||
|
||||
interface I18nContextValue {
|
||||
locale: UiLocale
|
||||
dir: 'ltr' | 'rtl'
|
||||
setLocale: (l: UiLocale) => void
|
||||
t: (key: keyof LocaleDict) => string
|
||||
}
|
||||
|
||||
const I18nContext = createContext<I18nContextValue | null>(null)
|
||||
|
||||
const STORAGE_KEY = 'lx-locale'
|
||||
|
||||
export function I18nProvider({ children }: { children: ReactNode }) {
|
||||
const [locale, setLocaleState] = useState<UiLocale>(() => {
|
||||
const saved = localStorage.getItem(STORAGE_KEY)
|
||||
return (saved === 'en' || saved === 'ar' || saved === 'zh' ? saved : 'zh') as UiLocale
|
||||
})
|
||||
|
||||
const dir: 'ltr' | 'rtl' = UI_LOCALES.find((l) => l.code === locale)?.rtl ? 'rtl' : 'ltr'
|
||||
|
||||
useEffect(() => {
|
||||
document.documentElement.lang = locale === 'zh' ? 'zh-CN' : locale
|
||||
document.documentElement.dir = dir
|
||||
localStorage.setItem(STORAGE_KEY, locale)
|
||||
}, [locale, dir])
|
||||
|
||||
const value = useMemo<I18nContextValue>(
|
||||
() => ({
|
||||
locale,
|
||||
dir,
|
||||
setLocale: setLocaleState,
|
||||
t: (key) => DICTS[locale][key] ?? zh[key] ?? String(key),
|
||||
}),
|
||||
[locale, dir],
|
||||
)
|
||||
|
||||
return <I18nContext.Provider value={value}>{children}</I18nContext.Provider>
|
||||
}
|
||||
|
||||
export function useI18n(): I18nContextValue {
|
||||
const ctx = useContext(I18nContext)
|
||||
if (!ctx) throw new Error('useI18n must be used within I18nProvider')
|
||||
return ctx
|
||||
}
|
||||
Reference in New Issue
Block a user