@seamly/web-ui 22.1.0 → 22.2.0

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.
Files changed (50) hide show
  1. package/build/dist/lib/components.js +429 -180
  2. package/build/dist/lib/components.js.map +1 -1
  3. package/build/dist/lib/components.min.js +1 -1
  4. package/build/dist/lib/components.min.js.LICENSE.txt +2 -2
  5. package/build/dist/lib/components.min.js.map +1 -1
  6. package/build/dist/lib/hooks.js +84 -19
  7. package/build/dist/lib/hooks.js.map +1 -1
  8. package/build/dist/lib/hooks.min.js +1 -1
  9. package/build/dist/lib/hooks.min.js.map +1 -1
  10. package/build/dist/lib/index.debug.js +38 -38
  11. package/build/dist/lib/index.debug.min.js +1 -1
  12. package/build/dist/lib/index.debug.min.js.map +1 -1
  13. package/build/dist/lib/index.js +462 -193
  14. package/build/dist/lib/index.js.map +1 -1
  15. package/build/dist/lib/index.min.js +1 -1
  16. package/build/dist/lib/index.min.js.LICENSE.txt +2 -2
  17. package/build/dist/lib/index.min.js.map +1 -1
  18. package/build/dist/lib/standalone.js +539 -216
  19. package/build/dist/lib/standalone.js.map +1 -1
  20. package/build/dist/lib/standalone.min.js +1 -1
  21. package/build/dist/lib/standalone.min.js.LICENSE.txt +1 -1
  22. package/build/dist/lib/standalone.min.js.map +1 -1
  23. package/build/dist/lib/style-guide.js +557 -190
  24. package/build/dist/lib/style-guide.js.map +1 -1
  25. package/build/dist/lib/style-guide.min.js +1 -1
  26. package/build/dist/lib/style-guide.min.js.LICENSE.txt +2 -2
  27. package/build/dist/lib/style-guide.min.js.map +1 -1
  28. package/build/dist/lib/styles-default-implementation.js +1 -1
  29. package/build/dist/lib/styles.css +1 -1
  30. package/build/dist/lib/styles.js +1 -1
  31. package/build/dist/lib/utils.js +459 -190
  32. package/build/dist/lib/utils.js.map +1 -1
  33. package/build/dist/lib/utils.min.js +1 -1
  34. package/build/dist/lib/utils.min.js.LICENSE.txt +1 -1
  35. package/build/dist/lib/utils.min.js.map +1 -1
  36. package/package.json +28 -28
  37. package/src/javascripts/api/index.ts +13 -1
  38. package/src/javascripts/domains/config/slice.ts +2 -1
  39. package/src/javascripts/domains/forms/selectors.ts +6 -8
  40. package/src/javascripts/domains/forms/slice.ts +1 -1
  41. package/src/javascripts/domains/translations/components/options-dialog/translation-option.tsx +3 -1
  42. package/src/javascripts/domains/translations/components/options-dialog/translation-options.tsx +62 -35
  43. package/src/javascripts/domains/translations/slice.ts +8 -1
  44. package/src/javascripts/lib/engine/index.tsx +3 -1
  45. package/src/javascripts/style-guide/states.js +47 -0
  46. package/src/javascripts/ui/components/entry/text-entry/hooks.ts +2 -2
  47. package/src/javascripts/ui/components/form-controls/wrapper.tsx +13 -3
  48. package/src/stylesheets/5-components/_input.scss +0 -5
  49. package/src/stylesheets/5-components/_options.scss +2 -2
  50. package/src/stylesheets/5-components/_translation-options.scss +23 -3
@@ -2104,6 +2104,7 @@ _ConversationConnector_connectionListeners = new WeakMap(), _ConversationConnect
2104
2104
  return !complete;
2105
2105
  }), "f");
2106
2106
  };
2107
+ /* harmony default export */ const conversation_connector = (ConversationConnector);
2107
2108
  ;// CONCATENATED MODULE: ./src/javascripts/api/index.ts
2108
2109
  var api_awaiter = undefined && undefined.__awaiter || function (thisArg, _arguments, P, generator) {
2109
2110
  function adopt(value) {
@@ -2143,6 +2144,14 @@ var api_classPrivateFieldGet = undefined && undefined.__classPrivateFieldGet ||
2143
2144
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
2144
2145
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
2145
2146
  };
2147
+ var __rest = undefined && undefined.__rest || function (s, e) {
2148
+ var t = {};
2149
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
2150
+ if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
2151
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
2152
+ }
2153
+ return t;
2154
+ };
2146
2155
  var _API_instances, _API_ready, _API_externalId, _API_conversationAuthToken, _API_layoutMode, _API_config, _API_getAccessToken, _API_setAccessToken, _API_setConversationUrl, _API_getChannelTopic, _API_setChannelTopic, _API_getLocale, _API_getUrlPrefix, _API_updateUrls, _API_createConversation, _API_getEnvironment;
2147
2156
 
2148
2157
 
