@intl-party/react 1.0.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/LICENSE +21 -0
- package/dist/index.js +1026 -0
- package/dist/index.mjs +958 -0
- package/package.json +63 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1026 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.tsx
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
AccessibleLocaleSelector: () => AccessibleLocaleSelector,
|
|
34
|
+
CompactLocaleSelector: () => CompactLocaleSelector,
|
|
35
|
+
ConditionalTrans: () => ConditionalTrans,
|
|
36
|
+
FlagLocaleSelector: () => FlagLocaleSelector,
|
|
37
|
+
I18nErrorBoundary: () => I18nErrorBoundary,
|
|
38
|
+
I18nProvider: () => I18nProvider,
|
|
39
|
+
LocaleSelector: () => LocaleSelector,
|
|
40
|
+
PluralTrans: () => PluralTrans,
|
|
41
|
+
RichTrans: () => RichTrans,
|
|
42
|
+
ScopedI18nProvider: () => ScopedI18nProvider,
|
|
43
|
+
Trans: () => Trans,
|
|
44
|
+
TypedI18nProvider: () => TypedI18nProvider,
|
|
45
|
+
VERSION: () => VERSION,
|
|
46
|
+
createI18nHook: () => createI18nHook,
|
|
47
|
+
createNamespaceHOC: () => createNamespaceHOC,
|
|
48
|
+
useBrowserLocale: () => useBrowserLocale,
|
|
49
|
+
useDirection: () => useDirection,
|
|
50
|
+
useFormatting: () => useFormatting,
|
|
51
|
+
useHasTranslation: () => useHasTranslation,
|
|
52
|
+
useI18nContext: () => useI18nContext,
|
|
53
|
+
useInterpolatedTranslation: () => useInterpolatedTranslation,
|
|
54
|
+
useLocale: () => useLocale,
|
|
55
|
+
useLocaleInfo: () => useLocaleInfo,
|
|
56
|
+
useLocalePreference: () => useLocalePreference,
|
|
57
|
+
useLocaleSwitch: () => useLocaleSwitch,
|
|
58
|
+
useMultipleNamespaces: () => useMultipleNamespaces,
|
|
59
|
+
useMultipleTranslations: () => useMultipleTranslations,
|
|
60
|
+
useNamespace: () => useNamespace,
|
|
61
|
+
useNamespaceInfo: () => useNamespaceInfo,
|
|
62
|
+
useNamespacePreloading: () => useNamespacePreloading,
|
|
63
|
+
useNamespaceSwitch: () => useNamespaceSwitch,
|
|
64
|
+
useOptionalTranslation: () => useOptionalTranslation,
|
|
65
|
+
usePluralization: () => usePluralization,
|
|
66
|
+
useScopedTranslations: () => useScopedTranslations,
|
|
67
|
+
useT: () => useT,
|
|
68
|
+
useTranslationValue: () => useTranslationValue,
|
|
69
|
+
useTranslationWithFallback: () => useTranslationWithFallback,
|
|
70
|
+
useTranslations: () => useTranslations,
|
|
71
|
+
useTypedI18nContext: () => useTypedI18nContext,
|
|
72
|
+
useTypedT: () => useTypedT,
|
|
73
|
+
useTypedTranslations: () => useTypedTranslations,
|
|
74
|
+
withI18n: () => withI18n
|
|
75
|
+
});
|
|
76
|
+
module.exports = __toCommonJS(index_exports);
|
|
77
|
+
var import_react7 = __toESM(require("react"));
|
|
78
|
+
|
|
79
|
+
// src/context/I18nContext.tsx
|
|
80
|
+
var import_react = require("react");
|
|
81
|
+
var import_core = require("@intl-party/core");
|
|
82
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
83
|
+
var I18nContext = (0, import_react.createContext)(null);
|
|
84
|
+
function I18nProvider({
|
|
85
|
+
children,
|
|
86
|
+
config,
|
|
87
|
+
i18n: externalI18n,
|
|
88
|
+
initialLocale,
|
|
89
|
+
initialNamespace,
|
|
90
|
+
loadingComponent,
|
|
91
|
+
fallbackComponent,
|
|
92
|
+
onLocaleChange,
|
|
93
|
+
onNamespaceChange,
|
|
94
|
+
onError
|
|
95
|
+
}) {
|
|
96
|
+
const i18nInstance = (0, import_react.useMemo)(() => {
|
|
97
|
+
if (externalI18n) {
|
|
98
|
+
return externalI18n;
|
|
99
|
+
}
|
|
100
|
+
if (!config) {
|
|
101
|
+
throw new Error(
|
|
102
|
+
"Either config or i18n instance must be provided to I18nProvider"
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
const instance = (0, import_core.createI18n)(config);
|
|
106
|
+
if (initialLocale && config.locales.includes(initialLocale)) {
|
|
107
|
+
instance.setLocale(initialLocale);
|
|
108
|
+
}
|
|
109
|
+
if (initialNamespace && config.namespaces.includes(initialNamespace)) {
|
|
110
|
+
instance.setNamespace(initialNamespace);
|
|
111
|
+
}
|
|
112
|
+
return instance;
|
|
113
|
+
}, [config, externalI18n, initialLocale, initialNamespace]);
|
|
114
|
+
const [locale, setLocaleState] = (0, import_react.useState)(i18nInstance.getLocale());
|
|
115
|
+
const [namespace, setNamespaceState] = (0, import_react.useState)(
|
|
116
|
+
i18nInstance.getNamespace()
|
|
117
|
+
);
|
|
118
|
+
const [isLoading, setIsLoading] = (0, import_react.useState)(false);
|
|
119
|
+
const [error, setError] = (0, import_react.useState)(null);
|
|
120
|
+
const handleLocaleChange = (newLocale) => {
|
|
121
|
+
try {
|
|
122
|
+
setIsLoading(true);
|
|
123
|
+
i18nInstance.setLocale(newLocale);
|
|
124
|
+
setLocaleState(newLocale);
|
|
125
|
+
onLocaleChange?.(newLocale);
|
|
126
|
+
} catch (err) {
|
|
127
|
+
const error2 = err instanceof Error ? err : new Error("Failed to change locale");
|
|
128
|
+
setError(error2);
|
|
129
|
+
onError?.(error2);
|
|
130
|
+
} finally {
|
|
131
|
+
setIsLoading(false);
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
const handleNamespaceChange = (newNamespace) => {
|
|
135
|
+
try {
|
|
136
|
+
i18nInstance.setNamespace(newNamespace);
|
|
137
|
+
setNamespaceState(newNamespace);
|
|
138
|
+
onNamespaceChange?.(newNamespace);
|
|
139
|
+
} catch (err) {
|
|
140
|
+
const error2 = err instanceof Error ? err : new Error("Failed to change namespace");
|
|
141
|
+
setError(error2);
|
|
142
|
+
onError?.(error2);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
(0, import_react.useEffect)(() => {
|
|
146
|
+
const handleLocaleChangeEvent = ({
|
|
147
|
+
locale: newLocale
|
|
148
|
+
}) => {
|
|
149
|
+
setLocaleState(newLocale);
|
|
150
|
+
onLocaleChange?.(newLocale);
|
|
151
|
+
};
|
|
152
|
+
const handleNamespaceChangeEvent = ({
|
|
153
|
+
namespace: newNamespace
|
|
154
|
+
}) => {
|
|
155
|
+
setNamespaceState(newNamespace);
|
|
156
|
+
onNamespaceChange?.(newNamespace);
|
|
157
|
+
};
|
|
158
|
+
const handleTranslationsPreloading = () => setIsLoading(true);
|
|
159
|
+
const handleTranslationsPreloaded = () => setIsLoading(false);
|
|
160
|
+
i18nInstance.on("localeChange", handleLocaleChangeEvent);
|
|
161
|
+
i18nInstance.on("namespaceChange", handleNamespaceChangeEvent);
|
|
162
|
+
i18nInstance.on("translationsPreloading", handleTranslationsPreloading);
|
|
163
|
+
i18nInstance.on("translationsPreloaded", handleTranslationsPreloaded);
|
|
164
|
+
return () => {
|
|
165
|
+
i18nInstance.off("localeChange", handleLocaleChangeEvent);
|
|
166
|
+
i18nInstance.off("namespaceChange", handleNamespaceChangeEvent);
|
|
167
|
+
i18nInstance.off("translationsPreloading", handleTranslationsPreloading);
|
|
168
|
+
i18nInstance.off("translationsPreloaded", handleTranslationsPreloaded);
|
|
169
|
+
};
|
|
170
|
+
}, [i18nInstance, onLocaleChange, onNamespaceChange]);
|
|
171
|
+
const contextValue = (0, import_react.useMemo)(
|
|
172
|
+
() => ({
|
|
173
|
+
i18n: i18nInstance,
|
|
174
|
+
locale,
|
|
175
|
+
namespace,
|
|
176
|
+
t: i18nInstance.t,
|
|
177
|
+
setLocale: handleLocaleChange,
|
|
178
|
+
setNamespace: handleNamespaceChange,
|
|
179
|
+
isLoading
|
|
180
|
+
}),
|
|
181
|
+
[i18nInstance, locale, namespace, isLoading]
|
|
182
|
+
);
|
|
183
|
+
if (error && fallbackComponent) {
|
|
184
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: fallbackComponent });
|
|
185
|
+
}
|
|
186
|
+
if (error) {
|
|
187
|
+
throw error;
|
|
188
|
+
}
|
|
189
|
+
if (isLoading && loadingComponent) {
|
|
190
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: loadingComponent });
|
|
191
|
+
}
|
|
192
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(I18nContext.Provider, { value: contextValue, children });
|
|
193
|
+
}
|
|
194
|
+
function useI18nContext() {
|
|
195
|
+
const context = (0, import_react.useContext)(I18nContext);
|
|
196
|
+
if (!context) {
|
|
197
|
+
throw new Error("useI18nContext must be used within an I18nProvider");
|
|
198
|
+
}
|
|
199
|
+
return context;
|
|
200
|
+
}
|
|
201
|
+
var TypedI18nContext = (0, import_react.createContext)(null);
|
|
202
|
+
function TypedI18nProvider({
|
|
203
|
+
children,
|
|
204
|
+
...props
|
|
205
|
+
}) {
|
|
206
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(I18nProvider, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TypedI18nContextWrapper, { children }) });
|
|
207
|
+
}
|
|
208
|
+
function TypedI18nContextWrapper({
|
|
209
|
+
children
|
|
210
|
+
}) {
|
|
211
|
+
const { i18n, locale, namespace, setLocale, setNamespace, isLoading } = useI18nContext();
|
|
212
|
+
const typedContextValue = (0, import_react.useMemo)(
|
|
213
|
+
() => ({
|
|
214
|
+
i18n,
|
|
215
|
+
locale,
|
|
216
|
+
namespace,
|
|
217
|
+
t: i18n.t,
|
|
218
|
+
setLocale,
|
|
219
|
+
setNamespace,
|
|
220
|
+
isLoading
|
|
221
|
+
}),
|
|
222
|
+
[i18n, locale, namespace, setLocale, setNamespace, isLoading]
|
|
223
|
+
);
|
|
224
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TypedI18nContext.Provider, { value: typedContextValue, children });
|
|
225
|
+
}
|
|
226
|
+
function useTypedI18nContext() {
|
|
227
|
+
const context = (0, import_react.useContext)(
|
|
228
|
+
TypedI18nContext
|
|
229
|
+
);
|
|
230
|
+
if (!context) {
|
|
231
|
+
throw new Error(
|
|
232
|
+
"useTypedI18nContext must be used within a TypedI18nProvider"
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
return context;
|
|
236
|
+
}
|
|
237
|
+
function withI18n(Component) {
|
|
238
|
+
const WrappedComponent = (props) => {
|
|
239
|
+
const i18nContext = useI18nContext();
|
|
240
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Component, { ...props, i18n: i18nContext });
|
|
241
|
+
};
|
|
242
|
+
WrappedComponent.displayName = `withI18n(${Component.displayName || Component.name})`;
|
|
243
|
+
return WrappedComponent;
|
|
244
|
+
}
|
|
245
|
+
function ScopedI18nProvider({
|
|
246
|
+
children,
|
|
247
|
+
namespace,
|
|
248
|
+
locale
|
|
249
|
+
}) {
|
|
250
|
+
const parentContext = useI18nContext();
|
|
251
|
+
const scopedContextValue = (0, import_react.useMemo)(
|
|
252
|
+
() => ({
|
|
253
|
+
...parentContext,
|
|
254
|
+
namespace,
|
|
255
|
+
locale: locale || parentContext.locale,
|
|
256
|
+
t: parentContext.i18n.createScopedTranslator(namespace)
|
|
257
|
+
}),
|
|
258
|
+
[parentContext, namespace, locale]
|
|
259
|
+
);
|
|
260
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(I18nContext.Provider, { value: scopedContextValue, children });
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// src/hooks/useTranslations.ts
|
|
264
|
+
var import_react2 = require("react");
|
|
265
|
+
function useTranslations(namespace) {
|
|
266
|
+
const { i18n, namespace: currentNamespace } = useI18nContext();
|
|
267
|
+
const targetNamespace = namespace || currentNamespace;
|
|
268
|
+
return (0, import_react2.useCallback)(
|
|
269
|
+
(key, options) => {
|
|
270
|
+
return i18n.t(key, { ...options, namespace: targetNamespace });
|
|
271
|
+
},
|
|
272
|
+
[i18n, targetNamespace]
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
function useTypedTranslations(namespace) {
|
|
276
|
+
const { i18n, namespace: currentNamespace } = useTypedI18nContext();
|
|
277
|
+
const targetNamespace = namespace || currentNamespace;
|
|
278
|
+
return (0, import_react2.useCallback)(
|
|
279
|
+
(key, options) => {
|
|
280
|
+
return i18n.t(key, {
|
|
281
|
+
...options,
|
|
282
|
+
namespace: targetNamespace
|
|
283
|
+
});
|
|
284
|
+
},
|
|
285
|
+
[i18n, targetNamespace]
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
var useT = useTranslations;
|
|
289
|
+
var useTypedT = useTypedTranslations;
|
|
290
|
+
function useScopedTranslations(namespace) {
|
|
291
|
+
const { i18n } = useI18nContext();
|
|
292
|
+
return (0, import_react2.useMemo)(() => {
|
|
293
|
+
return i18n.createScopedTranslator(namespace);
|
|
294
|
+
}, [i18n, namespace]);
|
|
295
|
+
}
|
|
296
|
+
function useMultipleTranslations(namespaces) {
|
|
297
|
+
const { i18n } = useI18nContext();
|
|
298
|
+
return (0, import_react2.useMemo)(() => {
|
|
299
|
+
const translators = {};
|
|
300
|
+
for (const namespace of namespaces) {
|
|
301
|
+
translators[namespace] = i18n.createScopedTranslator(namespace);
|
|
302
|
+
}
|
|
303
|
+
return translators;
|
|
304
|
+
}, [i18n, namespaces]);
|
|
305
|
+
}
|
|
306
|
+
function useOptionalTranslation(key, namespace, options) {
|
|
307
|
+
const { i18n, namespace: currentNamespace } = useI18nContext();
|
|
308
|
+
const targetNamespace = namespace || currentNamespace;
|
|
309
|
+
return (0, import_react2.useMemo)(() => {
|
|
310
|
+
if (i18n.hasTranslation(key, targetNamespace)) {
|
|
311
|
+
return i18n.t(key, { ...options, namespace: targetNamespace });
|
|
312
|
+
}
|
|
313
|
+
return void 0;
|
|
314
|
+
}, [i18n, key, targetNamespace, options]);
|
|
315
|
+
}
|
|
316
|
+
function useTranslationWithFallback(key, fallback, namespace, options) {
|
|
317
|
+
const { i18n, namespace: currentNamespace } = useI18nContext();
|
|
318
|
+
const targetNamespace = namespace || currentNamespace;
|
|
319
|
+
return (0, import_react2.useMemo)(() => {
|
|
320
|
+
return i18n.t(key, {
|
|
321
|
+
...options,
|
|
322
|
+
namespace: targetNamespace,
|
|
323
|
+
fallback
|
|
324
|
+
});
|
|
325
|
+
}, [i18n, key, fallback, targetNamespace, options]);
|
|
326
|
+
}
|
|
327
|
+
function useHasTranslation() {
|
|
328
|
+
const { i18n, namespace: currentNamespace } = useI18nContext();
|
|
329
|
+
return (0, import_react2.useCallback)(
|
|
330
|
+
(key, namespace) => {
|
|
331
|
+
const targetNamespace = namespace || currentNamespace;
|
|
332
|
+
return i18n.hasTranslation(key, targetNamespace);
|
|
333
|
+
},
|
|
334
|
+
[i18n, currentNamespace]
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
function useTranslationValue() {
|
|
338
|
+
const { i18n, namespace: currentNamespace } = useI18nContext();
|
|
339
|
+
return (0, import_react2.useCallback)(
|
|
340
|
+
(key, namespace) => {
|
|
341
|
+
const targetNamespace = namespace || currentNamespace;
|
|
342
|
+
return i18n.getTranslation(key, targetNamespace);
|
|
343
|
+
},
|
|
344
|
+
[i18n, currentNamespace]
|
|
345
|
+
);
|
|
346
|
+
}
|
|
347
|
+
function useInterpolatedTranslation(key, variables, namespace) {
|
|
348
|
+
const t = useTranslations(namespace);
|
|
349
|
+
return (0, import_react2.useMemo)(() => {
|
|
350
|
+
return t(key, { interpolation: variables });
|
|
351
|
+
}, [t, key, variables]);
|
|
352
|
+
}
|
|
353
|
+
function usePluralization(key, count, namespace, additionalOptions) {
|
|
354
|
+
const t = useTranslations(namespace);
|
|
355
|
+
return (0, import_react2.useMemo)(() => {
|
|
356
|
+
return t(key, { ...additionalOptions, count });
|
|
357
|
+
}, [t, key, count, additionalOptions]);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// src/hooks/useLocale.ts
|
|
361
|
+
var import_react3 = require("react");
|
|
362
|
+
function useLocale() {
|
|
363
|
+
const { locale, setLocale } = useI18nContext();
|
|
364
|
+
return [locale, setLocale];
|
|
365
|
+
}
|
|
366
|
+
function useLocaleInfo() {
|
|
367
|
+
const { locale, i18n } = useI18nContext();
|
|
368
|
+
return (0, import_react3.useMemo)(() => {
|
|
369
|
+
const availableLocales = i18n.getAvailableLocales();
|
|
370
|
+
const fallbackChain = i18n.getFallbackChain(locale);
|
|
371
|
+
return {
|
|
372
|
+
current: locale,
|
|
373
|
+
available: availableLocales,
|
|
374
|
+
fallbackChain,
|
|
375
|
+
isRTL: isRTLLocale(locale),
|
|
376
|
+
direction: isRTLLocale(locale) ? "rtl" : "ltr"
|
|
377
|
+
};
|
|
378
|
+
}, [locale, i18n]);
|
|
379
|
+
}
|
|
380
|
+
function useLocaleSwitch() {
|
|
381
|
+
const { i18n, setLocale } = useI18nContext();
|
|
382
|
+
const switchLocale = (0, import_react3.useCallback)(
|
|
383
|
+
(locale) => {
|
|
384
|
+
const availableLocales = i18n.getAvailableLocales();
|
|
385
|
+
if (!availableLocales.includes(locale)) {
|
|
386
|
+
throw new Error(
|
|
387
|
+
`Locale "${locale}" is not available. Available locales: ${availableLocales.join(", ")}`
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
setLocale(locale);
|
|
391
|
+
},
|
|
392
|
+
[i18n, setLocale]
|
|
393
|
+
);
|
|
394
|
+
const isLocaleAvailable = (0, import_react3.useCallback)(
|
|
395
|
+
(locale) => {
|
|
396
|
+
return i18n.getAvailableLocales().includes(locale);
|
|
397
|
+
},
|
|
398
|
+
[i18n]
|
|
399
|
+
);
|
|
400
|
+
return {
|
|
401
|
+
switchLocale,
|
|
402
|
+
isLocaleAvailable,
|
|
403
|
+
availableLocales: i18n.getAvailableLocales()
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
function useBrowserLocale() {
|
|
407
|
+
const { i18n } = useI18nContext();
|
|
408
|
+
return (0, import_react3.useMemo)(() => {
|
|
409
|
+
if (typeof window === "undefined") return null;
|
|
410
|
+
const detected = i18n.detectLocale({
|
|
411
|
+
request: void 0,
|
|
412
|
+
url: window.location.href,
|
|
413
|
+
userAgent: navigator.userAgent
|
|
414
|
+
});
|
|
415
|
+
return {
|
|
416
|
+
detected,
|
|
417
|
+
browser: navigator.language,
|
|
418
|
+
supported: i18n.getAvailableLocales().includes(detected)
|
|
419
|
+
};
|
|
420
|
+
}, [i18n]);
|
|
421
|
+
}
|
|
422
|
+
function useLocalePreference() {
|
|
423
|
+
const { locale, setLocale, i18n } = useI18nContext();
|
|
424
|
+
const savePreference = (0, import_react3.useCallback)(
|
|
425
|
+
(newLocale) => {
|
|
426
|
+
if (typeof window !== "undefined") {
|
|
427
|
+
localStorage.setItem("intl-party-locale", newLocale);
|
|
428
|
+
}
|
|
429
|
+
setLocale(newLocale);
|
|
430
|
+
},
|
|
431
|
+
[setLocale]
|
|
432
|
+
);
|
|
433
|
+
const loadPreference = (0, import_react3.useCallback)(() => {
|
|
434
|
+
if (typeof window === "undefined") return null;
|
|
435
|
+
const saved = localStorage.getItem("intl-party-locale");
|
|
436
|
+
if (saved && i18n.getAvailableLocales().includes(saved)) {
|
|
437
|
+
return saved;
|
|
438
|
+
}
|
|
439
|
+
return null;
|
|
440
|
+
}, [i18n]);
|
|
441
|
+
const clearPreference = (0, import_react3.useCallback)(() => {
|
|
442
|
+
if (typeof window !== "undefined") {
|
|
443
|
+
localStorage.removeItem("intl-party-locale");
|
|
444
|
+
}
|
|
445
|
+
}, []);
|
|
446
|
+
return {
|
|
447
|
+
current: locale,
|
|
448
|
+
save: savePreference,
|
|
449
|
+
load: loadPreference,
|
|
450
|
+
clear: clearPreference
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
function isRTLLocale(locale) {
|
|
454
|
+
const rtlLocales = [
|
|
455
|
+
"ar",
|
|
456
|
+
"arc",
|
|
457
|
+
"ckb",
|
|
458
|
+
"dv",
|
|
459
|
+
"fa",
|
|
460
|
+
"ha",
|
|
461
|
+
"he",
|
|
462
|
+
"khw",
|
|
463
|
+
"ks",
|
|
464
|
+
"ku",
|
|
465
|
+
"ps",
|
|
466
|
+
"sd",
|
|
467
|
+
"ur",
|
|
468
|
+
"yi"
|
|
469
|
+
];
|
|
470
|
+
const baseLocale = locale.split("-")[0];
|
|
471
|
+
return rtlLocales.includes(baseLocale);
|
|
472
|
+
}
|
|
473
|
+
function useDirection() {
|
|
474
|
+
const { locale } = useI18nContext();
|
|
475
|
+
return (0, import_react3.useMemo)(() => {
|
|
476
|
+
return isRTLLocale(locale) ? "rtl" : "ltr";
|
|
477
|
+
}, [locale]);
|
|
478
|
+
}
|
|
479
|
+
function useFormatting() {
|
|
480
|
+
const { i18n } = useI18nContext();
|
|
481
|
+
return (0, import_react3.useMemo)(
|
|
482
|
+
() => ({
|
|
483
|
+
formatDate: (date, options) => i18n.formatDate(date, options),
|
|
484
|
+
formatNumber: (number, options) => i18n.formatNumber(number, options),
|
|
485
|
+
formatCurrency: (amount, currency, options) => i18n.formatCurrency(amount, currency, options),
|
|
486
|
+
formatRelativeTime: (value, unit, options) => i18n.formatRelativeTime(value, unit, options)
|
|
487
|
+
}),
|
|
488
|
+
[i18n]
|
|
489
|
+
);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// src/hooks/useNamespace.ts
|
|
493
|
+
var import_react4 = require("react");
|
|
494
|
+
function useNamespace() {
|
|
495
|
+
const { namespace, setNamespace } = useI18nContext();
|
|
496
|
+
return [namespace, setNamespace];
|
|
497
|
+
}
|
|
498
|
+
function useNamespaceInfo() {
|
|
499
|
+
const { namespace, i18n } = useI18nContext();
|
|
500
|
+
return (0, import_react4.useMemo)(() => {
|
|
501
|
+
const availableNamespaces = i18n.getAvailableNamespaces();
|
|
502
|
+
return {
|
|
503
|
+
current: namespace,
|
|
504
|
+
available: availableNamespaces,
|
|
505
|
+
isAvailable: availableNamespaces.includes(namespace)
|
|
506
|
+
};
|
|
507
|
+
}, [namespace, i18n]);
|
|
508
|
+
}
|
|
509
|
+
function useNamespaceSwitch() {
|
|
510
|
+
const { i18n, setNamespace } = useI18nContext();
|
|
511
|
+
const switchNamespace = (0, import_react4.useCallback)(
|
|
512
|
+
(namespace) => {
|
|
513
|
+
const availableNamespaces = i18n.getAvailableNamespaces();
|
|
514
|
+
if (!availableNamespaces.includes(namespace)) {
|
|
515
|
+
throw new Error(
|
|
516
|
+
`Namespace "${namespace}" is not available. Available namespaces: ${availableNamespaces.join(", ")}`
|
|
517
|
+
);
|
|
518
|
+
}
|
|
519
|
+
setNamespace(namespace);
|
|
520
|
+
},
|
|
521
|
+
[i18n, setNamespace]
|
|
522
|
+
);
|
|
523
|
+
const isNamespaceAvailable = (0, import_react4.useCallback)(
|
|
524
|
+
(namespace) => {
|
|
525
|
+
return i18n.getAvailableNamespaces().includes(namespace);
|
|
526
|
+
},
|
|
527
|
+
[i18n]
|
|
528
|
+
);
|
|
529
|
+
return {
|
|
530
|
+
switchNamespace,
|
|
531
|
+
isNamespaceAvailable,
|
|
532
|
+
availableNamespaces: i18n.getAvailableNamespaces()
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
function useMultipleNamespaces(namespaces) {
|
|
536
|
+
const { i18n } = useI18nContext();
|
|
537
|
+
const translators = (0, import_react4.useMemo)(() => {
|
|
538
|
+
return namespaces.reduce(
|
|
539
|
+
(acc, ns) => {
|
|
540
|
+
acc[ns] = i18n.createScopedTranslator(ns);
|
|
541
|
+
return acc;
|
|
542
|
+
},
|
|
543
|
+
{}
|
|
544
|
+
);
|
|
545
|
+
}, [i18n, namespaces]);
|
|
546
|
+
const isAllAvailable = (0, import_react4.useMemo)(() => {
|
|
547
|
+
const available = i18n.getAvailableNamespaces();
|
|
548
|
+
return namespaces.every((ns) => available.includes(ns));
|
|
549
|
+
}, [i18n, namespaces]);
|
|
550
|
+
const getMissingNamespaces = (0, import_react4.useCallback)(() => {
|
|
551
|
+
const available = i18n.getAvailableNamespaces();
|
|
552
|
+
return namespaces.filter((ns) => !available.includes(ns));
|
|
553
|
+
}, [i18n, namespaces]);
|
|
554
|
+
return {
|
|
555
|
+
translators,
|
|
556
|
+
isAllAvailable,
|
|
557
|
+
getMissingNamespaces
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
function useNamespacePreloading() {
|
|
561
|
+
const { i18n, locale } = useI18nContext();
|
|
562
|
+
const preloadNamespace = (0, import_react4.useCallback)(
|
|
563
|
+
async (namespace) => {
|
|
564
|
+
await i18n.preloadTranslations(locale, namespace);
|
|
565
|
+
},
|
|
566
|
+
[i18n, locale]
|
|
567
|
+
);
|
|
568
|
+
const preloadNamespaces = (0, import_react4.useCallback)(
|
|
569
|
+
async (namespaces) => {
|
|
570
|
+
await i18n.preloadTranslations(locale, namespaces);
|
|
571
|
+
},
|
|
572
|
+
[i18n, locale]
|
|
573
|
+
);
|
|
574
|
+
return {
|
|
575
|
+
preloadNamespace,
|
|
576
|
+
preloadNamespaces
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// src/components/Trans.tsx
|
|
581
|
+
var import_react5 = __toESM(require("react"));
|
|
582
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
583
|
+
function Trans({
|
|
584
|
+
i18nKey,
|
|
585
|
+
namespace,
|
|
586
|
+
values = {},
|
|
587
|
+
components = {},
|
|
588
|
+
count,
|
|
589
|
+
fallback,
|
|
590
|
+
children
|
|
591
|
+
}) {
|
|
592
|
+
const t = useTranslations(namespace);
|
|
593
|
+
const rendered = (0, import_react5.useMemo)(() => {
|
|
594
|
+
const options = {
|
|
595
|
+
interpolation: values,
|
|
596
|
+
count,
|
|
597
|
+
fallback
|
|
598
|
+
};
|
|
599
|
+
const translation = t(i18nKey, options);
|
|
600
|
+
if (Object.keys(components).length === 0) {
|
|
601
|
+
return translation;
|
|
602
|
+
}
|
|
603
|
+
return parseTranslationWithComponents(translation, components);
|
|
604
|
+
}, [t, i18nKey, values, components, count, fallback]);
|
|
605
|
+
if (typeof rendered === "string") {
|
|
606
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react5.Fragment, { children: rendered });
|
|
607
|
+
}
|
|
608
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react5.Fragment, { children: rendered });
|
|
609
|
+
}
|
|
610
|
+
function ConditionalTrans({
|
|
611
|
+
when = true,
|
|
612
|
+
fallbackComponent,
|
|
613
|
+
...transProps
|
|
614
|
+
}) {
|
|
615
|
+
if (!when) {
|
|
616
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react5.Fragment, { children: fallbackComponent });
|
|
617
|
+
}
|
|
618
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Trans, { ...transProps });
|
|
619
|
+
}
|
|
620
|
+
function PluralTrans({
|
|
621
|
+
count,
|
|
622
|
+
zero,
|
|
623
|
+
one,
|
|
624
|
+
other,
|
|
625
|
+
i18nKey,
|
|
626
|
+
...props
|
|
627
|
+
}) {
|
|
628
|
+
const selectedKey = (0, import_react5.useMemo)(() => {
|
|
629
|
+
if (count === 0 && zero) return zero;
|
|
630
|
+
if (count === 1 && one) return one;
|
|
631
|
+
if (other) return other;
|
|
632
|
+
return i18nKey;
|
|
633
|
+
}, [count, zero, one, other, i18nKey]);
|
|
634
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
635
|
+
Trans,
|
|
636
|
+
{
|
|
637
|
+
...props,
|
|
638
|
+
i18nKey: selectedKey,
|
|
639
|
+
count,
|
|
640
|
+
values: { count, ...props.values }
|
|
641
|
+
}
|
|
642
|
+
);
|
|
643
|
+
}
|
|
644
|
+
function RichTrans({
|
|
645
|
+
allowedTags = ["strong", "em", "br", "span"],
|
|
646
|
+
sanitize = true,
|
|
647
|
+
...transProps
|
|
648
|
+
}) {
|
|
649
|
+
const t = useTranslations(transProps.namespace);
|
|
650
|
+
const rendered = (0, import_react5.useMemo)(() => {
|
|
651
|
+
const translation = t(transProps.i18nKey, {
|
|
652
|
+
interpolation: transProps.values,
|
|
653
|
+
count: transProps.count,
|
|
654
|
+
fallback: transProps.fallback
|
|
655
|
+
});
|
|
656
|
+
if (sanitize) {
|
|
657
|
+
const sanitized = translation.replace(
|
|
658
|
+
/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
|
|
659
|
+
""
|
|
660
|
+
);
|
|
661
|
+
return parseHTMLString(sanitized, allowedTags);
|
|
662
|
+
}
|
|
663
|
+
return parseHTMLString(translation, allowedTags);
|
|
664
|
+
}, [t, transProps, allowedTags, sanitize]);
|
|
665
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react5.Fragment, { children: rendered });
|
|
666
|
+
}
|
|
667
|
+
function parseTranslationWithComponents(text, components) {
|
|
668
|
+
const parts = [];
|
|
669
|
+
let currentIndex = 0;
|
|
670
|
+
const componentRegex = /<(\w+)>(.*?)<\/\1>/g;
|
|
671
|
+
let match;
|
|
672
|
+
while ((match = componentRegex.exec(text)) !== null) {
|
|
673
|
+
const [fullMatch, componentKey, content] = match;
|
|
674
|
+
const matchStart = match.index;
|
|
675
|
+
if (matchStart > currentIndex) {
|
|
676
|
+
parts.push(text.slice(currentIndex, matchStart));
|
|
677
|
+
}
|
|
678
|
+
if (components[componentKey]) {
|
|
679
|
+
if (import_react5.default.isValidElement(components[componentKey])) {
|
|
680
|
+
parts.push(
|
|
681
|
+
import_react5.default.cloneElement(
|
|
682
|
+
components[componentKey],
|
|
683
|
+
{ key: parts.length },
|
|
684
|
+
content
|
|
685
|
+
)
|
|
686
|
+
);
|
|
687
|
+
} else {
|
|
688
|
+
parts.push(components[componentKey]);
|
|
689
|
+
}
|
|
690
|
+
} else {
|
|
691
|
+
parts.push(content);
|
|
692
|
+
}
|
|
693
|
+
currentIndex = matchStart + fullMatch.length;
|
|
694
|
+
}
|
|
695
|
+
if (currentIndex < text.length) {
|
|
696
|
+
parts.push(text.slice(currentIndex));
|
|
697
|
+
}
|
|
698
|
+
return parts.length > 0 ? parts : [text];
|
|
699
|
+
}
|
|
700
|
+
function parseHTMLString(html, allowedTags) {
|
|
701
|
+
if (!allowedTags.length) {
|
|
702
|
+
return html;
|
|
703
|
+
}
|
|
704
|
+
const tagRegex = new RegExp(
|
|
705
|
+
`<(/?)(${allowedTags.join("|")})(?:\\s[^>]*)?>`,
|
|
706
|
+
"gi"
|
|
707
|
+
);
|
|
708
|
+
const parts = html.split(tagRegex).filter(Boolean);
|
|
709
|
+
const elements = [];
|
|
710
|
+
let i = 0;
|
|
711
|
+
while (i < parts.length) {
|
|
712
|
+
const part = parts[i];
|
|
713
|
+
if (allowedTags.some((tag) => part.toLowerCase() === tag)) {
|
|
714
|
+
const tag = part.toLowerCase();
|
|
715
|
+
let content = "";
|
|
716
|
+
let depth = 1;
|
|
717
|
+
i++;
|
|
718
|
+
while (i < parts.length && depth > 0) {
|
|
719
|
+
const nextPart = parts[i];
|
|
720
|
+
if (nextPart === "/") {
|
|
721
|
+
i++;
|
|
722
|
+
if (i < parts.length && parts[i].toLowerCase() === tag) {
|
|
723
|
+
depth--;
|
|
724
|
+
i++;
|
|
725
|
+
}
|
|
726
|
+
} else if (allowedTags.some((t) => nextPart.toLowerCase() === t)) {
|
|
727
|
+
depth++;
|
|
728
|
+
content += `<${nextPart}>`;
|
|
729
|
+
i++;
|
|
730
|
+
} else {
|
|
731
|
+
content += nextPart;
|
|
732
|
+
i++;
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
elements.push(
|
|
736
|
+
import_react5.default.createElement(tag, { key: elements.length }, content)
|
|
737
|
+
);
|
|
738
|
+
} else {
|
|
739
|
+
elements.push(part);
|
|
740
|
+
i++;
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
return elements.length === 1 ? elements[0] : elements;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
// src/components/LocaleSelector.tsx
|
|
747
|
+
var import_react6 = require("react");
|
|
748
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
749
|
+
function LocaleSelector({
|
|
750
|
+
className,
|
|
751
|
+
style,
|
|
752
|
+
placeholder = "Select language",
|
|
753
|
+
disabled = false,
|
|
754
|
+
showNativeNames = true,
|
|
755
|
+
filterLocales,
|
|
756
|
+
formatLocale,
|
|
757
|
+
onLocaleChange,
|
|
758
|
+
variant = "select"
|
|
759
|
+
}) {
|
|
760
|
+
const [currentLocale, setLocale] = useLocale();
|
|
761
|
+
const { available } = useLocaleInfo();
|
|
762
|
+
const filteredLocales = (0, import_react6.useMemo)(() => {
|
|
763
|
+
return filterLocales ? available.filter(filterLocales) : available;
|
|
764
|
+
}, [available, filterLocales]);
|
|
765
|
+
const handleLocaleChange = (locale) => {
|
|
766
|
+
setLocale(locale);
|
|
767
|
+
onLocaleChange?.(locale);
|
|
768
|
+
};
|
|
769
|
+
const formatLocaleDisplay = (locale) => {
|
|
770
|
+
if (formatLocale) {
|
|
771
|
+
return formatLocale(locale);
|
|
772
|
+
}
|
|
773
|
+
if (showNativeNames) {
|
|
774
|
+
try {
|
|
775
|
+
const intlLocale = new Intl.Locale(locale);
|
|
776
|
+
const displayNames = new Intl.DisplayNames([locale], {
|
|
777
|
+
type: "language"
|
|
778
|
+
});
|
|
779
|
+
return displayNames.of(intlLocale.language) || locale;
|
|
780
|
+
} catch {
|
|
781
|
+
return locale;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
return locale;
|
|
785
|
+
};
|
|
786
|
+
if (variant === "select") {
|
|
787
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
788
|
+
"select",
|
|
789
|
+
{
|
|
790
|
+
className,
|
|
791
|
+
style,
|
|
792
|
+
value: currentLocale,
|
|
793
|
+
disabled,
|
|
794
|
+
onChange: (e) => handleLocaleChange(e.target.value),
|
|
795
|
+
children: [
|
|
796
|
+
placeholder && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "", disabled: true, children: placeholder }),
|
|
797
|
+
filteredLocales.map((locale) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: locale, children: formatLocaleDisplay(locale) }, locale))
|
|
798
|
+
]
|
|
799
|
+
}
|
|
800
|
+
);
|
|
801
|
+
}
|
|
802
|
+
if (variant === "buttons") {
|
|
803
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className, style, children: filteredLocales.map((locale) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
804
|
+
"button",
|
|
805
|
+
{
|
|
806
|
+
type: "button",
|
|
807
|
+
disabled,
|
|
808
|
+
onClick: () => handleLocaleChange(locale),
|
|
809
|
+
style: {
|
|
810
|
+
fontWeight: currentLocale === locale ? "bold" : "normal",
|
|
811
|
+
opacity: currentLocale === locale ? 1 : 0.7
|
|
812
|
+
},
|
|
813
|
+
children: formatLocaleDisplay(locale)
|
|
814
|
+
},
|
|
815
|
+
locale
|
|
816
|
+
)) });
|
|
817
|
+
}
|
|
818
|
+
return null;
|
|
819
|
+
}
|
|
820
|
+
function FlagLocaleSelector({
|
|
821
|
+
flagMap = {},
|
|
822
|
+
showFlags = true,
|
|
823
|
+
showLabels = true,
|
|
824
|
+
variant = "buttons",
|
|
825
|
+
...props
|
|
826
|
+
}) {
|
|
827
|
+
const [currentLocale, setLocale] = useLocale();
|
|
828
|
+
const { available } = useLocaleInfo();
|
|
829
|
+
const defaultFlagMap = {
|
|
830
|
+
en: "\u{1F1FA}\u{1F1F8}",
|
|
831
|
+
es: "\u{1F1EA}\u{1F1F8}",
|
|
832
|
+
fr: "\u{1F1EB}\u{1F1F7}",
|
|
833
|
+
de: "\u{1F1E9}\u{1F1EA}",
|
|
834
|
+
it: "\u{1F1EE}\u{1F1F9}",
|
|
835
|
+
pt: "\u{1F1F5}\u{1F1F9}",
|
|
836
|
+
ru: "\u{1F1F7}\u{1F1FA}",
|
|
837
|
+
ja: "\u{1F1EF}\u{1F1F5}",
|
|
838
|
+
ko: "\u{1F1F0}\u{1F1F7}",
|
|
839
|
+
zh: "\u{1F1E8}\u{1F1F3}"
|
|
840
|
+
};
|
|
841
|
+
const combinedFlagMap = { ...defaultFlagMap, ...flagMap };
|
|
842
|
+
const formatLocaleWithFlag = (locale) => {
|
|
843
|
+
const parts = [];
|
|
844
|
+
if (showFlags && combinedFlagMap[locale]) {
|
|
845
|
+
parts.push(combinedFlagMap[locale]);
|
|
846
|
+
}
|
|
847
|
+
if (showLabels) {
|
|
848
|
+
if (props.formatLocale) {
|
|
849
|
+
parts.push(props.formatLocale(locale));
|
|
850
|
+
} else {
|
|
851
|
+
try {
|
|
852
|
+
const displayNames = new Intl.DisplayNames([locale], {
|
|
853
|
+
type: "language"
|
|
854
|
+
});
|
|
855
|
+
const intlLocale = new Intl.Locale(locale);
|
|
856
|
+
parts.push(displayNames.of(intlLocale.language) || locale);
|
|
857
|
+
} catch {
|
|
858
|
+
parts.push(locale);
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
return parts.join(" ");
|
|
863
|
+
};
|
|
864
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
865
|
+
LocaleSelector,
|
|
866
|
+
{
|
|
867
|
+
...props,
|
|
868
|
+
variant,
|
|
869
|
+
formatLocale: formatLocaleWithFlag,
|
|
870
|
+
showNativeNames: false
|
|
871
|
+
}
|
|
872
|
+
);
|
|
873
|
+
}
|
|
874
|
+
function CompactLocaleSelector({
|
|
875
|
+
maxVisibleLocales = 3,
|
|
876
|
+
...props
|
|
877
|
+
}) {
|
|
878
|
+
const { available } = useLocaleInfo();
|
|
879
|
+
if (available.length <= maxVisibleLocales) {
|
|
880
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(LocaleSelector, { ...props, variant: "buttons" });
|
|
881
|
+
}
|
|
882
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(LocaleSelector, { ...props, variant: "select" });
|
|
883
|
+
}
|
|
884
|
+
function AccessibleLocaleSelector({
|
|
885
|
+
ariaLabel = "Select language",
|
|
886
|
+
ariaDescribedBy,
|
|
887
|
+
...props
|
|
888
|
+
}) {
|
|
889
|
+
const [currentLocale] = useLocale();
|
|
890
|
+
const enhancedProps = {
|
|
891
|
+
...props,
|
|
892
|
+
style: {
|
|
893
|
+
...props.style,
|
|
894
|
+
// Ensure minimum touch target size for accessibility
|
|
895
|
+
minHeight: "44px",
|
|
896
|
+
minWidth: "44px"
|
|
897
|
+
}
|
|
898
|
+
};
|
|
899
|
+
if (props.variant === "select") {
|
|
900
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
901
|
+
LocaleSelector,
|
|
902
|
+
{
|
|
903
|
+
...enhancedProps,
|
|
904
|
+
className: `${props.className || ""} accessible-locale-selector`
|
|
905
|
+
}
|
|
906
|
+
);
|
|
907
|
+
}
|
|
908
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
909
|
+
"div",
|
|
910
|
+
{
|
|
911
|
+
role: "group",
|
|
912
|
+
"aria-label": ariaLabel,
|
|
913
|
+
"aria-describedby": ariaDescribedBy,
|
|
914
|
+
className: props.className,
|
|
915
|
+
style: props.style,
|
|
916
|
+
children: [
|
|
917
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(LocaleSelector, { ...enhancedProps }),
|
|
918
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "sr-only", children: [
|
|
919
|
+
"Current language: ",
|
|
920
|
+
currentLocale
|
|
921
|
+
] })
|
|
922
|
+
]
|
|
923
|
+
}
|
|
924
|
+
);
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
// src/index.tsx
|
|
928
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
929
|
+
var VERSION = "0.1.0";
|
|
930
|
+
function createI18nHook() {
|
|
931
|
+
return {
|
|
932
|
+
useTranslations: useTypedTranslations,
|
|
933
|
+
useT: useTypedTranslations
|
|
934
|
+
};
|
|
935
|
+
}
|
|
936
|
+
function createNamespaceHOC(namespace) {
|
|
937
|
+
return function withNamespace(Component) {
|
|
938
|
+
return function NamespacedComponent(props) {
|
|
939
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ScopedI18nProvider, { namespace, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Component, { ...props }) });
|
|
940
|
+
};
|
|
941
|
+
};
|
|
942
|
+
}
|
|
943
|
+
var I18nErrorBoundary = class extends import_react7.default.Component {
|
|
944
|
+
constructor(props) {
|
|
945
|
+
super(props);
|
|
946
|
+
this.state = { hasError: false };
|
|
947
|
+
}
|
|
948
|
+
static getDerivedStateFromError(error) {
|
|
949
|
+
return { hasError: true, error };
|
|
950
|
+
}
|
|
951
|
+
componentDidCatch(error, errorInfo) {
|
|
952
|
+
this.props.onError?.(error, errorInfo);
|
|
953
|
+
}
|
|
954
|
+
render() {
|
|
955
|
+
if (this.state.hasError) {
|
|
956
|
+
const FallbackComponent = this.props.fallback;
|
|
957
|
+
if (FallbackComponent && this.state.error) {
|
|
958
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FallbackComponent, { error: this.state.error });
|
|
959
|
+
}
|
|
960
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
961
|
+
"div",
|
|
962
|
+
{
|
|
963
|
+
style: {
|
|
964
|
+
padding: "1rem",
|
|
965
|
+
border: "1px solid red",
|
|
966
|
+
borderRadius: "4px"
|
|
967
|
+
},
|
|
968
|
+
children: [
|
|
969
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { children: "Translation Error" }),
|
|
970
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { children: "Something went wrong with translations." }),
|
|
971
|
+
process.env.NODE_ENV === "development" && this.state.error && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("details", { children: [
|
|
972
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("summary", { children: "Error details" }),
|
|
973
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("pre", { children: this.state.error.message })
|
|
974
|
+
] })
|
|
975
|
+
]
|
|
976
|
+
}
|
|
977
|
+
);
|
|
978
|
+
}
|
|
979
|
+
return this.props.children;
|
|
980
|
+
}
|
|
981
|
+
};
|
|
982
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
983
|
+
0 && (module.exports = {
|
|
984
|
+
AccessibleLocaleSelector,
|
|
985
|
+
CompactLocaleSelector,
|
|
986
|
+
ConditionalTrans,
|
|
987
|
+
FlagLocaleSelector,
|
|
988
|
+
I18nErrorBoundary,
|
|
989
|
+
I18nProvider,
|
|
990
|
+
LocaleSelector,
|
|
991
|
+
PluralTrans,
|
|
992
|
+
RichTrans,
|
|
993
|
+
ScopedI18nProvider,
|
|
994
|
+
Trans,
|
|
995
|
+
TypedI18nProvider,
|
|
996
|
+
VERSION,
|
|
997
|
+
createI18nHook,
|
|
998
|
+
createNamespaceHOC,
|
|
999
|
+
useBrowserLocale,
|
|
1000
|
+
useDirection,
|
|
1001
|
+
useFormatting,
|
|
1002
|
+
useHasTranslation,
|
|
1003
|
+
useI18nContext,
|
|
1004
|
+
useInterpolatedTranslation,
|
|
1005
|
+
useLocale,
|
|
1006
|
+
useLocaleInfo,
|
|
1007
|
+
useLocalePreference,
|
|
1008
|
+
useLocaleSwitch,
|
|
1009
|
+
useMultipleNamespaces,
|
|
1010
|
+
useMultipleTranslations,
|
|
1011
|
+
useNamespace,
|
|
1012
|
+
useNamespaceInfo,
|
|
1013
|
+
useNamespacePreloading,
|
|
1014
|
+
useNamespaceSwitch,
|
|
1015
|
+
useOptionalTranslation,
|
|
1016
|
+
usePluralization,
|
|
1017
|
+
useScopedTranslations,
|
|
1018
|
+
useT,
|
|
1019
|
+
useTranslationValue,
|
|
1020
|
+
useTranslationWithFallback,
|
|
1021
|
+
useTranslations,
|
|
1022
|
+
useTypedI18nContext,
|
|
1023
|
+
useTypedT,
|
|
1024
|
+
useTypedTranslations,
|
|
1025
|
+
withI18n
|
|
1026
|
+
});
|