@object-ui/i18n 17.6.0 → 17.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4320 -0
- package/README.md +192 -13
- package/dist/builtinAggregateLabels.d.ts +40 -0
- package/dist/builtinAggregateLabels.js +23 -0
- package/dist/currency.d.ts +27 -3
- package/dist/currency.js +28 -4
- package/dist/fallbackInterpolation.d.ts +79 -0
- package/dist/fallbackInterpolation.js +124 -0
- package/dist/i18n.d.ts +27 -1
- package/dist/i18n.js +99 -16
- package/dist/index.d.ts +7 -13
- package/dist/index.js +41 -17
- package/dist/locales/ar.d.ts +946 -113
- package/dist/locales/ar.js +1095 -161
- package/dist/locales/de.d.ts +618 -113
- package/dist/locales/de.js +715 -134
- package/dist/locales/en.d.ts +632 -127
- package/dist/locales/en.js +1044 -162
- package/dist/locales/es.d.ts +700 -113
- package/dist/locales/es.js +794 -130
- package/dist/locales/fr.d.ts +700 -113
- package/dist/locales/fr.js +795 -132
- package/dist/locales/index.d.ts +6990 -1169
- package/dist/locales/index.js +48 -9
- package/dist/locales/ja.d.ts +618 -113
- package/dist/locales/ja.js +708 -128
- package/dist/locales/ko.d.ts +618 -113
- package/dist/locales/ko.js +712 -132
- package/dist/locales/pt.d.ts +700 -113
- package/dist/locales/pt.js +794 -130
- package/dist/locales/registry.d.ts +102 -0
- package/dist/locales/registry.js +220 -0
- package/dist/locales/rtl.d.ts +24 -0
- package/dist/locales/rtl.js +26 -0
- package/dist/locales/ru.d.ts +782 -113
- package/dist/locales/ru.js +910 -152
- package/dist/locales/zh.d.ts +635 -130
- package/dist/locales/zh.js +725 -131
- package/dist/pickLocalized.d.ts +30 -0
- package/dist/pickLocalized.js +39 -0
- package/dist/provider.d.ts +101 -12
- package/dist/provider.js +335 -50
- package/dist/translateFn.d.ts +29 -0
- package/dist/translateFn.js +8 -0
- package/dist/useDisplayLocale.d.ts +11 -0
- package/dist/useDisplayLocale.js +11 -0
- package/dist/useObjectLabel.d.ts +40 -18
- package/dist/useObjectLabel.js +46 -14
- package/dist/useSafeTranslation.js +40 -42
- package/dist/utils/formatting.d.ts +16 -0
- package/dist/utils/formatting.js +23 -3
- package/dist/utils/spec-formatters.d.ts +13 -23
- package/dist/utils/spec-formatters.js +41 -2
- package/dist/utils/spec-translations.d.ts +16 -3
- package/dist/utils/spec-translations.js +52 -13
- package/package.json +12 -6
package/dist/i18n.d.ts
CHANGED
|
@@ -10,7 +10,15 @@ export interface I18nConfig {
|
|
|
10
10
|
defaultLanguage?: string;
|
|
11
11
|
/** Fallback language (default: 'en') */
|
|
12
12
|
fallbackLanguage?: string;
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* Additional translation resources, **deep-merged** over the built-in packs.
|
|
15
|
+
*
|
|
16
|
+
* The packs' top-level keys are the namespace groups (`common`, `calendar`,
|
|
17
|
+
* `list`, ...), so supplying a partial group merges into it and leaves the
|
|
18
|
+
* group's other keys in place:
|
|
19
|
+
* `{ en: { calendar: { today: 'Heute' } } }` overrides `calendar.today` only.
|
|
20
|
+
* Arrays are replaced wholesale, never concatenated (objectui#7572).
|
|
21
|
+
*/
|
|
14
22
|
resources?: Record<string, Record<string, unknown>>;
|
|
15
23
|
/** Whether to detect browser language automatically (default: true) */
|
|
16
24
|
detectBrowserLanguage?: boolean;
|
|
@@ -39,6 +47,24 @@ export interface I18nConfig {
|
|
|
39
47
|
* API — shared between `i18n.ts` and `useObjectLabel.ts` to avoid drift.
|
|
40
48
|
*/
|
|
41
49
|
export declare const I18N_PROBE_FLAG = "__ouiLabelProbe";
|
|
50
|
+
/**
|
|
51
|
+
* The language {@link createI18n} will boot in for this config — `defaultLanguage`,
|
|
52
|
+
* overridden by a browser language this renderer can produce.
|
|
53
|
+
*
|
|
54
|
+
* Exported because the answer is needed BEFORE an instance exists
|
|
55
|
+
* (objectui#7479): with the catalogues lazy, a host that wants its first render
|
|
56
|
+
* to already be in the right language has to know which catalogue to await, and
|
|
57
|
+
* the only alternative — create an instance, read `.language`, throw it away —
|
|
58
|
+
* would boot i18next in the wrong locale to find out what the right one is.
|
|
59
|
+
* `I18nProvider` and {@link preloadBootstrapLocale} answer with THIS function,
|
|
60
|
+
* so the host and the provider cannot disagree about which catalogue is active.
|
|
61
|
+
*
|
|
62
|
+
* ⚠️ Browser detection is asked of {@link isBuiltInLanguage} rather than of the
|
|
63
|
+
* merged resource map: a catalogue that has not been fetched yet is still a
|
|
64
|
+
* language this renderer can produce, and asking the map would have made
|
|
65
|
+
* detection depend on load order.
|
|
66
|
+
*/
|
|
67
|
+
export declare function pickInitialLanguage(config?: I18nConfig): string;
|
|
42
68
|
/**
|
|
43
69
|
* Create and initialize an i18next instance with Object UI defaults
|
|
44
70
|
*/
|
package/dist/i18n.js
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import i18next from 'i18next';
|
|
7
7
|
import { initReactI18next } from 'react-i18next';
|
|
8
|
-
import {
|
|
8
|
+
import { BUILT_IN_LANGUAGE_CODES, getLoadedBuiltInLocales, isBuiltInLanguage, } from './locales/registry.js';
|
|
9
|
+
import { isRTL } from './locales/rtl.js';
|
|
9
10
|
/**
|
|
10
11
|
* Internal `t()` option flag set by `useObjectLabel` on its convention-key
|
|
11
12
|
* probes. The missing-key handler skips any lookup carrying this flag, so the
|
|
@@ -37,19 +38,108 @@ function createMissingKeyHandler() {
|
|
|
37
38
|
console.warn(`[object-ui i18n] Missing translation for "${key}" (language "${lng}") — falling back to ${fb}.`);
|
|
38
39
|
};
|
|
39
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* A plain object — the only shape the resource merge recurses into. Arrays and
|
|
43
|
+
* `null` are excluded on purpose; see {@link deepMergeTranslations}.
|
|
44
|
+
*/
|
|
45
|
+
function isPlainObject(value) {
|
|
46
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Deep-merge caller-supplied translations over a built-in language pack.
|
|
50
|
+
*
|
|
51
|
+
* A language pack's top-level keys ARE the namespace groups (`common`,
|
|
52
|
+
* `calendar`, `list`, ...), each a nested object, so the one-level merge this
|
|
53
|
+
* replaced made `resources: { en: { calendar: { today: 'Heute' } } }` **replace**
|
|
54
|
+
* the whole `calendar` group: `month` / `week` / `day` / `allDay` / `newEvent` /
|
|
55
|
+
* `moreEvents` / `unscheduled` left the instance, `t('calendar.allDay')` returned
|
|
56
|
+
* the bare key, and `calendar.allDay` reached the DOM as literal text
|
|
57
|
+
* (objectui#7572). Packs nest up to four levels below the group
|
|
58
|
+
* (`console.ai.empty.build.title`), so the merge recurses rather than adding one
|
|
59
|
+
* fixed extra level.
|
|
60
|
+
*
|
|
61
|
+
* ARRAYS ARE REPLACED, NOT CONCATENATED — a deliberate choice, not a library
|
|
62
|
+
* default. Measured: no built-in pack carries an array value today (every leaf
|
|
63
|
+
* in all ten packs is a string), so nothing observable rides on this; the rule
|
|
64
|
+
* decides what a future array means. An author who writes an array is naming the
|
|
65
|
+
* whole list, so replacement is the only rule that lets them shorten or reorder
|
|
66
|
+
* one, and the only one that is idempotent when the merge runs again. This is
|
|
67
|
+
* narrower than i18next's own `deepExtend` (which the provider's async
|
|
68
|
+
* `addResourceBundle` path uses): that recurses into arrays index-wise and would
|
|
69
|
+
* leave a longer base array's tail behind — the same silent-hybrid shape this
|
|
70
|
+
* issue is about.
|
|
71
|
+
*
|
|
72
|
+
* `__proto__` is skipped. Recursive assignment, unlike the object spread it
|
|
73
|
+
* replaces, would otherwise reach the prototype setter; i18next's `deepExtend`
|
|
74
|
+
* guards the same key.
|
|
75
|
+
*/
|
|
76
|
+
function deepMergeTranslations(base, override) {
|
|
77
|
+
const merged = { ...base };
|
|
78
|
+
for (const key of Object.keys(override)) {
|
|
79
|
+
if (key === '__proto__')
|
|
80
|
+
continue;
|
|
81
|
+
const incoming = override[key];
|
|
82
|
+
const existing = merged[key];
|
|
83
|
+
merged[key] =
|
|
84
|
+
isPlainObject(existing) && isPlainObject(incoming)
|
|
85
|
+
? deepMergeTranslations(existing, incoming)
|
|
86
|
+
: incoming;
|
|
87
|
+
}
|
|
88
|
+
return merged;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The language {@link createI18n} will boot in for this config — `defaultLanguage`,
|
|
92
|
+
* overridden by a browser language this renderer can produce.
|
|
93
|
+
*
|
|
94
|
+
* Exported because the answer is needed BEFORE an instance exists
|
|
95
|
+
* (objectui#7479): with the catalogues lazy, a host that wants its first render
|
|
96
|
+
* to already be in the right language has to know which catalogue to await, and
|
|
97
|
+
* the only alternative — create an instance, read `.language`, throw it away —
|
|
98
|
+
* would boot i18next in the wrong locale to find out what the right one is.
|
|
99
|
+
* `I18nProvider` and {@link preloadBootstrapLocale} answer with THIS function,
|
|
100
|
+
* so the host and the provider cannot disagree about which catalogue is active.
|
|
101
|
+
*
|
|
102
|
+
* ⚠️ Browser detection is asked of {@link isBuiltInLanguage} rather than of the
|
|
103
|
+
* merged resource map: a catalogue that has not been fetched yet is still a
|
|
104
|
+
* language this renderer can produce, and asking the map would have made
|
|
105
|
+
* detection depend on load order.
|
|
106
|
+
*/
|
|
107
|
+
export function pickInitialLanguage(config = {}) {
|
|
108
|
+
const { defaultLanguage = 'en', resources = {}, detectBrowserLanguage = true } = config;
|
|
109
|
+
if (!detectBrowserLanguage || typeof navigator === 'undefined')
|
|
110
|
+
return defaultLanguage;
|
|
111
|
+
const browserLang = navigator.language?.split('-')[0];
|
|
112
|
+
if (!browserLang)
|
|
113
|
+
return defaultLanguage;
|
|
114
|
+
const known = isBuiltInLanguage(browserLang) ||
|
|
115
|
+
Object.prototype.hasOwnProperty.call(resources, browserLang);
|
|
116
|
+
return known ? browserLang : defaultLanguage;
|
|
117
|
+
}
|
|
40
118
|
/**
|
|
41
119
|
* Create and initialize an i18next instance with Object UI defaults
|
|
42
120
|
*/
|
|
43
121
|
export function createI18n(config = {}) {
|
|
44
|
-
const {
|
|
45
|
-
//
|
|
122
|
+
const { fallbackLanguage = 'en', resources = {}, interpolation, warnMissingKeys = isDevEnv(), } = config;
|
|
123
|
+
// `defaultLanguage` and `detectBrowserLanguage` are read by
|
|
124
|
+
// {@link pickInitialLanguage}, which owns that precedence for this function
|
|
125
|
+
// AND for the hosts that must know the answer before an instance exists.
|
|
126
|
+
// Merge the catalogues that are RESIDENT with user-provided resources.
|
|
127
|
+
//
|
|
128
|
+
// ⛔ Every built-in code gets a bundle here even when its catalogue has not
|
|
129
|
+
// been fetched yet (objectui#7479). The empty bundle is load-bearing, not a
|
|
130
|
+
// placeholder: it keeps `instance.options.resources` — which
|
|
131
|
+
// {@link getAvailableLanguages}, the browser detection below and i18next's
|
|
132
|
+
// own `hasResourceBundle` all read — enumerating every language this package
|
|
133
|
+
// can produce, instead of shrinking to whatever happened to be loaded at
|
|
134
|
+
// instance-creation time. Until the catalogue lands, `fallbackLng` renders
|
|
135
|
+
// those keys through `en`; `I18nProvider` then deep-merges the real
|
|
136
|
+
// catalogue in WITHOUT overwriting anything `resources` put there, so the
|
|
137
|
+
// precedence below survives the async arrival.
|
|
46
138
|
const mergedResources = {};
|
|
47
|
-
|
|
139
|
+
const residentCatalogues = getLoadedBuiltInLocales();
|
|
140
|
+
for (const lang of BUILT_IN_LANGUAGE_CODES) {
|
|
48
141
|
mergedResources[lang] = {
|
|
49
|
-
translation: {
|
|
50
|
-
...translations,
|
|
51
|
-
...(resources[lang] || {}),
|
|
52
|
-
},
|
|
142
|
+
translation: deepMergeTranslations((residentCatalogues[lang] ?? {}), resources[lang] || {}),
|
|
53
143
|
};
|
|
54
144
|
}
|
|
55
145
|
// Add any additional languages from resources not in built-in locales
|
|
@@ -58,14 +148,7 @@ export function createI18n(config = {}) {
|
|
|
58
148
|
mergedResources[lang] = { translation: translations };
|
|
59
149
|
}
|
|
60
150
|
}
|
|
61
|
-
|
|
62
|
-
let lng = defaultLanguage;
|
|
63
|
-
if (detectBrowserLanguage && typeof navigator !== 'undefined') {
|
|
64
|
-
const browserLang = navigator.language?.split('-')[0];
|
|
65
|
-
if (browserLang && mergedResources[browserLang]) {
|
|
66
|
-
lng = browserLang;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
151
|
+
const lng = pickInitialLanguage(config);
|
|
69
152
|
const instance = i18next.createInstance();
|
|
70
153
|
// IMPORTANT: disable react-i18next Suspense. Otherwise `useTranslation()`
|
|
71
154
|
// calls during bootstrap throw a Suspense promise (the i18n instance is
|
package/dist/index.d.ts
CHANGED
|
@@ -30,25 +30,19 @@
|
|
|
30
30
|
*
|
|
31
31
|
* @packageDocumentation
|
|
32
32
|
*/
|
|
33
|
-
export { createI18n, getDirection, getAvailableLanguages, type I18nConfig, type TranslationKeys } from './i18n.js';
|
|
34
|
-
export { I18nProvider, useObjectTranslation, useI18nContext, LOCALE_STORAGE_KEY, readStoredLanguage, LOCALE_SEED_STORAGE_KEY, readCachedLanguageSeed, cacheLanguageSeed, type I18nProviderProps, } from './provider.js';
|
|
33
|
+
export { createI18n, getDirection, getAvailableLanguages, pickInitialLanguage, type I18nConfig, type TranslationKeys, } from './i18n.js';
|
|
34
|
+
export { I18nProvider, useObjectTranslation, useI18nContext, LOCALE_STORAGE_KEY, readStoredLanguage, LOCALE_SEED_STORAGE_KEY, readCachedLanguageSeed, cacheLanguageSeed, resolveBootstrapLanguage, preloadBootstrapLocale, type BootstrapLocaleOptions, type I18nProviderProps, } from './provider.js';
|
|
35
35
|
export { createSafeTranslation, useSafeTranslate } from './useSafeTranslation.js';
|
|
36
|
+
export { builtinAggregateLabels, type SafeTranslate } from './builtinAggregateLabels.js';
|
|
37
|
+
export type { TranslateFn } from './translateFn.js';
|
|
36
38
|
export { useObjectLabel, useSafeFieldLabel } from './useObjectLabel.js';
|
|
37
|
-
export {
|
|
39
|
+
export { isRTL, RTL_LANGUAGES } from './locales/rtl.js';
|
|
40
|
+
export { BUILT_IN_LANGUAGE_CODES, DEFAULT_BUILT_IN_LANGUAGE, getLoadedBuiltInLocales, isBuiltInLanguage, isBuiltInLocaleLoaded, loadBuiltInLocale, type LocaleCatalogue, } from './locales/registry.js';
|
|
38
41
|
export { default as en } from './locales/en.js';
|
|
39
|
-
export { default as zh } from './locales/zh.js';
|
|
40
|
-
export { default as ja } from './locales/ja.js';
|
|
41
|
-
export { default as ko } from './locales/ko.js';
|
|
42
|
-
export { default as de } from './locales/de.js';
|
|
43
|
-
export { default as fr } from './locales/fr.js';
|
|
44
|
-
export { default as es } from './locales/es.js';
|
|
45
|
-
export { default as pt } from './locales/pt.js';
|
|
46
|
-
export { default as ru } from './locales/ru.js';
|
|
47
|
-
export { default as ar } from './locales/ar.js';
|
|
48
42
|
export { formatDate, formatDateTime, formatRelativeTime, formatCurrency, formatNumber, type DateFormatOptions, type CurrencyFormatOptions, type NumberFormatOptions, } from './utils/index.js';
|
|
49
43
|
export { resolvePlural, formatDateSpec, formatNumberSpec, applyLocaleConfig, type SpecPluralRule, type SpecDateFormat, type SpecNumberFormat, type SpecLocaleConfig, } from './utils/index.js';
|
|
50
44
|
export { isSpecTranslationData, transformSpecTranslations, type SpecTranslationData, } from './utils/index.js';
|
|
51
|
-
export { pickLocalized, setLocalized } from './pickLocalized.js';
|
|
45
|
+
export { pickLocalized, setLocalized, clearLocalized } from './pickLocalized.js';
|
|
52
46
|
export { LocalizationProvider, useLocalization, type LocalizationValue } from './LocalizationContext.js';
|
|
53
47
|
export { resolveFieldCurrency } from './currency.js';
|
|
54
48
|
export { useDisplayLocale } from './useDisplayLocale.js';
|
package/dist/index.js
CHANGED
|
@@ -31,33 +31,57 @@
|
|
|
31
31
|
* @packageDocumentation
|
|
32
32
|
*/
|
|
33
33
|
// Core i18n setup
|
|
34
|
-
export { createI18n, getDirection, getAvailableLanguages } from './i18n.js';
|
|
34
|
+
export { createI18n, getDirection, getAvailableLanguages, pickInitialLanguage, } from './i18n.js';
|
|
35
35
|
// React integration
|
|
36
36
|
export { I18nProvider, useObjectTranslation, useI18nContext,
|
|
37
37
|
// Language-preference persistence: the key the provider writes, and the
|
|
38
38
|
// reader apps that bring their own i18next instance need to honour it.
|
|
39
39
|
LOCALE_STORAGE_KEY, readStoredLanguage,
|
|
40
|
-
//
|
|
41
|
-
// choice above, and never a substitute for it. An app that fetches
|
|
42
|
-
//
|
|
40
|
+
// Locale seed (objectui#4035) — a SEPARATE slot from the explicit
|
|
41
|
+
// choice above, and never a substitute for it. An app that fetches the
|
|
42
|
+
// server's resolved locale for the last signed-in caller caches it here; the provider applies it at
|
|
43
43
|
// bootstrap only when the user has chosen nothing themselves.
|
|
44
|
-
LOCALE_SEED_STORAGE_KEY, readCachedLanguageSeed, cacheLanguageSeed,
|
|
44
|
+
LOCALE_SEED_STORAGE_KEY, readCachedLanguageSeed, cacheLanguageSeed,
|
|
45
|
+
// Resolve the boot language, and fetch its catalogue, BEFORE first render
|
|
46
|
+
// (objectui#7479). A host with an await before `createRoot().render()` spends
|
|
47
|
+
// it here and paints in the user's language; a host without one gets the
|
|
48
|
+
// documented `en`-while-loading render instead.
|
|
49
|
+
resolveBootstrapLanguage, preloadBootstrapLocale, } from './provider.js';
|
|
45
50
|
// Safe translation hook factory
|
|
46
51
|
export { createSafeTranslation, useSafeTranslate } from './useSafeTranslation.js';
|
|
52
|
+
// objectui#7258 — locale labels for the server's built-in default measures,
|
|
53
|
+
// handed to core's `buildChartSeries` as `builtinAggregateLabels`.
|
|
54
|
+
export { builtinAggregateLabels } from './builtinAggregateLabels.js';
|
|
47
55
|
// Convention-based object/field label i18n
|
|
48
56
|
export { useObjectLabel, useSafeFieldLabel } from './useObjectLabel.js';
|
|
49
|
-
// Locale packs
|
|
50
|
-
|
|
57
|
+
// Locale packs — ⛔ ONE catalogue is statically re-exported here, not ten
|
|
58
|
+
// (objectui#7479).
|
|
59
|
+
//
|
|
60
|
+
// This entry used to re-export all ten packs and `builtInLocales`, which made
|
|
61
|
+
// every one of them statically reachable from any import of this package. The
|
|
62
|
+
// console measured the result: ~450 KB gzipped of translation data in the EAGER
|
|
63
|
+
// closure, ten catalogues fetched before first paint for a viewer who reads
|
|
64
|
+
// one, and every new key paid for by every visitor in every language.
|
|
65
|
+
//
|
|
66
|
+
// ⛔ Do not restore a static re-export of a second catalogue here, and do not
|
|
67
|
+
// re-export `builtInLocales` from this entry. Both put all ten back:
|
|
68
|
+
// `builtInLocales` names every pack in one object literal, so nothing can shake
|
|
69
|
+
// it. `scripts/check-eager-locale-catalogues.mjs` fails the build if a
|
|
70
|
+
// non-active catalogue reappears in the console's eager closure, and
|
|
71
|
+
// `src/__tests__/entry-locale-shape-7479.test.ts` fails on the SOURCE shape so
|
|
72
|
+
// the reason is legible without a console build.
|
|
73
|
+
//
|
|
74
|
+
// What replaced them:
|
|
75
|
+
// - `en` stays — it is `fallbackLng`, the source of `TranslationKeys`, and
|
|
76
|
+
// the synchronous dictionary the app-shell splash renders from before i18n
|
|
77
|
+
// is usable. See `./locales/registry.js` for the full argument.
|
|
78
|
+
// - `loadBuiltInLocale(code)` fetches any of the ten on demand.
|
|
79
|
+
// - `BUILT_IN_LANGUAGE_CODES` enumerates them at zero payload.
|
|
80
|
+
// - `@object-ui/i18n/locales` is the explicit, published door to all ten for
|
|
81
|
+
// a caller that genuinely wants them all resident (the parity suites do).
|
|
82
|
+
export { isRTL, RTL_LANGUAGES } from './locales/rtl.js';
|
|
83
|
+
export { BUILT_IN_LANGUAGE_CODES, DEFAULT_BUILT_IN_LANGUAGE, getLoadedBuiltInLocales, isBuiltInLanguage, isBuiltInLocaleLoaded, loadBuiltInLocale, } from './locales/registry.js';
|
|
51
84
|
export { default as en } from './locales/en.js';
|
|
52
|
-
export { default as zh } from './locales/zh.js';
|
|
53
|
-
export { default as ja } from './locales/ja.js';
|
|
54
|
-
export { default as ko } from './locales/ko.js';
|
|
55
|
-
export { default as de } from './locales/de.js';
|
|
56
|
-
export { default as fr } from './locales/fr.js';
|
|
57
|
-
export { default as es } from './locales/es.js';
|
|
58
|
-
export { default as pt } from './locales/pt.js';
|
|
59
|
-
export { default as ru } from './locales/ru.js';
|
|
60
|
-
export { default as ar } from './locales/ar.js';
|
|
61
85
|
// Formatting utilities
|
|
62
86
|
export { formatDate, formatDateTime, formatRelativeTime, formatCurrency, formatNumber, } from './utils/index.js';
|
|
63
87
|
// Spec-aligned formatters (v2.0.7)
|
|
@@ -66,7 +90,7 @@ export { resolvePlural, formatDateSpec, formatNumberSpec, applyLocaleConfig, } f
|
|
|
66
90
|
// `useObjectLabel`). Exposed so apps don't have to copy/paste — see
|
|
67
91
|
// `apps/console/src/loadLanguage.ts` for the canonical consumer.
|
|
68
92
|
export { isSpecTranslationData, transformSpecTranslations, } from './utils/index.js';
|
|
69
|
-
export { pickLocalized, setLocalized } from './pickLocalized.js';
|
|
93
|
+
export { pickLocalized, setLocalized, clearLocalized } from './pickLocalized.js';
|
|
70
94
|
export { LocalizationProvider, useLocalization } from './LocalizationContext.js';
|
|
71
95
|
export { resolveFieldCurrency } from './currency.js';
|
|
72
96
|
// The one number-display formatter (objectui#4033) and the locale it formats
|