@sonenta/react-i18next 2.2.0 → 2.3.1
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/README.md +35 -0
- package/dist/index.cjs +93 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +51 -1
- package/dist/index.d.ts +51 -1
- package/dist/index.js +92 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -83,6 +83,20 @@ interface LanguageMeta {
|
|
|
83
83
|
/** CLDR plural categories present for this language. */
|
|
84
84
|
plural_categories?: string[];
|
|
85
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* A language PUBLISHED for the active version (task: available-languages) — a
|
|
88
|
+
* {@link LanguageMeta} (enriched from the catalog) plus publish info from the
|
|
89
|
+
* per-version CDN manifest. Returned by `i18n.availableLanguages` /
|
|
90
|
+
* `useAvailableLanguages()`.
|
|
91
|
+
*/
|
|
92
|
+
interface AvailableLanguage extends LanguageMeta {
|
|
93
|
+
/** ISO timestamp this language was published for the active version, when
|
|
94
|
+
* the manifest provides it (optional / forward-compat). Render a
|
|
95
|
+
* "recently added" hint if present; ignore if absent. */
|
|
96
|
+
published_at?: string;
|
|
97
|
+
/** True when this is the project's default locale for the active version. */
|
|
98
|
+
is_default?: boolean;
|
|
99
|
+
}
|
|
86
100
|
interface MissingKeyEvent {
|
|
87
101
|
key: string;
|
|
88
102
|
namespace: Namespace;
|
|
@@ -162,6 +176,14 @@ interface SonentaConfig {
|
|
|
162
176
|
* you supply {@link SonentaConfig.languageCatalog} yourself.
|
|
163
177
|
*/
|
|
164
178
|
disableLanguageCatalog?: boolean;
|
|
179
|
+
/**
|
|
180
|
+
* Skip the best-effort fetch of the per-version published-languages manifest
|
|
181
|
+
* (`{apiBase}/cdn/v1/{project}/{version}/latest/languages.json`, public, no
|
|
182
|
+
* auth, CORS-open) that powers `i18n.availableLanguages` /
|
|
183
|
+
* `useAvailableLanguages()`. When skipped (or on a 404), `availableLanguages`
|
|
184
|
+
* falls back to the configured `defaultLocale` + `fallbackLng`.
|
|
185
|
+
*/
|
|
186
|
+
disableLanguageManifest?: boolean;
|
|
165
187
|
/**
|
|
166
188
|
* Interpolation hooks forwarded to i18next. Currently exposes `format`, the
|
|
167
189
|
* value formatter i18next invokes for `{{value, format}}` placeholders — wire
|
|
@@ -434,6 +456,15 @@ interface I18nInstance {
|
|
|
434
456
|
* parent, …), defaulting to the active locale; `undefined` if unknown.
|
|
435
457
|
*/
|
|
436
458
|
languageMeta: (lng?: Locale) => LanguageMeta | undefined;
|
|
459
|
+
/**
|
|
460
|
+
* The languages PUBLISHED for the active version (from the per-version CDN
|
|
461
|
+
* manifest, enriched with catalog metadata) — drives a runtime language
|
|
462
|
+
* switcher that updates when a new language ships WITHOUT recompiling the
|
|
463
|
+
* app. Falls back to `defaultLocale` + `fallbackLng` when no manifest is
|
|
464
|
+
* available. Refreshed on `reload()`. Prefer the `useAvailableLanguages()`
|
|
465
|
+
* hook in React (reactive).
|
|
466
|
+
*/
|
|
467
|
+
availableLanguages: AvailableLanguage[];
|
|
437
468
|
/**
|
|
438
469
|
* The underlying real `i18next` instance powering this SDK (thin-wrapper,
|
|
439
470
|
* #805). Exposed for react-i18next DROP-IN: pass it to react-i18next's own
|
|
@@ -490,6 +521,25 @@ interface UseTranslationResult {
|
|
|
490
521
|
* contribution is keyed to THIS hook instance and dropped on unmount, so
|
|
491
522
|
* navigating away removes its keys automatically. */
|
|
492
523
|
declare function useTranslation(defaultNamespace?: string): UseTranslationResult;
|
|
524
|
+
/**
|
|
525
|
+
* React hook — the languages PUBLISHED for the active version, enriched with
|
|
526
|
+
* catalog metadata (native_name / rtl / …). Drives a runtime language switcher
|
|
527
|
+
* that picks up a newly-published language WITHOUT recompiling the app: the
|
|
528
|
+
* per-version manifest is CDN-served, so the new language appears on the next
|
|
529
|
+
* load (or after `i18n.reload()`). Falls back to `defaultLocale` +
|
|
530
|
+
* `fallbackLng` when no manifest is available.
|
|
531
|
+
*
|
|
532
|
+
* ```tsx
|
|
533
|
+
* const langs = useAvailableLanguages();
|
|
534
|
+
* const { i18n } = useTranslation();
|
|
535
|
+
* return langs.map((l) => (
|
|
536
|
+
* <button key={l.code} onClick={() => i18n.setLocale(l.code)}>
|
|
537
|
+
* {l.native_name ?? l.code}{l.is_default ? " ★" : ""}
|
|
538
|
+
* </button>
|
|
539
|
+
* ));
|
|
540
|
+
* ```
|
|
541
|
+
*/
|
|
542
|
+
declare function useAvailableLanguages(): AvailableLanguage[];
|
|
493
543
|
|
|
494
544
|
interface TransProps {
|
|
495
545
|
/** The translation key (optionally `ns:key`). */
|
|
@@ -625,4 +675,4 @@ declare class KeyRegistry {
|
|
|
625
675
|
/** Process-wide singleton — there is exactly one on-screen registry. */
|
|
626
676
|
declare const keyRegistry: KeyRegistry;
|
|
627
677
|
|
|
628
|
-
export { A11Y_SURFACES, type A11ySurface, type AssetRef, DEFAULT_SURFACE_BREAKPOINTS, type DeclaredKey, type I18nInstance, type LanguageMeta, type Locale, type MissingHandlerMode, type MissingKeyEvent, type Namespace, type SonentaConfig, type SonentaPlugin, type SonentaPluginContext, SonentaProvider, type Surface, type SurfaceBreakpoints, Trans, type TranslationFunction, type TranslationOptions, type Transport, type SonentaConfig as VerbumiaConfig, type SonentaPlugin as VerbumiaPlugin, type SonentaPluginContext as VerbumiaPluginContext, SonentaProvider as VerbumiaProvider, defaultTransport, getI18n, getI18nSafe, keyRegistry, logTransport, surfaceForWidth, t, useTranslation };
|
|
678
|
+
export { A11Y_SURFACES, type A11ySurface, type A11yTranslationFunction, type AssetRef, type AvailableLanguage, DEFAULT_SURFACE_BREAKPOINTS, type DeclaredKey, type I18nInstance, type LanguageMeta, type Locale, type MissingHandlerMode, type MissingKeyEvent, type Namespace, type SonentaConfig, type SonentaPlugin, type SonentaPluginContext, SonentaProvider, type Surface, type SurfaceBreakpoints, Trans, type TranslationFunction, type TranslationOptions, type Transport, type SonentaConfig as VerbumiaConfig, type SonentaPlugin as VerbumiaPlugin, type SonentaPluginContext as VerbumiaPluginContext, SonentaProvider as VerbumiaProvider, defaultTransport, getI18n, getI18nSafe, keyRegistry, logTransport, surfaceForWidth, t, useAvailableLanguages, useTranslation };
|
package/dist/index.d.ts
CHANGED
|
@@ -83,6 +83,20 @@ interface LanguageMeta {
|
|
|
83
83
|
/** CLDR plural categories present for this language. */
|
|
84
84
|
plural_categories?: string[];
|
|
85
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* A language PUBLISHED for the active version (task: available-languages) — a
|
|
88
|
+
* {@link LanguageMeta} (enriched from the catalog) plus publish info from the
|
|
89
|
+
* per-version CDN manifest. Returned by `i18n.availableLanguages` /
|
|
90
|
+
* `useAvailableLanguages()`.
|
|
91
|
+
*/
|
|
92
|
+
interface AvailableLanguage extends LanguageMeta {
|
|
93
|
+
/** ISO timestamp this language was published for the active version, when
|
|
94
|
+
* the manifest provides it (optional / forward-compat). Render a
|
|
95
|
+
* "recently added" hint if present; ignore if absent. */
|
|
96
|
+
published_at?: string;
|
|
97
|
+
/** True when this is the project's default locale for the active version. */
|
|
98
|
+
is_default?: boolean;
|
|
99
|
+
}
|
|
86
100
|
interface MissingKeyEvent {
|
|
87
101
|
key: string;
|
|
88
102
|
namespace: Namespace;
|
|
@@ -162,6 +176,14 @@ interface SonentaConfig {
|
|
|
162
176
|
* you supply {@link SonentaConfig.languageCatalog} yourself.
|
|
163
177
|
*/
|
|
164
178
|
disableLanguageCatalog?: boolean;
|
|
179
|
+
/**
|
|
180
|
+
* Skip the best-effort fetch of the per-version published-languages manifest
|
|
181
|
+
* (`{apiBase}/cdn/v1/{project}/{version}/latest/languages.json`, public, no
|
|
182
|
+
* auth, CORS-open) that powers `i18n.availableLanguages` /
|
|
183
|
+
* `useAvailableLanguages()`. When skipped (or on a 404), `availableLanguages`
|
|
184
|
+
* falls back to the configured `defaultLocale` + `fallbackLng`.
|
|
185
|
+
*/
|
|
186
|
+
disableLanguageManifest?: boolean;
|
|
165
187
|
/**
|
|
166
188
|
* Interpolation hooks forwarded to i18next. Currently exposes `format`, the
|
|
167
189
|
* value formatter i18next invokes for `{{value, format}}` placeholders — wire
|
|
@@ -434,6 +456,15 @@ interface I18nInstance {
|
|
|
434
456
|
* parent, …), defaulting to the active locale; `undefined` if unknown.
|
|
435
457
|
*/
|
|
436
458
|
languageMeta: (lng?: Locale) => LanguageMeta | undefined;
|
|
459
|
+
/**
|
|
460
|
+
* The languages PUBLISHED for the active version (from the per-version CDN
|
|
461
|
+
* manifest, enriched with catalog metadata) — drives a runtime language
|
|
462
|
+
* switcher that updates when a new language ships WITHOUT recompiling the
|
|
463
|
+
* app. Falls back to `defaultLocale` + `fallbackLng` when no manifest is
|
|
464
|
+
* available. Refreshed on `reload()`. Prefer the `useAvailableLanguages()`
|
|
465
|
+
* hook in React (reactive).
|
|
466
|
+
*/
|
|
467
|
+
availableLanguages: AvailableLanguage[];
|
|
437
468
|
/**
|
|
438
469
|
* The underlying real `i18next` instance powering this SDK (thin-wrapper,
|
|
439
470
|
* #805). Exposed for react-i18next DROP-IN: pass it to react-i18next's own
|
|
@@ -490,6 +521,25 @@ interface UseTranslationResult {
|
|
|
490
521
|
* contribution is keyed to THIS hook instance and dropped on unmount, so
|
|
491
522
|
* navigating away removes its keys automatically. */
|
|
492
523
|
declare function useTranslation(defaultNamespace?: string): UseTranslationResult;
|
|
524
|
+
/**
|
|
525
|
+
* React hook — the languages PUBLISHED for the active version, enriched with
|
|
526
|
+
* catalog metadata (native_name / rtl / …). Drives a runtime language switcher
|
|
527
|
+
* that picks up a newly-published language WITHOUT recompiling the app: the
|
|
528
|
+
* per-version manifest is CDN-served, so the new language appears on the next
|
|
529
|
+
* load (or after `i18n.reload()`). Falls back to `defaultLocale` +
|
|
530
|
+
* `fallbackLng` when no manifest is available.
|
|
531
|
+
*
|
|
532
|
+
* ```tsx
|
|
533
|
+
* const langs = useAvailableLanguages();
|
|
534
|
+
* const { i18n } = useTranslation();
|
|
535
|
+
* return langs.map((l) => (
|
|
536
|
+
* <button key={l.code} onClick={() => i18n.setLocale(l.code)}>
|
|
537
|
+
* {l.native_name ?? l.code}{l.is_default ? " ★" : ""}
|
|
538
|
+
* </button>
|
|
539
|
+
* ));
|
|
540
|
+
* ```
|
|
541
|
+
*/
|
|
542
|
+
declare function useAvailableLanguages(): AvailableLanguage[];
|
|
493
543
|
|
|
494
544
|
interface TransProps {
|
|
495
545
|
/** The translation key (optionally `ns:key`). */
|
|
@@ -625,4 +675,4 @@ declare class KeyRegistry {
|
|
|
625
675
|
/** Process-wide singleton — there is exactly one on-screen registry. */
|
|
626
676
|
declare const keyRegistry: KeyRegistry;
|
|
627
677
|
|
|
628
|
-
export { A11Y_SURFACES, type A11ySurface, type AssetRef, DEFAULT_SURFACE_BREAKPOINTS, type DeclaredKey, type I18nInstance, type LanguageMeta, type Locale, type MissingHandlerMode, type MissingKeyEvent, type Namespace, type SonentaConfig, type SonentaPlugin, type SonentaPluginContext, SonentaProvider, type Surface, type SurfaceBreakpoints, Trans, type TranslationFunction, type TranslationOptions, type Transport, type SonentaConfig as VerbumiaConfig, type SonentaPlugin as VerbumiaPlugin, type SonentaPluginContext as VerbumiaPluginContext, SonentaProvider as VerbumiaProvider, defaultTransport, getI18n, getI18nSafe, keyRegistry, logTransport, surfaceForWidth, t, useTranslation };
|
|
678
|
+
export { A11Y_SURFACES, type A11ySurface, type A11yTranslationFunction, type AssetRef, type AvailableLanguage, DEFAULT_SURFACE_BREAKPOINTS, type DeclaredKey, type I18nInstance, type LanguageMeta, type Locale, type MissingHandlerMode, type MissingKeyEvent, type Namespace, type SonentaConfig, type SonentaPlugin, type SonentaPluginContext, SonentaProvider, type Surface, type SurfaceBreakpoints, Trans, type TranslationFunction, type TranslationOptions, type Transport, type SonentaConfig as VerbumiaConfig, type SonentaPlugin as VerbumiaPlugin, type SonentaPluginContext as VerbumiaPluginContext, SonentaProvider as VerbumiaProvider, defaultTransport, getI18n, getI18nSafe, keyRegistry, logTransport, surfaceForWidth, t, useAvailableLanguages, useTranslation };
|
package/dist/index.js
CHANGED
|
@@ -210,7 +210,7 @@ function flattenPlurals(tree, locale) {
|
|
|
210
210
|
|
|
211
211
|
// src/transport.ts
|
|
212
212
|
var SDK_LIB = "@sonenta/react-i18next";
|
|
213
|
-
var SDK_VER = true ? "2.
|
|
213
|
+
var SDK_VER = true ? "2.3.1" : "0.0.0-dev";
|
|
214
214
|
function defaultTransport(opts) {
|
|
215
215
|
return async (batch) => {
|
|
216
216
|
if (!batch.length) return;
|
|
@@ -402,6 +402,14 @@ var SonentaI18n = class {
|
|
|
402
402
|
// config.languageCatalog and/or the public GET /v1/languages in start().
|
|
403
403
|
_catalog = new LanguageCatalog();
|
|
404
404
|
_catalogDisabled = false;
|
|
405
|
+
// Published-languages manifest (available-languages feature). Per-version,
|
|
406
|
+
// public CDN, no auth: the SET of locales published for the active version.
|
|
407
|
+
// Codes are enriched from `_catalog` (#803) for native_name/rtl/etc.
|
|
408
|
+
_manifestDisabled = false;
|
|
409
|
+
_manifest = null;
|
|
410
|
+
// The configured default locale (the initial `this.locale`, which is mutable
|
|
411
|
+
// via setLocale) — used as the available-languages fallback + default marker.
|
|
412
|
+
_defaultLocale;
|
|
405
413
|
_config;
|
|
406
414
|
// Surface variant (#911). When set, each loaded (locale,ns) is composed as
|
|
407
415
|
// base ⊕ sparse `{ns}.{surface}.json` overlay (overlay wins per key). We
|
|
@@ -449,6 +457,7 @@ var SonentaI18n = class {
|
|
|
449
457
|
);
|
|
450
458
|
}
|
|
451
459
|
this.locale = config.defaultLocale;
|
|
460
|
+
this._defaultLocale = config.defaultLocale;
|
|
452
461
|
this.fallbackLng = config.fallbackLng;
|
|
453
462
|
this._surface = config.surface;
|
|
454
463
|
for (const s of config.a11ySurfaces ?? []) this._a11ySurfaces.add(s);
|
|
@@ -551,6 +560,7 @@ var SonentaI18n = class {
|
|
|
551
560
|
this._rebindFormat();
|
|
552
561
|
this._catalogDisabled = config.disableLanguageCatalog === true;
|
|
553
562
|
this._catalog.merge(config.languageCatalog);
|
|
563
|
+
this._manifestDisabled = config.disableLanguageManifest === true;
|
|
554
564
|
const active = config.initialBundles?.[this.locale];
|
|
555
565
|
if (active && this._config.namespaces.every(
|
|
556
566
|
(n) => active[n] && Object.keys(active[n]).length > 0
|
|
@@ -647,6 +657,7 @@ var SonentaI18n = class {
|
|
|
647
657
|
dir: this.dir,
|
|
648
658
|
nativeName: this.nativeName,
|
|
649
659
|
languageMeta: this.languageMeta,
|
|
660
|
+
availableLanguages: this.availableLanguages,
|
|
650
661
|
i18next: this._i18next
|
|
651
662
|
};
|
|
652
663
|
}
|
|
@@ -708,7 +719,9 @@ var SonentaI18n = class {
|
|
|
708
719
|
// Best-effort: align the key separator with the version's key_style (#754).
|
|
709
720
|
this._loadKeyStyle(fetchImpl),
|
|
710
721
|
// Best-effort: load the public language catalog for dir()/nativeName().
|
|
711
|
-
this._loadCatalog(fetchImpl)
|
|
722
|
+
this._loadCatalog(fetchImpl),
|
|
723
|
+
// Best-effort: load the per-version published-languages manifest.
|
|
724
|
+
this._loadManifest(fetchImpl)
|
|
712
725
|
]);
|
|
713
726
|
await this._syncLanguage();
|
|
714
727
|
this.ready = true;
|
|
@@ -732,6 +745,73 @@ var SonentaI18n = class {
|
|
|
732
745
|
}
|
|
733
746
|
/** Best-effort: fetch the PUBLIC language catalog and merge it in (#803).
|
|
734
747
|
* Skipped when disabled; a failure keeps any embedded catalog. */
|
|
748
|
+
/**
|
|
749
|
+
* Best-effort: fetch the per-version published-languages manifest
|
|
750
|
+
* (`{apiBase}/cdn/v1/{project}/{version}/latest/languages.json`, public, no
|
|
751
|
+
* auth, CORS-open, CDN-cached `max-age=60` + ETag) — the SET of locales
|
|
752
|
+
* published for the active version (compute-on-serve from cdn_releases,
|
|
753
|
+
* always in sync with what is published). Codes only; enriched from the
|
|
754
|
+
* catalog. A 404/offline keeps any prior manifest (`availableLanguages` then
|
|
755
|
+
* falls back to default + fallback). Same route on prod + dev (backend task
|
|
756
|
+
* 989+; the authed `/v1/projects/{id}/languages` is ALL project languages,
|
|
757
|
+
* not the published set — this manifest is the in-production set).
|
|
758
|
+
*/
|
|
759
|
+
async _loadManifest(fetchImpl, opts = {}) {
|
|
760
|
+
if (this._manifestDisabled) return;
|
|
761
|
+
const url = `${this._config.apiBase.replace(/\/+$/, "")}/cdn/v1/${this._config.projectUuid}/${this._config.version}/latest/languages.json`;
|
|
762
|
+
const init = { method: "GET", credentials: "omit" };
|
|
763
|
+
if (opts.bust) init.cache = "reload";
|
|
764
|
+
try {
|
|
765
|
+
const r = await fetchImpl(url, init);
|
|
766
|
+
if (!r.ok) return;
|
|
767
|
+
const data = await r.json();
|
|
768
|
+
const raw = Array.isArray(data.languages) ? data.languages : [];
|
|
769
|
+
const languages = [];
|
|
770
|
+
for (const e of raw) {
|
|
771
|
+
if (typeof e === "string") {
|
|
772
|
+
languages.push({ code: e });
|
|
773
|
+
} else if (e && typeof e === "object" && typeof e.code === "string") {
|
|
774
|
+
const obj = e;
|
|
775
|
+
languages.push({
|
|
776
|
+
code: obj.code,
|
|
777
|
+
published_at: typeof obj.published_at === "string" ? obj.published_at : void 0
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
this._manifest = {
|
|
782
|
+
default_locale: typeof data.default_locale === "string" ? data.default_locale : void 0,
|
|
783
|
+
languages
|
|
784
|
+
};
|
|
785
|
+
} catch {
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
/** Languages PUBLISHED for the active version (available-languages feature):
|
|
789
|
+
* the manifest's codes enriched with catalog metadata, marked with the
|
|
790
|
+
* default locale + any `published_at`. Falls back to the configured
|
|
791
|
+
* `defaultLocale` + `fallbackLng` when no manifest is available. */
|
|
792
|
+
get availableLanguages() {
|
|
793
|
+
const def = this._manifest?.default_locale ?? this._defaultLocale;
|
|
794
|
+
let entries = this._manifest?.languages;
|
|
795
|
+
if (!entries || entries.length === 0) {
|
|
796
|
+
const seen = /* @__PURE__ */ new Set();
|
|
797
|
+
entries = [];
|
|
798
|
+
for (const c of [this._defaultLocale, ...asArray(this.fallbackLng)]) {
|
|
799
|
+
if (c && !seen.has(c)) {
|
|
800
|
+
seen.add(c);
|
|
801
|
+
entries.push({ code: c });
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
return entries.map(({ code, published_at }) => {
|
|
806
|
+
const meta = this.languageMeta(code);
|
|
807
|
+
return {
|
|
808
|
+
...meta ?? {},
|
|
809
|
+
code,
|
|
810
|
+
...published_at ? { published_at } : {},
|
|
811
|
+
is_default: code === def
|
|
812
|
+
};
|
|
813
|
+
});
|
|
814
|
+
}
|
|
735
815
|
async _loadCatalog(fetchImpl) {
|
|
736
816
|
if (this._catalogDisabled) return;
|
|
737
817
|
this._catalog.merge(await loadCatalog(this._config.apiBase, fetchImpl));
|
|
@@ -822,12 +902,14 @@ var SonentaI18n = class {
|
|
|
822
902
|
if (opts.namespace && opts.namespace !== ns) continue;
|
|
823
903
|
targets.push({ locale, ns });
|
|
824
904
|
}
|
|
825
|
-
if (targets.length === 0) return;
|
|
826
|
-
|
|
827
|
-
|
|
905
|
+
if (targets.length === 0 && (opts.locale || opts.namespace)) return;
|
|
906
|
+
const manifest = this._loadManifest(fetch, { bust: true });
|
|
907
|
+
await Promise.all([
|
|
908
|
+
manifest,
|
|
909
|
+
...targets.map(
|
|
828
910
|
(t2) => this._loadBundle(t2.locale, t2.ns, fetch, { bust: true })
|
|
829
911
|
)
|
|
830
|
-
);
|
|
912
|
+
]);
|
|
831
913
|
this._notify();
|
|
832
914
|
};
|
|
833
915
|
/**
|
|
@@ -1418,6 +1500,9 @@ function useTranslation(defaultNamespace) {
|
|
|
1418
1500
|
}, []);
|
|
1419
1501
|
return { t: t2, i18n: snapshot };
|
|
1420
1502
|
}
|
|
1503
|
+
function useAvailableLanguages() {
|
|
1504
|
+
return useI18nSnapshot().availableLanguages;
|
|
1505
|
+
}
|
|
1421
1506
|
|
|
1422
1507
|
// src/trans.tsx
|
|
1423
1508
|
import { Children, cloneElement, isValidElement } from "react";
|
|
@@ -1471,6 +1556,7 @@ export {
|
|
|
1471
1556
|
logTransport,
|
|
1472
1557
|
surfaceForWidth,
|
|
1473
1558
|
t,
|
|
1559
|
+
useAvailableLanguages,
|
|
1474
1560
|
useTranslation
|
|
1475
1561
|
};
|
|
1476
1562
|
//# sourceMappingURL=index.js.map
|