@yamada-ui/react
Version:
React UI components of the Yamada, by the Yamada, for the Yamada built with React and Emotion
1 lines • 9.15 kB
Source Map (JSON)
{"version":3,"file":"i18n-provider.cjs","names":["DEFAULT_LANGUAGE: Language","DEFAULT_DIRECTION","DEFAULT_LOCALE","INTL","I18nProvider: FC<I18nProviderProps>","locale","value","key","IntlMessageFormat"],"sources":["../../../../src/providers/i18n-provider/i18n-provider.tsx"],"sourcesContent":["\"use client\"\n\nimport type { Formats, Options } from \"intl-messageformat\"\nimport type { FC, ReactNode } from \"react\"\nimport type { TextDirection } from \"../../core\"\nimport type { AnyString, Dict, Path, Value } from \"../../utils\"\nimport type { IcuArgs } from \"./icu.types\"\nimport type { DefaultIntlData } from \"./intl\"\nimport IntlMessageFormat from \"intl-messageformat\"\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from \"react\"\nimport { DEFAULT_DIRECTION, DEFAULT_LOCALE } from \"../../core\"\nimport {\n createdDom,\n getMemoizedObject as get,\n isEmptyObject,\n isRtl,\n isString,\n isUndefined,\n noop,\n useUpdateEffect,\n} from \"../../utils\"\nimport INTL from \"./intl\"\n\nexport interface Language {\n dir: TextDirection\n locale: string\n}\n\nconst DEFAULT_LANGUAGE: Language = {\n dir: DEFAULT_DIRECTION,\n locale: DEFAULT_LOCALE,\n}\n\nexport const LOCALES = Object.keys(INTL) as readonly Locale[]\n\nexport function getLanguage(locale?: string, dir?: TextDirection): Language {\n locale ??= createdDom() ? navigator.language : DEFAULT_LOCALE\n\n try {\n Intl.DateTimeFormat.supportedLocalesOf([locale])\n } catch (_err) {\n locale = DEFAULT_LOCALE\n }\n\n dir ??= isRtl(locale) ? \"rtl\" : \"ltr\"\n\n return { dir, locale }\n}\n\ntype IntlData = DefaultIntlData\ntype IntlKey = keyof IntlData\ntype IntlPath = Path<IntlData>\n\nexport type Locale = keyof typeof INTL\n\ntype Translation<Y extends object = IntlData, M extends string = IntlPath> = <\n D extends M,\n>(\n path: D,\n ...args: IcuArgs<Value<Y, D>> extends never\n ? [replaceValues?: IcuArgs<Value<Y, D>, IntlPath | M>]\n : [replaceValues: IcuArgs<Value<Y, D>, IntlPath | M>]\n) => string\n\ninterface I18nContext<Y extends object = IntlData, M extends string = IntlPath>\n extends Language {\n changeLanguage: (locale?: string, dir?: TextDirection) => void\n getTranslation: (key?: IntlKey) => Translation<Y, M>\n t: Translation<Y, M>\n}\n\nexport const I18nContext = createContext<I18nContext>({\n ...DEFAULT_LANGUAGE,\n changeLanguage: noop,\n getTranslation: () => () => \"\",\n t: () => \"\",\n})\n\nexport interface I18nProviderProps {\n children?: ReactNode\n /**\n * The text direction to apply to the application.\n *\n * If not provided, the direction will be determined by the locale.\n */\n dir?: TextDirection\n /**\n * The formats to pass to the `intlMessageFormat` instance.\n */\n formats?: Formats\n /**\n * The internationalization messages to apply to the application.\n *\n * This prop expects a dictionary object where the keys are locale strings (e.g., \"en-US\").\n */\n intl?: Dict\n /**\n * The options to pass to the `intlMessageFormat` instance.\n */\n intlMessageFormatOptions?: Options\n /**\n * The locale to apply to the application.\n *\n * If not provided, the locale will be determined by the browser.\n */\n locale?: AnyString | Locale\n}\n\nexport const I18nProvider: FC<I18nProviderProps> = ({\n children,\n dir: forcedDir,\n formats,\n intl = INTL as Dict,\n intlMessageFormatOptions,\n locale: forcedLocale,\n}) => {\n const [language, setLanguage] = useState(getLanguage(forcedLocale, forcedDir))\n const controlled = !isUndefined(forcedLocale)\n const { locale } = language\n\n const messages = useMemo(() => intl[locale], [intl, locale])\n\n const changeSystemLanguage = useCallback(() => {\n setLanguage(getLanguage())\n }, [])\n\n const changeLanguage = useCallback((locale?: string, dir?: TextDirection) => {\n setLanguage(getLanguage(locale, dir))\n }, [])\n\n const getValue = useCallback(\n (path: number | string) => {\n const value = get<string | undefined>(messages, path)\n\n if (!isUndefined(value)) {\n return value\n } else {\n path = path.toString().replace(/^[^.]+\\./g, \"\")\n\n return get<string | undefined>(messages, path)\n }\n },\n [messages],\n )\n\n const getTranslation = useCallback(\n (key?: IntlKey) =>\n <Y extends IntlPath>(\n path: Y,\n replaceValues?: IcuArgs<Value<IntlData, Y>, IntlPath>,\n ) => {\n const value = getValue(key ? `${key}.${path}` : path) ?? path\n\n if (isUndefined(replaceValues)) return value\n\n try {\n const resolvedReplaceValues = Object.entries(replaceValues).reduce<{\n [key: string]: any\n }>((prev, [key, pathOrValue]) => {\n if (isString(pathOrValue)) {\n const resolvedPathOrValue = String(pathOrValue)\n const value =\n getValue(\n key ? `${key}.${resolvedPathOrValue}` : resolvedPathOrValue,\n ) ?? resolvedPathOrValue\n\n prev[key] = value\n } else {\n prev[key] = pathOrValue\n }\n\n return prev\n }, {})\n\n const message = new IntlMessageFormat(\n value,\n locale,\n formats,\n intlMessageFormatOptions,\n )\n\n return message.format(resolvedReplaceValues) as string\n } catch (e) {\n if (e instanceof Error) console.warn(e.message)\n\n return value\n }\n },\n [getValue, locale, formats, intlMessageFormatOptions],\n )\n\n const value = useMemo(() => {\n const rest = { changeLanguage, getTranslation, t: getTranslation() }\n\n return { ...language, ...rest }\n }, [changeLanguage, getTranslation, language])\n\n useEffect(() => {\n if (controlled) return\n\n window.addEventListener(\"languagechange\", changeSystemLanguage)\n\n return () => {\n window.removeEventListener(\"languagechange\", changeSystemLanguage)\n }\n }, [controlled, changeSystemLanguage])\n\n useUpdateEffect(() => {\n setLanguage(getLanguage(forcedLocale, forcedDir))\n }, [forcedLocale, forcedDir])\n\n return <I18nContext value={value}>{children}</I18nContext>\n}\n\nexport function useI18n(): I18nContext\n\nexport function useI18n<Y extends IntlKey>(\n key: Y,\n): I18nContext<IntlData[Y], Path<IntlData[Y]>>\n\nexport function useI18n<Y extends IntlKey>(key?: Y) {\n const context = useContext(I18nContext)\n\n const translation = useCallback(\n <M extends Path<IntlData[Y]>>(\n path: M,\n replaceValues?: IcuArgs<\n Value<IntlData[Y], M>,\n IntlPath | Path<IntlData[Y]>\n >,\n ) => context.getTranslation(key)(path as any, replaceValues as any),\n [key, context],\n )\n\n if (isEmptyObject(context))\n return {\n ...DEFAULT_LANGUAGE,\n changeLanguage: noop,\n t: () => \"\",\n }\n\n if (key) {\n return { ...context, t: translation }\n } else {\n return context\n }\n}\n"],"mappings":"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"}