{"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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"}