UNPKG

sanity

Version:

Sanity is a real-time content infrastructure with a scalable, hosted backend featuring a Graph Oriented Query Language (GROQ), asset pipelines and fast edge caches

70 lines (61 loc) 2.55 kB
import {useMemo} from 'react' import {useTranslation} from './useTranslation' /** * Enforces the shape of an object allowed to be passed into `useI18nText`. * @internal */ export type I18nNode<TNode extends {i18n?: {[TProp in string]: {key: string; ns: string}}}> = { i18n?: {[K in keyof TNode['i18n']]: {key: string; ns: string}} } & { [K in keyof TNode['i18n']]: string } /** * A React hook for localizing strings in a given object (`node`) using the * `useTranslation` hook. * * This hook expects an object (`node`) with top-level keys associated with * string values. If an `i18n` property is present within the object, it should * contain localization configurations for each top-level key. Each * configuration must include a `key` and `ns` (namespace) used for the * translation of the corresponding string value. * * The hook uses a proxy to intercept access to properties of the `node`. For * properties defined in the `i18n` object, it returns the translated string * using the `t` function. If no translation is found, the original string value * is used as a fallback. For properties not defined in the `i18n` object, their * original values are returned. * * @param node - The object containing strings to be localized along with * optional i18n configurations. * @returns A proxy of the original `node` object where each property access * returns localized strings. * @internal */ export function useI18nText<TNode extends I18nNode<TNode>>(node: TNode): TNode { const namespaces = useMemo(() => { if (!node.i18n) return [] return Array.from(new Set(Object.values(node.i18n).map(({ns}) => ns))).sort() }, [node.i18n]) const {t} = useTranslation(namespaces) return useMemo(() => { const {i18n} = node if (!i18n) return node return new Proxy(node, { get: (target, property) => { const defaultValue = target[property as keyof TNode] if (typeof property === 'string' && property in i18n) { const {key, ns} = i18n[property as keyof TNode['i18n']] return t(key, { ns, // `defaultValue` is a special key in the i18next `t` API that // allows us to provide a fallback value if no translation is found // using the given key and namespace. if the value on the node // is a string, then we'll use that as the fallback value ...(typeof defaultValue === 'string' && {defaultValue}), }) } return defaultValue }, }) }, [node, t]) }