@@ -2230,7 +2239,7 @@ class API {
2230
2239
  _API_conversationAuthToken.set(this, void 0);
2231
2240
  _API_layoutMode.set(this, void 0);
2232
2241
  _API_config.set(this, void 0);
2233
- this.conversation = new ConversationConnector();
2242
+ this.conversation = new conversation_connector();
2234
2243
  _API_getLocale.set(this, locale => locale || this.locale);
2235
2244
  this.store = objectStore(`${namespace}.connection${context.locale ? `.${context.locale}` : ''}`, config.storageProvider || store);
2236
2245
  this.connectionInfo = {
@@ -2503,6 +2512,7 @@ class API {
2503
2512
  this.conversation.pushToChannel(command, buildPayload(command, payload), 10000);
2504
2513
  }
2505
2514
  sendContext(context) {
2515
+ var _a;
2506
2516
  const {
2507
2517
  locale,
2508
2518
  variables
@@ -2524,7 +2534,15 @@ class API {
2524
2534
  if (Object.keys(payload).length === 0 && payload.constructor === Object) {
2525
2535
  return;
2526
2536
  }
2527
- this.send('context', payload, false);
2537
+ // Destructure the server locale from the payload
2538
+ const {
2539
+ locale: _
2540
+ } = payload,
2541
+ restPayload = __rest(payload, ["locale"]);
2542
+ const configLocale = (_a = api_classPrivateFieldGet(this, _API_config, "f").context) === null || _a === void 0 ? void 0 : _a.locale;
2543
+ this.send('context', Object.assign(Object.assign({}, configLocale ? {
2544
+ locale: configLocale
2545
+ } : {}), restPayload), false);
2528
2546
  }
2529
2547
  }
2530
2548
  _API_ready = new WeakMap(), _API_externalId = new WeakMap(), _API_conversationAuthToken = new WeakMap(), _API_layoutMode = new WeakMap(), _API_config = new WeakMap(), _API_getLocale = new WeakMap(), _API_instances = new WeakSet(), _API_getAccessToken = function _API_getAccessToken() {
@@ -2601,7 +2619,7 @@ _API_ready = new WeakMap(), _API_externalId = new WeakMap(), _API_conversationAu
2601
2619
  return {
2602
2620
  clientName: "@seamly/web-ui",
2603
2621
  clientVariant: api_classPrivateFieldGet(this, _API_layoutMode, "f"),
2604
- clientVersion: "22.1.0",
2622
+ clientVersion: "22.2.0",
2605
2623
  currentUrl: window.location.toString(),
2606
2624
  screenResolution: `${window.screen.width}x${window.screen.height}`,
2607
2625
  timezone: getTimeZone(),
@@ -2637,15 +2655,52 @@ const setBatch = newBatch => batch = newBatch; // Supply a getter just to skip d
2637
2655
  const getBatch = () => batch;
2638
2656
  ;// CONCATENATED MODULE: ./node_modules/react-redux/es/components/Context.js
2639
2657
 
2640
- const Context_ReactReduxContext = /*#__PURE__*/(0,compat_module.createContext)(null);
2658
+ const ContextKey = Symbol.for(`react-redux-context-${compat_module.version}`);
2659
+ const gT = globalThis;
2660
+
2661
+ function getContext() {
2662
+ let realContext = gT[ContextKey];
2663
+
2664
+ if (!realContext) {
2665
+ realContext = (0,compat_module.createContext)(null);
2666
+
2667
+ if (false) {}
2668
+
2669
+ gT[ContextKey] = realContext;
2670
+ }
2671
+
2672
+ return realContext;
2673
+ }
2674
+
2675
+ const Context_ReactReduxContext = /*#__PURE__*/new Proxy({}, /*#__PURE__*/new Proxy({}, {
2676
+ get(_, handler) {
2677
+ const target = getContext(); // @ts-ignore
2641
2678
 
2642
- if (false) {}
2679
+ return (_target, ...args) => Reflect[handler](target, ...args);
2680
+ }
2643
2681
 
2682
+ }));
2644
2683
  /* harmony default export */ const Context = ((/* unused pure expression or super */ null && (Context_ReactReduxContext)));
2645
2684
  ;// CONCATENATED MODULE: ./node_modules/react-redux/es/hooks/useReduxContext.js
2646
2685
 
2647
2686
 
2648
2687
 
2688
+ /**
2689
+ * Hook factory, which creates a `useReduxContext` hook bound to a given context. This is a low-level
2690
+ * hook that you should usually not need to call directly.
2691
+ *
2692
+ * @param {React.Context} [context=ReactReduxContext] Context passed to your `<Provider>`.
2693
+ * @returns {Function} A `useReduxContext` hook bound to the specified context.
2694
+ */
2695
+ function createReduxContextHook(context = Context_ReactReduxContext) {
2696
+ return function useReduxContext() {
2697
+ const contextValue = (0,compat_module.useContext)(context);
2698
+
2699
+ if (false) {}
2700
+
2701
+ return contextValue;
2702
+ };
2703
+ }
2649
2704
  /**
2650
2705
  * A hook to access the value of the `ReactReduxContext`. This is a low-level
2651
2706
  * hook that you should usually not need to call directly.
@@ -2662,13 +2717,8 @@ if (false) {}
2662
2717
  * return <div>{store.getState()}</div>
2663
2718
  * }
2664
2719
  */
2665
- function useReduxContext_useReduxContext() {
2666
- const contextValue = (0,compat_module.useContext)(Context_ReactReduxContext);
2667
2720
 
2668
- if (false) {}
2669
-
2670
- return contextValue;
2671
- }
2721
+ const useReduxContext_useReduxContext = /*#__PURE__*/createReduxContextHook();
2672
2722
  ;// CONCATENATED MODULE: ./node_modules/react-redux/es/utils/useSyncExternalStore.js
2673
2723
  const useSyncExternalStore_notInitialized = () => {
2674
2724
  throw new Error('uSES not initialized!');
@@ -2693,16 +2743,37 @@ const refEquality = (a, b) => a === b;
2693
2743
 
2694
2744
 
2695
2745
  function createSelectorHook(context = Context_ReactReduxContext) {
2696
- const useReduxContext = context === Context_ReactReduxContext ? useReduxContext_useReduxContext : () => (0,compat_module.useContext)(context);
2697
- return function useSelector(selector, equalityFn = refEquality) {
2746
+ const useReduxContext = context === Context_ReactReduxContext ? useReduxContext_useReduxContext : createReduxContextHook(context);
2747
+ return function useSelector(selector, equalityFnOrOptions = {}) {
2748
+ const {
2749
+ equalityFn = refEquality,
2750
+ stabilityCheck = undefined,
2751
+ noopCheck = undefined
2752
+ } = typeof equalityFnOrOptions === 'function' ? {
2753
+ equalityFn: equalityFnOrOptions
2754
+ } : equalityFnOrOptions;
2755
+
2698
2756
  if (false) {}
2699
2757
 
2700
2758
  const {
2701
2759
  store,
2702
2760
  subscription,
2703
- getServerState
2761
+ getServerState,
2762
+ stabilityCheck: globalStabilityCheck,
2763
+ noopCheck: globalNoopCheck
2704
2764
  } = useReduxContext();
2705
- const selectedState = useSyncExternalStoreWithSelector(subscription.addNestedSub, store.getState, getServerState || store.getState, selector, equalityFn);
2765
+ const firstRun = (0,compat_module.useRef)(true);
2766
+ const wrappedSelector = (0,compat_module.useCallback)({
2767
+ [selector.name](state) {
2768
+ const selected = selector(state);
2769
+
2770
+ if (false) {}
2771
+
2772
+ return selected;
2773
+ }
2774
+
2775
+ }[selector.name], [selector, globalStabilityCheck, stabilityCheck]);
2776
+ const selectedState = useSyncExternalStoreWithSelector(subscription.addNestedSub, store.getState, getServerState || store.getState, wrappedSelector, equalityFn);
2706
2777
  (0,compat_module.useDebugValue)(selectedState);
2707
2778
  return selectedState;
2708
2779
  };
@@ -3289,16 +3360,20 @@ function Provider({
3289
3360
  store,
3290
3361
  context,
3291
3362
  children,
3292
- serverState
3363
+ serverState,
3364
+ stabilityCheck = 'once',
3365
+ noopCheck = 'once'
3293
3366
  }) {
3294
3367
  const contextValue = (0,compat_module.useMemo)(() => {
3295
3368
  const subscription = Subscription_createSubscription(store);
3296
3369
  return {
3297
3370
  store,
3298
3371
  subscription,
3299
- getServerState: serverState ? () => serverState : undefined
3372
+ getServerState: serverState ? () => serverState : undefined,
3373
+ stabilityCheck,
3374
+ noopCheck
3300
3375
  };
3301
- }, [store, serverState]);
3376
+ }, [store, serverState, stabilityCheck, noopCheck]);
3302
3377
  const previousState = (0,compat_module.useMemo)(() => store.getState(), [store]);
3303
3378
  useIsomorphicLayoutEffect_useIsomorphicLayoutEffect(() => {
3304
3379
  const {
@@ -3327,7 +3402,6 @@ function Provider({
3327
3402
  ;// CONCATENATED MODULE: ./node_modules/react-redux/es/hooks/useStore.js
3328
3403
 
3329
3404
 
3330
-
3331
3405
  /**
3332
3406
  * Hook factory, which creates a `useStore` hook bound to a given context.
3333
3407
  *
@@ -3337,7 +3411,8 @@ function Provider({
3337
3411
 
3338
3412
  function createStoreHook(context = Context_ReactReduxContext) {
3339
3413
  const useReduxContext = // @ts-ignore
3340
- context === Context_ReactReduxContext ? useReduxContext_useReduxContext : () => (0,compat_module.useContext)(context);
3414
+ context === Context_ReactReduxContext ? useReduxContext_useReduxContext : // @ts-ignore
3415
+ createReduxContextHook(context);
3341
3416
  return function useStore() {
3342
3417
  const {
3343
3418
  store
@@ -7775,7 +7850,7 @@ const {
7775
7850
  } = storeSlice.actions;
7776
7851
  /* harmony default export */ const store_slice = (storeSlice.reducer);
7777
7852
  ;// CONCATENATED MODULE: ./src/javascripts/domains/config/slice.ts
7778
- var __rest = undefined && undefined.__rest || function (s, e) {
7853
+ var slice_rest = undefined && undefined.__rest || function (s, e) {
7779
7854
  var t = {};
7780
7855
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
7781
7856
  if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
@@ -7818,7 +7893,7 @@ const updateState = (state, config) => {
7818
7893
  {
7819
7894
  messages
7820
7895
  } = _a,
7821
- partialConfig = __rest(_a, ["messages"]);
7896
+ partialConfig = slice_rest(_a, ["messages"]);
7822
7897
  let newState = state;
7823
7898
  if (Object.keys(partialConfig).length > 0) {
7824
7899
  newState = Object.assign(Object.assign({}, newState), partialConfig);
@@ -7852,13 +7927,15 @@ const configSlice = createSlice({
7852
7927
  preChat,
7853
7928
  agentParticipant,
7854
7929
  userParticipant,
7855
- startChatIcon
7930
+ startChatIcon,
7931
+ locale
7856
7932
  }
7857
7933
  }) => {
7858
7934
  state.preChatEvents = preChat.map(payload => ({
7859
7935
  type: 'message',
7860
7936
  payload
7861
7937
  }));
7938
+ state.context.locale = locale;
7862
7939
  state.agentParticipant = agentParticipant;
7863
7940
  state.userParticipant = userParticipant;
7864
7941
  state.startChatIcon = startChatIcon;
@@ -8300,7 +8377,13 @@ const translationSlice = createSlice({
8300
8377
  const feature = (_a = payload === null || payload === void 0 ? void 0 : payload.features) === null || _a === void 0 ? void 0 : _a.translation;
8301
8378
  if (!feature) return;
8302
8379
  state.isAvailable = feature.enabled === true;
8303
- state.languages = feature.languages;
8380
+ state.languages = [...feature.languages].sort((a, b) => {
8381
+ if (a.locale === payload.locale) return -1;
8382
+ if (b.locale === payload.locale) return 1;
8383
+ return a.nativeName.localeCompare(b.nativeName, undefined, {
8384
+ sensitivity: 'base'
8385
+ });
8386
+ });
8304
8387
  }).addCase(setHistory, (state, {
8305
8388
  payload
8306
8389
  }) => {
@@ -11578,7 +11661,7 @@ const TimeIndicator = ({
11578
11661
  /* harmony default export */ const time_indicator = (TimeIndicator);
11579
11662
  ;// CONCATENATED MODULE: ./node_modules/tabbable/dist/index.esm.js
11580
11663
  /*!
11581
- * tabbable 6.1.2
11664
+ * tabbable 6.2.0
11582
11665
  * @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE
11583
11666
  */
11584
11667
  // NOTE: separate `:not()` selectors has broader browser support than the newer
@@ -11758,7 +11841,27 @@ var getCandidatesIteratively = function getCandidatesIteratively(elements, inclu
11758
11841
  }
11759
11842
  return candidates;
11760
11843
  };
11761
- var getTabindex = function getTabindex(node, isScope) {
11844
+
11845
+ /**
11846
+ * @private
11847
+ * Determines if the node has an explicitly specified `tabindex` attribute.
11848
+ * @param {HTMLElement} node
11849
+ * @returns {boolean} True if so; false if not.
11850
+ */
11851
+ var hasTabIndex = function hasTabIndex(node) {
11852
+ return !isNaN(parseInt(node.getAttribute('tabindex'), 10));
11853
+ };
11854
+
11855
+ /**
11856
+ * Determine the tab index of a given node.
11857
+ * @param {HTMLElement} node
11858
+ * @returns {number} Tab order (negative, 0, or positive number).
11859
+ * @throws {Error} If `node` is falsy.
11860
+ */
11861
+ var getTabIndex = function getTabIndex(node) {
11862
+ if (!node) {
11863
+ throw new Error('No node provided');
11864
+ }
11762
11865
  if (node.tabIndex < 0) {
11763
11866
  // in Chrome, <details/>, <audio controls/> and <video controls/> elements get a default
11764
11867
  // `tabIndex` of -1 when the 'tabindex' attribute isn't specified in the DOM,
@@ -11767,16 +11870,28 @@ var getTabindex = function getTabindex(node, isScope) {
11767
11870
  // order, consider their tab index to be 0.
11768
11871
  // Also browsers do not return `tabIndex` correctly for contentEditable nodes;
11769
11872
  // so if they don't have a tabindex attribute specifically set, assume it's 0.
11770
- //
11771
- // isScope is positive for custom element with shadow root or slot that by default
11772
- // have tabIndex -1, but need to be sorted by document order in order for their
11773
- // content to be inserted in the correct position
11774
- if ((isScope || /^(AUDIO|VIDEO|DETAILS)$/.test(node.tagName) || isContentEditable(node)) && isNaN(parseInt(node.getAttribute('tabindex'), 10))) {
11873
+ if ((/^(AUDIO|VIDEO|DETAILS)$/.test(node.tagName) || isContentEditable(node)) && !hasTabIndex(node)) {
11775
11874
  return 0;
11776
11875
  }
11777
11876
  }
11778
11877
  return node.tabIndex;
11779
11878
  };
11879
+
11880
+ /**
11881
+ * Determine the tab index of a given node __for sort order purposes__.
11882
+ * @param {HTMLElement} node
11883
+ * @param {boolean} [isScope] True for a custom element with shadow root or slot that, by default,
11884
+ * has tabIndex -1, but needs to be sorted by document order in order for its content to be
11885
+ * inserted into the correct sort position.
11886
+ * @returns {number} Tab order (negative, 0, or positive number).
11887
+ */
11888
+ var getSortOrderTabIndex = function getSortOrderTabIndex(node, isScope) {
11889
+ var tabIndex = getTabIndex(node);
11890
+ if (tabIndex < 0 && isScope && !hasTabIndex(node)) {
11891
+ return 0;
11892
+ }
11893
+ return tabIndex;
11894
+ };
11780
11895
  var sortOrderedTabbables = function sortOrderedTabbables(a, b) {
11781
11896
  return a.tabIndex === b.tabIndex ? a.documentOrder - b.documentOrder : a.tabIndex - b.tabIndex;
11782
11897
  };
@@ -12019,7 +12134,7 @@ var isNodeMatchingSelectorFocusable = function isNodeMatchingSelectorFocusable(o
12019
12134
  return true;
12020
12135
  };
12021
12136
  var isNodeMatchingSelectorTabbable = function isNodeMatchingSelectorTabbable(options, node) {
12022
- if (isNonTabbableRadio(node) || getTabindex(node) < 0 || !isNodeMatchingSelectorFocusable(options, node)) {
12137
+ if (isNonTabbableRadio(node) || getTabIndex(node) < 0 || !isNodeMatchingSelectorFocusable(options, node)) {
12023
12138
  return false;
12024
12139
  }
12025
12140
  return true;
@@ -12044,7 +12159,7 @@ var sortByOrder = function sortByOrder(candidates) {
12044
12159
  candidates.forEach(function (item, i) {
12045
12160
  var isScope = !!item.scopeParent;
12046
12161
  var element = isScope ? item.scopeParent : item;
12047
- var candidateTabindex = getTabindex(element, isScope);
12162
+ var candidateTabindex = getSortOrderTabIndex(element, isScope);
12048
12163
  var elements = isScope ? sortByOrder(item.candidates) : element;
12049
12164
  if (candidateTabindex === 0) {
12050
12165
  isScope ? regularTabbables.push.apply(regularTabbables, elements) : regularTabbables.push(element);
@@ -12063,32 +12178,32 @@ var sortByOrder = function sortByOrder(candidates) {
12063
12178
  return acc;
12064
12179
  }, []).concat(regularTabbables);
12065
12180
  };
12066
- var tabbable = function tabbable(el, options) {
12181
+ var tabbable = function tabbable(container, options) {
12067
12182
  options = options || {};
12068
12183
  var candidates;
12069
12184
  if (options.getShadowRoot) {
12070
- candidates = getCandidatesIteratively([el], options.includeContainer, {
12185
+ candidates = getCandidatesIteratively([container], options.includeContainer, {
12071
12186
  filter: isNodeMatchingSelectorTabbable.bind(null, options),
12072
12187
  flatten: false,
12073
12188
  getShadowRoot: options.getShadowRoot,
12074
12189
  shadowRootFilter: isValidShadowRootTabbable
12075
12190
  });
12076
12191
  } else {
12077
- candidates = getCandidates(el, options.includeContainer, isNodeMatchingSelectorTabbable.bind(null, options));
12192
+ candidates = getCandidates(container, options.includeContainer, isNodeMatchingSelectorTabbable.bind(null, options));
12078
12193
  }
12079
12194
  return sortByOrder(candidates);
12080
12195
  };
12081
- var focusable = function focusable(el, options) {
12196
+ var focusable = function focusable(container, options) {
12082
12197
  options = options || {};
12083
12198
  var candidates;
12084
12199
  if (options.getShadowRoot) {
12085
- candidates = getCandidatesIteratively([el], options.includeContainer, {
12200
+ candidates = getCandidatesIteratively([container], options.includeContainer, {
12086
12201
  filter: isNodeMatchingSelectorFocusable.bind(null, options),
12087
12202
  flatten: true,
12088
12203
  getShadowRoot: options.getShadowRoot
12089
12204
  });
12090
12205
  } else {
12091
- candidates = getCandidates(el, options.includeContainer, isNodeMatchingSelectorFocusable.bind(null, options));
12206
+ candidates = getCandidates(container, options.includeContainer, isNodeMatchingSelectorFocusable.bind(null, options));
12092
12207
  }
12093
12208
  return candidates;
12094
12209
  };
@@ -12119,7 +12234,7 @@ var isFocusable = function isFocusable(node, options) {
12119
12234
 
12120
12235
  ;// CONCATENATED MODULE: ./node_modules/focus-trap/dist/focus-trap.esm.js
12121
12236
  /*!
12122
- * focus-trap 7.4.3
12237
+ * focus-trap 7.5.2
12123
12238
  * @license MIT, https://github.com/focus-trap/focus-trap/blob/master/LICENSE
12124
12239
  */
12125
12240
 
@@ -12205,10 +12320,10 @@ var isSelectableInput = function isSelectableInput(node) {
12205
12320
  return node.tagName && node.tagName.toLowerCase() === 'input' && typeof node.select === 'function';
12206
12321
  };
12207
12322
  var isEscapeEvent = function isEscapeEvent(e) {
12208
- return e.key === 'Escape' || e.key === 'Esc' || e.keyCode === 27;
12323
+ return (e === null || e === void 0 ? void 0 : e.key) === 'Escape' || (e === null || e === void 0 ? void 0 : e.key) === 'Esc' || (e === null || e === void 0 ? void 0 : e.keyCode) === 27;
12209
12324
  };
12210
12325
  var isTabEvent = function isTabEvent(e) {
12211
- return e.key === 'Tab' || e.keyCode === 9;
12326
+ return (e === null || e === void 0 ? void 0 : e.key) === 'Tab' || (e === null || e === void 0 ? void 0 : e.keyCode) === 9;
12212
12327
  };
12213
12328
 
12214
12329
  // checks for TAB by default
@@ -12292,8 +12407,11 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
12292
12407
  // container: HTMLElement,
12293
12408
  // tabbableNodes: Array<HTMLElement>, // empty if none
12294
12409
  // focusableNodes: Array<HTMLElement>, // empty if none
12295
- // firstTabbableNode: HTMLElement|null,
12296
- // lastTabbableNode: HTMLElement|null,
12410
+ // posTabIndexesFound: boolean,
12411
+ // firstTabbableNode: HTMLElement|undefined,
12412
+ // lastTabbableNode: HTMLElement|undefined,
12413
+ // firstDomTabbableNode: HTMLElement|undefined,
12414
+ // lastDomTabbableNode: HTMLElement|undefined,
12297
12415
  // nextTabbableNode: (node: HTMLElement, forward: boolean) => HTMLElement|undefined
12298
12416
  // }>}
12299
12417
  containerGroups: [],
@@ -12310,7 +12428,9 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
12310
12428
  paused: false,
12311
12429
  // timer ID for when delayInitialFocus is true and initial focus in this trap
12312
12430
  // has been delayed during activation
12313
- delayInitialFocusTimer: undefined
12431
+ delayInitialFocusTimer: undefined,
12432
+ // the most recent KeyboardEvent for the configured nav key (typically [SHIFT+]TAB), if any
12433
+ recentNavEvent: undefined
12314
12434
  };
12315
12435
  var trap; // eslint-disable-line prefer-const -- some private functions reference it, and its methods reference private functions, so we must declare here and define later
12316
12436
 
@@ -12329,7 +12449,9 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
12329
12449
  /**
12330
12450
  * Finds the index of the container that contains the element.
12331
12451
  * @param {HTMLElement} element
12332
- * @param {Event} [event]
12452
+ * @param {Event} [event] If available, and `element` isn't directly found in any container,
12453
+ * the event's composed path is used to see if includes any known trap containers in the
12454
+ * case where the element is inside a Shadow DOM.
12333
12455
  * @returns {number} Index of the container in either `state.containers` or
12334
12456
  * `state.containerGroups` (the order/length of these lists are the same); -1
12335
12457
  * if the element isn't found.
@@ -12424,14 +12546,41 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
12424
12546
  var tabbableNodes = tabbable(container, config.tabbableOptions);
12425
12547
 
12426
12548
  // NOTE: if we have tabbable nodes, we must have focusable nodes; focusable nodes
12427
- // are a superset of tabbable nodes
12549
+ // are a superset of tabbable nodes since nodes with negative `tabindex` attributes
12550
+ // are focusable but not tabbable
12428
12551
  var focusableNodes = focusable(container, config.tabbableOptions);
12552
+ var firstTabbableNode = tabbableNodes.length > 0 ? tabbableNodes[0] : undefined;
12553
+ var lastTabbableNode = tabbableNodes.length > 0 ? tabbableNodes[tabbableNodes.length - 1] : undefined;
12554
+ var firstDomTabbableNode = focusableNodes.find(function (node) {
12555
+ return isTabbable(node);
12556
+ });
12557
+ var lastDomTabbableNode = focusableNodes.slice().reverse().find(function (node) {
12558
+ return isTabbable(node);
12559
+ });
12560
+ var posTabIndexesFound = !!tabbableNodes.find(function (node) {
12561
+ return getTabIndex(node) > 0;
12562
+ });
12429
12563
  return {
12430
12564
  container: container,
12431
12565
  tabbableNodes: tabbableNodes,
12432
12566
  focusableNodes: focusableNodes,
12433
- firstTabbableNode: tabbableNodes.length > 0 ? tabbableNodes[0] : null,
12434
- lastTabbableNode: tabbableNodes.length > 0 ? tabbableNodes[tabbableNodes.length - 1] : null,
12567
+ /** True if at least one node with positive `tabindex` was found in this container. */
12568
+ posTabIndexesFound: posTabIndexesFound,
12569
+ /** First tabbable node in container, __tabindex__ order; `undefined` if none. */
12570
+ firstTabbableNode: firstTabbableNode,
12571
+ /** Last tabbable node in container, __tabindex__ order; `undefined` if none. */
12572
+ lastTabbableNode: lastTabbableNode,
12573
+ // NOTE: DOM order is NOT NECESSARILY "document position" order, but figuring that out
12574
+ // would require more than just https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition
12575
+ // because that API doesn't work with Shadow DOM as well as it should (@see
12576
+ // https://github.com/whatwg/dom/issues/320) and since this first/last is only needed, so far,
12577
+ // to address an edge case related to positive tabindex support, this seems like a much easier,
12578
+ // "close enough most of the time" alternative for positive tabindexes which should generally
12579
+ // be avoided anyway...
12580
+ /** First tabbable node in container, __DOM__ order; `undefined` if none. */
12581
+ firstDomTabbableNode: firstDomTabbableNode,
12582
+ /** Last tabbable node in container, __DOM__ order; `undefined` if none. */
12583
+ lastDomTabbableNode: lastDomTabbableNode,
12435
12584
  /**
12436
12585
  * Finds the __tabbable__ node that follows the given node in the specified direction,
12437
12586
  * in this container, if any.
@@ -12442,30 +12591,24 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
12442
12591
  */
12443
12592
  nextTabbableNode: function nextTabbableNode(node) {
12444
12593
  var forward = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
12445
- // NOTE: If tabindex is positive (in order to manipulate the tab order separate
12446
- // from the DOM order), this __will not work__ because the list of focusableNodes,
12447
- // while it contains tabbable nodes, does not sort its nodes in any order other
12448
- // than DOM order, because it can't: Where would you place focusable (but not
12449
- // tabbable) nodes in that order? They have no order, because they aren't tabbale...
12450
- // Support for positive tabindex is already broken and hard to manage (possibly
12451
- // not supportable, TBD), so this isn't going to make things worse than they
12452
- // already are, and at least makes things better for the majority of cases where
12453
- // tabindex is either 0/unset or negative.
12454
- // FYI, positive tabindex issue: https://github.com/focus-trap/focus-trap/issues/375
12455
- var nodeIdx = focusableNodes.findIndex(function (n) {
12456
- return n === node;
12457
- });
12594
+ var nodeIdx = tabbableNodes.indexOf(node);
12458
12595
  if (nodeIdx < 0) {
12459
- return undefined;
12460
- }
12461
- if (forward) {
12462
- return focusableNodes.slice(nodeIdx + 1).find(function (n) {
12463
- return isTabbable(n, config.tabbableOptions);
12596
+ // either not tabbable nor focusable, or was focused but not tabbable (negative tabindex):
12597
+ // since `node` should at least have been focusable, we assume that's the case and mimic
12598
+ // what browsers do, which is set focus to the next node in __document position order__,
12599
+ // regardless of positive tabindexes, if any -- and for reasons explained in the NOTE
12600
+ // above related to `firstDomTabbable` and `lastDomTabbable` properties, we fall back to
12601
+ // basic DOM order
12602
+ if (forward) {
12603
+ return focusableNodes.slice(focusableNodes.indexOf(node) + 1).find(function (el) {
12604
+ return isTabbable(el);
12605
+ });
12606
+ }
12607
+ return focusableNodes.slice(0, focusableNodes.indexOf(node)).reverse().find(function (el) {
12608
+ return isTabbable(el);
12464
12609
  });
12465
12610
  }
12466
- return focusableNodes.slice(0, nodeIdx).reverse().find(function (n) {
12467
- return isTabbable(n, config.tabbableOptions);
12468
- });
12611
+ return tabbableNodes[nodeIdx + (forward ? 1 : -1)];
12469
12612
  }
12470
12613
  };
12471
12614
  });
@@ -12478,6 +12621,19 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
12478
12621
  ) {
12479
12622
  throw new Error('Your focus-trap must have at least one container with at least one tabbable node in it at all times');
12480
12623
  }
12624
+
12625
+ // NOTE: Positive tabindexes are only properly supported in single-container traps because
12626
+ // doing it across multiple containers where tabindexes could be all over the place
12627
+ // would require Tabbable to support multiple containers, would require additional
12628
+ // specialized Shadow DOM support, and would require Tabbable's multi-container support
12629
+ // to look at those containers in document position order rather than user-provided
12630
+ // order (as they are treated in Focus-trap, for legacy reasons). See discussion on
12631
+ // https://github.com/focus-trap/focus-trap/issues/375 for more details.
12632
+ if (state.containerGroups.find(function (g) {
12633
+ return g.posTabIndexesFound;
12634
+ }) && state.containerGroups.length > 1) {
12635
+ throw new Error("At least one node with a positive tabindex was found in one of your focus-trap's multiple containers. Positive tabindexes are only supported in single-container focus-traps.");
12636
+ }
12481
12637
  };
12482
12638
  var tryFocus = function tryFocus(node) {
12483
12639
  if (node === false) {
@@ -12493,6 +12649,7 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
12493
12649
  node.focus({
12494
12650
  preventScroll: !!config.preventScroll
12495
12651
  });
12652
+ // NOTE: focus() API does not trigger focusIn event so set MRU node manually
12496
12653
  state.mostRecentlyFocusedNode = node;
12497
12654
  if (isSelectableInput(node)) {
12498
12655
  node.select();
@@ -12503,64 +12660,23 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
12503
12660
  return node ? node : node === false ? false : previousActiveElement;
12504
12661
  };
12505
12662
 
12506
- // This needs to be done on mousedown and touchstart instead of click
12507
- // so that it precedes the focus event.
12508
- var checkPointerDown = function checkPointerDown(e) {
12509
- var target = getActualTarget(e);
12510
- if (findContainerIndex(target, e) >= 0) {
12511
- // allow the click since it ocurred inside the trap
12512
- return;
12513
- }
12514
- if (valueOrHandler(config.clickOutsideDeactivates, e)) {
12515
- // immediately deactivate the trap
12516
- trap.deactivate({
12517
- // NOTE: by setting `returnFocus: false`, deactivate() will do nothing,
12518
- // which will result in the outside click setting focus to the node
12519
- // that was clicked (and if not focusable, to "nothing"); by setting
12520
- // `returnFocus: true`, we'll attempt to re-focus the node originally-focused
12521
- // on activation (or the configured `setReturnFocus` node), whether the
12522
- // outside click was on a focusable node or not
12523
- returnFocus: config.returnFocusOnDeactivate
12524
- });
12525
- return;
12526
- }
12527
-
12528
- // This is needed for mobile devices.
12529
- // (If we'll only let `click` events through,
12530
- // then on mobile they will be blocked anyways if `touchstart` is blocked.)
12531
- if (valueOrHandler(config.allowOutsideClick, e)) {
12532
- // allow the click outside the trap to take place
12533
- return;
12534
- }
12535
-
12536
- // otherwise, prevent the click
12537
- e.preventDefault();
12538
- };
12539
-
12540
- // In case focus escapes the trap for some strange reason, pull it back in.
12541
- var checkFocusIn = function checkFocusIn(e) {
12542
- var target = getActualTarget(e);
12543
- var targetContained = findContainerIndex(target, e) >= 0;
12544
-
12545
- // In Firefox when you Tab out of an iframe the Document is briefly focused.
12546
- if (targetContained || target instanceof Document) {
12547
- if (targetContained) {
12548
- state.mostRecentlyFocusedNode = target;
12549
- }
12550
- } else {
12551
- // escaped! pull it back in to where it just left
12552
- e.stopImmediatePropagation();
12553
- tryFocus(state.mostRecentlyFocusedNode || getInitialFocusNode());
12554
- }
12555
- };
12556
-
12557
- // Hijack key nav events on the first and last focusable nodes of the trap,
12558
- // in order to prevent focus from escaping. If it escapes for even a
12559
- // moment it can end up scrolling the page and causing confusion so we
12560
- // kind of need to capture the action at the keydown phase.
12561
- var checkKeyNav = function checkKeyNav(event) {
12562
- var isBackward = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
12563
- var target = getActualTarget(event);
12663
+ /**
12664
+ * Finds the next node (in either direction) where focus should move according to a
12665
+ * keyboard focus-in event.
12666
+ * @param {Object} params
12667
+ * @param {Node} [params.target] Known target __from which__ to navigate, if any.
12668
+ * @param {KeyboardEvent|FocusEvent} [params.event] Event to use if `target` isn't known (event
12669
+ * will be used to determine the `target`). Ignored if `target` is specified.
12670
+ * @param {boolean} [params.isBackward] True if focus should move backward.
12671
+ * @returns {Node|undefined} The next node, or `undefined` if a next node couldn't be
12672
+ * determined given the current state of the trap.
12673
+ */
12674
+ var findNextNavNode = function findNextNavNode(_ref2) {
12675
+ var target = _ref2.target,
12676
+ event = _ref2.event,
12677
+ _ref2$isBackward = _ref2.isBackward,
12678
+ isBackward = _ref2$isBackward === void 0 ? false : _ref2$isBackward;
12679
+ target = target || getActualTarget(event);
12564
12680
  updateTabbableNodes();
12565
12681
  var destinationNode = null;
12566
12682
  if (state.tabbableGroups.length > 0) {
@@ -12583,8 +12699,8 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
12583
12699
  // REVERSE
12584
12700
 
12585
12701
  // is the target the first tabbable node in a group?
12586
- var startOfGroupIndex = findIndex(state.tabbableGroups, function (_ref2) {
12587
- var firstTabbableNode = _ref2.firstTabbableNode;
12702
+ var startOfGroupIndex = findIndex(state.tabbableGroups, function (_ref3) {
12703
+ var firstTabbableNode = _ref3.firstTabbableNode;
12588
12704
  return target === firstTabbableNode;
12589
12705
  });
12590
12706
  if (startOfGroupIndex < 0 && (containerGroup.container === target || isFocusable(target, config.tabbableOptions) && !isTabbable(target, config.tabbableOptions) && !containerGroup.nextTabbableNode(target, false))) {
@@ -12602,7 +12718,7 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
12602
12718
  // the LAST group if it's the first tabbable node of the FIRST group)
12603
12719
  var destinationGroupIndex = startOfGroupIndex === 0 ? state.tabbableGroups.length - 1 : startOfGroupIndex - 1;
12604
12720
  var destinationGroup = state.tabbableGroups[destinationGroupIndex];
12605
- destinationNode = destinationGroup.lastTabbableNode;
12721
+ destinationNode = getTabIndex(target) >= 0 ? destinationGroup.lastTabbableNode : destinationGroup.lastDomTabbableNode;
12606
12722
  } else if (!isTabEvent(event)) {
12607
12723
  // user must have customized the nav keys so we have to move focus manually _within_
12608
12724
  // the active group: do this based on the order determined by tabbable()
@@ -12612,8 +12728,8 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
12612
12728
  // FORWARD
12613
12729
 
12614
12730
  // is the target the last tabbable node in a group?
12615
- var lastOfGroupIndex = findIndex(state.tabbableGroups, function (_ref3) {
12616
- var lastTabbableNode = _ref3.lastTabbableNode;
12731
+ var lastOfGroupIndex = findIndex(state.tabbableGroups, function (_ref4) {
12732
+ var lastTabbableNode = _ref4.lastTabbableNode;
12617
12733
  return target === lastTabbableNode;
12618
12734
  });
12619
12735
  if (lastOfGroupIndex < 0 && (containerGroup.container === target || isFocusable(target, config.tabbableOptions) && !isTabbable(target, config.tabbableOptions) && !containerGroup.nextTabbableNode(target))) {
@@ -12631,7 +12747,7 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
12631
12747
  // group if it's the last tabbable node of the LAST group)
12632
12748
  var _destinationGroupIndex = lastOfGroupIndex === state.tabbableGroups.length - 1 ? 0 : lastOfGroupIndex + 1;
12633
12749
  var _destinationGroup = state.tabbableGroups[_destinationGroupIndex];
12634
- destinationNode = _destinationGroup.firstTabbableNode;
12750
+ destinationNode = getTabIndex(target) >= 0 ? _destinationGroup.firstTabbableNode : _destinationGroup.firstDomTabbableNode;
12635
12751
  } else if (!isTabEvent(event)) {
12636
12752
  // user must have customized the nav keys so we have to move focus manually _within_
12637
12753
  // the active group: do this based on the order determined by tabbable()
@@ -12643,6 +12759,153 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
12643
12759
  // NOTE: the fallbackFocus option does not support returning false to opt-out
12644
12760
  destinationNode = getNodeForOption('fallbackFocus');
12645
12761
  }
12762
+ return destinationNode;
12763
+ };
12764
+
12765
+ // This needs to be done on mousedown and touchstart instead of click
12766
+ // so that it precedes the focus event.
12767
+ var checkPointerDown = function checkPointerDown(e) {
12768
+ var target = getActualTarget(e);
12769
+ if (findContainerIndex(target, e) >= 0) {
12770
+ // allow the click since it ocurred inside the trap
12771
+ return;
12772
+ }
12773
+ if (valueOrHandler(config.clickOutsideDeactivates, e)) {
12774
+ // immediately deactivate the trap
12775
+ trap.deactivate({
12776
+ // NOTE: by setting `returnFocus: false`, deactivate() will do nothing,
12777
+ // which will result in the outside click setting focus to the node
12778
+ // that was clicked (and if not focusable, to "nothing"); by setting
12779
+ // `returnFocus: true`, we'll attempt to re-focus the node originally-focused
12780
+ // on activation (or the configured `setReturnFocus` node), whether the
12781
+ // outside click was on a focusable node or not
12782
+ returnFocus: config.returnFocusOnDeactivate
12783
+ });
12784
+ return;
12785
+ }
12786
+
12787
+ // This is needed for mobile devices.
12788
+ // (If we'll only let `click` events through,
12789
+ // then on mobile they will be blocked anyways if `touchstart` is blocked.)
12790
+ if (valueOrHandler(config.allowOutsideClick, e)) {
12791
+ // allow the click outside the trap to take place
12792
+ return;
12793
+ }
12794
+
12795
+ // otherwise, prevent the click
12796
+ e.preventDefault();
12797
+ };
12798
+
12799
+ // In case focus escapes the trap for some strange reason, pull it back in.
12800
+ // NOTE: the focusIn event is NOT cancelable, so if focus escapes, it may cause unexpected
12801
+ // scrolling if the node that got focused was out of view; there's nothing we can do to
12802
+ // prevent that from happening by the time we discover that focus escaped
12803
+ var checkFocusIn = function checkFocusIn(event) {
12804
+ var target = getActualTarget(event);
12805
+ var targetContained = findContainerIndex(target, event) >= 0;
12806
+
12807
+ // In Firefox when you Tab out of an iframe the Document is briefly focused.
12808
+ if (targetContained || target instanceof Document) {
12809
+ if (targetContained) {
12810
+ state.mostRecentlyFocusedNode = target;
12811
+ }
12812
+ } else {
12813
+ // escaped! pull it back in to where it just left
12814
+ event.stopImmediatePropagation();
12815
+
12816
+ // focus will escape if the MRU node had a positive tab index and user tried to nav forward;
12817
+ // it will also escape if the MRU node had a 0 tab index and user tried to nav backward
12818
+ // toward a node with a positive tab index
12819
+ var nextNode; // next node to focus, if we find one
12820
+ var navAcrossContainers = true;
12821
+ if (state.mostRecentlyFocusedNode) {
12822
+ if (getTabIndex(state.mostRecentlyFocusedNode) > 0) {
12823
+ // MRU container index must be >=0 otherwise we wouldn't have it as an MRU node...
12824
+ var mruContainerIdx = findContainerIndex(state.mostRecentlyFocusedNode);
12825
+ // there MAY not be any tabbable nodes in the container if there are at least 2 containers
12826
+ // and the MRU node is focusable but not tabbable (focus-trap requires at least 1 container
12827
+ // with at least one tabbable node in order to function, so this could be the other container
12828
+ // with nothing tabbable in it)
12829
+ var tabbableNodes = state.containerGroups[mruContainerIdx].tabbableNodes;
12830
+ if (tabbableNodes.length > 0) {
12831
+ // MRU tab index MAY not be found if the MRU node is focusable but not tabbable
12832
+ var mruTabIdx = tabbableNodes.findIndex(function (node) {
12833
+ return node === state.mostRecentlyFocusedNode;
12834
+ });
12835
+ if (mruTabIdx >= 0) {
12836
+ if (config.isKeyForward(state.recentNavEvent)) {
12837
+ if (mruTabIdx + 1 < tabbableNodes.length) {
12838
+ nextNode = tabbableNodes[mruTabIdx + 1];
12839
+ navAcrossContainers = false;
12840
+ }
12841
+ // else, don't wrap within the container as focus should move to next/previous
12842
+ // container
12843
+ } else {
12844
+ if (mruTabIdx - 1 >= 0) {
12845
+ nextNode = tabbableNodes[mruTabIdx - 1];
12846
+ navAcrossContainers = false;
12847
+ }
12848
+ // else, don't wrap within the container as focus should move to next/previous
12849
+ // container
12850
+ }
12851
+ // else, don't find in container order without considering direction too
12852
+ }
12853
+ }
12854
+ // else, no tabbable nodes in that container (which means we must have at least one other
12855
+ // container with at least one tabbable node in it, otherwise focus-trap would've thrown
12856
+ // an error the last time updateTabbableNodes() was run): find next node among all known
12857
+ // containers
12858
+ } else {
12859
+ // check to see if there's at least one tabbable node with a positive tab index inside
12860
+ // the trap because focus seems to escape when navigating backward from a tabbable node
12861
+ // with tabindex=0 when this is the case (instead of wrapping to the tabbable node with
12862
+ // the greatest positive tab index like it should)
12863
+ if (!state.containerGroups.some(function (g) {
12864
+ return g.tabbableNodes.some(function (n) {
12865
+ return getTabIndex(n) > 0;
12866
+ });
12867
+ })) {
12868
+ // no containers with tabbable nodes with positive tab indexes which means the focus
12869
+ // escaped for some other reason and we should just execute the fallback to the
12870
+ // MRU node or initial focus node, if any
12871
+ navAcrossContainers = false;
12872
+ }
12873
+ }
12874
+ } else {
12875
+ // no MRU node means we're likely in some initial condition when the trap has just
12876
+ // been activated and initial focus hasn't been given yet, in which case we should
12877
+ // fall through to trying to focus the initial focus node, which is what should
12878
+ // happen below at this point in the logic
12879
+ navAcrossContainers = false;
12880
+ }
12881
+ if (navAcrossContainers) {
12882
+ nextNode = findNextNavNode({
12883
+ // move FROM the MRU node, not event-related node (which will be the node that is
12884
+ // outside the trap causing the focus escape we're trying to fix)
12885
+ target: state.mostRecentlyFocusedNode,
12886
+ isBackward: config.isKeyBackward(state.recentNavEvent)
12887
+ });
12888
+ }
12889
+ if (nextNode) {
12890
+ tryFocus(nextNode);
12891
+ } else {
12892
+ tryFocus(state.mostRecentlyFocusedNode || getInitialFocusNode());
12893
+ }
12894
+ }
12895
+ state.recentNavEvent = undefined; // clear
12896
+ };
12897
+
12898
+ // Hijack key nav events on the first and last focusable nodes of the trap,
12899
+ // in order to prevent focus from escaping. If it escapes for even a
12900
+ // moment it can end up scrolling the page and causing confusion so we
12901
+ // kind of need to capture the action at the keydown phase.
12902
+ var checkKeyNav = function checkKeyNav(event) {
12903
+ var isBackward = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
12904
+ state.recentNavEvent = event;
12905
+ var destinationNode = findNextNavNode({
12906
+ event: event,
12907
+ isBackward: isBackward
12908
+ });
12646
12909
  if (destinationNode) {
12647
12910
  if (isTabEvent(event)) {
12648
12911
  // since tab natively moves focus, we wouldn't have a destination node unless we
@@ -13529,7 +13792,7 @@ const SeamlyActivityMonitor = ({ children }) => {
13529
13792
  // It is important to use keyUp here as focus may be set from outside the
13530
13793
  // chat container via keyboard. In this case the keyDown handler would not
13531
13794
  // be fired inside the container on the initial focus event.
13532
- return ((0,jsx_runtime_namespaceObject.jsx)("div", Object.assign({ className: css_className('activity-monitor'), tabIndex: -1, onMouseDown: onActivityHandler, onKeyUp: onActivityHandler, onTouchStart: onActivityHandler, onMouseMove: onActivityHandler, onWheel: onActivityHandler, onPointerDown: onActivityHandler, onPointerMove: onActivityHandler }, { children: (0,jsx_runtime_namespaceObject.jsx)(seamly_activity_event_context.Provider, Object.assign({ value: onActivityHandler }, { children: children })) })));
13795
+ return ((0,jsx_runtime_namespaceObject.jsx)("div", { className: css_className('activity-monitor'), tabIndex: -1, onMouseDown: onActivityHandler, onKeyUp: onActivityHandler, onTouchStart: onActivityHandler, onMouseMove: onActivityHandler, onWheel: onActivityHandler, onPointerDown: onActivityHandler, onPointerMove: onActivityHandler, children: (0,jsx_runtime_namespaceObject.jsx)(seamly_activity_event_context.Provider, { value: onActivityHandler, children: children }) }));
13533
13796
  };
13534
13797
  /* harmony default export */ const seamly_activity_monitor = (SeamlyActivityMonitor);
13535
13798
 
@@ -13936,7 +14199,7 @@ const SeamlyFileUpload = ({ children }) => {
13936
14199
  uploadHandle,
13937
14200
  }));
13938
14201
  }, [addImageToSessionStorage, addUploadBubble, api, dispatch, t]);
13939
- return ((0,jsx_runtime_namespaceObject.jsx)(seamly_file_upload_context.Provider, Object.assign({ value: onUploadFileHandler }, { children: children })));
14202
+ return ((0,jsx_runtime_namespaceObject.jsx)(seamly_file_upload_context.Provider, { value: onUploadFileHandler, children: children }));
13940
14203
  };
13941
14204
  /* harmony default export */ const seamly_file_upload = (SeamlyFileUpload);
13942
14205
 
@@ -14327,7 +14590,7 @@ const SeamlyCore = ({ store, children, eventBus, api }) => {
14327
14590
  (0,hooks_.useErrorBoundary)((error) => {
14328
14591
  store.dispatch(catchError(error));
14329
14592
  });
14330
- return ((0,jsx_runtime_namespaceObject.jsx)(components_Provider, Object.assign({ store: store }, { children: (0,jsx_runtime_namespaceObject.jsx)(SeamlyEventBusContext.Provider, Object.assign({ value: eventBus }, { children: (0,jsx_runtime_namespaceObject.jsx)(SeamlyApiContext.Provider, Object.assign({ value: api }, { children: (0,jsx_runtime_namespaceObject.jsx)(seamly_live_region, { children: (0,jsx_runtime_namespaceObject.jsx)(seamly_chat, { children: (0,jsx_runtime_namespaceObject.jsxs)(component_filter, { children: [(0,jsx_runtime_namespaceObject.jsx)(seamly_initializer, {}), (0,jsx_runtime_namespaceObject.jsx)(seamly_event_subscriber, {}), (0,jsx_runtime_namespaceObject.jsx)(seamly_read_state, {}), (0,jsx_runtime_namespaceObject.jsx)(seamly_new_notifications, {}), (0,jsx_runtime_namespaceObject.jsx)(seamly_idle_detach_counter, {}), (0,jsx_runtime_namespaceObject.jsxs)(seamly_activity_monitor, { children: [(0,jsx_runtime_namespaceObject.jsx)(seamly_instance_functions_loader, {}), (0,jsx_runtime_namespaceObject.jsx)(seamly_file_upload, { children: children })] })] }) }) }) })) })) })));
14593
+ return ((0,jsx_runtime_namespaceObject.jsx)(components_Provider, { store: store, children: (0,jsx_runtime_namespaceObject.jsx)(SeamlyEventBusContext.Provider, { value: eventBus, children: (0,jsx_runtime_namespaceObject.jsx)(SeamlyApiContext.Provider, { value: api, children: (0,jsx_runtime_namespaceObject.jsx)(seamly_live_region, { children: (0,jsx_runtime_namespaceObject.jsx)(seamly_chat, { children: (0,jsx_runtime_namespaceObject.jsxs)(component_filter, { children: [(0,jsx_runtime_namespaceObject.jsx)(seamly_initializer, {}), (0,jsx_runtime_namespaceObject.jsx)(seamly_event_subscriber, {}), (0,jsx_runtime_namespaceObject.jsx)(seamly_read_state, {}), (0,jsx_runtime_namespaceObject.jsx)(seamly_new_notifications, {}), (0,jsx_runtime_namespaceObject.jsx)(seamly_idle_detach_counter, {}), (0,jsx_runtime_namespaceObject.jsxs)(seamly_activity_monitor, { children: [(0,jsx_runtime_namespaceObject.jsx)(seamly_instance_functions_loader, {}), (0,jsx_runtime_namespaceObject.jsx)(seamly_file_upload, { children: children })] })] }) }) }) }) }) }));
14331
14594
  };
14332
14595
  /* harmony default export */ const seamly_core = (SeamlyCore);
14333
14596
 
@@ -14388,9 +14651,9 @@ const useDebounce = (value, delay = 20) => {
14388
14651
  const getState = ({
14389
14652
  forms
14390
14653
  }) => forms;
14391
- const getFormById = es_createSelector(getState, (_, {
14654
+ const getFormById = es_createSelector([getState, (_, {
14392
14655
  formId
14393
- }) => formId, (forms, formId) => forms[formId]);
14656
+ }) => formId], (forms, formId) => forms[formId]);
14394
14657
  const getFormControlsByFormId = es_createSelector(getFormById, form => (form === null || form === void 0 ? void 0 : form.controls) || {});
14395
14658
  const getFormValuesByFormId = es_createSelector(getFormControlsByFormId, controls => {
14396
14659
  const valuesObj = {};
@@ -14401,15 +14664,15 @@ const getFormValuesByFormId = es_createSelector(getFormControlsByFormId, control
14401
14664
  });
14402
14665
  return valuesObj;
14403
14666
  });
14404
- const getControlValueByName = es_createSelector(getFormControlsByFormId, (_, {
14667
+ const getControlValueByName = es_createSelector([getFormControlsByFormId, (_, {
14405
14668
  name
14406
- }) => name, (controls, name) => {
14669
+ }) => name], (controls, name) => {
14407
14670
  var _a;
14408
14671
  return (_a = controls[name]) === null || _a === void 0 ? void 0 : _a.value;
14409
14672
  });
14410
- const getControlTouchedByName = es_createSelector(getFormControlsByFormId, (_, {
14673
+ const getControlTouchedByName = es_createSelector([getFormControlsByFormId, (_, {
14411
14674
  name
14412
- }) => name, (controls, name) => {
14675
+ }) => name], (controls, name) => {
14413
14676
  var _a;
14414
14677
  return (_a = controls[name]) === null || _a === void 0 ? void 0 : _a.touched;
14415
14678
  });
@@ -14604,7 +14867,7 @@ const useEntryTextTranslation = controlName => {
14604
14867
  text: (text === null || text === void 0 ? void 0 : text.label) || t('input.inputLabelText'),
14605
14868
  limit: !(text === null || text === void 0 ? void 0 : text.label) && hasCharacterLimit ? characterLimit : null
14606
14869
  }), [t, hasCharacterLimit, characterLimit, text === null || text === void 0 ? void 0 : text.label]);
14607
- const labelClass = (0,hooks_.useMemo)(() => (text === null || text === void 0 ? void 0 : text.label) ? 'input__label' : 'visually-hidden', [text === null || text === void 0 ? void 0 : text.label]);
14870
+ const labelClass = (0,hooks_.useMemo)(() => (text === null || text === void 0 ? void 0 : text.label) ? 'label' : 'visually-hidden', [text === null || text === void 0 ? void 0 : text.label]);
14608
14871
  return {
14609
14872
  placeholder,
14610
14873
  label,
@@ -14649,14 +14912,14 @@ function AbortTransactionButton() {
14649
14912
  });
14650
14913
  clearEntryAbortTransaction();
14651
14914
  };
14652
- return ((0,jsx_runtime_namespaceObject.jsx)("li", Object.assign({ className: css_className([
14915
+ return ((0,jsx_runtime_namespaceObject.jsx)("li", { className: css_className([
14653
14916
  'cvco-conversation__item',
14654
14917
  'cvco-conversation__item--abort-transaction',
14655
- ]) }, { children: (0,jsx_runtime_namespaceObject.jsx)("button", Object.assign({ className: css_className([
14918
+ ]), children: (0,jsx_runtime_namespaceObject.jsx)("button", { className: css_className([
14656
14919
  'button',
14657
14920
  'button--secondary',
14658
14921
  'abort-transaction__button',
14659
- ]), type: "button", onClick: handleAbortTransaction }, { children: abortTransaction.label })) })));
14922
+ ]), type: "button", onClick: handleAbortTransaction, children: abortTransaction.label }) }));
14660
14923
  }
14661
14924
 
14662
14925
  ;// CONCATENATED MODULE: external "preact/compat"
@@ -14731,7 +14994,7 @@ const Event = ({ event, newParticipant }) => {
14731
14994
  if (newParticipant) {
14732
14995
  classNames.push('conversation__item--new-participant');
14733
14996
  }
14734
- return ((0,jsx_runtime_namespaceObject.jsxs)("li", Object.assign({ className: css_className(classNames), ref: containerRef }, { children: [event.timeIndicator && (0,jsx_runtime_namespaceObject.jsx)(time_indicator, { event: event }), (0,jsx_runtime_namespaceObject.jsx)(Component, Object.assign({ event: event }, { children: (0,jsx_runtime_namespaceObject.jsx)(SubComponent, { event: event }) }))] })));
14997
+ return ((0,jsx_runtime_namespaceObject.jsxs)("li", { className: css_className(classNames), ref: containerRef, children: [event.timeIndicator && (0,jsx_runtime_namespaceObject.jsx)(time_indicator, { event: event }), (0,jsx_runtime_namespaceObject.jsx)(Component, { event: event, children: (0,jsx_runtime_namespaceObject.jsx)(SubComponent, { event: event }) })] }));
14735
14998
  };
14736
14999
  /* harmony default export */ const event_event = (Event);
14737
15000
 
@@ -14816,7 +15079,7 @@ const Conversation = () => {
14816
15079
  e.preventDefault();
14817
15080
  focusSkiplinkTarget();
14818
15081
  };
14819
- return ((0,jsx_runtime_namespaceObject.jsxs)(jsx_runtime_namespaceObject.Fragment, { children: [isOpen && ((0,jsx_runtime_namespaceObject.jsx)("a", Object.assign({ className: css_className('skip-link'), href: `#${skiplinkTargetId}`, onClick: onClickHandler }, { children: t('skiplinkText') }))), (0,jsx_runtime_namespaceObject.jsx)("div", Object.assign({ className: css_className('chat__body') }, { children: (0,jsx_runtime_namespaceObject.jsxs)("div", Object.assign({ className: css_className('conversation__container') }, { children: [(0,jsx_runtime_namespaceObject.jsx)(privacy_disclaimer, {}), (0,jsx_runtime_namespaceObject.jsxs)("ol", Object.assign({ className: css_className('conversation') }, { children: [(0,jsx_runtime_namespaceObject.jsx)(component_filter, { children: (0,jsx_runtime_namespaceObject.jsx)(Events, {}) }), debouncedIsLoading ? (0,jsx_runtime_namespaceObject.jsx)(loader, {}) : null, (0,jsx_runtime_namespaceObject.jsx)(AbortTransactionButton, {})] }))] })) }))] }));
15082
+ return ((0,jsx_runtime_namespaceObject.jsxs)(jsx_runtime_namespaceObject.Fragment, { children: [isOpen && ((0,jsx_runtime_namespaceObject.jsx)("a", { className: css_className('skip-link'), href: `#${skiplinkTargetId}`, onClick: onClickHandler, children: t('skiplinkText') })), (0,jsx_runtime_namespaceObject.jsx)("div", { className: css_className('chat__body'), children: (0,jsx_runtime_namespaceObject.jsxs)("div", { className: css_className('conversation__container'), children: [(0,jsx_runtime_namespaceObject.jsx)(privacy_disclaimer, {}), (0,jsx_runtime_namespaceObject.jsxs)("ol", { className: css_className('conversation'), children: [(0,jsx_runtime_namespaceObject.jsx)(component_filter, { children: (0,jsx_runtime_namespaceObject.jsx)(Events, {}) }), debouncedIsLoading ? (0,jsx_runtime_namespaceObject.jsx)(loader, {}) : null, (0,jsx_runtime_namespaceObject.jsx)(AbortTransactionButton, {})] })] }) })] }));
14820
15083
  };
14821
15084
  /* harmony default export */ const conversation = (Conversation);
14822
15085
 
@@ -15211,16 +15474,16 @@ const OptionsFrame = ({ className: givenClassName, children, onCancel, headingTe
15211
15474
  (0,hooks_.useEffect)(() => {
15212
15475
  focusElement(container.current);
15213
15476
  }, [container]);
15214
- return ((0,jsx_runtime_namespaceObject.jsx)("section", Object.assign({ className: css_className('options', {
15477
+ return ((0,jsx_runtime_namespaceObject.jsx)("section", { className: css_className('options', {
15215
15478
  'options--right': position.horizontal === 'right',
15216
15479
  'options--left': position.horizontal === 'left',
15217
15480
  'options--top': position.vertical === 'top',
15218
15481
  'options--bottom': position.vertical === 'bottom',
15219
- }, givenClassName), "aria-labelledby": mainHeadingId, tabIndex: -1, ref: container }, { children: (0,jsx_runtime_namespaceObject.jsxs)("div", Object.assign({ className: css_className('options__body') }, { children: [(0,jsx_runtime_namespaceObject.jsx)("h2", Object.assign({ id: mainHeadingId, className: css_className('options__title') }, { children: headingText })), (0,jsx_runtime_namespaceObject.jsxs)("button", Object.assign({ type: "button", onClick: onCancelHandler, "aria-describedby": mainHeadingId, className: css_className('button', 'options__close'), ref: (btn) => {
15482
+ }, givenClassName), "aria-labelledby": mainHeadingId, tabIndex: -1, ref: container, children: (0,jsx_runtime_namespaceObject.jsxs)("div", { className: css_className('options__body'), children: [(0,jsx_runtime_namespaceObject.jsx)("h2", { id: mainHeadingId, className: css_className('options__title'), children: headingText }), (0,jsx_runtime_namespaceObject.jsxs)("button", { type: "button", onClick: onCancelHandler, "aria-describedby": mainHeadingId, className: css_className('button', 'options__close'), ref: (btn) => {
15220
15483
  if (cancelButtonRef) {
15221
15484
  cancelButtonRef.current = btn;
15222
15485
  }
15223
- } }, { children: [(0,jsx_runtime_namespaceObject.jsx)(layout_icon, { name: "close", size: "16", alt: "" }), (0,jsx_runtime_namespaceObject.jsx)("span", { children: cancelButtonText })] })), description ? ((0,jsx_runtime_namespaceObject.jsx)("p", Object.assign({ className: css_className('options__description'), id: descriptionId }, { children: description }))) : null, (0,jsx_runtime_namespaceObject.jsx)("div", Object.assign({ className: css_className('options__wrapper') }, { children: children }))] })) })));
15486
+ }, children: [(0,jsx_runtime_namespaceObject.jsx)(layout_icon, { name: "close", size: "16", alt: "" }), (0,jsx_runtime_namespaceObject.jsx)("span", { children: cancelButtonText })] }), description ? ((0,jsx_runtime_namespaceObject.jsx)("p", { className: css_className('options__description'), id: descriptionId, children: description })) : null, (0,jsx_runtime_namespaceObject.jsx)("div", { className: css_className('options__wrapper'), children: children })] }) }));
15224
15487
  };
15225
15488
  /* harmony default export */ const options_frame = (OptionsFrame);
15226
15489
 
@@ -15357,7 +15620,7 @@ function FormProvider(_a) {
15357
15620
  console.error('"onSubmit" is required.');
15358
15621
  return null;
15359
15622
  }
15360
- return ((0,jsx_runtime_namespaceObject.jsx)(context_Provider, Object.assign({}, props, { value: contextValue }, { children: children })));
15623
+ return ((0,jsx_runtime_namespaceObject.jsx)(context_Provider, Object.assign({}, props, { value: contextValue, children: children })));
15361
15624
  }
15362
15625
 
15363
15626
  ;// CONCATENATED MODULE: ./src/javascripts/ui/components/form-controls/form.js
@@ -15423,8 +15686,8 @@ function error_Error({
15423
15686
 
15424
15687
 
15425
15688
 
15426
- const FormControlWrapper = ({ contentHint, id, labelText, labelClass = css_className('label'), validity, errorText, children, }) => {
15427
- return ((0,jsx_runtime_namespaceObject.jsxs)(jsx_runtime_namespaceObject.Fragment, { children: [contentHint && ((0,jsx_runtime_namespaceObject.jsx)("span", Object.assign({ id: `${id}-content-hint`, className: css_className('input__content-hint') }, { children: contentHint }))), (0,jsx_runtime_namespaceObject.jsx)(error_Error, { id: `${id}-error`, error: !validity && errorText }), (0,jsx_runtime_namespaceObject.jsxs)("div", Object.assign({ className: css_className('form-control__wrapper') }, { children: [(0,jsx_runtime_namespaceObject.jsx)("label", Object.assign({ htmlFor: id, className: labelClass }, { children: labelText })), children] }))] }));
15689
+ const FormControlWrapper = ({ contentHint, id, labelText, labelClass, validity, errorText, children, }) => {
15690
+ return ((0,jsx_runtime_namespaceObject.jsxs)(jsx_runtime_namespaceObject.Fragment, { children: [contentHint && ((0,jsx_runtime_namespaceObject.jsx)("span", { id: `${id}-content-hint`, className: css_className('input__content-hint'), children: contentHint })), (0,jsx_runtime_namespaceObject.jsx)(error_Error, { id: `${id}-error`, error: !validity && errorText }), (0,jsx_runtime_namespaceObject.jsxs)("div", { className: css_className('form-control__wrapper'), children: [(0,jsx_runtime_namespaceObject.jsx)("label", { htmlFor: id, className: css_className(labelClass), children: labelText }), children] })] }));
15428
15691
  };
15429
15692
  /* harmony default export */ const wrapper = (FormControlWrapper);
15430
15693
 
@@ -15459,7 +15722,7 @@ function Input(_a) {
15459
15722
  describedByIds.push(`${id}-error`);
15460
15723
  }
15461
15724
  // todo: destructure Field
15462
- return ((0,jsx_runtime_namespaceObject.jsx)(wrapper, Object.assign({ id: id, contentHint: contentHint, validity: !hasError, errorText: error, labelText: labelText, labelClass: labelClass }, { children: (0,jsx_runtime_namespaceObject.jsx)("input", Object.assign({ id: id, name: name, type: type, "aria-invalid": hasError ? 'true' : 'false', "aria-describedby": describedByIds.join(' ') || null }, field, props)) })));
15725
+ return ((0,jsx_runtime_namespaceObject.jsx)(wrapper, { id: id, contentHint: contentHint, validity: !hasError, errorText: error, labelText: labelText, labelClass: labelClass, children: (0,jsx_runtime_namespaceObject.jsx)("input", Object.assign({ id: id, name: name, type: type, "aria-invalid": hasError ? 'true' : 'false', "aria-describedby": describedByIds.join(' ') || null }, field, props)) }));
15463
15726
  }
15464
15727
  /* harmony default export */ const input = (Input);
15465
15728
 
@@ -15807,14 +16070,14 @@ const OptionsButton = () => {
15807
16070
 
15808
16071
 
15809
16072
 
15810
- const TranslationOption = ({ label, checked, description, onChange, id, }) => {
16073
+ const TranslationOption = ({ label, checked, description, onChange, id, itemClassName, }) => {
15811
16074
  const onKeyDown = (e) => {
15812
16075
  if (e.code === 'Space' || e.code === 'Enter') {
15813
16076
  e.preventDefault();
15814
16077
  onChange();
15815
16078
  }
15816
16079
  };
15817
- return ((0,jsx_runtime_namespaceObject.jsxs)("li", Object.assign({ className: css_className('translation-options__item'), "aria-selected": checked, role: "option", tabIndex: 0, onClick: onChange, onKeyDown: onKeyDown, id: id }, { children: [(0,jsx_runtime_namespaceObject.jsx)(layout_icon, { alt: "", name: "check", size: "16" }), label, " ", description && (0,jsx_runtime_namespaceObject.jsxs)("span", { children: ["(", description, ")"] })] })));
16080
+ return ((0,jsx_runtime_namespaceObject.jsxs)("li", { className: css_className([itemClassName, 'translation-options__item']), "aria-selected": checked, role: "option", tabIndex: 0, onClick: onChange, onKeyDown: onKeyDown, id: id, children: [(0,jsx_runtime_namespaceObject.jsx)(layout_icon, { alt: "", name: "check", size: "16" }), label, " ", description && (0,jsx_runtime_namespaceObject.jsxs)("span", { children: ["(", description, ")"] })] }));
15818
16081
  };
15819
16082
  /* harmony default export */ const translation_option = (TranslationOption);
15820
16083
 
@@ -15826,12 +16089,13 @@ const TranslationOption = ({ label, checked, description, onChange, id, }) => {
15826
16089
 
15827
16090
 
15828
16091
 
16092
+ const isChecked = (language, currentLocale, isOriginal) => currentLocale === language.locale || (!currentLocale && isOriginal);
15829
16093
  const TranslationOptions = ({ onChange, describedById, }) => {
15830
16094
  const { context: { locale: defaultLocale }, } = useConfig();
15831
16095
  const { t } = useI18n();
15832
16096
  const { focusContainer } = useTranslationsContainer();
15833
16097
  const { languages, currentLocale, enableTranslations, disableTranslations } = useTranslations();
15834
- const handleChange = ({ locale }) => () => {
16098
+ const handleChange = (locale) => () => {
15835
16099
  if (locale === currentLocale || defaultLocale === locale) {
15836
16100
  disableTranslations();
15837
16101
  }
@@ -15841,22 +16105,25 @@ const TranslationOptions = ({ onChange, describedById, }) => {
15841
16105
  onChange();
15842
16106
  focusContainer();
15843
16107
  };
15844
- const sortedLanguages = (0,hooks_.useMemo)(() => {
15845
- return [...languages].sort((a, b) => {
15846
- if (a.locale === defaultLocale)
15847
- return -1;
15848
- if (b.locale === defaultLocale)
15849
- return 1;
15850
- return a.nativeName.localeCompare(b.nativeName, undefined, {
15851
- sensitivity: 'base',
15852
- });
15853
- });
15854
- }, [languages, defaultLocale]);
15855
- return ((0,jsx_runtime_namespaceObject.jsx)("ul", Object.assign({ "aria-describedby": describedById, role: "listbox", tabIndex: -1, className: css_className('translation-options') }, { children: sortedLanguages.map((language, idx) => {
15856
- const isOriginal = idx === 0;
15857
- const checked = currentLocale === language.locale || (!currentLocale && isOriginal);
15858
- return ((0,jsx_runtime_namespaceObject.jsx)(translation_option, { id: language.locale, label: language.nativeName, checked: checked, description: isOriginal && t('translations.settings.original'), onChange: handleChange(language) }, language.locale));
15859
- }) })));
16108
+ const { primaryLanguages, remainingLanguages } = (0,compat_namespaceObject.useMemo)(() => languages.reduce((acc, language) => {
16109
+ const isOriginal = language.locale === defaultLocale;
16110
+ const checked = isChecked(language, currentLocale, isOriginal);
16111
+ if (language.locale !== defaultLocale) {
16112
+ acc.remainingLanguages.push(Object.assign(Object.assign({}, language), { checked, isOriginal }));
16113
+ }
16114
+ const selectedIdx = acc.remainingLanguages.findIndex((l) => l.locale === currentLocale);
16115
+ if (isOriginal || (checked && selectedIdx > 4)) {
16116
+ acc.primaryLanguages.push(Object.assign(Object.assign({}, language), { checked, isOriginal }));
16117
+ }
16118
+ return acc;
16119
+ }, {
16120
+ primaryLanguages: [],
16121
+ remainingLanguages: [],
16122
+ }), [currentLocale, defaultLocale, languages]);
16123
+ return ((0,jsx_runtime_namespaceObject.jsxs)("ul", { "aria-describedby": describedById, role: "listbox", tabIndex: -1, className: css_className('translation-options'), children: [primaryLanguages.map(({ locale, nativeName, checked, isOriginal }, idx) => ((0,jsx_runtime_namespaceObject.jsx)(translation_option, { id: locale, label: nativeName, checked: checked, description: isOriginal && t('translations.settings.original'), onChange: handleChange(locale), itemClassName: css_className({
16124
+ 'translation-options__item--original': isOriginal,
16125
+ 'translation-options__item--selected': checked && idx !== 0,
16126
+ }) }, locale))), remainingLanguages.map(({ locale, nativeName, checked, isOriginal }) => ((0,jsx_runtime_namespaceObject.jsx)(translation_option, { id: locale, label: nativeName, checked: checked, description: isOriginal && t('translations.settings.original'), onChange: handleChange(locale) }, locale)))] }));
15860
16127
  };
15861
16128
  /* harmony default export */ const translation_options = (TranslationOptions);
15862
16129
 
@@ -15869,7 +16136,7 @@ const TranslationOptions = ({ onChange, describedById, }) => {
15869
16136
  function TranslationsOptionsDialog({ onClose, position, }) {
15870
16137
  const { t } = useI18n();
15871
16138
  const descriptionId = useGeneratedId();
15872
- return ((0,jsx_runtime_namespaceObject.jsx)(options_frame, Object.assign({ onCancel: onClose, headingText: t('translations.menu.title'), cancelButtonText: t('translations.settings.cancelButtonText'), description: t('translations.menu.description'), descriptionId: descriptionId, position: position, disableButtonFocusing: true }, { children: (0,jsx_runtime_namespaceObject.jsx)(translation_options, { describedById: descriptionId, onChange: onClose }) })));
16139
+ return ((0,jsx_runtime_namespaceObject.jsx)(options_frame, { onCancel: onClose, headingText: t('translations.menu.title'), cancelButtonText: t('translations.settings.cancelButtonText'), description: t('translations.menu.description'), descriptionId: descriptionId, position: position, disableButtonFocusing: true, children: (0,jsx_runtime_namespaceObject.jsx)(translation_options, { describedById: descriptionId, onChange: onClose }) }));
15873
16140
  }
15874
16141
  /* harmony default export */ const options_dialog = (TranslationsOptionsDialog);
15875
16142
 
@@ -15909,11 +16176,11 @@ function TranslationsOptionsButton({ children, position = {
15909
16176
  e.preventDefault();
15910
16177
  }
15911
16178
  };
15912
- return ((0,jsx_runtime_namespaceObject.jsxs)("div", Object.assign({ className: css_className('translations__container'), onKeyDown: onMainKeyDownHandler }, { children: [(0,jsx_runtime_namespaceObject.jsx)(in_out_transition, Object.assign({ transitionStartState: transitionStartStates.notRendered, isActive: menuIsOpen }, { children: (0,jsx_runtime_namespaceObject.jsx)("div", Object.assign({ className: css_className('options__dialog'), role: "dialog" }, { children: (0,jsx_runtime_namespaceObject.jsx)(options_dialog, { onClose: handleDialogClose, position: position }) })) })), (0,jsx_runtime_namespaceObject.jsx)("button", Object.assign({ type: "button", className: css_className([
16179
+ return ((0,jsx_runtime_namespaceObject.jsxs)("div", { className: css_className('translations__container'), onKeyDown: onMainKeyDownHandler, children: [(0,jsx_runtime_namespaceObject.jsx)(in_out_transition, { transitionStartState: transitionStartStates.notRendered, isActive: menuIsOpen, children: (0,jsx_runtime_namespaceObject.jsx)("div", { className: css_className('options__dialog'), role: "dialog", children: (0,jsx_runtime_namespaceObject.jsx)(options_dialog, { onClose: handleDialogClose, position: position }) }) }), (0,jsx_runtime_namespaceObject.jsx)("button", { type: "button", className: css_className([
15913
16180
  'button',
15914
16181
  'chat__options__button',
15915
16182
  ...classNames,
15916
- ]), id: toggleButtonId, onClick: handleToggleClick, onKeyDown: handleToggleKeyDown, ref: toggleButton, "aria-haspopup": "dialog", "aria-expanded": menuIsOpen }, { children: children }))] })));
16183
+ ]), id: toggleButtonId, onClick: handleToggleClick, onKeyDown: handleToggleKeyDown, ref: toggleButton, "aria-haspopup": "dialog", "aria-expanded": menuIsOpen, children: children })] }));
15917
16184
  }
15918
16185
 
15919
16186
  ;// CONCATENATED MODULE: ./src/javascripts/ui/components/app-options/index.js
@@ -15983,7 +16250,7 @@ const UnreadMessagesButton = () => {
15983
16250
  const { scrollToRef, unreadIds } = (0,hooks_.useContext)(chat_scroll_context);
15984
16251
  const { isMinimized } = useVisibility();
15985
16252
  const { t } = useI18n();
15986
- return ((0,jsx_runtime_namespaceObject.jsx)(in_out_transition, Object.assign({ isActive: !!unreadIds.length && !isMinimized }, { children: (0,jsx_runtime_namespaceObject.jsx)("div", Object.assign({ className: css_className('unread-messages') }, { children: (0,jsx_runtime_namespaceObject.jsxs)("button", Object.assign({ type: "button", className: css_className('button', 'button--primary'), onClick: scrollToRef }, { children: [t('message.unreadMessagesCount', { unreadCount: unreadIds.length }), (0,jsx_runtime_namespaceObject.jsx)(layout_icon, { name: "chevronDown", size: "32", alt: "" })] })) })) })));
16253
+ return ((0,jsx_runtime_namespaceObject.jsx)(in_out_transition, { isActive: !!unreadIds.length && !isMinimized, children: (0,jsx_runtime_namespaceObject.jsx)("div", { className: css_className('unread-messages'), children: (0,jsx_runtime_namespaceObject.jsxs)("button", { type: "button", className: css_className('button', 'button--primary'), onClick: scrollToRef, children: [t('message.unreadMessagesCount', { unreadCount: unreadIds.length }), (0,jsx_runtime_namespaceObject.jsx)(layout_icon, { name: "chevronDown", size: "32", alt: "" })] }) }) }));
15987
16254
  };
15988
16255
  /* harmony default export */ const unread_messages_button = (UnreadMessagesButton);
15989
16256
 
@@ -16131,13 +16398,13 @@ const ChatScrollProvider = ({ children }) => {
16131
16398
  return acc;
16132
16399
  }, {}), [events]);
16133
16400
  const { scrollToRef, scrollToBottom, containerRef, unreadIds } = use_chat_scroll(eventRefs);
16134
- return ((0,jsx_runtime_namespaceObject.jsx)(chat_scroll_context.Provider, Object.assign({ value: {
16401
+ return ((0,jsx_runtime_namespaceObject.jsx)(chat_scroll_context.Provider, { value: {
16135
16402
  eventRefs,
16136
16403
  unreadIds,
16137
16404
  scrollToRef,
16138
16405
  scrollToBottom,
16139
16406
  containerRef,
16140
- } }, { children: (0,jsx_runtime_namespaceObject.jsxs)("div", Object.assign({ className: css_className('chat__container') }, { children: [(0,jsx_runtime_namespaceObject.jsx)("div", Object.assign({ className: css_className('chat__container__scroll-area'), ref: containerRef }, { children: children })), (0,jsx_runtime_namespaceObject.jsx)(unread_messages_button, {})] })) })));
16407
+ }, children: (0,jsx_runtime_namespaceObject.jsxs)("div", { className: css_className('chat__container'), children: [(0,jsx_runtime_namespaceObject.jsx)("div", { className: css_className('chat__container__scroll-area'), ref: containerRef, children: children }), (0,jsx_runtime_namespaceObject.jsx)(unread_messages_button, {})] }) }));
16141
16408
  };
16142
16409
  /* harmony default export */ const chat_scroll_provider = (ChatScrollProvider);
16143
16410
 
@@ -16428,13 +16695,13 @@ function TextEntryForm({ controlName, skipLinkId }) {
16428
16695
  // When a message is submitted, the keyboard should be prevented from closing on mobile devices
16429
16696
  event.preventDefault();
16430
16697
  };
16431
- return ((0,jsx_runtime_namespaceObject.jsxs)(form_controls_form, Object.assign({ className: css_className('entry-form'), disableValidationClasses: true, noValidate: "true" }, { children: [(0,jsx_runtime_namespaceObject.jsxs)("div", Object.assign({ className: css_className([
16698
+ return ((0,jsx_runtime_namespaceObject.jsxs)(form_controls_form, { className: css_className('entry-form'), disableValidationClasses: true, noValidate: "true", children: [(0,jsx_runtime_namespaceObject.jsxs)("div", { className: css_className([
16432
16699
  'input--text__container',
16433
16700
  ...(reachedCharacterWarning && !reachedCharacterLimit
16434
16701
  ? ['character-warning']
16435
16702
  : []),
16436
16703
  ...(reachedCharacterLimit ? ['character-exceeded'] : []),
16437
- ]) }, { children: [(0,jsx_runtime_namespaceObject.jsx)(input, { id: skipLinkId, type: "text", name: controlName, className: css_className('input__text'), autocomplete: "off", placeholder: placeholder, labelText: label, labelClass: css_className(labelClass), "aria-invalid": hasCharacterLimit ? reachedCharacterLimit : null, onKeyUp: handleKeyUp, onFocus: handleFocus }), (0,jsx_runtime_namespaceObject.jsx)("div", Object.assign({ className: css_className('character-count') }, { children: reachedCharacterWarning && (0,jsx_runtime_namespaceObject.jsx)("span", { children: remainingChars }) }))] })), (0,jsx_runtime_namespaceObject.jsx)("button", Object.assign({ className: css_className('button', 'input__submit'), type: "submit", onPointerDown: handlePointerDown, "aria-disabled": !hasValue || reachedCharacterLimit ? 'true' : null }, { children: (0,jsx_runtime_namespaceObject.jsx)(layout_icon, { name: "send", size: "32", alt: t('input.sendMessage') }) }))] })));
16704
+ ]), children: [(0,jsx_runtime_namespaceObject.jsx)(input, { id: skipLinkId, type: "text", name: controlName, className: css_className('input__text'), autocomplete: "off", placeholder: placeholder, labelText: label, labelClass: css_className(labelClass), "aria-invalid": hasCharacterLimit ? reachedCharacterLimit : null, onKeyUp: handleKeyUp, onFocus: handleFocus }), (0,jsx_runtime_namespaceObject.jsx)("div", { className: css_className('character-count'), children: reachedCharacterWarning && (0,jsx_runtime_namespaceObject.jsx)("span", { children: remainingChars }) })] }), (0,jsx_runtime_namespaceObject.jsx)("button", { className: css_className('button', 'input__submit'), type: "submit", onPointerDown: handlePointerDown, "aria-disabled": !hasValue || reachedCharacterLimit ? 'true' : null, children: (0,jsx_runtime_namespaceObject.jsx)(layout_icon, { name: "send", size: "32", alt: t('input.sendMessage') }) })] }));
16438
16705
  }
16439
16706
 
16440
16707
  ;// CONCATENATED MODULE: ./src/javascripts/ui/components/entry/text-entry/index.js
@@ -17092,7 +17359,7 @@ const CollapseButton = () => {
17092
17359
 
17093
17360
  const ChatStatus = ({ children, handleClose, title, closeButtonText, srCloseButtonText, id, }) => {
17094
17361
  const headingId = useGeneratedId();
17095
- return ((0,jsx_runtime_namespaceObject.jsxs)("section", Object.assign({ tabIndex: -1, id: id, "aria-labelledby": title ? headingId : undefined, className: css_className('chat-status', !title && 'chat-status--condensed') }, { children: [(0,jsx_runtime_namespaceObject.jsxs)("div", Object.assign({ className: css_className('chat-status__body') }, { children: [title ? ((0,jsx_runtime_namespaceObject.jsx)("h2", Object.assign({ className: css_className('chat-status__title'), id: headingId }, { children: title }))) : null, children] })), typeof handleClose === 'function' && ((0,jsx_runtime_namespaceObject.jsxs)("button", Object.assign({ type: "button", onClick: handleClose, className: css_className('button', 'button--tertiary', 'chat-status__close') }, { children: [closeButtonText || (0,jsx_runtime_namespaceObject.jsx)(layout_icon, { name: "close", size: "16", alt: "" }), srCloseButtonText && ((0,jsx_runtime_namespaceObject.jsx)("span", Object.assign({ className: css_className('visually-hidden') }, { children: srCloseButtonText })))] })))] })));
17362
+ return ((0,jsx_runtime_namespaceObject.jsxs)("section", { tabIndex: -1, id: id, "aria-labelledby": title ? headingId : undefined, className: css_className('chat-status', !title && 'chat-status--condensed'), children: [(0,jsx_runtime_namespaceObject.jsxs)("div", { className: css_className('chat-status__body'), children: [title ? ((0,jsx_runtime_namespaceObject.jsx)("h2", { className: css_className('chat-status__title'), id: headingId, children: title })) : null, children] }), typeof handleClose === 'function' && ((0,jsx_runtime_namespaceObject.jsxs)("button", { type: "button", onClick: handleClose, className: css_className('button', 'button--tertiary', 'chat-status__close'), children: [closeButtonText || (0,jsx_runtime_namespaceObject.jsx)(layout_icon, { name: "close", size: "16", alt: "" }), srCloseButtonText && ((0,jsx_runtime_namespaceObject.jsx)("span", { className: css_className('visually-hidden'), children: srCloseButtonText }))] }))] }));
17096
17363
  };
17097
17364
  /* harmony default export */ const chat_status = (ChatStatus);
17098
17365
 
@@ -17127,7 +17394,7 @@ function TranslationChatStatus() {
17127
17394
 
17128
17395
 
17129
17396
 
17130
- const ChatStatusAction = ({ handleClick, icon, title, srButtonText, }) => ((0,jsx_runtime_namespaceObject.jsxs)("button", Object.assign({ type: "button", onClick: handleClick, className: css_className('button', 'button--primary', 'chat-status__button') }, { children: [(0,jsx_runtime_namespaceObject.jsx)(layout_icon, { name: icon, size: "16", alt: "" }), title, srButtonText && ((0,jsx_runtime_namespaceObject.jsx)("span", Object.assign({ className: css_className('visually-hidden') }, { children: srButtonText })))] })));
17397
+ const ChatStatusAction = ({ handleClick, icon, title, srButtonText, }) => ((0,jsx_runtime_namespaceObject.jsxs)("button", { type: "button", onClick: handleClick, className: css_className('button', 'button--primary', 'chat-status__button'), children: [(0,jsx_runtime_namespaceObject.jsx)(layout_icon, { name: icon, size: "16", alt: "" }), title, srButtonText && ((0,jsx_runtime_namespaceObject.jsx)("span", { className: css_className('visually-hidden'), children: srButtonText }))] }));
17131
17398
  /* harmony default export */ const chat_status_action = (ChatStatusAction);
17132
17399
 
17133
17400
  ;// CONCATENATED MODULE: ./src/javascripts/ui/components/translation-proposal/index.tsx
@@ -17141,7 +17408,7 @@ function TranslationProposal() {
17141
17408
  if (!showProposal) {
17142
17409
  return null;
17143
17410
  }
17144
- return ((0,jsx_runtime_namespaceObject.jsx)(chat_status, Object.assign({ handleClose: dismissTranslationProposal, srCloseButtonText: translationProposal.srDismissButtonText, id: id, title: translationProposal.titleLabel }, { children: (0,jsx_runtime_namespaceObject.jsx)(chat_status_action, { handleClick: activateTranslationProposal, icon: "newTranslation", title: translationProposal.buttonLabel }) })));
17411
+ return ((0,jsx_runtime_namespaceObject.jsx)(chat_status, { handleClose: dismissTranslationProposal, srCloseButtonText: translationProposal.srDismissButtonText, id: id, title: translationProposal.titleLabel, children: (0,jsx_runtime_namespaceObject.jsx)(chat_status_action, { handleClick: activateTranslationProposal, icon: "newTranslation", title: translationProposal.buttonLabel }) }));
17145
17412
  }
17146
17413
 
17147
17414
  ;// CONCATENATED MODULE: ./src/javascripts/domains/translations/components/translation-status.tsx
@@ -17446,7 +17713,7 @@ const WindowView = () => {
17446
17713
  },
17447
17714
  },
17448
17715
  }), [continueChatText]);
17449
- return ((0,jsx_runtime_namespaceObject.jsxs)(jsx_runtime_namespaceObject.Fragment, { children: [(0,jsx_runtime_namespaceObject.jsx)(window_open_button, { onClick: openChat }), (0,jsx_runtime_namespaceObject.jsx)(in_out_transition, Object.assign({ isActive: preChat && !isOpen && !userHasResponded, exitAfter: getDelay(preChat, 'exitAfter'), enterDelay: getDelay(preChat, 'enterDelay'), transitionStartState: transitionStartStates.rendered }, { children: (0,jsx_runtime_namespaceObject.jsx)("div", Object.assign({ className: css_className('unstarted-wrapper', 'unstarted-wrapper--window') }, { children: (0,jsx_runtime_namespaceObject.jsx)(PreChatMessages, {}) })) })), (0,jsx_runtime_namespaceObject.jsx)(in_out_transition, Object.assign({ isActive: continueChat && !isOpen && userHasResponded, exitAfter: getDelay(continueChat, 'exitAfter'), enterDelay: getDelay(continueChat, 'enterDelay'), transitionStartState: transitionStartStates.notRendered }, { children: (0,jsx_runtime_namespaceObject.jsx)("div", Object.assign({ className: css_className('unstarted-wrapper', 'unstarted-wrapper--window', 'unstarted-wrapper--continue') }, { children: (0,jsx_runtime_namespaceObject.jsx)(event_text, { event: continueChatEvent }) })) })), (0,jsx_runtime_namespaceObject.jsx)(in_out_transition, Object.assign({ isActive: isOpen, transitionStartState: transitionStartStates.notRendered }, { children: (0,jsx_runtime_namespaceObject.jsx)(chat, { children: (0,jsx_runtime_namespaceObject.jsx)(chat_frame, { children: (0,jsx_runtime_namespaceObject.jsx)(conversation, {}) }) }) }))] }));
17716
+ return ((0,jsx_runtime_namespaceObject.jsxs)(jsx_runtime_namespaceObject.Fragment, { children: [(0,jsx_runtime_namespaceObject.jsx)(window_open_button, { onClick: openChat }), (0,jsx_runtime_namespaceObject.jsx)(in_out_transition, { isActive: preChat && !isOpen && !userHasResponded, exitAfter: getDelay(preChat, 'exitAfter'), enterDelay: getDelay(preChat, 'enterDelay'), transitionStartState: transitionStartStates.rendered, children: (0,jsx_runtime_namespaceObject.jsx)("div", { className: css_className('unstarted-wrapper', 'unstarted-wrapper--window'), children: (0,jsx_runtime_namespaceObject.jsx)(PreChatMessages, {}) }) }), (0,jsx_runtime_namespaceObject.jsx)(in_out_transition, { isActive: continueChat && !isOpen && userHasResponded, exitAfter: getDelay(continueChat, 'exitAfter'), enterDelay: getDelay(continueChat, 'enterDelay'), transitionStartState: transitionStartStates.notRendered, children: (0,jsx_runtime_namespaceObject.jsx)("div", { className: css_className('unstarted-wrapper', 'unstarted-wrapper--window', 'unstarted-wrapper--continue'), children: (0,jsx_runtime_namespaceObject.jsx)(event_text, { event: continueChatEvent }) }) }), (0,jsx_runtime_namespaceObject.jsx)(in_out_transition, { isActive: isOpen, transitionStartState: transitionStartStates.notRendered, children: (0,jsx_runtime_namespaceObject.jsx)(chat, { children: (0,jsx_runtime_namespaceObject.jsx)(chat_frame, { children: (0,jsx_runtime_namespaceObject.jsx)(conversation, {}) }) }) })] }));
17450
17717
  };
17451
17718
  /* harmony default export */ const window_view = (WindowView);
17452
17719
 
@@ -17661,7 +17928,7 @@ const View = ({ children }) => {
17661
17928
  if (userHasResponded) {
17662
17929
  classNames.push('app--user-responded');
17663
17930
  }
17664
- return (isVisible && ((0,jsx_runtime_namespaceObject.jsx)("div", Object.assign({ className: css_className(classNames), lang: blockLang, tabIndex: -1, "data-nosnippet": true, style: { zIndex }, ref: containerElementRef }, { children: children || (0,jsx_runtime_namespaceObject.jsx)(ViewComponent, {}) }))));
17931
+ return (isVisible && ((0,jsx_runtime_namespaceObject.jsx)("div", { className: css_className(classNames), lang: blockLang, tabIndex: -1, "data-nosnippet": true, style: { zIndex }, ref: containerElementRef, children: children || (0,jsx_runtime_namespaceObject.jsx)(ViewComponent, {}) })));
17665
17932
  };
17666
17933
  /* harmony default export */ const view = (View);
17667
17934
 
@@ -17751,14 +18018,16 @@ class Engine {
17751
18018
  yield store.dispatch(initializeConfig());
17752
18019
  try {
17753
18020
  const { locale } = yield store.dispatch(initializeApp()).unwrap();
17754
- yield store.dispatch(setLocale(locale));
18021
+ if (locale) {
18022
+ yield store.dispatch(setLocale(locale));
18023
+ }
17755
18024
  }
17756
18025
  catch (rejectedValueOrSerializedError) {
17757
18026
  // nothing to do
17758
18027
  }
17759
18028
  store.dispatch(initializeVisibility());
17760
18029
  if (View) {
17761
- (0,external_preact_.render)((0,jsx_runtime_namespaceObject.jsx)(seamly_core, Object.assign({ eventBus: this.eventBus, store: store, api: this.api }, { children: (0,jsx_runtime_namespaceObject.jsx)(View, {}) })), this.parentElement);
18030
+ (0,external_preact_.render)((0,jsx_runtime_namespaceObject.jsx)(seamly_core, { eventBus: this.eventBus, store: store, api: this.api, children: (0,jsx_runtime_namespaceObject.jsx)(View, {}) }), this.parentElement);
17762
18031
  }
17763
18032
  else {
17764
18033
  (0,external_preact_.render)((0,jsx_runtime_namespaceObject.jsx)(chat_app, { config: renderConfig, eventBus: this.eventBus, store: store, api: this.api }), this.parentElement);
@@ -19856,6 +20125,104 @@ const standardState = {
19856
20125
  }]
19857
20126
  }
19858
20127
  },
20128
+ translationsActiveLarge: {
20129
+ category: categoryKeys.translations,
20130
+ headingText: 'Show translations active (large list)',
20131
+ description: '',
20132
+ ...baseState,
20133
+ config: {
20134
+ ...baseState.config,
20135
+ context: {
20136
+ ...baseState.context,
20137
+ locale: 'nl'
20138
+ }
20139
+ },
20140
+ translations: {
20141
+ ...translationsSlice,
20142
+ currentLocale: 'lv',
20143
+ isActive: true,
20144
+ isAvailable: true,
20145
+ languages: [{
20146
+ locale: 'nl',
20147
+ nativeName: 'Dutch'
20148
+ }, {
20149
+ locale: 'en',
20150
+ nativeName: 'English'
20151
+ }, {
20152
+ locale: 'ar',
20153
+ nativeName: 'Arabic'
20154
+ }, {
20155
+ locale: 'bg',
20156
+ nativeName: 'Bulgarian'
20157
+ }, {
20158
+ locale: 'zh',
20159
+ nativeName: 'Chinese'
20160
+ }, {
20161
+ locale: 'cs',
20162
+ nativeName: 'Czech'
20163
+ }, {
20164
+ locale: 'da',
20165
+ nativeName: 'Danish'
20166
+ }, {
20167
+ locale: 'et',
20168
+ nativeName: 'Estonian'
20169
+ }, {
20170
+ locale: 'fi',
20171
+ nativeName: 'Finnish'
20172
+ }, {
20173
+ locale: 'fr',
20174
+ nativeName: 'French'
20175
+ }, {
20176
+ locale: 'de-informal',
20177
+ nativeName: 'German'
20178
+ }, {
20179
+ locale: 'el',
20180
+ nativeName: 'Greek'
20181
+ }, {
20182
+ locale: 'hu',
20183
+ nativeName: 'Hungarian'
20184
+ }, {
20185
+ locale: 'it',
20186
+ nativeName: 'Italian'
20187
+ }, {
20188
+ locale: 'ja',
20189
+ nativeName: 'Japanese'
20190
+ }, {
20191
+ locale: 'lv',
20192
+ nativeName: 'Latvian'
20193
+ }, {
20194
+ locale: 'pl',
20195
+ nativeName: 'Polish'
20196
+ }, {
20197
+ locale: 'ro',
20198
+ nativeName: 'Romanian'
20199
+ }, {
20200
+ locale: 'ru',
20201
+ nativeName: 'Russian'
20202
+ }, {
20203
+ locale: 'sk',
20204
+ nativeName: 'Slovak'
20205
+ }, {
20206
+ locale: 'sl',
20207
+ nativeName: 'Slovenian'
20208
+ }, {
20209
+ locale: 'es-informal',
20210
+ nativeName: 'Spanish'
20211
+ }, {
20212
+ locale: 'sv',
20213
+ nativeName: 'Swedish'
20214
+ }, {
20215
+ locale: 'ti',
20216
+ nativeName: 'Tigrinya'
20217
+ }, {
20218
+ locale: 'tr',
20219
+ nativeName: 'Turkish'
20220
+ }, {
20221
+ locale: 'uk',
20222
+ nativeName: 'Ukrainian'
20223
+ }]
20224
+ }
20225
+ },
19859
20226
  translationsFullConversation: {
19860
20227
  category: categoryKeys.translations,
19861
20228
  headingText: 'Show translated messages',