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.d.mts +144 -0
- package/dist/index.d.ts +144 -0
- package/dist/index.js +357 -44
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +369 -36
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/context/LokalContext.tsx +475 -37
- package/src/hooks/useStandaloneTranslate.ts +117 -0
- package/src/index.ts +30 -4
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { useState, useEffect, useCallback, useMemo } from 'react';
|
|
2
|
+
import type { LocaleData } from 'lokal-core';
|
|
3
|
+
import type { ExtendedTranslateFunction, StorageInterface } from '../context/LokalContext';
|
|
4
|
+
|
|
5
|
+
// Re-implement the translation logic for standalone use
|
|
6
|
+
function getNestedValue(obj: any, path: string): string {
|
|
7
|
+
const keys = path.split('.');
|
|
8
|
+
let value: any = obj;
|
|
9
|
+
|
|
10
|
+
for (const k of keys) {
|
|
11
|
+
if (value && typeof value === 'object' && k in value) {
|
|
12
|
+
value = value[k];
|
|
13
|
+
} else {
|
|
14
|
+
return '';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return typeof value === 'string' ? value : '';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function getPluralCategory(locale: string, count: number): string {
|
|
22
|
+
const rules: Record<string, (n: number) => string> = {
|
|
23
|
+
en: (n) => n === 1 ? 'one' : 'other',
|
|
24
|
+
fr: (n) => n === 0 || n === 1 ? 'one' : 'many',
|
|
25
|
+
es: (n) => n === 1 ? 'one' : 'many',
|
|
26
|
+
de: (n) => n === 1 ? 'one' : 'other',
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const rule = rules[locale] || rules['en'];
|
|
30
|
+
return rule(count);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Create a standalone translation function
|
|
35
|
+
* Useful for non-React contexts or when you want to avoid hooks
|
|
36
|
+
*/
|
|
37
|
+
export function createTranslate(
|
|
38
|
+
translations: LocaleData,
|
|
39
|
+
locale: string = 'en'
|
|
40
|
+
): ExtendedTranslateFunction {
|
|
41
|
+
const translate = (key: string, params?: Record<string, string | number>): string => {
|
|
42
|
+
const value = getNestedValue(translations, key);
|
|
43
|
+
|
|
44
|
+
if (!value) return key;
|
|
45
|
+
|
|
46
|
+
if (params) {
|
|
47
|
+
return Object.entries(params).reduce(
|
|
48
|
+
(str, [paramKey, paramValue]) =>
|
|
49
|
+
str.replace(new RegExp(`{{${paramKey}}}`, 'g'), String(paramValue)),
|
|
50
|
+
value
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return value;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const translatePlural = (key: string, params: any): string => {
|
|
58
|
+
const { count, ...restParams } = params;
|
|
59
|
+
const pluralCategory = getPluralCategory(locale, count);
|
|
60
|
+
|
|
61
|
+
let value = getNestedValue(translations, `${key}_${pluralCategory}`);
|
|
62
|
+
if (!value) value = getNestedValue(translations, key);
|
|
63
|
+
|
|
64
|
+
if (!value) return key;
|
|
65
|
+
|
|
66
|
+
const allParams = { count, ...restParams };
|
|
67
|
+
return Object.entries(allParams).reduce(
|
|
68
|
+
(str, [paramKey, paramValue]) =>
|
|
69
|
+
str.replace(new RegExp(`{{${paramKey}}}`, 'g'), String(paramValue)),
|
|
70
|
+
value
|
|
71
|
+
);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const translateGender = (key: string, params: any): string => {
|
|
75
|
+
const { gender, ...restParams } = params;
|
|
76
|
+
|
|
77
|
+
let value = getNestedValue(translations, `${key}_${gender}`);
|
|
78
|
+
if (!value) value = getNestedValue(translations, key);
|
|
79
|
+
|
|
80
|
+
if (!value) return key;
|
|
81
|
+
|
|
82
|
+
const allParams = { gender, ...restParams };
|
|
83
|
+
return Object.entries(allParams).reduce(
|
|
84
|
+
(str, [paramKey, paramValue]) =>
|
|
85
|
+
str.replace(new RegExp(`{{${paramKey}}}`, 'g'), String(paramValue)),
|
|
86
|
+
value
|
|
87
|
+
);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const translateChoice = (key: string, params: { value: string | number }): string => {
|
|
91
|
+
const { value } = params;
|
|
92
|
+
|
|
93
|
+
let translation = getNestedValue(translations, `${key}_${value}`);
|
|
94
|
+
if (!translation) translation = getNestedValue(translations, key);
|
|
95
|
+
|
|
96
|
+
return translation || key;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const extendedFn = translate as ExtendedTranslateFunction;
|
|
100
|
+
extendedFn.plural = translatePlural;
|
|
101
|
+
extendedFn.gender = translateGender;
|
|
102
|
+
extendedFn.choice = translateChoice;
|
|
103
|
+
|
|
104
|
+
return extendedFn;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Hook to create a standalone translate function from context
|
|
109
|
+
* This is useful when you want to pass translation function to non-React code
|
|
110
|
+
*/
|
|
111
|
+
export function useStandaloneTranslate(): ExtendedTranslateFunction {
|
|
112
|
+
const { t, translations, locale } = require('../context/LokalContext').useLokal();
|
|
113
|
+
|
|
114
|
+
return useMemo(() => createTranslate(translations, locale), [translations, locale]);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export default createTranslate;
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,33 @@
|
|
|
1
|
-
// Main exports
|
|
2
|
-
export {
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
// Main exports - Hooks & Components
|
|
2
|
+
export {
|
|
3
|
+
LokalProvider,
|
|
4
|
+
useLokal,
|
|
5
|
+
useTranslate,
|
|
6
|
+
useLocale,
|
|
7
|
+
useFormatters,
|
|
8
|
+
useIsLoading,
|
|
9
|
+
useLazyTranslations,
|
|
10
|
+
useHydrated,
|
|
11
|
+
useSafeTranslations,
|
|
12
|
+
T
|
|
13
|
+
} from './context/LokalContext';
|
|
14
|
+
|
|
15
|
+
// Standalone translation
|
|
16
|
+
export { createTranslate, useStandaloneTranslate } from './hooks/useStandaloneTranslate';
|
|
17
|
+
|
|
18
|
+
export type {
|
|
19
|
+
LokalProviderProps,
|
|
20
|
+
TranslateFunction,
|
|
21
|
+
ExtendedTranslateFunction,
|
|
22
|
+
StorageInterface,
|
|
23
|
+
LokalContextValue,
|
|
24
|
+
PluralParams,
|
|
25
|
+
PluralCategory,
|
|
26
|
+
GenderParams,
|
|
27
|
+
GenderCategory,
|
|
28
|
+
DateFormatOptions,
|
|
29
|
+
NumberFormatOptions
|
|
30
|
+
} from './context/LokalContext';
|
|
5
31
|
|
|
6
32
|
// Re-export types from lokal-core
|
|
7
33
|
export type { LocaleData } from 'lokal-core';
|