lokal-react 1.3.2 → 1.3.6

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/dist/index.js CHANGED
@@ -3,6 +3,9 @@ var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __esm = (fn, res) => function __init() {
7
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
+ };
6
9
  var __export = (target, all) => {
7
10
  for (var name in all)
8
11
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -17,29 +20,61 @@ var __copyProps = (to, from, except, desc) => {
17
20
  };
18
21
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
22
 
20
- // packages/react/src/index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
23
+ // packages/react/src/context/LokalContext.tsx
24
+ var LokalContext_exports = {};
25
+ __export(LokalContext_exports, {
23
26
  LokalProvider: () => LokalProvider,
24
- useLokal: () => useLokal
27
+ T: () => T,
28
+ default: () => LokalContext_default,
29
+ useFormatters: () => useFormatters,
30
+ useHydrated: () => useHydrated,
31
+ useIsLoading: () => useIsLoading,
32
+ useLazyTranslations: () => useLazyTranslations,
33
+ useLocale: () => useLocale,
34
+ useLokal: () => useLokal,
35
+ useSafeTranslations: () => useSafeTranslations,
36
+ useTranslate: () => useTranslate
25
37
  });
26
- module.exports = __toCommonJS(index_exports);
27
-
28
- // packages/react/src/context/LokalContext.tsx
29
- var import_react = require("react");
30
- var import_jsx_runtime = require("react/jsx-runtime");
31
- var defaultStorage = {
32
- getItem: (key) => {
33
- if (typeof window === "undefined") return Promise.resolve(null);
34
- return Promise.resolve(localStorage.getItem(key));
35
- },
36
- setItem: (key, value) => {
37
- if (typeof window === "undefined") return Promise.resolve();
38
- localStorage.setItem(key, value);
39
- return Promise.resolve();
38
+ function getPluralCategory(locale, count) {
39
+ const rules = {
40
+ en: (n) => n === 1 ? "one" : "other",
41
+ fr: (n) => n === 0 || n === 1 ? "one" : "many",
42
+ es: (n) => n === 1 ? "one" : "many",
43
+ de: (n) => n === 1 ? "one" : "other",
44
+ it: (n) => n === 1 ? "one" : "other",
45
+ ru: (n) => {
46
+ const mod10 = n % 10;
47
+ const mod100 = n % 100;
48
+ if (n === 1) return "one";
49
+ if (mod10 >= 2 && mod10 <= 4 && !(mod100 >= 12 && mod100 <= 14)) return "few";
50
+ if (mod10 === 0 || mod10 >= 5 || mod10 >= 11 && mod10 <= 15) return "many";
51
+ return "other";
52
+ },
53
+ ar: (n) => {
54
+ if (n === 0) return "zero";
55
+ if (n === 1) return "one";
56
+ if (n === 2) return "two";
57
+ const mod100 = n % 100;
58
+ if (mod100 >= 3 && mod100 <= 10) return "few";
59
+ if (mod100 >= 11 && mod100 <= 99) return "many";
60
+ return "other";
61
+ }
62
+ };
63
+ const rule = rules[locale] || rules["en"];
64
+ return rule(count);
65
+ }
66
+ function getNestedValue(obj, path) {
67
+ const keys = path.split(".");
68
+ let value = obj;
69
+ for (const k of keys) {
70
+ if (value && typeof value === "object" && k in value) {
71
+ value = value[k];
72
+ } else {
73
+ return "";
74
+ }
40
75
  }
41
- };
42
- var LokalContext = (0, import_react.createContext)(null);
76
+ return typeof value === "string" ? value : "";
77
+ }
43
78
  function LokalProvider({
44
79
  children,
45
80
  locale: initialLocale = "en",
@@ -48,31 +83,46 @@ function LokalProvider({
48
83
  storage = defaultStorage,
49
84
  namespace = "locales",
50
85
  defaultLocale = "en",
51
- onLocaleChange
86
+ onLocaleChange,
87
+ initialLocale: ssrInitialLocale,
88
+ initialTranslations: ssrInitialTranslations,
89
+ fallbackLocale = "en"
52
90
  }) {
53
- const [locale, setLocaleState] = (0, import_react.useState)(initialLocale);
54
- const [translations, setTranslations] = (0, import_react.useState)(initialTranslations);
55
- const [isLoading, setIsLoading] = (0, import_react.useState)(true);
91
+ const [locale, setLocaleState] = (0, import_react.useState)(ssrInitialLocale || initialLocale);
92
+ const [translations, setTranslations] = (0, import_react.useState)(ssrInitialTranslations || initialTranslations);
93
+ const [isLoading, setIsLoading] = (0, import_react.useState)(!!ssrInitialLocale);
94
+ const [isHydrated, setIsHydrated] = (0, import_react.useState)(!!ssrInitialLocale);
95
+ (0, import_react.useEffect)(() => {
96
+ if (ssrInitialLocale && !isHydrated) {
97
+ setIsHydrated(true);
98
+ setIsLoading(false);
99
+ }
100
+ }, [ssrInitialLocale, isHydrated]);
56
101
  (0, import_react.useEffect)(() => {
57
102
  const loadLocale = async () => {
58
103
  try {
59
104
  const savedLocale = await storage.getItem(`${namespace}-locale`);
60
105
  if (savedLocale && locales.includes(savedLocale)) {
61
106
  setLocaleState(savedLocale);
62
- } else {
63
- const browserLocale = navigator.language.split("-")[0];
64
- if (locales.includes(browserLocale)) {
65
- setLocaleState(browserLocale);
107
+ } else if (!ssrInitialLocale) {
108
+ if (typeof navigator !== "undefined") {
109
+ const browserLocale = navigator.language.split("-")[0];
110
+ if (locales.includes(browserLocale)) {
111
+ setLocaleState(browserLocale);
112
+ }
66
113
  }
67
114
  }
68
115
  } catch (error) {
69
116
  console.warn("Failed to load locale from storage:", error);
117
+ if (!ssrInitialLocale) {
118
+ setLocaleState(fallbackLocale);
119
+ }
70
120
  } finally {
71
121
  setIsLoading(false);
72
122
  }
73
123
  };
74
124
  loadLocale();
75
- }, [storage, locales, namespace]);
125
+ }, [storage, locales, namespace, ssrInitialLocale, fallbackLocale]);
76
126
  (0, import_react.useEffect)(() => {
77
127
  const loadTranslations = async () => {
78
128
  try {
@@ -87,32 +137,24 @@ function LokalProvider({
87
137
  console.warn("Failed to load translations from storage:", error);
88
138
  }
89
139
  };
90
- if (!isLoading) {
140
+ if (!isLoading && !ssrInitialTranslations) {
91
141
  loadTranslations();
92
142
  }
93
- }, [locale, storage, namespace, isLoading]);
143
+ }, [locale, storage, namespace, isLoading, ssrInitialTranslations]);
94
144
  const setLocale = (0, import_react.useCallback)((newLocale) => {
95
145
  if (!locales.includes(newLocale)) {
96
146
  console.warn(`Locale ${newLocale} is not in the list of available locales`);
97
147
  return;
98
148
  }
99
149
  setLocaleState(newLocale);
100
- storage.setItem(`${namespace}-locale`, newLocale);
150
+ storage.setItem(`${namespace}-locale`, newLocale).catch(console.warn);
101
151
  if (onLocaleChange) {
102
152
  onLocaleChange(newLocale);
103
153
  }
104
154
  }, [locales, storage, namespace, onLocaleChange]);
105
- const t = (0, import_react.useCallback)((key, params) => {
106
- const keys = key.split(".");
107
- let value = translations;
108
- for (const k of keys) {
109
- if (value && typeof value === "object" && k in value) {
110
- value = value[k];
111
- } else {
112
- return key;
113
- }
114
- }
115
- if (typeof value !== "string") {
155
+ const translate = (0, import_react.useCallback)((key, params) => {
156
+ const value = getNestedValue(translations, key);
157
+ if (!value) {
116
158
  return key;
117
159
  }
118
160
  if (params) {
@@ -123,13 +165,85 @@ function LokalProvider({
123
165
  }
124
166
  return value;
125
167
  }, [translations]);
168
+ const translatePlural = (0, import_react.useCallback)((key, params) => {
169
+ const { count, ...restParams } = params;
170
+ const pluralCategory = getPluralCategory(locale, count);
171
+ const pluralKey = `${key}_${pluralCategory}`;
172
+ let value = getNestedValue(translations, pluralKey);
173
+ if (!value) {
174
+ value = getNestedValue(translations, key);
175
+ }
176
+ if (!value) {
177
+ return key;
178
+ }
179
+ const allParams = { count, ...restParams };
180
+ return Object.entries(allParams).reduce(
181
+ (str, [paramKey, paramValue]) => str.replace(new RegExp(`{{${paramKey}}}`, "g"), String(paramValue)),
182
+ value
183
+ );
184
+ }, [locale, translations]);
185
+ const translateGender = (0, import_react.useCallback)((key, params) => {
186
+ const { gender, ...restParams } = params;
187
+ const genderKey = `${key}_${gender}`;
188
+ let value = getNestedValue(translations, genderKey);
189
+ if (!value) {
190
+ value = getNestedValue(translations, key);
191
+ }
192
+ if (!value) {
193
+ return key;
194
+ }
195
+ const allParams = { gender, ...restParams };
196
+ return Object.entries(allParams).reduce(
197
+ (str, [paramKey, paramValue]) => str.replace(new RegExp(`{{${paramKey}}}`, "g"), String(paramValue)),
198
+ value
199
+ );
200
+ }, [translations]);
201
+ const translateChoice = (0, import_react.useCallback)((key, params) => {
202
+ const { value } = params;
203
+ const choiceKey = `${key}_${value}`;
204
+ let translation = getNestedValue(translations, choiceKey);
205
+ if (!translation) {
206
+ translation = getNestedValue(translations, key);
207
+ }
208
+ if (!translation) {
209
+ return key;
210
+ }
211
+ return translation;
212
+ }, [translations]);
213
+ const t = (0, import_react.useCallback)(Object.assign(
214
+ translate,
215
+ {
216
+ plural: translatePlural,
217
+ gender: translateGender,
218
+ choice: translateChoice
219
+ }
220
+ ), [translate, translatePlural, translateGender, translateChoice]);
221
+ const formatDate = (0, import_react.useCallback)((date, options) => {
222
+ const dateObj = typeof date === "string" ? new Date(date) : date;
223
+ try {
224
+ return new Intl.DateTimeFormat(locale, options).format(dateObj);
225
+ } catch (error) {
226
+ console.warn("Date formatting failed:", error);
227
+ return dateObj.toLocaleDateString();
228
+ }
229
+ }, [locale]);
230
+ const formatNumber = (0, import_react.useCallback)((num, options) => {
231
+ try {
232
+ return new Intl.NumberFormat(locale, options).format(num);
233
+ } catch (error) {
234
+ console.warn("Number formatting failed:", error);
235
+ return num.toString();
236
+ }
237
+ }, [locale]);
126
238
  const contextValue = {
127
239
  locale,
128
240
  setLocale,
129
241
  locales,
130
242
  t,
131
243
  translations,
132
- isLoading
244
+ isLoading,
245
+ formatDate,
246
+ formatNumber
133
247
  };
134
248
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LokalContext.Provider, { value: contextValue, children });
135
249
  }
@@ -140,4 +254,203 @@ function useLokal() {
140
254
  }
141
255
  return context;
142
256
  }
257
+ function useTranslate() {
258
+ const { t } = useLokal();
259
+ return t;
260
+ }
261
+ function useLocale() {
262
+ const { locale, setLocale, locales } = useLokal();
263
+ return { locale, setLocale, locales };
264
+ }
265
+ function useFormatters() {
266
+ const { formatDate, formatNumber } = useLokal();
267
+ return { formatDate, formatNumber };
268
+ }
269
+ function useIsLoading() {
270
+ const { isLoading } = useLokal();
271
+ return isLoading;
272
+ }
273
+ function T({
274
+ children,
275
+ params,
276
+ plural,
277
+ gender,
278
+ className,
279
+ as: Component = "span"
280
+ }) {
281
+ const { t } = useLokal();
282
+ let translatedText;
283
+ if (plural !== void 0) {
284
+ translatedText = t.plural(children, { count: plural, ...params || {} });
285
+ } else if (gender) {
286
+ translatedText = t.gender(children, { gender, ...params || {} });
287
+ } else {
288
+ translatedText = t(children, params);
289
+ }
290
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Component, { className, children: translatedText });
291
+ }
292
+ function useLazyTranslations(namespace) {
293
+ const { t, translations, isLoading } = useLokal();
294
+ const translate = (0, import_react.useCallback)((key, params) => {
295
+ const namespacedKey = `${namespace}.${key}`;
296
+ const value = getNestedValue(translations, namespacedKey);
297
+ if (!value) {
298
+ return key;
299
+ }
300
+ if (params) {
301
+ return Object.entries(params).reduce(
302
+ (str, [paramKey, paramValue]) => str.replace(new RegExp(`{{${paramKey}}}`, "g"), String(paramValue)),
303
+ value
304
+ );
305
+ }
306
+ return value;
307
+ }, [translations, namespace]);
308
+ return { t: translate, isLoading };
309
+ }
310
+ function useHydrated() {
311
+ const [hydrated, setHydrated] = (0, import_react.useState)(false);
312
+ (0, import_react.useEffect)(() => {
313
+ setHydrated(true);
314
+ }, []);
315
+ return hydrated;
316
+ }
317
+ function useSafeTranslations() {
318
+ const { t } = useLokal();
319
+ const isHydrated = useHydrated();
320
+ const safeT = (key, params) => {
321
+ if (!isHydrated) {
322
+ return key;
323
+ }
324
+ return t(key, params);
325
+ };
326
+ safeT.plural = (key, params) => {
327
+ if (!isHydrated) return key;
328
+ return t.plural(key, params);
329
+ };
330
+ safeT.gender = (key, params) => {
331
+ if (!isHydrated) return key;
332
+ return t.gender(key, params);
333
+ };
334
+ safeT.choice = (key, params) => {
335
+ if (!isHydrated) return key;
336
+ return t.choice(key, params);
337
+ };
338
+ return { t: safeT, isHydrated };
339
+ }
340
+ var import_react, import_jsx_runtime, LokalContext, defaultStorage, LokalContext_default;
341
+ var init_LokalContext = __esm({
342
+ "packages/react/src/context/LokalContext.tsx"() {
343
+ "use strict";
344
+ import_react = require("react");
345
+ import_jsx_runtime = require("react/jsx-runtime");
346
+ LokalContext = (0, import_react.createContext)(null);
347
+ defaultStorage = {
348
+ getItem: (key) => {
349
+ if (typeof window === "undefined") return Promise.resolve(null);
350
+ return Promise.resolve(localStorage.getItem(key));
351
+ },
352
+ setItem: (key, value) => {
353
+ if (typeof window === "undefined") return Promise.resolve();
354
+ localStorage.setItem(key, value);
355
+ return Promise.resolve();
356
+ }
357
+ };
358
+ LokalContext_default = LokalContext;
359
+ }
360
+ });
361
+
362
+ // packages/react/src/index.ts
363
+ var index_exports = {};
364
+ __export(index_exports, {
365
+ LokalProvider: () => LokalProvider,
366
+ T: () => T,
367
+ createTranslate: () => createTranslate,
368
+ useFormatters: () => useFormatters,
369
+ useHydrated: () => useHydrated,
370
+ useIsLoading: () => useIsLoading,
371
+ useLazyTranslations: () => useLazyTranslations,
372
+ useLocale: () => useLocale,
373
+ useLokal: () => useLokal,
374
+ useSafeTranslations: () => useSafeTranslations,
375
+ useStandaloneTranslate: () => useStandaloneTranslate,
376
+ useTranslate: () => useTranslate
377
+ });
378
+ module.exports = __toCommonJS(index_exports);
379
+ init_LokalContext();
380
+
381
+ // packages/react/src/hooks/useStandaloneTranslate.ts
382
+ var import_react2 = require("react");
383
+ function getNestedValue2(obj, path) {
384
+ const keys = path.split(".");
385
+ let value = obj;
386
+ for (const k of keys) {
387
+ if (value && typeof value === "object" && k in value) {
388
+ value = value[k];
389
+ } else {
390
+ return "";
391
+ }
392
+ }
393
+ return typeof value === "string" ? value : "";
394
+ }
395
+ function getPluralCategory2(locale, count) {
396
+ const rules = {
397
+ en: (n) => n === 1 ? "one" : "other",
398
+ fr: (n) => n === 0 || n === 1 ? "one" : "many",
399
+ es: (n) => n === 1 ? "one" : "many",
400
+ de: (n) => n === 1 ? "one" : "other"
401
+ };
402
+ const rule = rules[locale] || rules["en"];
403
+ return rule(count);
404
+ }
405
+ function createTranslate(translations, locale = "en") {
406
+ const translate = (key, params) => {
407
+ const value = getNestedValue2(translations, key);
408
+ if (!value) return key;
409
+ if (params) {
410
+ return Object.entries(params).reduce(
411
+ (str, [paramKey, paramValue]) => str.replace(new RegExp(`{{${paramKey}}}`, "g"), String(paramValue)),
412
+ value
413
+ );
414
+ }
415
+ return value;
416
+ };
417
+ const translatePlural = (key, params) => {
418
+ const { count, ...restParams } = params;
419
+ const pluralCategory = getPluralCategory2(locale, count);
420
+ let value = getNestedValue2(translations, `${key}_${pluralCategory}`);
421
+ if (!value) value = getNestedValue2(translations, key);
422
+ if (!value) return key;
423
+ const allParams = { count, ...restParams };
424
+ return Object.entries(allParams).reduce(
425
+ (str, [paramKey, paramValue]) => str.replace(new RegExp(`{{${paramKey}}}`, "g"), String(paramValue)),
426
+ value
427
+ );
428
+ };
429
+ const translateGender = (key, params) => {
430
+ const { gender, ...restParams } = params;
431
+ let value = getNestedValue2(translations, `${key}_${gender}`);
432
+ if (!value) value = getNestedValue2(translations, key);
433
+ if (!value) return key;
434
+ const allParams = { gender, ...restParams };
435
+ return Object.entries(allParams).reduce(
436
+ (str, [paramKey, paramValue]) => str.replace(new RegExp(`{{${paramKey}}}`, "g"), String(paramValue)),
437
+ value
438
+ );
439
+ };
440
+ const translateChoice = (key, params) => {
441
+ const { value } = params;
442
+ let translation = getNestedValue2(translations, `${key}_${value}`);
443
+ if (!translation) translation = getNestedValue2(translations, key);
444
+ return translation || key;
445
+ };
446
+ const extendedFn = translate;
447
+ extendedFn.plural = translatePlural;
448
+ extendedFn.gender = translateGender;
449
+ extendedFn.choice = translateChoice;
450
+ return extendedFn;
451
+ }
452
+ function useStandaloneTranslate() {
453
+ const { t, translations, locale } = (init_LokalContext(), __toCommonJS(LokalContext_exports)).useLokal();
454
+ return (0, import_react2.useMemo)(() => createTranslate(translations, locale), [translations, locale]);
455
+ }
143
456
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/context/LokalContext.tsx"],"sourcesContent":["// Main exports\nexport { LokalProvider, useLokal } from './context/LokalContext';\nexport type { LokalProviderProps, TranslateFunction, StorageInterface } from './context/LokalContext';\nexport type { LokalContextValue } from './context/LokalContext';\n\n// Re-export types from lokal-core\nexport type { LocaleData } from 'lokal-core';\n","import React, { createContext, useContext, useState, useEffect, useCallback, ReactNode } from 'react';\nimport type { LocaleData } from 'lokal-core';\n\n// Type for translation function\nexport type TranslateFunction = <K extends string>(\n key: K,\n params?: Record<string, string | number>\n) => string;\n\n// Storage interface for different platforms\nexport interface StorageInterface {\n getItem(key: string): Promise<string | null>;\n setItem(key: string, value: string): Promise<void>;\n}\n\n// Default to localStorage for web\nconst defaultStorage: StorageInterface = {\n getItem: (key: string) => {\n if (typeof window === 'undefined') return Promise.resolve(null);\n return Promise.resolve(localStorage.getItem(key));\n },\n setItem: (key: string, value: string) => {\n if (typeof window === 'undefined') return Promise.resolve();\n localStorage.setItem(key, value);\n return Promise.resolve();\n },\n};\n\nexport interface LokalContextValue {\n locale: string;\n setLocale: (locale: string) => void;\n locales: string[];\n t: TranslateFunction;\n translations: LocaleData;\n isLoading: boolean;\n}\n\nconst LokalContext = createContext<LokalContextValue | null>(null);\n\nexport interface LokalProviderProps {\n children: ReactNode;\n locale?: string;\n locales?: string[];\n translations?: LocaleData;\n storage?: StorageInterface;\n namespace?: string;\n defaultLocale?: string;\n onLocaleChange?: (locale: string) => void;\n}\n\ninterface StoredTranslations {\n [locale: string]: LocaleData;\n}\n\n/**\n * LokalProvider - Provides localization context to your React app\n */\nexport function LokalProvider({\n children,\n locale: initialLocale = 'en',\n locales = ['en'],\n translations: initialTranslations = {},\n storage = defaultStorage,\n namespace = 'locales',\n defaultLocale = 'en',\n onLocaleChange,\n}: LokalProviderProps) {\n const [locale, setLocaleState] = useState<string>(initialLocale);\n const [translations, setTranslations] = useState<LocaleData>(initialTranslations);\n const [isLoading, setIsLoading] = useState<boolean>(true);\n\n // Load saved locale and translations from storage\n useEffect(() => {\n const loadLocale = async () => {\n try {\n const savedLocale = await storage.getItem(`${namespace}-locale`);\n if (savedLocale && locales.includes(savedLocale)) {\n setLocaleState(savedLocale);\n } else {\n // Try to detect from browser\n const browserLocale = navigator.language.split('-')[0];\n if (locales.includes(browserLocale)) {\n setLocaleState(browserLocale);\n }\n }\n } catch (error) {\n console.warn('Failed to load locale from storage:', error);\n } finally {\n setIsLoading(false);\n }\n };\n\n loadLocale();\n }, [storage, locales, namespace]);\n\n // Load translations for current locale\n useEffect(() => {\n const loadTranslations = async () => {\n try {\n const storedData = await storage.getItem(`${namespace}-translations`);\n if (storedData) {\n const parsed: StoredTranslations = JSON.parse(storedData);\n if (parsed[locale]) {\n setTranslations(parsed[locale]);\n }\n }\n } catch (error) {\n console.warn('Failed to load translations from storage:', error);\n }\n };\n\n if (!isLoading) {\n loadTranslations();\n }\n }, [locale, storage, namespace, isLoading]);\n\n // Set locale and persist\n const setLocale = useCallback((newLocale: string) => {\n if (!locales.includes(newLocale)) {\n console.warn(`Locale ${newLocale} is not in the list of available locales`);\n return;\n }\n\n setLocaleState(newLocale);\n storage.setItem(`${namespace}-locale`, newLocale);\n\n if (onLocaleChange) {\n onLocaleChange(newLocale);\n }\n }, [locales, storage, namespace, onLocaleChange]);\n\n // Translation function\n const t = useCallback<TranslateFunction>((key, params) => {\n const keys = key.split('.');\n let value: any = translations;\n\n for (const k of keys) {\n if (value && typeof value === 'object' && k in value) {\n value = value[k];\n } else {\n // Return key if not found\n return key;\n }\n }\n\n if (typeof value !== 'string') {\n return key;\n }\n\n // Replace parameters\n if (params) {\n return Object.entries(params).reduce(\n (str, [paramKey, paramValue]) => str.replace(new RegExp(`{{${paramKey}}}`, 'g'), String(paramValue)),\n value\n );\n }\n\n return value;\n }, [translations]);\n\n const contextValue: LokalContextValue = {\n locale,\n setLocale,\n locales,\n t,\n translations,\n isLoading,\n };\n\n return (\n <LokalContext.Provider value={contextValue}>\n {children}\n </LokalContext.Provider>\n );\n}\n\n/**\n * Hook to access the Lokal context\n */\nexport function useLokal(): LokalContextValue {\n const context = useContext(LokalContext);\n\n if (!context) {\n throw new Error('useLokal must be used within a LokalProvider');\n }\n\n return context;\n}\n\nexport default LokalContext;\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/context/LokalContext.tsx","../src/index.ts","../src/hooks/useStandaloneTranslate.ts"],"sourcesContent":["import React, { createContext, useContext, useState, useEffect, useCallback, ReactNode } from 'react';\nimport type { LocaleData } from 'lokal-core';\n\n// ============================================\n// Type Definitions\n// ============================================\n\n// Type for translation function\nexport type TranslateFunction = <K extends string>(\n key: K,\n params?: Record<string, string | number>\n) => string;\n\n// Pluralization types\nexport type PluralCategory = 'zero' | 'one' | 'two' | 'few' | 'many' | 'other';\n\nexport interface PluralParams {\n count: number;\n [key: string]: string | number;\n}\n\n// Gender types\nexport type GenderCategory = 'male' | 'female' | 'other';\n\nexport interface GenderParams {\n gender: GenderCategory;\n [key: string]: string | number;\n}\n\n// Extended translation function with pluralization and gender\nexport interface ExtendedTranslateFunction {\n // Basic translation\n <K extends string>(key: K, params?: Record<string, string | number>): string;\n\n // Pluralization - use key like \"items_plural\" with {count}\n plural: <K extends string>(key: K, params: PluralParams) => string;\n\n // Gender - use key like \"user_gender\" with {gender}\n gender: <K extends string>(key: K, params: GenderParams) => string;\n\n // Choice/select - use key like \"color_choice\" with {value}\n choice: <K extends string>(key: K, params: { value: string | number }) => string;\n}\n\n// Storage interface for different platforms\nexport interface StorageInterface {\n getItem(key: string): Promise<string | null>;\n setItem(key: string, value: string): Promise<void>;\n}\n\n// Date formatting options\nexport interface DateFormatOptions {\n year?: 'numeric' | '2-digit';\n month?: 'numeric' | '2-digit' | 'long' | 'short' | 'narrow';\n day?: 'numeric' | '2-digit';\n hour?: 'numeric' | '2-digit';\n minute?: 'numeric' | '2-digit';\n second?: 'numeric' | '2-digit';\n timeZoneName?: 'short' | 'long';\n}\n\n// Number formatting options\nexport interface NumberFormatOptions {\n style?: 'decimal' | 'currency' | 'percent' | 'unit';\n currency?: string;\n currencyDisplay?: 'symbol' | 'code' | 'name';\n minimumFractionDigits?: number;\n maximumFractionDigits?: number;\n useGrouping?: boolean;\n unit?: string;\n unitDisplay?: 'long' | 'short' | 'narrow';\n}\n\n// ============================================\n// Context Value\n// ============================================\n\nexport interface LokalContextValue {\n locale: string;\n setLocale: (locale: string) => void;\n locales: string[];\n t: ExtendedTranslateFunction;\n translations: LocaleData;\n isLoading: boolean;\n // Date/Number formatting\n formatDate: (date: Date | string, options?: DateFormatOptions) => string;\n formatNumber: (num: number, options?: NumberFormatOptions) => string;\n}\n\n// ============================================\n// Context Creation\n// ============================================\n\nconst LokalContext = createContext<LokalContextValue | null>(null);\n\n// ============================================\n// Storage Interface\n// ============================================\n\n// Default to localStorage for web\nconst defaultStorage: StorageInterface = {\n getItem: (key: string) => {\n if (typeof window === 'undefined') return Promise.resolve(null);\n return Promise.resolve(localStorage.getItem(key));\n },\n setItem: (key: string, value: string) => {\n if (typeof window === 'undefined') return Promise.resolve();\n localStorage.setItem(key, value);\n return Promise.resolve();\n },\n};\n\n// ============================================\n// Helper Functions\n// ============================================\n\n/**\n * Get plural category based on locale and count\n */\nfunction getPluralCategory(locale: string, count: number): PluralCategory {\n // CLDR plural rules implementation\n const rules: Record<string, (n: number) => PluralCategory> = {\n en: (n) => n === 1 ? 'one' : 'other',\n fr: (n) => n === 0 || n === 1 ? 'one' : 'many',\n es: (n) => n === 1 ? 'one' : 'many',\n de: (n) => n === 1 ? 'one' : 'other',\n it: (n) => n === 1 ? 'one' : 'other',\n ru: (n) => {\n const mod10 = n % 10;\n const mod100 = n % 100;\n if (n === 1) return 'one';\n if (mod10 >= 2 && mod10 <= 4 && !(mod100 >= 12 && mod100 <= 14)) return 'few';\n if (mod10 === 0 || mod10 >= 5 || mod10 >= 11 && mod10 <= 15) return 'many';\n return 'other';\n },\n ar: (n) => {\n if (n === 0) return 'zero';\n if (n === 1) return 'one';\n if (n === 2) return 'two';\n const mod100 = n % 100;\n if (mod100 >= 3 && mod100 <= 10) return 'few';\n if (mod100 >= 11 && mod100 <= 99) return 'many';\n return 'other';\n },\n };\n\n const rule = rules[locale] || rules['en'];\n return rule(count);\n}\n\n/**\n * Get nested value from object using dot notation\n */\nfunction getNestedValue(obj: any, path: string): string {\n const keys = path.split('.');\n let value: any = obj;\n\n for (const k of keys) {\n if (value && typeof value === 'object' && k in value) {\n value = value[k];\n } else {\n return '';\n }\n }\n\n return typeof value === 'string' ? value : '';\n}\n\n/**\n * Set nested value in object using dot notation\n */\nfunction setNestedValue(obj: any, path: string, value: string): void {\n const keys = path.split('.');\n let current = obj;\n\n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i];\n if (!(key in current)) {\n current[key] = {};\n }\n current = current[key];\n }\n\n current[keys[keys.length - 1]] = value;\n}\n\n// ============================================\n// Provider Props\n// ============================================\n\nexport interface LokalProviderProps {\n children: ReactNode;\n locale?: string;\n locales?: string[];\n translations?: LocaleData;\n storage?: StorageInterface;\n namespace?: string;\n defaultLocale?: string;\n onLocaleChange?: (locale: string) => void;\n // SSR Support\n initialLocale?: string;\n initialTranslations?: LocaleData;\n fallbackLocale?: string;\n}\n\ninterface StoredTranslations {\n [locale: string]: LocaleData;\n}\n\n// ============================================\n// LokalProvider Component\n// ============================================\n\nexport function LokalProvider({\n children,\n locale: initialLocale = 'en',\n locales = ['en'],\n translations: initialTranslations = {},\n storage = defaultStorage,\n namespace = 'locales',\n defaultLocale = 'en',\n onLocaleChange,\n initialLocale: ssrInitialLocale,\n initialTranslations: ssrInitialTranslations,\n fallbackLocale = 'en',\n}: LokalProviderProps) {\n // Use SSR initial values if provided, otherwise use client-side state\n const [locale, setLocaleState] = useState<string>(ssrInitialLocale || initialLocale);\n const [translations, setTranslations] = useState<LocaleData>(ssrInitialTranslations || initialTranslations);\n const [isLoading, setIsLoading] = useState<boolean>(!!ssrInitialLocale);\n const [isHydrated, setIsHydrated] = useState<boolean>(!!ssrInitialLocale);\n\n // Handle hydration for SSR\n useEffect(() => {\n if (ssrInitialLocale && !isHydrated) {\n setIsHydrated(true);\n setIsLoading(false);\n }\n }, [ssrInitialLocale, isHydrated]);\n\n // Load saved locale and translations from storage\n useEffect(() => {\n const loadLocale = async () => {\n try {\n const savedLocale = await storage.getItem(`${namespace}-locale`);\n if (savedLocale && locales.includes(savedLocale)) {\n setLocaleState(savedLocale);\n } else if (!ssrInitialLocale) {\n // Try to detect from browser\n if (typeof navigator !== 'undefined') {\n const browserLocale = navigator.language.split('-')[0];\n if (locales.includes(browserLocale)) {\n setLocaleState(browserLocale);\n }\n }\n }\n } catch (error) {\n console.warn('Failed to load locale from storage:', error);\n if (!ssrInitialLocale) {\n setLocaleState(fallbackLocale);\n }\n } finally {\n setIsLoading(false);\n }\n };\n\n loadLocale();\n }, [storage, locales, namespace, ssrInitialLocale, fallbackLocale]);\n\n // Load translations for current locale\n useEffect(() => {\n const loadTranslations = async () => {\n try {\n const storedData = await storage.getItem(`${namespace}-translations`);\n if (storedData) {\n const parsed: StoredTranslations = JSON.parse(storedData);\n if (parsed[locale]) {\n setTranslations(parsed[locale]);\n }\n }\n } catch (error) {\n console.warn('Failed to load translations from storage:', error);\n }\n };\n\n if (!isLoading && !ssrInitialTranslations) {\n loadTranslations();\n }\n }, [locale, storage, namespace, isLoading, ssrInitialTranslations]);\n\n // Set locale and persist\n const setLocale = useCallback((newLocale: string) => {\n if (!locales.includes(newLocale)) {\n console.warn(`Locale ${newLocale} is not in the list of available locales`);\n return;\n }\n\n setLocaleState(newLocale);\n storage.setItem(`${namespace}-locale`, newLocale).catch(console.warn);\n\n if (onLocaleChange) {\n onLocaleChange(newLocale);\n }\n }, [locales, storage, namespace, onLocaleChange]);\n\n // Basic translation function\n const translate = useCallback((key: string, params?: Record<string, string | number>): string => {\n const value = getNestedValue(translations, key);\n\n if (!value) {\n // Return key if not found\n return key;\n }\n\n // Replace parameters\n if (params) {\n return Object.entries(params).reduce(\n (str, [paramKey, paramValue]) => str.replace(new RegExp(`{{${paramKey}}}`, 'g'), String(paramValue)),\n value\n );\n }\n\n return value;\n }, [translations]);\n\n // Extended translation function with pluralization\n const translatePlural = useCallback((key: string, params: PluralParams): string => {\n const { count, ...restParams } = params;\n const pluralCategory = getPluralCategory(locale, count);\n\n // Try plural-specific key first (e.g., \"items_one\", \"items_other\")\n const pluralKey = `${key}_${pluralCategory}`;\n let value = getNestedValue(translations, pluralKey);\n\n // Fall back to base key if plural form not found\n if (!value) {\n value = getNestedValue(translations, key);\n }\n\n if (!value) {\n return key;\n }\n\n // Replace all parameters including count\n const allParams = { count, ...restParams };\n return Object.entries(allParams).reduce(\n (str, [paramKey, paramValue]) => str.replace(new RegExp(`{{${paramKey}}}`, 'g'), String(paramValue)),\n value\n );\n }, [locale, translations]);\n\n // Extended translation function with gender\n const translateGender = useCallback((key: string, params: GenderParams): string => {\n const { gender, ...restParams } = params;\n\n // Try gender-specific key first (e.g., \"user_male\", \"user_female\")\n const genderKey = `${key}_${gender}`;\n let value = getNestedValue(translations, genderKey);\n\n // Fall back to base key if gender form not found\n if (!value) {\n value = getNestedValue(translations, key);\n }\n\n if (!value) {\n return key;\n }\n\n // Replace all parameters including gender\n const allParams = { gender, ...restParams };\n return Object.entries(allParams).reduce(\n (str, [paramKey, paramValue]) => str.replace(new RegExp(`{{${paramKey}}}`, 'g'), String(paramValue)),\n value\n );\n }, [translations]);\n\n // Choice/select translation\n const translateChoice = useCallback((key: string, params: { value: string | number }): string => {\n const { value } = params;\n\n // Try value-specific key first (e.g., \"color_red\", \"color_blue\")\n const choiceKey = `${key}_${value}`;\n let translation = getNestedValue(translations, choiceKey);\n\n // Fall back to base key if choice not found\n if (!translation) {\n translation = getNestedValue(translations, key);\n }\n\n if (!translation) {\n return key;\n }\n\n return translation;\n }, [translations]);\n\n // Extended translate function\n const t = useCallback<ExtendedTranslateFunction>(Object.assign(\n translate,\n {\n plural: translatePlural,\n gender: translateGender,\n choice: translateChoice,\n }\n ), [translate, translatePlural, translateGender, translateChoice]);\n\n // Date formatting\n const formatDate = useCallback((date: Date | string, options?: DateFormatOptions): string => {\n const dateObj = typeof date === 'string' ? new Date(date) : date;\n\n try {\n return new Intl.DateTimeFormat(locale, options as Intl.DateTimeFormatOptions).format(dateObj);\n } catch (error) {\n console.warn('Date formatting failed:', error);\n return dateObj.toLocaleDateString();\n }\n }, [locale]);\n\n // Number formatting\n const formatNumber = useCallback((num: number, options?: NumberFormatOptions): string => {\n try {\n return new Intl.NumberFormat(locale, options as Intl.NumberFormatOptions).format(num);\n } catch (error) {\n console.warn('Number formatting failed:', error);\n return num.toString();\n }\n }, [locale]);\n\n const contextValue: LokalContextValue = {\n locale,\n setLocale,\n locales,\n t,\n translations,\n isLoading,\n formatDate,\n formatNumber,\n };\n\n return (\n <LokalContext.Provider value={contextValue}>\n {children}\n </LokalContext.Provider>\n );\n}\n\n// ============================================\n// Hooks\n// ============================================\n\n/**\n * Hook to access the full Lokal context\n */\nexport function useLokal(): LokalContextValue {\n const context = useContext(LokalContext);\n\n if (!context) {\n throw new Error('useLokal must be used within a LokalProvider');\n }\n\n return context;\n}\n\n/**\n * Hook to access only the translation function\n */\nexport function useTranslate(): ExtendedTranslateFunction {\n const { t } = useLokal();\n return t;\n}\n\n/**\n * Hook to access locale and setter\n */\nexport function useLocale(): { locale: string; setLocale: (locale: string) => void; locales: string[] } {\n const { locale, setLocale, locales } = useLokal();\n return { locale, setLocale, locales };\n}\n\n/**\n * Hook to access date/number formatters\n */\nexport function useFormatters(): { formatDate: (date: Date | string, options?: DateFormatOptions) => string; formatNumber: (num: number, options?: NumberFormatOptions) => string } {\n const { formatDate, formatNumber } = useLokal();\n return { formatDate, formatNumber };\n}\n\n/**\n * Hook to check if translations are loading\n */\nexport function useIsLoading(): boolean {\n const { isLoading } = useLokal();\n return isLoading;\n}\n\n// ============================================\n// T Component JSX Trans forlations\n// ============================================\n\ninterface TComponentProps {\n children: string;\n params?: Record<string, string | number>;\n plural?: number;\n gender?: GenderCategory;\n className?: string;\n as?: React.ElementType;\n}\n\n/**\n * T Component - Translate content directly in JSX\n * Usage: <T>hello_world</T> or <T params={{name: 'John'}}>greeting</T>\n */\nexport function T({\n children,\n params,\n plural,\n gender,\n className,\n as: Component = 'span'\n}: TComponentProps) {\n const { t } = useLokal();\n\n let translatedText: string;\n\n if (plural !== undefined) {\n translatedText = t.plural(children, { count: plural, ...(params || {}) });\n } else if (gender) {\n translatedText = t.gender(children, { gender, ...(params || {}) });\n } else {\n translatedText = t(children as any, params);\n }\n\n return (\n <Component className={className}>\n {translatedText}\n </Component>\n );\n}\n\n// ============================================\n// Lazy Translation Hook\n// ============================================\n\n/**\n * Hook for lazy-loaded translations (useful for code splitting)\n */\nexport function useLazyTranslations(namespace: string) {\n const { t, translations, isLoading } = useLokal();\n\n const translate = useCallback((key: string, params?: Record<string, string | number>): string => {\n const namespacedKey = `${namespace}.${key}`;\n const value = getNestedValue(translations, namespacedKey);\n\n if (!value) {\n return key;\n }\n\n if (params) {\n return Object.entries(params).reduce(\n (str, [paramKey, paramValue]) =>\n str.replace(new RegExp(`{{${paramKey}}}`, 'g'), String(paramValue)),\n value\n );\n }\n\n return value;\n }, [translations, namespace]);\n\n return { t: translate, isLoading };\n}\n\n// ============================================\n// SSR Hydration Helper\n// ============================================\n\n/**\n * Hook to handle SSR hydration\n * Returns true until client-side hydration is complete\n */\nexport function useHydrated(): boolean {\n const [hydrated, setHydrated] = useState(false);\n\n useEffect(() => {\n setHydrated(true);\n }, []);\n\n return hydrated;\n}\n\n/**\n * Hook to get translations only after hydration\n * Prevents hydration mismatches\n */\nexport function useSafeTranslations(): { t: ExtendedTranslateFunction; isHydrated: boolean } {\n const { t } = useLokal();\n const isHydrated = useHydrated();\n \n // Simple wrapper that returns key during SSR to prevent mismatch\n const safeT = (key: string, params?: Record<string, string | number>): string => {\n if (!isHydrated) {\n return key;\n }\n return t(key, params);\n };\n \n safeT.plural = (key: string, params: PluralParams): string => {\n if (!isHydrated) return key;\n return t.plural(key, params);\n };\n \n safeT.gender = (key: string, params: GenderParams): string => {\n if (!isHydrated) return key;\n return t.gender(key, params);\n };\n \n safeT.choice = (key: string, params: { value: string | number }): string => {\n if (!isHydrated) return key;\n return t.choice(key, params);\n };\n \n return { t: safeT as ExtendedTranslateFunction, isHydrated };\n}\n\n// ============================================\n// Default Export\n// ============================================\n\nexport default LokalContext;\n","// Main exports - Hooks & Components\nexport { \n LokalProvider, \n useLokal, \n useTranslate, \n useLocale, \n useFormatters, \n useIsLoading,\n useLazyTranslations,\n useHydrated,\n useSafeTranslations,\n T \n} from './context/LokalContext';\n\n// Standalone translation\nexport { createTranslate, useStandaloneTranslate } from './hooks/useStandaloneTranslate';\n\nexport type { \n LokalProviderProps, \n TranslateFunction, \n ExtendedTranslateFunction,\n StorageInterface,\n LokalContextValue,\n PluralParams,\n PluralCategory,\n GenderParams,\n GenderCategory,\n DateFormatOptions,\n NumberFormatOptions\n} from './context/LokalContext';\n\n// Re-export types from lokal-core\nexport type { LocaleData } from 'lokal-core';\n","import { useState, useEffect, useCallback, useMemo } from 'react';\nimport type { LocaleData } from 'lokal-core';\nimport type { ExtendedTranslateFunction, StorageInterface } from '../context/LokalContext';\n\n// Re-implement the translation logic for standalone use\nfunction getNestedValue(obj: any, path: string): string {\n const keys = path.split('.');\n let value: any = obj;\n\n for (const k of keys) {\n if (value && typeof value === 'object' && k in value) {\n value = value[k];\n } else {\n return '';\n }\n }\n\n return typeof value === 'string' ? value : '';\n}\n\nfunction getPluralCategory(locale: string, count: number): string {\n const rules: Record<string, (n: number) => string> = {\n en: (n) => n === 1 ? 'one' : 'other',\n fr: (n) => n === 0 || n === 1 ? 'one' : 'many',\n es: (n) => n === 1 ? 'one' : 'many',\n de: (n) => n === 1 ? 'one' : 'other',\n };\n\n const rule = rules[locale] || rules['en'];\n return rule(count);\n}\n\n/**\n * Create a standalone translation function\n * Useful for non-React contexts or when you want to avoid hooks\n */\nexport function createTranslate(\n translations: LocaleData,\n locale: string = 'en'\n): ExtendedTranslateFunction {\n const translate = (key: string, params?: Record<string, string | number>): string => {\n const value = getNestedValue(translations, key);\n\n if (!value) return key;\n\n if (params) {\n return Object.entries(params).reduce(\n (str, [paramKey, paramValue]) =>\n str.replace(new RegExp(`{{${paramKey}}}`, 'g'), String(paramValue)),\n value\n );\n }\n\n return value;\n };\n\n const translatePlural = (key: string, params: any): string => {\n const { count, ...restParams } = params;\n const pluralCategory = getPluralCategory(locale, count);\n\n let value = getNestedValue(translations, `${key}_${pluralCategory}`);\n if (!value) value = getNestedValue(translations, key);\n\n if (!value) return key;\n\n const allParams = { count, ...restParams };\n return Object.entries(allParams).reduce(\n (str, [paramKey, paramValue]) =>\n str.replace(new RegExp(`{{${paramKey}}}`, 'g'), String(paramValue)),\n value\n );\n };\n\n const translateGender = (key: string, params: any): string => {\n const { gender, ...restParams } = params;\n\n let value = getNestedValue(translations, `${key}_${gender}`);\n if (!value) value = getNestedValue(translations, key);\n\n if (!value) return key;\n\n const allParams = { gender, ...restParams };\n return Object.entries(allParams).reduce(\n (str, [paramKey, paramValue]) =>\n str.replace(new RegExp(`{{${paramKey}}}`, 'g'), String(paramValue)),\n value\n );\n };\n\n const translateChoice = (key: string, params: { value: string | number }): string => {\n const { value } = params;\n\n let translation = getNestedValue(translations, `${key}_${value}`);\n if (!translation) translation = getNestedValue(translations, key);\n\n return translation || key;\n };\n\n const extendedFn = translate as ExtendedTranslateFunction;\n extendedFn.plural = translatePlural;\n extendedFn.gender = translateGender;\n extendedFn.choice = translateChoice;\n\n return extendedFn;\n}\n\n/**\n * Hook to create a standalone translate function from context\n * This is useful when you want to pass translation function to non-React code\n */\nexport function useStandaloneTranslate(): ExtendedTranslateFunction {\n const { t, translations, locale } = require('../context/LokalContext').useLokal();\n\n return useMemo(() => createTranslate(translations, locale), [translations, locale]);\n}\n\nexport default createTranslate;\n"],"mappings":"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","names":["import_react","getNestedValue","getPluralCategory"]}