@dcl/hooks 1.4.1-20260819185956.commit-73b020b → 1.5.1-20260824213741.commit-4c7fe76
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.
|
@@ -7,8 +7,8 @@ import { TranslationOptions, TranslationResult } from "./useTranslation.type";
|
|
|
7
7
|
* 2. Without options (context mode): Uses TranslationProvider context
|
|
8
8
|
*
|
|
9
9
|
* @param options - Optional configuration options for translations. If not provided, will use TranslationProvider context.
|
|
10
|
-
* @param options.locale - The
|
|
11
|
-
* @param options.translations - An object containing all translations for all locales (required in standalone mode)
|
|
10
|
+
* @param options.locale - The locale to use (required in standalone mode). Changing it switches the active language, so a consumer can drive the language from the outside. A language set through `setLocale` is kept while this prop stays the same, so passing a literal keeps `setLocale` in charge
|
|
11
|
+
* @param options.translations - An object containing all translations for all locales (required in standalone mode). It is read on every render, so a locale added after mount becomes available to `setLocale`. Keep it in state or memoize it: a new object on every render re-flattens every locale and rebuilds the `intl` instance
|
|
12
12
|
* @param options.fallbackLocale - Optional fallback locale if a translation is not found
|
|
13
13
|
*
|
|
14
14
|
* @returns An object with translation utilities including the full IntlShape instance
|
|
@@ -26,8 +26,8 @@ const flattenTranslations = (translations, parentKey = "", result = {}) => {
|
|
|
26
26
|
* 2. Without options (context mode): Uses TranslationProvider context
|
|
27
27
|
*
|
|
28
28
|
* @param options - Optional configuration options for translations. If not provided, will use TranslationProvider context.
|
|
29
|
-
* @param options.locale - The
|
|
30
|
-
* @param options.translations - An object containing all translations for all locales (required in standalone mode)
|
|
29
|
+
* @param options.locale - The locale to use (required in standalone mode). Changing it switches the active language, so a consumer can drive the language from the outside. A language set through `setLocale` is kept while this prop stays the same, so passing a literal keeps `setLocale` in charge
|
|
30
|
+
* @param options.translations - An object containing all translations for all locales (required in standalone mode). It is read on every render, so a locale added after mount becomes available to `setLocale`. Keep it in state or memoize it: a new object on every render re-flattens every locale and rebuilds the `intl` instance
|
|
31
31
|
* @param options.fallbackLocale - Optional fallback locale if a translation is not found
|
|
32
32
|
*
|
|
33
33
|
* @returns An object with translation utilities including the full IntlShape instance
|
|
@@ -107,25 +107,40 @@ const useTranslation = (options) => {
|
|
|
107
107
|
throw new Error("translations is required when using useTranslation with options");
|
|
108
108
|
}
|
|
109
109
|
const validatedOptions = options;
|
|
110
|
+
const { translations, fallbackLocale } = validatedOptions;
|
|
110
111
|
const [state, setState] = useState({
|
|
111
112
|
locale: validatedOptions.locale,
|
|
112
|
-
|
|
113
|
+
propLocale: validatedOptions.locale,
|
|
113
114
|
error: null,
|
|
114
115
|
});
|
|
116
|
+
// `translations` and `locale` stay props instead of being copied into state.
|
|
117
|
+
// Snapshotting them on the first render leaves a consumer that loads a locale
|
|
118
|
+
// on demand with no way to hand it over: the language would be stuck on
|
|
119
|
+
// whatever was available when the provider mounted.
|
|
120
|
+
//
|
|
121
|
+
// The prop is adjusted during render rather than in an effect so the new
|
|
122
|
+
// language is on screen in the same paint. An effect would render once with
|
|
123
|
+
// the previous locale first.
|
|
124
|
+
if (state.propLocale !== validatedOptions.locale) {
|
|
125
|
+
setState({
|
|
126
|
+
locale: validatedOptions.locale,
|
|
127
|
+
propLocale: validatedOptions.locale,
|
|
128
|
+
error: null,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
115
131
|
const flattenedTranslations = useMemo(() => {
|
|
116
132
|
const locales = {};
|
|
117
|
-
Object.entries(
|
|
118
|
-
locales[locale] = flattenTranslations(
|
|
133
|
+
Object.entries(translations).forEach(([locale, localeTranslations]) => {
|
|
134
|
+
locales[locale] = flattenTranslations(localeTranslations);
|
|
119
135
|
});
|
|
120
136
|
return locales;
|
|
121
|
-
}, [
|
|
137
|
+
}, [translations]);
|
|
122
138
|
// Create intl instance with current locale and translations
|
|
123
139
|
const intl = useMemo(() => {
|
|
124
140
|
const currentTranslations = flattenedTranslations[state.locale];
|
|
125
|
-
const fallbackTranslations =
|
|
126
|
-
flattenedTranslations[validatedOptions.fallbackLocale];
|
|
141
|
+
const fallbackTranslations = fallbackLocale && flattenedTranslations[fallbackLocale];
|
|
127
142
|
if (!currentTranslations && fallbackTranslations) {
|
|
128
|
-
console.error(`No translations found for locale "${state.locale}". Using fallback locale "${
|
|
143
|
+
console.error(`No translations found for locale "${state.locale}". Using fallback locale "${fallbackLocale}".`);
|
|
129
144
|
return createIntl({
|
|
130
145
|
locale: state.locale,
|
|
131
146
|
messages: fallbackTranslations,
|
|
@@ -138,9 +153,7 @@ const useTranslation = (options) => {
|
|
|
138
153
|
messages: {},
|
|
139
154
|
}, cache);
|
|
140
155
|
}
|
|
141
|
-
const shouldMergeFallback =
|
|
142
|
-
state.locale !== validatedOptions.fallbackLocale &&
|
|
143
|
-
fallbackTranslations;
|
|
156
|
+
const shouldMergeFallback = fallbackLocale && state.locale !== fallbackLocale && fallbackTranslations;
|
|
144
157
|
const messages = shouldMergeFallback
|
|
145
158
|
? {
|
|
146
159
|
...fallbackTranslations,
|
|
@@ -151,14 +164,14 @@ const useTranslation = (options) => {
|
|
|
151
164
|
locale: state.locale,
|
|
152
165
|
messages,
|
|
153
166
|
}, cache);
|
|
154
|
-
}, [state.locale, flattenedTranslations,
|
|
167
|
+
}, [state.locale, flattenedTranslations, fallbackLocale]);
|
|
155
168
|
// Simplified t() function using intl.formatMessage
|
|
156
169
|
const t = useCallback((key, values) => {
|
|
157
170
|
return intl.formatMessage({ id: key }, values);
|
|
158
171
|
}, [intl]);
|
|
159
172
|
const setLocale = useCallback((newLocale) => {
|
|
160
|
-
if (!
|
|
161
|
-
console.error(`Locale "${newLocale}" not found in translations. Available locales: ${Object.keys(
|
|
173
|
+
if (!translations[newLocale]) {
|
|
174
|
+
console.error(`Locale "${newLocale}" not found in translations. Available locales: ${Object.keys(translations).join(", ")}`);
|
|
162
175
|
setState((current) => ({
|
|
163
176
|
...current,
|
|
164
177
|
error: `Locale "${newLocale}" not found`,
|
|
@@ -170,7 +183,7 @@ const useTranslation = (options) => {
|
|
|
170
183
|
locale: newLocale,
|
|
171
184
|
error: null,
|
|
172
185
|
}));
|
|
173
|
-
}, [
|
|
186
|
+
}, [translations]);
|
|
174
187
|
return {
|
|
175
188
|
t,
|
|
176
189
|
intl,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTranslation.js","sourceRoot":"","sources":["../../../src/hooks/useTranslation/useTranslation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAClE,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAO5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+CAA+C,CAAA;AAElF,2DAA2D;AAC3D,MAAM,KAAK,GAAG,eAAe,EAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"useTranslation.js","sourceRoot":"","sources":["../../../src/hooks/useTranslation/useTranslation.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dcl/hooks",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.1-20260824213741.commit-4c7fe76",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "esm/index.js",
|
|
6
6
|
"module": "esm/index.js",
|
|
@@ -80,5 +80,5 @@
|
|
|
80
80
|
"<rootDir>/test/setup.ts"
|
|
81
81
|
]
|
|
82
82
|
},
|
|
83
|
-
"commit": "
|
|
83
|
+
"commit": "4c7fe76398e7941d22048e18a23b1a0125478f02"
|
|
84
84
|
}
|