UNPKG

react-intlayer

Version:

Easily internationalize i18n your React applications with type-safe multilingual content management.

1 lines 3.15 kB
{"version":3,"sources":["../../../src/client/useI18n.ts"],"sourcesContent":["'use client';\n\nimport type { LocalesValues } from '@intlayer/config/client';\nimport type {\n DictionaryKeys,\n GetSubPath,\n ValidDotPathsFor,\n} from '@intlayer/core';\nimport type { DeepTransformContent } from '../plugins';\n// @ts-ignore intlayer declared for module augmentation\nimport { getIntlayer, type IntlayerDictionaryTypesConnector } from 'intlayer';\nimport { useContext, useMemo } from 'react';\nimport { IntlayerClientContext } from './IntlayerProvider';\n\n/**\n * Hook that provides a translation function `t()` for accessing nested content by key.\n * This hook mimics the pattern found in libraries like i18next, next-intl, and vue-i18n.\n *\n * @param namespace - The dictionary key to scope translations to\n * @param locale - Optional locale override. If not provided, uses the current context locale\n * @returns A translation function `t(key)` that returns the translated content for the given key\n *\n * @example\n * ```tsx\n * const t = useI18n('IndexPage');\n * const title = t('title'); // Returns translated string for 'IndexPage.title'\n * const nestedContent = t('section.subtitle'); // Returns 'IndexPage.section.subtitle'\n * // For attributes like `aria-label`, use `.value` to get the plain string\n * const ariaLabel = t('button.ariaLabel').value; // 'Close modal'\n * ```\n */\nexport const useI18n = <T extends DictionaryKeys>(\n namespace: T,\n locale?: LocalesValues\n) => {\n const { locale: currentLocale } = useContext(IntlayerClientContext);\n const localeTarget = useMemo(\n () => locale ?? currentLocale,\n [currentLocale, locale]\n );\n\n // Get the dictionary content for the namespace\n let dictionaryContent: DeepTransformContent<\n IntlayerDictionaryTypesConnector[T]['content']\n > = useMemo(\n () => getIntlayer(namespace, localeTarget),\n [namespace, localeTarget]\n );\n\n // Return the translation function\n const t = <P extends ValidDotPathsFor<T>>(\n path: P\n ): GetSubPath<\n DeepTransformContent<IntlayerDictionaryTypesConnector[T]['content']>,\n P\n > => {\n if (!path) {\n return dictionaryContent as any;\n }\n\n const pathArray = (path as string).split('.');\n let current: any = dictionaryContent;\n\n for (const key of pathArray) {\n current = current?.[key];\n if (current === undefined) {\n // Return the whole dictionary as fallback if path is not found\n return dictionaryContent as any;\n }\n }\n\n return current;\n };\n\n return t;\n};\n"],"mappings":";AAUA,SAAS,mBAA0D;AACnE,SAAS,YAAY,eAAe;AACpC,SAAS,6BAA6B;AAmB/B,MAAM,UAAU,CACrB,WACA,WACG;AACH,QAAM,EAAE,QAAQ,cAAc,IAAI,WAAW,qBAAqB;AAClE,QAAM,eAAe;AAAA,IACnB,MAAM,UAAU;AAAA,IAChB,CAAC,eAAe,MAAM;AAAA,EACxB;AAGA,MAAI,oBAEA;AAAA,IACF,MAAM,YAAY,WAAW,YAAY;AAAA,IACzC,CAAC,WAAW,YAAY;AAAA,EAC1B;AAGA,QAAM,IAAI,CACR,SAIG;AACH,QAAI,CAAC,MAAM;AACT,aAAO;AAAA,IACT;AAEA,UAAM,YAAa,KAAgB,MAAM,GAAG;AAC5C,QAAI,UAAe;AAEnB,eAAW,OAAO,WAAW;AAC3B,gBAAU,UAAU,GAAG;AACvB,UAAI,YAAY,QAAW;AAEzB,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;","names":[]}