@arcgis/components-utils 4.32.0-next.9 → 4.32.0-next.91

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.cjs CHANGED
@@ -33,6 +33,7 @@ __export(src_exports, {
33
33
  devToolsAwareTimeout: () => devToolsAwareTimeout,
34
34
  extractMinorVersion: () => extractMinorVersion,
35
35
  fetchT9nStringsBundle: () => fetchT9nStringsBundle,
36
+ focusElement: () => focusElement,
36
37
  generateGuid: () => generateGuid,
37
38
  getElementAttribute: () => getElementAttribute,
38
39
  getElementDir: () => getElementDir,
@@ -41,6 +42,7 @@ __export(src_exports, {
41
42
  getPreamble: () => getPreamble,
42
43
  hasSameOrigin: () => hasSameOrigin,
43
44
  identity: () => identity,
45
+ isEsriInternalEnv: () => isEsriInternalEnv,
44
46
  isNotNull: () => isNotNull,
45
47
  isNotUndefined: () => isNotUndefined,
46
48
  isURL: () => isURL,
@@ -205,16 +207,16 @@ function getElementAttribute(el, prop, fallbackValue) {
205
207
  function isElement(ref) {
206
208
  return ref.nodeType === Node.ELEMENT_NODE;
207
209
  }
208
- function isHTMLWithSetFocus(ref) {
209
- return "setFocus" in ref && typeof ref.setFocus === "function";
210
+ function hasSetFocus(ref) {
211
+ return typeof ref.setFocus === "function";
210
212
  }
211
213
  function setFocus(ref, selector = "") {
212
214
  if (!isElement(ref)) {
213
215
  return false;
214
216
  }
215
217
  if (ref.matches(selector)) {
216
- if (isHTMLWithSetFocus(ref)) {
217
- setTimeout(() => ref.setFocus(), 0);
218
+ if (hasSetFocus(ref)) {
219
+ setTimeout(() => void ref.setFocus(), 0);
218
220
  }
219
221
  return true;
220
222
  }
@@ -233,6 +235,16 @@ function setFocus(ref, selector = "") {
233
235
  }
234
236
  return false;
235
237
  }
238
+ async function focusElement(el) {
239
+ if (el == null) {
240
+ return;
241
+ }
242
+ if (hasSetFocus(el)) {
243
+ await el.setFocus();
244
+ } else {
245
+ el.focus();
246
+ }
247
+ }
236
248
  function setFocusOnElement(ref, selector) {
237
249
  if (!ref?.shadowRoot) {
238
250
  return;
@@ -241,17 +253,13 @@ function setFocusOnElement(ref, selector) {
241
253
  setFocus(ref, selector);
242
254
  return;
243
255
  }
244
- const mutationObserver = new MutationObserver(() => {
245
- mutationObserver.disconnect();
246
- setFocus(ref, selector);
247
- });
248
- mutationObserver.observe(ref, {
249
- attributes: true,
250
- attributeFilter: ["hydrated", "calcite-hydrated"]
251
- });
256
+ void Promise.resolve(ref.componentOnReady?.()).then(() => setFocus(ref, selector));
252
257
  }
253
258
 
254
259
  // src/errors.ts
260
+ function isEsriInternalEnv() {
261
+ return typeof globalThis.process === "object" && !!process.env.ESRI_INTERNAL;
262
+ }
255
263
  function safeCall(callback, thisContext, ...rest) {
256
264
  try {
257
265
  return callback?.call(thisContext, ...rest);
@@ -308,6 +316,7 @@ var supportedLocalesArray = [
308
316
  "lv",
309
317
  "nl",
310
318
  "nb",
319
+ "no",
311
320
  "pl",
312
321
  "pt-BR",
313
322
  "pt-PT",
@@ -325,13 +334,13 @@ var supportedLocalesArray = [
325
334
  "zh-HK",
326
335
  "zh-TW"
327
336
  ];
328
- var supportedLocales = new Set(supportedLocalesArray);
337
+ var supportedLocales = /* @__PURE__ */ new Set(supportedLocalesArray);
329
338
  var defaultLocale = "en";
330
339
  var localeEquivalencies = {
331
- // We use `pt-BR` as it will have the same translations as `pt`, which has no corresponding bundle
340
+ // We use `pt-PT` as it will have the same translations as `pt`, which has no corresponding bundle
332
341
  pt: "pt-PT",
333
- // We support both 'nb' and 'no' (BCP 47) for Norwegian but only `nb` has corresponding bundle
334
- no: "nb",
342
+ // We support both 'nb' and 'no' (BCP 47) for Norwegian but only `no` has corresponding bundle
343
+ nb: "no",
335
344
  // We use `zh-CN` as base translation for chinese locales which has no corresponding bundle.
336
345
  zh: "zh-CN"
337
346
  };
@@ -350,7 +359,16 @@ async function fetchBundle(locale, path) {
350
359
  return await response.json();
351
360
  }
352
361
  } catch (error) {
353
- console.error(error);
362
+ if (process.env.NODE_ENV !== "production") {
363
+ const is404ViteFallback = String(error).includes(`Unexpected token '<', "<!doctype "... is not valid JSON`);
364
+ if (is404ViteFallback) {
365
+ console.error(`[404] Localization strings not found at ${filePath}`);
366
+ } else {
367
+ console.error(`Error fetching localization strings at ${filePath}`, error);
368
+ }
369
+ } else {
370
+ console.error(error);
371
+ }
354
372
  return {};
355
373
  }
356
374
  if (locale === defaultLocale) {
@@ -392,7 +410,7 @@ function startLocaleObserver(element, assetsPath, onUpdated, assetName) {
392
410
  async function updateComponentLocaleState(element, assetsPath, assetName = element.tagName.toLowerCase().split("-").slice(1).join("-")) {
393
411
  const { lang, t9nLocale } = getElementLocales(element);
394
412
  const t9nAssetsPath = `${assetsPath}/${assetName}/t9n`;
395
- const prefix = `${assetName}.t9n.`;
413
+ const prefix = `messages.`;
396
414
  const t9nStrings = (
397
415
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
398
416
  assetName === null ? {} : await fetchT9nStringsBundle(t9nLocale, t9nAssetsPath, prefix)
@@ -535,6 +553,7 @@ function isURL(url) {
535
553
  devToolsAwareTimeout,
536
554
  extractMinorVersion,
537
555
  fetchT9nStringsBundle,
556
+ focusElement,
538
557
  generateGuid,
539
558
  getElementAttribute,
540
559
  getElementDir,
@@ -543,6 +562,7 @@ function isURL(url) {
543
562
  getPreamble,
544
563
  hasSameOrigin,
545
564
  identity,
565
+ isEsriInternalEnv,
546
566
  isNotNull,
547
567
  isNotUndefined,
548
568
  isURL,
package/dist/index.d.cts CHANGED
@@ -125,6 +125,10 @@ declare function getElementDir(el: HTMLElement): "ltr" | "rtl";
125
125
  * @returns The attribute value or the fallback value if the attribute is not found.
126
126
  */
127
127
  declare function getElementAttribute(el: Element, prop: string, fallbackValue: string): string;
128
+ interface FocusableElement extends HTMLElement {
129
+ setFocus?: () => Promise<void>;
130
+ }
131
+ declare function focusElement(el: FocusableElement | undefined): Promise<void>;
128
132
  /**
129
133
  * Set the focus on the element that matches the selector.
130
134
  * It will traverse the element's ancestors to find the target element.
@@ -134,21 +138,44 @@ declare function getElementAttribute(el: Element, prop: string, fallbackValue: s
134
138
  * @param ref The element to start the search from.
135
139
  * @param selector The selector to match.
136
140
  * @returns Returns true if the focus is set on the element.
141
+ *
142
+ * REFACTOR: this is doing too much. break it into separate find element and focus
143
+ * element utilities
137
144
  */
138
- declare function setFocusOnElement(ref: Element | null | undefined, selector: string): void;
145
+ declare function setFocusOnElement(ref: (Element & {
146
+ componentOnReady?: () => Promise<void>;
147
+ }) | null | undefined, selector: string): void;
139
148
 
149
+ /**
150
+ * Check whether the code is executing in an Esri internal environment (for
151
+ * example, Lumina dev server). When true, your code can enable extra validation
152
+ * to detect incorrect usages or do runtime bug detection.
153
+ *
154
+ * The call to isEsriInternalEnv() MUST always appear behind one of the
155
+ * following guards to ensure it is correctly eliminated in production bundles:
156
+ *
157
+ * - `process.env.NODE_ENV !== "production"`
158
+ * - `process.env.NODE_ENV === "development"`
159
+ * - `process.env.NODE_ENV === "test"`
160
+ *
161
+ * @remarks
162
+ * This function is primary for usage in support packages. In Lumina component
163
+ * packages, simpler alternatives are provided:
164
+ * https://qawebgis.esri.com/components/lumina/publishing#bundling-code-conditionally
165
+ */
166
+ declare function isEsriInternalEnv(): boolean;
140
167
  /**
141
168
  * Calls a sync method and catch any errors. Returns undefined if error occurred.
142
169
  *
143
170
  * Can also provide a thisContext and rest arguments
144
171
  */
145
- declare function safeCall<Callback extends (...args: any) => any>(callback?: Callback, thisContext?: ThisParameterType<Callback>, ...rest: Parameters<Callback>): ReturnType<Callback> | void;
172
+ declare function safeCall<Callback extends (...args: never[]) => unknown>(callback?: Callback, thisContext?: ThisParameterType<Callback>, ...rest: Parameters<Callback>): ReturnType<Callback> | void;
146
173
  /**
147
174
  * Calls an async method and catch any errors. Returns undefined if error occurred.
148
175
  *
149
176
  * Can also provide a thisContext and rest arguments
150
177
  */
151
- declare function safeAsyncCall<Callback extends (...args: any) => any>(callback?: Callback, thisContext?: ThisParameterType<Callback>, ...rest: Parameters<Callback>): Promise<Awaited<ReturnType<Callback>> | void>;
178
+ declare function safeAsyncCall<Callback extends (...args: never[]) => unknown>(callback?: Callback, thisContext?: ThisParameterType<Callback>, ...rest: Parameters<Callback>): Promise<Awaited<ReturnType<Callback>> | void>;
152
179
 
153
180
  /**
154
181
  * Generates a GUID string.
@@ -162,11 +189,11 @@ declare function generateGuid(): string;
162
189
  interface GenericT9nStrings {
163
190
  [key: string]: GenericT9nStrings | string;
164
191
  }
165
- declare const supportedLocalesArray: readonly ["ar", "bg", "bs", "ca", "cs", "da", "de", "el", "en", "es", "et", "fi", "fr", "he", "hr", "hu", "id", "it", "ja", "ko", "lt", "lv", "nl", "nb", "pl", "pt-BR", "pt-PT", "ro", "ru", "sk", "sl", "sr", "sv", "th", "tr", "uk", "vi", "zh-CN", "zh-HK", "zh-TW"];
192
+ declare const supportedLocalesArray: readonly ["ar", "bg", "bs", "ca", "cs", "da", "de", "el", "en", "es", "et", "fi", "fr", "he", "hr", "hu", "id", "it", "ja", "ko", "lt", "lv", "nl", "nb", "no", "pl", "pt-BR", "pt-PT", "ro", "ru", "sk", "sl", "sr", "sv", "th", "tr", "uk", "vi", "zh-CN", "zh-HK", "zh-TW"];
166
193
  /**
167
194
  * The list of supported locales for ArcGIS Maps SDK for JavaScript components.
168
195
  */
169
- declare const supportedLocales: Set<"hr" | "th" | "tr" | "ar" | "bg" | "bs" | "ca" | "cs" | "da" | "de" | "el" | "en" | "es" | "et" | "fi" | "fr" | "he" | "hu" | "id" | "it" | "ja" | "ko" | "lt" | "lv" | "nl" | "nb" | "pl" | "pt-BR" | "pt-PT" | "ro" | "ru" | "sk" | "sl" | "sr" | "sv" | "uk" | "vi" | "zh-CN" | "zh-HK" | "zh-TW">;
196
+ declare const supportedLocales: Set<"hr" | "th" | "tr" | "ar" | "bg" | "bs" | "ca" | "cs" | "da" | "de" | "el" | "en" | "es" | "et" | "fi" | "fr" | "he" | "hu" | "id" | "it" | "ja" | "ko" | "lt" | "lv" | "nl" | "nb" | "no" | "pl" | "pt-BR" | "pt-PT" | "ro" | "ru" | "sk" | "sl" | "sr" | "sv" | "uk" | "vi" | "zh-CN" | "zh-HK" | "zh-TW">;
170
197
  type SupportedLocale = (typeof supportedLocalesArray)[number];
171
198
  declare const defaultLocale = "en";
172
199
  /**
@@ -180,7 +207,7 @@ declare const defaultLocale = "en";
180
207
  *
181
208
  * @example
182
209
  * ```ts
183
- * const t9nStrings = await fetchT9nStringsBundle("en", getAssetPath("./assets/coding-editor/t9n"), "coding-editor.t9n.");
210
+ * const t9nStrings = await fetchT9nStringsBundle("en", getAssetPath("./assets/coding-editor/t9n"), "messages.");
184
211
  * ```
185
212
  */
186
213
  declare function fetchT9nStringsBundle<Strings extends GenericT9nStrings>(
@@ -340,4 +367,4 @@ declare function hasSameOrigin(url1: string | null | undefined, url2: string | n
340
367
  */
341
368
  declare function isURL(url: string): boolean;
342
369
 
343
- export { Deferred, type GenericT9nStrings, type IHandle, type LocaleObserver, type Nil, type SupportedLocale, type Writable, addLTRMark, camelToHuman, camelToKebab, capitalize, classes, closestElement, createFilterExpression, debounce, defaultLocale, devToolsAwareTimeout, extractMinorVersion, fetchT9nStringsBundle, generateGuid, getElementAttribute, getElementDir, getElementLocales, getElementTheme, getPreamble, hasSameOrigin, identity, isNotNull, isNotUndefined, isURL, kebabToPascal, mappedFind, normalizeLocale, observeAncestorsMutation, quoteString, safeAsyncCall, safeCall, setFocusOnElement, setValuesInString, startLocaleObserver, supportedLocales, uncapitalize };
370
+ export { Deferred, type FocusableElement, type GenericT9nStrings, type IHandle, type LocaleObserver, type Nil, type SupportedLocale, type Writable, addLTRMark, camelToHuman, camelToKebab, capitalize, classes, closestElement, createFilterExpression, debounce, defaultLocale, devToolsAwareTimeout, extractMinorVersion, fetchT9nStringsBundle, focusElement, generateGuid, getElementAttribute, getElementDir, getElementLocales, getElementTheme, getPreamble, hasSameOrigin, identity, isEsriInternalEnv, isNotNull, isNotUndefined, isURL, kebabToPascal, mappedFind, normalizeLocale, observeAncestorsMutation, quoteString, safeAsyncCall, safeCall, setFocusOnElement, setValuesInString, startLocaleObserver, supportedLocales, uncapitalize };
package/dist/index.d.ts CHANGED
@@ -125,6 +125,10 @@ declare function getElementDir(el: HTMLElement): "ltr" | "rtl";
125
125
  * @returns The attribute value or the fallback value if the attribute is not found.
126
126
  */
127
127
  declare function getElementAttribute(el: Element, prop: string, fallbackValue: string): string;
128
+ interface FocusableElement extends HTMLElement {
129
+ setFocus?: () => Promise<void>;
130
+ }
131
+ declare function focusElement(el: FocusableElement | undefined): Promise<void>;
128
132
  /**
129
133
  * Set the focus on the element that matches the selector.
130
134
  * It will traverse the element's ancestors to find the target element.
@@ -134,21 +138,44 @@ declare function getElementAttribute(el: Element, prop: string, fallbackValue: s
134
138
  * @param ref The element to start the search from.
135
139
  * @param selector The selector to match.
136
140
  * @returns Returns true if the focus is set on the element.
141
+ *
142
+ * REFACTOR: this is doing too much. break it into separate find element and focus
143
+ * element utilities
137
144
  */
138
- declare function setFocusOnElement(ref: Element | null | undefined, selector: string): void;
145
+ declare function setFocusOnElement(ref: (Element & {
146
+ componentOnReady?: () => Promise<void>;
147
+ }) | null | undefined, selector: string): void;
139
148
 
149
+ /**
150
+ * Check whether the code is executing in an Esri internal environment (for
151
+ * example, Lumina dev server). When true, your code can enable extra validation
152
+ * to detect incorrect usages or do runtime bug detection.
153
+ *
154
+ * The call to isEsriInternalEnv() MUST always appear behind one of the
155
+ * following guards to ensure it is correctly eliminated in production bundles:
156
+ *
157
+ * - `process.env.NODE_ENV !== "production"`
158
+ * - `process.env.NODE_ENV === "development"`
159
+ * - `process.env.NODE_ENV === "test"`
160
+ *
161
+ * @remarks
162
+ * This function is primary for usage in support packages. In Lumina component
163
+ * packages, simpler alternatives are provided:
164
+ * https://qawebgis.esri.com/components/lumina/publishing#bundling-code-conditionally
165
+ */
166
+ declare function isEsriInternalEnv(): boolean;
140
167
  /**
141
168
  * Calls a sync method and catch any errors. Returns undefined if error occurred.
142
169
  *
143
170
  * Can also provide a thisContext and rest arguments
144
171
  */
145
- declare function safeCall<Callback extends (...args: any) => any>(callback?: Callback, thisContext?: ThisParameterType<Callback>, ...rest: Parameters<Callback>): ReturnType<Callback> | void;
172
+ declare function safeCall<Callback extends (...args: never[]) => unknown>(callback?: Callback, thisContext?: ThisParameterType<Callback>, ...rest: Parameters<Callback>): ReturnType<Callback> | void;
146
173
  /**
147
174
  * Calls an async method and catch any errors. Returns undefined if error occurred.
148
175
  *
149
176
  * Can also provide a thisContext and rest arguments
150
177
  */
151
- declare function safeAsyncCall<Callback extends (...args: any) => any>(callback?: Callback, thisContext?: ThisParameterType<Callback>, ...rest: Parameters<Callback>): Promise<Awaited<ReturnType<Callback>> | void>;
178
+ declare function safeAsyncCall<Callback extends (...args: never[]) => unknown>(callback?: Callback, thisContext?: ThisParameterType<Callback>, ...rest: Parameters<Callback>): Promise<Awaited<ReturnType<Callback>> | void>;
152
179
 
153
180
  /**
154
181
  * Generates a GUID string.
@@ -162,11 +189,11 @@ declare function generateGuid(): string;
162
189
  interface GenericT9nStrings {
163
190
  [key: string]: GenericT9nStrings | string;
164
191
  }
165
- declare const supportedLocalesArray: readonly ["ar", "bg", "bs", "ca", "cs", "da", "de", "el", "en", "es", "et", "fi", "fr", "he", "hr", "hu", "id", "it", "ja", "ko", "lt", "lv", "nl", "nb", "pl", "pt-BR", "pt-PT", "ro", "ru", "sk", "sl", "sr", "sv", "th", "tr", "uk", "vi", "zh-CN", "zh-HK", "zh-TW"];
192
+ declare const supportedLocalesArray: readonly ["ar", "bg", "bs", "ca", "cs", "da", "de", "el", "en", "es", "et", "fi", "fr", "he", "hr", "hu", "id", "it", "ja", "ko", "lt", "lv", "nl", "nb", "no", "pl", "pt-BR", "pt-PT", "ro", "ru", "sk", "sl", "sr", "sv", "th", "tr", "uk", "vi", "zh-CN", "zh-HK", "zh-TW"];
166
193
  /**
167
194
  * The list of supported locales for ArcGIS Maps SDK for JavaScript components.
168
195
  */
169
- declare const supportedLocales: Set<"hr" | "th" | "tr" | "ar" | "bg" | "bs" | "ca" | "cs" | "da" | "de" | "el" | "en" | "es" | "et" | "fi" | "fr" | "he" | "hu" | "id" | "it" | "ja" | "ko" | "lt" | "lv" | "nl" | "nb" | "pl" | "pt-BR" | "pt-PT" | "ro" | "ru" | "sk" | "sl" | "sr" | "sv" | "uk" | "vi" | "zh-CN" | "zh-HK" | "zh-TW">;
196
+ declare const supportedLocales: Set<"hr" | "th" | "tr" | "ar" | "bg" | "bs" | "ca" | "cs" | "da" | "de" | "el" | "en" | "es" | "et" | "fi" | "fr" | "he" | "hu" | "id" | "it" | "ja" | "ko" | "lt" | "lv" | "nl" | "nb" | "no" | "pl" | "pt-BR" | "pt-PT" | "ro" | "ru" | "sk" | "sl" | "sr" | "sv" | "uk" | "vi" | "zh-CN" | "zh-HK" | "zh-TW">;
170
197
  type SupportedLocale = (typeof supportedLocalesArray)[number];
171
198
  declare const defaultLocale = "en";
172
199
  /**
@@ -180,7 +207,7 @@ declare const defaultLocale = "en";
180
207
  *
181
208
  * @example
182
209
  * ```ts
183
- * const t9nStrings = await fetchT9nStringsBundle("en", getAssetPath("./assets/coding-editor/t9n"), "coding-editor.t9n.");
210
+ * const t9nStrings = await fetchT9nStringsBundle("en", getAssetPath("./assets/coding-editor/t9n"), "messages.");
184
211
  * ```
185
212
  */
186
213
  declare function fetchT9nStringsBundle<Strings extends GenericT9nStrings>(
@@ -340,4 +367,4 @@ declare function hasSameOrigin(url1: string | null | undefined, url2: string | n
340
367
  */
341
368
  declare function isURL(url: string): boolean;
342
369
 
343
- export { Deferred, type GenericT9nStrings, type IHandle, type LocaleObserver, type Nil, type SupportedLocale, type Writable, addLTRMark, camelToHuman, camelToKebab, capitalize, classes, closestElement, createFilterExpression, debounce, defaultLocale, devToolsAwareTimeout, extractMinorVersion, fetchT9nStringsBundle, generateGuid, getElementAttribute, getElementDir, getElementLocales, getElementTheme, getPreamble, hasSameOrigin, identity, isNotNull, isNotUndefined, isURL, kebabToPascal, mappedFind, normalizeLocale, observeAncestorsMutation, quoteString, safeAsyncCall, safeCall, setFocusOnElement, setValuesInString, startLocaleObserver, supportedLocales, uncapitalize };
370
+ export { Deferred, type FocusableElement, type GenericT9nStrings, type IHandle, type LocaleObserver, type Nil, type SupportedLocale, type Writable, addLTRMark, camelToHuman, camelToKebab, capitalize, classes, closestElement, createFilterExpression, debounce, defaultLocale, devToolsAwareTimeout, extractMinorVersion, fetchT9nStringsBundle, focusElement, generateGuid, getElementAttribute, getElementDir, getElementLocales, getElementTheme, getPreamble, hasSameOrigin, identity, isEsriInternalEnv, isNotNull, isNotUndefined, isURL, kebabToPascal, mappedFind, normalizeLocale, observeAncestorsMutation, quoteString, safeAsyncCall, safeCall, setFocusOnElement, setValuesInString, startLocaleObserver, supportedLocales, uncapitalize };
package/dist/index.js CHANGED
@@ -144,16 +144,16 @@ function getElementAttribute(el, prop, fallbackValue) {
144
144
  function isElement(ref) {
145
145
  return ref.nodeType === Node.ELEMENT_NODE;
146
146
  }
147
- function isHTMLWithSetFocus(ref) {
148
- return "setFocus" in ref && typeof ref.setFocus === "function";
147
+ function hasSetFocus(ref) {
148
+ return typeof ref.setFocus === "function";
149
149
  }
150
150
  function setFocus(ref, selector = "") {
151
151
  if (!isElement(ref)) {
152
152
  return false;
153
153
  }
154
154
  if (ref.matches(selector)) {
155
- if (isHTMLWithSetFocus(ref)) {
156
- setTimeout(() => ref.setFocus(), 0);
155
+ if (hasSetFocus(ref)) {
156
+ setTimeout(() => void ref.setFocus(), 0);
157
157
  }
158
158
  return true;
159
159
  }
@@ -172,6 +172,16 @@ function setFocus(ref, selector = "") {
172
172
  }
173
173
  return false;
174
174
  }
175
+ async function focusElement(el) {
176
+ if (el == null) {
177
+ return;
178
+ }
179
+ if (hasSetFocus(el)) {
180
+ await el.setFocus();
181
+ } else {
182
+ el.focus();
183
+ }
184
+ }
175
185
  function setFocusOnElement(ref, selector) {
176
186
  if (!ref?.shadowRoot) {
177
187
  return;
@@ -180,17 +190,13 @@ function setFocusOnElement(ref, selector) {
180
190
  setFocus(ref, selector);
181
191
  return;
182
192
  }
183
- const mutationObserver = new MutationObserver(() => {
184
- mutationObserver.disconnect();
185
- setFocus(ref, selector);
186
- });
187
- mutationObserver.observe(ref, {
188
- attributes: true,
189
- attributeFilter: ["hydrated", "calcite-hydrated"]
190
- });
193
+ void Promise.resolve(ref.componentOnReady?.()).then(() => setFocus(ref, selector));
191
194
  }
192
195
 
193
196
  // src/errors.ts
197
+ function isEsriInternalEnv() {
198
+ return typeof globalThis.process === "object" && !!process.env.ESRI_INTERNAL;
199
+ }
194
200
  function safeCall(callback, thisContext, ...rest) {
195
201
  try {
196
202
  return callback?.call(thisContext, ...rest);
@@ -247,6 +253,7 @@ var supportedLocalesArray = [
247
253
  "lv",
248
254
  "nl",
249
255
  "nb",
256
+ "no",
250
257
  "pl",
251
258
  "pt-BR",
252
259
  "pt-PT",
@@ -264,13 +271,13 @@ var supportedLocalesArray = [
264
271
  "zh-HK",
265
272
  "zh-TW"
266
273
  ];
267
- var supportedLocales = new Set(supportedLocalesArray);
274
+ var supportedLocales = /* @__PURE__ */ new Set(supportedLocalesArray);
268
275
  var defaultLocale = "en";
269
276
  var localeEquivalencies = {
270
- // We use `pt-BR` as it will have the same translations as `pt`, which has no corresponding bundle
277
+ // We use `pt-PT` as it will have the same translations as `pt`, which has no corresponding bundle
271
278
  pt: "pt-PT",
272
- // We support both 'nb' and 'no' (BCP 47) for Norwegian but only `nb` has corresponding bundle
273
- no: "nb",
279
+ // We support both 'nb' and 'no' (BCP 47) for Norwegian but only `no` has corresponding bundle
280
+ nb: "no",
274
281
  // We use `zh-CN` as base translation for chinese locales which has no corresponding bundle.
275
282
  zh: "zh-CN"
276
283
  };
@@ -289,7 +296,16 @@ async function fetchBundle(locale, path) {
289
296
  return await response.json();
290
297
  }
291
298
  } catch (error) {
292
- console.error(error);
299
+ if (process.env.NODE_ENV !== "production") {
300
+ const is404ViteFallback = String(error).includes(`Unexpected token '<', "<!doctype "... is not valid JSON`);
301
+ if (is404ViteFallback) {
302
+ console.error(`[404] Localization strings not found at ${filePath}`);
303
+ } else {
304
+ console.error(`Error fetching localization strings at ${filePath}`, error);
305
+ }
306
+ } else {
307
+ console.error(error);
308
+ }
293
309
  return {};
294
310
  }
295
311
  if (locale === defaultLocale) {
@@ -331,7 +347,7 @@ function startLocaleObserver(element, assetsPath, onUpdated, assetName) {
331
347
  async function updateComponentLocaleState(element, assetsPath, assetName = element.tagName.toLowerCase().split("-").slice(1).join("-")) {
332
348
  const { lang, t9nLocale } = getElementLocales(element);
333
349
  const t9nAssetsPath = `${assetsPath}/${assetName}/t9n`;
334
- const prefix = `${assetName}.t9n.`;
350
+ const prefix = `messages.`;
335
351
  const t9nStrings = (
336
352
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
337
353
  assetName === null ? {} : await fetchT9nStringsBundle(t9nLocale, t9nAssetsPath, prefix)
@@ -473,6 +489,7 @@ export {
473
489
  devToolsAwareTimeout,
474
490
  extractMinorVersion,
475
491
  fetchT9nStringsBundle,
492
+ focusElement,
476
493
  generateGuid,
477
494
  getElementAttribute,
478
495
  getElementDir,
@@ -481,6 +498,7 @@ export {
481
498
  getPreamble,
482
499
  hasSameOrigin,
483
500
  identity,
501
+ isEsriInternalEnv,
484
502
  isNotNull,
485
503
  isNotUndefined,
486
504
  isURL,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcgis/components-utils",
3
- "version": "4.32.0-next.9",
3
+ "version": "4.32.0-next.91",
4
4
  "description": "Collection of common internal patterns and utilities for ArcGIS Maps SDK for JavaScript components.",
5
5
  "homepage": "https://developers.arcgis.com/javascript/latest/",
6
6
  "sideEffects": false,