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.
@@ -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 { LokalProvider, useLokal } from './context/LokalContext';
3
- export type { LokalProviderProps, TranslateFunction, StorageInterface } from './context/LokalContext';
4
- export type { LokalContextValue } from './context/LokalContext';
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';