Press n or j to go to the next uncovered block, b, p or k for the previous block.
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 | 1x 1x 1x 1x 10x 10x 10x 10x 10x 10x 2x 7x 7x 7x 8x 10x 10x 10x 10x 10x 10x 10x 1x 13x 13x 2x 2x 11x 11x 1x 1x 1x | import { type I18n, type LocaleLang, type TFunction, type TFunctionArgs } from "@embra/i18n"; import { useValue } from "@embra/reactivity/react"; import { type FC, type PropsWithChildren, createContext, createElement, useContext, useMemo } from "react"; interface Ctx { t: TFunction; i18n: I18n; } const I18nContext = /* @__PURE__ */ createContext<Ctx | null>(null); export interface I18nProviderProps { i18n: I18n; } /** * Provides the I18n instance to the rest of the app. * * @example * ```tsx * <I18nProvider i18n={i18n}> * <App /> * </I18nProvider> */ export const I18nProvider: FC<PropsWithChildren<I18nProviderProps>> = ({ i18n, children }) => { const currentT = useValue(i18n.t$); const depT = useContext(I18nContext)?.t; return createElement(I18nContext.Provider, { value: useMemo( () => ({ t: depT ? (keyPath: string, args?: TFunctionArgs): string => { const result = currentT(keyPath, args); return result === keyPath ? depT(keyPath, args) : result; } : currentT, i18n, }), [currentT, depT], ), children, }); }; interface UseI18nCtx { (): Ctx; (optional?: false): Ctx; (optional?: boolean): Ctx | null; } const useI18nCtx: UseI18nCtx = (optional => { const ctx = useContext(I18nContext); if (!ctx && !optional) { throw new Error("I18nProvider not found"); } return ctx; }) as UseI18nCtx; export interface UseTranslate { (): TFunction; (optional?: false): TFunction; (optional?: boolean): TFunction | undefined; } /** * @returns A {@link TFunction} that translates the key from the nearest {@link I18nProvider} and fallbacks outwards. * If no {@link I18nProvider} found, throws an error unless `optional` is true. */ export const useTranslate: UseTranslate = (optional => useI18nCtx(optional)?.t) as UseTranslate; export interface UseI18n { (): I18n; (optional?: false): I18n; (optional?: boolean): I18n | undefined; } /** * @returns The {@link I18n} instance from the nearest {@link I18nProvider}. * If no {@link I18nProvider} found, throws an error unless `optional` is true. */ export const useI18n: UseI18n = (optional => useI18nCtx(optional)?.i18n) as UseI18n; export interface UseLang { (): LocaleLang; (optional?: false): LocaleLang; (optional?: boolean): LocaleLang | undefined; } /** * @returns The {@link LocaleLang} from the nearest {@link I18nProvider}. * If no {@link I18nProvider} found, throws an error unless `optional` is true. */ export const useLang: UseLang = (optional => useValue(useI18n(optional)?.lang$)) as UseLang; |