3.4 KiB
useLocaleAdapter
(no submodules)
Purpose
useLocaleAdapter<TLocale>(id) resolves a registered LocaleAdapterPlugin<TLocale> against the active locale and returns its library-specific output. The canonical use case is react-day-picker's <Calendar>, which wants a date-fns Locale object — the component calls useLocaleAdapter<Locale>("date-fns") and the consumer registers an adapter that maps the active BCP-47 locale to the corresponding date-fns reference. The package stays library-agnostic; the consumer wires the date / time library they already use.
Features
- Strict resolution — throws
REACT_I18N.LOCALE_ADAPTER_NOT_REGISTEREDfor an unknown id. - Memoized on
(registry, id, locale)so a no-op re-render does not re-invokeplugin.resolve. - Built-in
"intl"identity adapter is auto-registered by<RegistryProvider>so any consumer that just needs the locale string back gets it without registering a plugin.
Usage: Basic Example
import { useLocaleAdapter } from "@suaveplan/react-i18n";
function HtmlLang(): JSX.Element {
const lang = useLocaleAdapter<string>("intl");
return <meta name="content-language" content={lang} />;
}
Usage: Advanced Example
A <Calendar> component asks for the date-fns adapter:
import { useLocaleAdapter } from "@suaveplan/react-i18n";
import { DayPicker } from "react-day-picker";
import type { Locale as DateFnsLocale } from "date-fns";
function Calendar(props: CalendarProps): JSX.Element {
const dateFnsLocale = useLocaleAdapter<DateFnsLocale>("date-fns");
return <DayPicker {...props} locale={dateFnsLocale} />;
}
The consumer wires the adapter once in <RegistryProvider>:
import { createDateFnsLocaleAdapter, RegistryProvider } from "@suaveplan/react-i18n";
import { enGB, frFR, zhCN } from "date-fns/locale";
const dateFnsAdapter = createDateFnsLocaleAdapter({
locales: { enGB, frFR, zhCN },
});
<RegistryProvider plugins={[{ kind: "locale-adapter", plugin: dateFnsAdapter }]}>
{/* … Calendar resolves "date-fns" to the active locale's Locale object */}
</RegistryProvider>;
Without registering the adapter, <Calendar> throws REACT_I18N.LOCALE_ADAPTER_NOT_REGISTERED on first render. This is intentional — silent fallback to a hardcoded English locale would be surprising in an RTL locale.
API Reference
useLocaleAdapter<TLocale>(id: string): TLocale
id: the registered plugin's id. The built-in"intl"is auto-registered; other ids ("date-fns","luxon","temporal") are consumer-registered.
Throws ReactI18nError(REACT_I18N.LOCALE_ADAPTER_NOT_REGISTERED) for an unknown id, REACT_I18N.REGISTRY_NOT_PROVIDED outside a <RegistryProvider>.
Implementation Notes
- The hook is memoized on
(registry, id, resolvedLocale). Adapter implementations must be pure — callingresolve(locale)twice with the same locale must return referentially-equal output for the memo to be useful. - Adapters typically hold their locale map at construction time (see
createDateFnsLocaleAdapter); this means the adapter object identity is stable across renders, which keeps the memoization key stable. - A consumer registering multiple adapters under different ids (e.g.
"date-fns"AND"luxon") gets two independent resolution paths. Components decide which library they need by passing the matching id.