@pure-ds/core 0.7.37 → 0.7.39

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.
@@ -765,6 +765,16 @@
765
765
  "name": "COMPONENT_TAG",
766
766
  "description": "PdsLiveTemplateCanvas component"
767
767
  },
768
+ {
769
+ "name": "pds-locale",
770
+ "description": "Locale switcher component.\r\n\r\nThe component only persists canonical 5-letter locale tags (`xx-YY`),\r\nfor example `en-US` and `nl-NL`.",
771
+ "attributes": [
772
+ {
773
+ "name": "data-label",
774
+ "description": "Accessible label for the locale radio group."
775
+ }
776
+ ]
777
+ },
768
778
  {
769
779
  "name": "pds-omnibox",
770
780
  "description": "PdsOmnibox component",
@@ -71,6 +71,59 @@ function normalizeAliasMap(aliases = {}) {
71
71
  return normalized;
72
72
  }
73
73
 
74
+ function resolveAliasTarget(aliasKey, aliases, localeSet) {
75
+ const values = Array.isArray(aliases?.[aliasKey]) ? aliases[aliasKey] : [];
76
+ for (const value of values) {
77
+ const normalizedValue = normalizeLocaleTag(value);
78
+ if (localeSet.has(normalizedValue)) {
79
+ return normalizedValue;
80
+ }
81
+ }
82
+ return "";
83
+ }
84
+
85
+ function createAliasLookup({ aliases, localeSet }) {
86
+ const lookup = new Map();
87
+
88
+ for (const locale of localeSet) {
89
+ lookup.set(locale, locale);
90
+ }
91
+
92
+ for (const key of Object.keys(aliases || {})) {
93
+ const target = resolveAliasTarget(key, aliases, localeSet);
94
+ if (!target) {
95
+ throw new Error(
96
+ `[i18n] Locale alias "${key}" does not map to any configured locale.`
97
+ );
98
+ }
99
+ lookup.set(key, target);
100
+ }
101
+
102
+ return lookup;
103
+ }
104
+
105
+ function resolveConfiguredLocale(locale, { defaultLocale, aliasLookup }) {
106
+ const normalized = normalizeLocaleTag(locale);
107
+ if (!normalized) {
108
+ return defaultLocale;
109
+ }
110
+
111
+ const direct = aliasLookup.get(normalized);
112
+ if (direct) {
113
+ return direct;
114
+ }
115
+
116
+ const base = toBaseLocale(normalized);
117
+ const baseMapped = base ? aliasLookup.get(base) : "";
118
+ if (baseMapped) {
119
+ return baseMapped;
120
+ }
121
+
122
+ throw new Error(
123
+ `[i18n] Locale alias "${locale}" is not configured. Add an alias entry for "${base || normalized}".`
124
+ );
125
+ }
126
+
74
127
  function normalizeBundleShape(bundle) {
75
128
  if (!bundle || typeof bundle !== "object" || Array.isArray(bundle)) {
76
129
  return {};
@@ -177,6 +230,7 @@ function buildCandidateLocales({ locale, effectiveLocale, defaultLocale, aliases
177
230
  * locales: string[],
178
231
  * provider: {
179
232
  * locales: string[],
233
+ * resolveLocale: (locale: string) => string,
180
234
  * loadLocale: (context: { locale: string }) => Promise<Record<string, string | { content?: string }>>,
181
235
  * },
182
236
  * }}
@@ -186,6 +240,7 @@ export function createJSONLocalization(options = {}) {
186
240
  const locales = toLocaleList(options?.locales, defaultLocale);
187
241
  const localeSet = new Set(locales);
188
242
  const aliases = normalizeAliasMap(options?.aliases || {});
243
+ const aliasLookup = createAliasLookup({ aliases, localeSet });
189
244
  const cache = options?.cache instanceof Map ? options.cache : new Map();
190
245
  const basePath = normalizeBasePath(options?.basePath);
191
246
  const requestInit =
@@ -194,21 +249,10 @@ export function createJSONLocalization(options = {}) {
194
249
  : {};
195
250
 
196
251
  const resolveEffectiveLocale = (locale) => {
197
- const normalized = normalizeLocaleTag(locale);
198
- if (!normalized) {
199
- return defaultLocale;
200
- }
201
-
202
- if (localeSet.has(normalized)) {
203
- return normalized;
204
- }
205
-
206
- const base = toBaseLocale(normalized);
207
- if (localeSet.has(base)) {
208
- return base;
209
- }
210
-
211
- return defaultLocale;
252
+ return resolveConfiguredLocale(locale, {
253
+ defaultLocale,
254
+ aliasLookup,
255
+ });
212
256
  };
213
257
 
214
258
  const loadLocale = async ({ locale }) => {
@@ -268,6 +312,7 @@ export function createJSONLocalization(options = {}) {
268
312
  locales: [...locales],
269
313
  provider: {
270
314
  locales: [...locales],
315
+ resolveLocale: resolveEffectiveLocale,
271
316
  loadLocale,
272
317
  },
273
318
  };
@@ -45,6 +45,15 @@ function __resolveLocaleCandidate(locale) {
45
45
  if (!normalized) {
46
46
  return __localizationState.defaultLocale;
47
47
  }
48
+
49
+ const resolveLocale = __localizationState.provider?.resolveLocale;
50
+ if (typeof resolveLocale === "function") {
51
+ const resolved = __normalizeLocale(resolveLocale(locale));
52
+ if (resolved) {
53
+ return resolved;
54
+ }
55
+ }
56
+
48
57
  return normalized;
49
58
  }
50
59
 
@@ -110,7 +119,14 @@ function __resolveProvider(config) {
110
119
  ? provider.setLocale
111
120
  : null;
112
121
 
113
- if (!translate && !loadLocale && !setLocale) {
122
+ const resolveLocale =
123
+ typeof config?.resolveLocale === "function"
124
+ ? config.resolveLocale
125
+ : typeof provider?.resolveLocale === "function"
126
+ ? provider.resolveLocale
127
+ : null;
128
+
129
+ if (!translate && !loadLocale && !setLocale && !resolveLocale) {
114
130
  return null;
115
131
  }
116
132
 
@@ -118,6 +134,7 @@ function __resolveProvider(config) {
118
134
  translate,
119
135
  loadLocale,
120
136
  setLocale,
137
+ resolveLocale,
121
138
  };
122
139
  }
123
140
 
@@ -905,11 +922,18 @@ export function configureLocalization(config = null) {
905
922
  Object.prototype.hasOwnProperty.call(config, "provider") ||
906
923
  Object.prototype.hasOwnProperty.call(config, "translate") ||
907
924
  Object.prototype.hasOwnProperty.call(config, "loadLocale") ||
908
- Object.prototype.hasOwnProperty.call(config, "setLocale")
925
+ Object.prototype.hasOwnProperty.call(config, "setLocale") ||
926
+ Object.prototype.hasOwnProperty.call(config, "resolveLocale")
909
927
  ) {
910
928
  __localizationState.provider = __resolveProvider(config);
911
929
  }
912
930
 
931
+ if (__localizationState.provider?.resolveLocale) {
932
+ __localizationState.defaultLocale = __resolveLocaleCandidate(
933
+ __localizationState.defaultLocale
934
+ );
935
+ }
936
+
913
937
  __attachLangObserver();
914
938
  __scheduleReconcile();
915
939
 
@@ -3,6 +3,7 @@
3
3
  * Separated to keep the base runtime bundle lean for production/static usage.
4
4
  */
5
5
  import { Generator } from "./pds-generator.js";
6
+ import { msg } from "../common/localization.js";
6
7
  import { applyStyles, adoptLayers, adoptPrimitives } from "./pds-runtime.js";
7
8
  import {
8
9
  presets,
@@ -309,10 +310,10 @@ async function ensureLiveEditToggleButton() {
309
310
  return li;
310
311
  };
311
312
 
312
- menu.appendChild(createItem("toggle", "Toggle live editing", "pencil"));
313
- menu.appendChild(createItem("open-settings", "Open Settings", "gear"));
313
+ menu.appendChild(createItem("toggle", msg("Toggle live editing"), "pencil"));
314
+ menu.appendChild(createItem("open-settings", msg("Open Settings"), "gear"));
314
315
  menu.appendChild(createSeparator());
315
- menu.appendChild(createItem("reset-config", "Reset Config", "arrow-counter-clockwise"));
316
+ menu.appendChild(createItem("reset-config", msg("Reset Config"), "arrow-counter-clockwise"));
316
317
 
317
318
  await ensureSharedQuickModeToggleMenuItem(menu);
318
319
 
package/src/js/pds.d.ts CHANGED
@@ -124,6 +124,7 @@ export interface PDSLocalizationTranslateContext {
124
124
 
125
125
  export interface PDSLocalizationProvider {
126
126
  translate?: (context: PDSLocalizationTranslateContext) => string | undefined | null;
127
+ resolveLocale?: (locale: string) => string;
127
128
  loadLocale?: (context: {
128
129
  locale: string;
129
130
  defaultLocale: string;
@@ -154,6 +155,7 @@ export interface PDSLocalizationConfig {
154
155
  messages?: PDSLocalizationMessages;
155
156
  provider?: PDSLocalizationProvider;
156
157
  translate?: PDSLocalizationProvider["translate"];
158
+ resolveLocale?: PDSLocalizationProvider["resolveLocale"];
157
159
  loadLocale?: PDSLocalizationProvider["loadLocale"];
158
160
  setLocale?: PDSLocalizationProvider["setLocale"];
159
161
  }