@skyscanner/backpack-web 42.27.0 → 42.27.1

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.
@@ -71,6 +71,19 @@ const FALLBACK_LOCALE_BY_DIRECTION = {
71
71
  // Intl.Locale.textInfo is unavailable (Node < 22, older browsers).
72
72
  const RTL_LANGUAGE_SUBTAGS = new Set(['ar', 'he', 'fa', 'ur', 'yi', 'iw', 'ps', 'sd', 'ug', 'ku']);
73
73
 
74
+ // Returns true when `locale` is a BCP 47 string that Intl.Locale accepts.
75
+ // Ark's LocaleProvider calls `new Intl.Locale(locale)` without a try/catch,
76
+ // so any value we hand it must be validated here first or it throws
77
+ // "Incorrect locale information provided".
78
+ const isValidLocale = locale => {
79
+ try {
80
+ // Reading a property on the result (rather than bare `new`) satisfies the no-new lint rule.
81
+ return Boolean(new Intl.Locale(locale).baseName);
82
+ } catch {
83
+ return false;
84
+ }
85
+ };
86
+
74
87
  // Returns the text direction implied by a BCP 47 locale string.
75
88
  // Uses Intl.Locale.textInfo when available (Chrome 99+, Safari 15.4+, Firefox 126+, Node 22+);
76
89
  // falls back to a known-RTL-subtag lookup.
@@ -88,11 +101,18 @@ const getLangDir = locale => {
88
101
  //
89
102
  // Priority rules:
90
103
  // 1. If html[dir] is explicitly set:
91
- // - Use html[lang] only when its direction is consistent with html[dir].
104
+ // - Use html[lang] only when it is a valid locale AND its direction is
105
+ // consistent with html[dir].
92
106
  // - Otherwise fall back to FALLBACK_LOCALE_BY_DIRECTION[dir].
93
107
  // This prevents an LTR html[lang] (e.g. 'en' from a page template) from
94
108
  // overriding an explicit html[dir]="rtl" signal (e.g. from a dev RTL toggle).
95
- // 2. If html[dir] is not set: use html[lang] if present, else 'en-US'.
109
+ // 2. If html[dir] is not set: use html[lang] if it is a valid locale, else 'en-US'.
110
+ //
111
+ // Every value returned here is validated with isValidLocale() because Ark's
112
+ // LocaleProvider passes it straight to `new Intl.Locale()`, which throws on
113
+ // malformed input (e.g. '', '123', 'en_US'). An unvalidated value crashes the
114
+ // provider, and when the ErrorBoundary fallback also mounts BpkProvider the same
115
+ // bad value is re-read on every remount, producing an indefinite crash loop.
96
116
  //
97
117
  // SSR-safe: returns 'en-US' when document is unavailable.
98
118
  const getArkLocale = () => {
@@ -100,17 +120,12 @@ const getArkLocale = () => {
100
120
  const explicitDir = document.documentElement.getAttribute('dir');
101
121
  const lang = document.documentElement.getAttribute('lang');
102
122
  if (explicitDir === 'rtl' || explicitDir === 'ltr') {
103
- if (lang && getLangDir(lang) === explicitDir) return lang;
104
- return FALLBACK_LOCALE_BY_DIRECTION[explicitDir];
105
- }
106
- if (lang) {
107
- try {
108
- const locale = new Intl.Locale(lang);
109
- if (locale) return lang;
110
- } catch {
111
- // Invalid locale string — fall through to default
123
+ if (lang && isValidLocale(lang) && getLangDir(lang) === explicitDir) {
124
+ return lang;
112
125
  }
126
+ return FALLBACK_LOCALE_BY_DIRECTION[explicitDir];
113
127
  }
128
+ if (lang && isValidLocale(lang)) return lang;
114
129
  return 'en-US';
115
130
  };
116
131
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skyscanner/backpack-web",
3
- "version": "42.27.0",
3
+ "version": "42.27.1",
4
4
  "description": "Backpack Design System web library",
5
5
  "repository": {
6
6
  "type": "git",