@depict-ai/ui 4.10.13 → 4.10.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/latest/index.d.ts CHANGED
@@ -11,7 +11,7 @@ import { GetListingRequest } from "@depict-ai/types/api/GetListingRequest";
11
11
  import { BaseSearchRequestV3 } from "@depict-ai/types/api/BaseSearchRequestV3";
12
12
  import { FeaturedInDisplay } from "@depict-ai/types/api/FeaturedInResponseV3";
13
13
  import { SearchFilter as _SearchFilter3 } from "@depict-ai/types/api/SearchRequestV2";
14
- export const version = "4.10.13";
14
+ export const version = "4.10.14";
15
15
  /**
16
16
  * Use `javascript_media_query` but return a reactive accessor instead of taking a callback function
17
17
  */
package/latest/index.js CHANGED
@@ -7,7 +7,7 @@ import { createStore as $9HbP8$createStore, reconcile as $9HbP8$reconcile } from
7
7
  /*! Depict.ai search and product listing SDK */
8
8
  import { register_es_version } from "../multi_import_deduplicator.mjs";
9
9
  register_es_version("ui", "latest");
10
- const $ec291e0010116877$export$83d89fbfd8236492 = "4.10.13";
10
+ const $ec291e0010116877$export$83d89fbfd8236492 = "4.10.14";
11
11
  function $dc9262ef6f786812$export$d9f36cf74e24d595(media_query) {
12
12
  const signal = $9HbP8$createSignal(false);
13
13
  $9HbP8$onCleanup($9HbP8$javascript_media_query(media_query, ({
@@ -2599,14 +2599,39 @@ function $f8a56ba74eedd0c6$export$f21ab0717a89c77f(props) {
2599
2599
  var $67b173f9db427028$var$_tmpl$ = /*#__PURE__*/$9HbP8$template(`<button type=button class=expand-filter><!$><!/><span>`);
2600
2600
  function $67b173f9db427028$export$ca21a16d65b3dd8({
2601
2601
  show_extras_: [get_show_extras, set_show_extras],
2602
- i18n_: i18n_
2602
+ i18n_: i18n_,
2603
+ expanding_container_element_: expanding_container_element_
2603
2604
  }) {
2605
+ let button;
2604
2606
  return (() => {
2605
2607
  var _el$ = $9HbP8$getNextElement($67b173f9db427028$var$_tmpl$),
2606
2608
  _el$3 = _el$.firstChild,
2607
2609
  [_el$4, _co$] = $9HbP8$getNextMarker(_el$3.nextSibling),
2608
2610
  _el$2 = _el$4.nextSibling;
2609
- $9HbP8$addEventListener(_el$, "click", $9HbP8$catchify1(() => set_show_extras(p => !p)), true);
2611
+ $9HbP8$addEventListener(_el$, "click", $9HbP8$catchify1(event => {
2612
+ const container = expanding_container_element_;
2613
+ const will_expand = !get_show_extras();
2614
+ // A click from Enter/Space on the button reports `detail === 0`; a real pointer click reports >= 1.
2615
+ // Only hijack focus for keyboard activation - mouse users can see the revealed options and don't need it
2616
+ // (and would otherwise get the viewport scrolled and an unexpected focus ring).
2617
+ const keyboard_activated = event.detail === 0;
2618
+ const had_focus_inside = !!container && container.contains(document.activeElement);
2619
+ set_show_extras(will_expand);
2620
+ if (will_expand) {
2621
+ if (!keyboard_activated) return;
2622
+ // The container's `expand()` (run from the consumer's effect after this handler) clears `inert`/`visibility`;
2623
+ // focus the first revealed option on the next frame so Tab continues through the newly shown options.
2624
+ // `preventScroll` so moving focus never yanks the viewport down to the first checkbox.
2625
+ requestAnimationFrame($9HbP8$catchify1(() => container?.querySelector("input:not(:disabled)")?.focus({
2626
+ preventScroll: true
2627
+ })));
2628
+ } else if (had_focus_inside)
2629
+ // Keep focus on the toggle when collapsing, otherwise making the container `inert` dumps focus to <body>
2630
+ // (Safari doesn't focus buttons on mouse click, so focus can still be inside the container here).
2631
+ button.focus();
2632
+ }), true);
2633
+ var _ref$ = button;
2634
+ typeof _ref$ === "function" ? $9HbP8$use(_ref$, _el$) : button = _el$;
2610
2635
  $9HbP8$insert(_el$, $9HbP8$createComponent((0, $f8a56ba74eedd0c6$export$f21ab0717a89c77f), {}), _el$4, _co$);
2611
2636
  $9HbP8$insert(_el$2, (() => {
2612
2637
  var _c$ = $9HbP8$memo(() => !!get_show_extras());
@@ -2796,7 +2821,8 @@ function $a4601e6bea3ed1e6$export$dd948f91abc3a1c4({
2796
2821
  $9HbP8$createRenderEffect(() => {
2797
2822
  set_view_more_button_below_group_(togglable_rest() ? $9HbP8$createComponent((0, $67b173f9db427028$export$ca21a16d65b3dd8), {
2798
2823
  show_extras_: show_extras_signal,
2799
- i18n_: i18n_
2824
+ i18n_: i18n_,
2825
+ expanding_container_element_: expanding_container_els
2800
2826
  }) : []);
2801
2827
  });
2802
2828
  $9HbP8$onCleanup(() => set_view_more_button_below_group_());
@@ -3725,7 +3751,8 @@ function $1c8cac76cb67e9af$export$a32086fa6616eafd({
3725
3751
  $9HbP8$createRenderEffect(() => {
3726
3752
  set_view_more_button_below_group(some_top_level_are_hidden() ? $9HbP8$createComponent((0, $67b173f9db427028$export$ca21a16d65b3dd8), {
3727
3753
  show_extras_: show_extras,
3728
- i18n_: i18n_
3754
+ i18n_: i18n_,
3755
+ expanding_container_element_: expanding_container_els
3729
3756
  }) : []);
3730
3757
  });
3731
3758
  $9HbP8$onCleanup(() => set_view_more_button_below_group());
@@ -4466,7 +4493,8 @@ function $e731d52d97444b7c$export$82ed4b28ecb67608({
4466
4493
  $9HbP8$createRenderEffect(() => {
4467
4494
  set_view_more_button_below_group_(togglable_rest() ? $9HbP8$createComponent((0, $67b173f9db427028$export$ca21a16d65b3dd8), {
4468
4495
  show_extras_: show_extras_signal,
4469
- i18n_: i18n_
4496
+ i18n_: i18n_,
4497
+ expanding_container_element_: expanding_container_els
4470
4498
  }) : []);
4471
4499
  });
4472
4500
  $9HbP8$onCleanup(() => set_view_more_button_below_group_());
@@ -5859,8 +5887,8 @@ var $11d594c749b76228$var$_tmpl$ = /*#__PURE__*/$9HbP8$template(`<svg xmlns=http
5859
5887
  function $11d594c749b76228$export$cb808a3c41736d8e() {
5860
5888
  return $9HbP8$getNextElement($11d594c749b76228$var$_tmpl$);
5861
5889
  }
5862
- var $cdea4cf8c5c071ef$var$_tmpl$ = /*#__PURE__*/$9HbP8$template(`<div class=filters><div class=body>`),
5863
- $cdea4cf8c5c071ef$var$_tmpl$2 = /*#__PURE__*/$9HbP8$template(`<div class=sorting><div class=body>`),
5890
+ var $cdea4cf8c5c071ef$var$_tmpl$ = /*#__PURE__*/$9HbP8$template(`<section class=filters tabindex=-1><div class=body>`),
5891
+ $cdea4cf8c5c071ef$var$_tmpl$2 = /*#__PURE__*/$9HbP8$template(`<section class=sorting tabindex=-1><div class=body>`),
5864
5892
  $cdea4cf8c5c071ef$var$_tmpl$3 = /*#__PURE__*/$9HbP8$template(`<div class=sort-and-filter-buttons><div class=outer><div class=inner><!$><!/><!$><!/><!$><!/>`),
5865
5893
  $cdea4cf8c5c071ef$var$_tmpl$4 = /*#__PURE__*/$9HbP8$template(`<span class=num-filters>`),
5866
5894
  $cdea4cf8c5c071ef$var$_tmpl$5 = /*#__PURE__*/$9HbP8$template(`<div class=open-filters-button-container><!$><!/><button type=button><!$><!/><span>`),
@@ -5929,6 +5957,27 @@ function $cdea4cf8c5c071ef$export$d7841e452f2e59a8({
5929
5957
  available_sortings_: available_sortings_,
5930
5958
  meta_of_currently_selected_sorting_: meta_of_currently_selected_sorting_
5931
5959
  };
5960
+ // Keyboard accessibility for the desktop panels (rendered after the product grid in the DOM): when the user
5961
+ // opens a panel we move focus into it, and restore focus to the toggle button on close. Intent is tracked with
5962
+ // a plain flag set in the buttons' click handlers - `filters_open`/`sorting_open` also change programmatically
5963
+ // (undo toast, history-state restore, SDK consumers), and those must not steal focus.
5964
+ let user_opened_panel = false;
5965
+ let filter_toggle_button;
5966
+ let sort_toggle_button;
5967
+ let current_panel;
5968
+ let current_panel_toggle_button;
5969
+ const focus_panel_when_in_dom = panel => $9HbP8$catchify1(async () => {
5970
+ // Bounded wait: if the panel never lands in the DOM (e.g. it's superseded by a rapid re-render before
5971
+ // insertion), the timeout lets this promise resolve instead of keeping `panel` - and the observer
5972
+ // listener it registers - referenced forever.
5973
+ await (0, $9HbP8$observer).wait_for_element(panel, 4000);
5974
+ if (panel.isConnected) panel.focus();
5975
+ })();
5976
+ const register_desktop_panel = (el, toggle_button, should_focus) => {
5977
+ current_panel = el;
5978
+ current_panel_toggle_button = toggle_button;
5979
+ if (should_focus) focus_panel_when_in_dom(el);
5980
+ };
5932
5981
  const make_open_filters_button = (adhere_to_width = false, is_tabbable = false) => $9HbP8$createComponent($cdea4cf8c5c071ef$var$OpenFiltersButton, {
5933
5982
  tabindex_: is_tabbable ? 0 : -1,
5934
5983
  i18n_: i18n_,
@@ -5936,7 +5985,9 @@ function $cdea4cf8c5c071ef$export$d7841e452f2e59a8({
5936
5985
  search_sorting_open_: search_sorting_open_,
5937
5986
  number_of_rendered_selected_filters_items_: number_of_rendered_selected_filters_items_,
5938
5987
  filter_button_width_: adhere_to_width ? filter_button_width_ : undefined,
5939
- hide_button_: hide_filters
5988
+ hide_button_: hide_filters,
5989
+ on_user_open_: () => user_opened_panel = true,
5990
+ button_ref_: is_tabbable ? el => filter_toggle_button = el : undefined
5940
5991
  });
5941
5992
  const make_open_sorting_button = (adhere_to_width = false, is_tabbable = false) => $9HbP8$createComponent($cdea4cf8c5c071ef$var$OpenSortingButton, {
5942
5993
  tabindex_: is_tabbable ? 0 : -1,
@@ -5946,7 +5997,9 @@ function $cdea4cf8c5c071ef$export$d7841e452f2e59a8({
5946
5997
  search_sorting_open_: search_sorting_open_,
5947
5998
  available_sortings_: available_sortings_,
5948
5999
  sort_button_width_: adhere_to_width ? sort_button_width_ : undefined,
5949
- meta_of_currently_selected_sorting_: meta_of_currently_selected_sorting_
6000
+ meta_of_currently_selected_sorting_: meta_of_currently_selected_sorting_,
6001
+ on_user_open_: () => user_opened_panel = true,
6002
+ button_ref_: is_tabbable ? el => sort_toggle_button = el : undefined
5950
6003
  });
5951
6004
  let open_modal_;
5952
6005
  let close_modal_;
@@ -5965,9 +6018,46 @@ function $cdea4cf8c5c071ef$export$d7841e452f2e59a8({
5965
6018
  grid_is_in_original_state = true;
5966
6019
  }
5967
6020
  });
6021
+ // Restore focus to the relevant toggle button when a desktop panel is torn down while focus is still inside it.
6022
+ const restore_focus_to_toggle_on_close = () => {
6023
+ const button_to_restore = current_panel_toggle_button;
6024
+ const focus_was_in_panel = !!current_panel && current_panel.contains(document.activeElement);
6025
+ current_panel = undefined;
6026
+ current_panel_toggle_button = undefined;
6027
+ if (focus_was_in_panel) button_to_restore?.focus();
6028
+ };
6029
+ // `<section>` + `aria-label` so the panel announces itself ("Filters"/"Sort") when we move focus to it; the bare
6030
+ // tabindex=-1 container would otherwise give screen readers nothing to read on focus. A semantic <section> avoids
6031
+ // an ARIA role and the UA styling pitfalls of <fieldset>; the existing CSS targets the `.filters`/`.sorting` class.
6032
+ const FiltersPanel = should_focus => $9HbP8$createComponent((0, $9HbP8$Show), {
6033
+ get when() {
6034
+ return !hide_filters();
6035
+ },
6036
+ get children() {
6037
+ var _el$ = $9HbP8$getNextElement($cdea4cf8c5c071ef$var$_tmpl$),
6038
+ _el$2 = _el$.firstChild;
6039
+ $9HbP8$use(el => register_desktop_panel(el, filter_toggle_button, should_focus), _el$);
6040
+ $9HbP8$insert(_el$2, $9HbP8$createComponent((0, $fab07f52c9861732$export$3f1a388cc0d8fed7), filter_options));
6041
+ $9HbP8$effect(() => $9HbP8$setAttribute(_el$, "aria-label", i18n_.filters_()));
6042
+ return _el$;
6043
+ }
6044
+ });
6045
+ const SortingPanel = should_focus => (() => {
6046
+ var _el$3 = $9HbP8$getNextElement($cdea4cf8c5c071ef$var$_tmpl$2),
6047
+ _el$4 = _el$3.firstChild;
6048
+ $9HbP8$use(el => register_desktop_panel(el, sort_toggle_button, should_focus), _el$3);
6049
+ $9HbP8$insert(_el$4, $9HbP8$createComponent((0, $68a258a92b88f02f$export$1f1775a58da589b5), sorting_options));
6050
+ $9HbP8$effect(() => $9HbP8$setAttribute(_el$3, "aria-label", i18n_.sorting_text_()));
6051
+ return _el$3;
6052
+ })();
5968
6053
  $9HbP8$createEffect(() => {
6054
+ // Consume the user-intent flag once per run, in every branch, so a stale flag can't leak into a later
6055
+ // resize-triggered re-render and steal focus.
6056
+ const should_focus_panel = user_opened_panel;
6057
+ user_opened_panel = false;
5969
6058
  if (!filters_open() && !sorting_open()) {
5970
6059
  close_modal_?.();
6060
+ restore_focus_to_toggle_on_close();
5971
6061
  set_extra_els_in_results_container_("");
5972
6062
  } else if (isSmall()()) {
5973
6063
  if ($9HbP8$untrack(() => input_modal_open_?.())) {
@@ -5976,26 +6066,14 @@ function $cdea4cf8c5c071ef$export$d7841e452f2e59a8({
5976
6066
  set_sorting_open(false);
5977
6067
  return;
5978
6068
  }
6069
+ // The modal manages its own focus; just drop the desktop panel reference.
6070
+ current_panel = undefined;
6071
+ current_panel_toggle_button = undefined;
5979
6072
  open_modal_?.();
5980
6073
  set_extra_els_in_results_container_("");
5981
6074
  } else {
5982
6075
  close_modal_?.();
5983
- if (filters_open()) set_extra_els_in_results_container_(() => $9HbP8$createComponent((0, $9HbP8$Show), {
5984
- get when() {
5985
- return !hide_filters();
5986
- },
5987
- get children() {
5988
- var _el$ = $9HbP8$getNextElement($cdea4cf8c5c071ef$var$_tmpl$),
5989
- _el$2 = _el$.firstChild;
5990
- $9HbP8$insert(_el$2, $9HbP8$createComponent((0, $fab07f52c9861732$export$3f1a388cc0d8fed7), filter_options));
5991
- return _el$;
5992
- }
5993
- }));else set_extra_els_in_results_container_((() => {
5994
- var _el$3 = $9HbP8$getNextElement($cdea4cf8c5c071ef$var$_tmpl$2),
5995
- _el$4 = _el$3.firstChild;
5996
- $9HbP8$insert(_el$4, $9HbP8$createComponent((0, $68a258a92b88f02f$export$1f1775a58da589b5), sorting_options));
5997
- return _el$3;
5998
- })());
6076
+ if (filters_open()) set_extra_els_in_results_container_(() => FiltersPanel(should_focus_panel));else set_extra_els_in_results_container_(SortingPanel(should_focus_panel));
5999
6077
  }
6000
6078
  });
6001
6079
  $9HbP8$catchify1(async () => {
@@ -6059,7 +6137,9 @@ function $cdea4cf8c5c071ef$var$OpenFiltersButton({
6059
6137
  filter_button_width_: filter_button_width_,
6060
6138
  tabindex_: tabindex_,
6061
6139
  number_of_rendered_selected_filters_items_: [num_selected_filters],
6062
- hide_button_: hide_button_
6140
+ hide_button_: hide_button_,
6141
+ on_user_open_: on_user_open_,
6142
+ button_ref_: button_ref_
6063
6143
  }) {
6064
6144
  const filters_closed = $9HbP8$createMemo(() => !search_filters_open_[0]());
6065
6145
  // We assume in embedded_num_products that this is a single HTMLElement so pls change there if you change it here
@@ -6087,9 +6167,12 @@ function $cdea4cf8c5c071ef$var$OpenFiltersButton({
6087
6167
  search_filters_open_[1](false);
6088
6168
  return;
6089
6169
  }
6170
+ on_user_open_?.();
6090
6171
  search_filters_open_[1](true);
6091
6172
  search_sorting_open_[1](false);
6092
6173
  })), true);
6174
+ var _ref$2 = button_ref_;
6175
+ typeof _ref$2 === "function" ? $9HbP8$use(_ref$2, _el$16) : button_ref_ = _el$16;
6093
6176
  $9HbP8$setAttribute(_el$16, "tabindex", tabindex_);
6094
6177
  $9HbP8$className(_el$16, "filter toggle-button major-minor-transition" + ((0, $9HbP8$isServer) ? " minor" : ""));
6095
6178
  $9HbP8$insert(_el$16, $9HbP8$createComponent((0, $9HbP8$Show), {
@@ -6111,21 +6194,24 @@ function $cdea4cf8c5c071ef$var$OpenFiltersButton({
6111
6194
  _v$2 = !filters_closed(),
6112
6195
  _v$3 = !!filters_closed(),
6113
6196
  _v$4 = (filters_closed() ? i18n_.open_filters_ : i18n_.close_filters_)(),
6114
- _v$5 = filter_button_width_?.() ? {
6197
+ _v$5 = !filters_closed(),
6198
+ _v$6 = filter_button_width_?.() ? {
6115
6199
  width: filter_button_width_() + "px"
6116
6200
  } : {};
6117
6201
  _p$.e = $9HbP8$style(_el$14, _v$, _p$.e);
6118
6202
  _v$2 !== _p$.t && _el$16.classList.toggle("major", _p$.t = _v$2);
6119
6203
  _v$3 !== _p$.a && _el$16.classList.toggle("minor", _p$.a = _v$3);
6120
6204
  _v$4 !== _p$.o && $9HbP8$setAttribute(_el$16, "aria-label", _p$.o = _v$4);
6121
- _p$.i = $9HbP8$style(_el$16, _v$5, _p$.i);
6205
+ _v$5 !== _p$.i && $9HbP8$setAttribute(_el$16, "aria-expanded", _p$.i = _v$5);
6206
+ _p$.n = $9HbP8$style(_el$16, _v$6, _p$.n);
6122
6207
  return _p$;
6123
6208
  }, {
6124
6209
  e: undefined,
6125
6210
  t: undefined,
6126
6211
  a: undefined,
6127
6212
  o: undefined,
6128
- i: undefined
6213
+ i: undefined,
6214
+ n: undefined
6129
6215
  });
6130
6216
  $9HbP8$runHydrationEvents();
6131
6217
  return _el$14;
@@ -6139,7 +6225,9 @@ function $cdea4cf8c5c071ef$var$OpenSortingButton({
6139
6225
  search_sorting_open_: search_sorting_open_,
6140
6226
  sort_button_width_: sort_button_width_,
6141
6227
  tabindex_: tabindex_,
6142
- meta_of_currently_selected_sorting_: meta_of_currently_selected_sorting_
6228
+ meta_of_currently_selected_sorting_: meta_of_currently_selected_sorting_,
6229
+ on_user_open_: on_user_open_,
6230
+ button_ref_: button_ref_
6143
6231
  }) {
6144
6232
  const sorting_closed = $9HbP8$createMemo(() => !search_sorting_open_[0]());
6145
6233
  // We assume in embedded_num_products that this is a single HTMLElement so pls change there if you change it here
@@ -6153,9 +6241,12 @@ function $cdea4cf8c5c071ef$var$OpenSortingButton({
6153
6241
  search_sorting_open_[1](false);
6154
6242
  return;
6155
6243
  }
6244
+ on_user_open_?.();
6156
6245
  search_filters_open_[1](false);
6157
6246
  search_sorting_open_[1](true);
6158
6247
  })), true);
6248
+ var _ref$3 = button_ref_;
6249
+ typeof _ref$3 === "function" ? $9HbP8$use(_ref$3, _el$22) : button_ref_ = _el$22;
6159
6250
  $9HbP8$setAttribute(_el$22, "tabindex", tabindex_);
6160
6251
  $9HbP8$insert(_el$23, (() => {
6161
6252
  var _c$ = $9HbP8$memo(() => !!sorting_closed());
@@ -6177,22 +6268,25 @@ function $cdea4cf8c5c071ef$var$OpenSortingButton({
6177
6268
  }
6178
6269
  }), _el$25, _co$6);
6179
6270
  $9HbP8$effect(_p$ => {
6180
- var _v$6 = !sorting_closed(),
6181
- _v$7 = !!sorting_closed(),
6182
- _v$8 = (sorting_closed() ? i18n_.open_sorting_ : i18n_.close_sorting_)(),
6183
- _v$9 = sort_button_width_?.() ? {
6271
+ var _v$7 = !sorting_closed(),
6272
+ _v$8 = !!sorting_closed(),
6273
+ _v$9 = (sorting_closed() ? i18n_.open_sorting_ : i18n_.close_sorting_)(),
6274
+ _v$10 = !sorting_closed(),
6275
+ _v$11 = sort_button_width_?.() ? {
6184
6276
  width: sort_button_width_() + "px"
6185
6277
  } : {};
6186
- _v$6 !== _p$.e && _el$22.classList.toggle("major", _p$.e = _v$6);
6187
- _v$7 !== _p$.t && _el$22.classList.toggle("minor", _p$.t = _v$7);
6188
- _v$8 !== _p$.a && $9HbP8$setAttribute(_el$22, "aria-label", _p$.a = _v$8);
6189
- _p$.o = $9HbP8$style(_el$22, _v$9, _p$.o);
6278
+ _v$7 !== _p$.e && _el$22.classList.toggle("major", _p$.e = _v$7);
6279
+ _v$8 !== _p$.t && _el$22.classList.toggle("minor", _p$.t = _v$8);
6280
+ _v$9 !== _p$.a && $9HbP8$setAttribute(_el$22, "aria-label", _p$.a = _v$9);
6281
+ _v$10 !== _p$.o && $9HbP8$setAttribute(_el$22, "aria-expanded", _p$.o = _v$10);
6282
+ _p$.i = $9HbP8$style(_el$22, _v$11, _p$.i);
6190
6283
  return _p$;
6191
6284
  }, {
6192
6285
  e: undefined,
6193
6286
  t: undefined,
6194
6287
  a: undefined,
6195
- o: undefined
6288
+ o: undefined,
6289
+ i: undefined
6196
6290
  });
6197
6291
  $9HbP8$runHydrationEvents();
6198
6292
  return _el$22;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@depict-ai/ui",
3
- "version": "4.10.13",
3
+ "version": "4.10.14",
4
4
  "description": "Base package containing the actual UI of Depict UI along with translations, with a not-simplified API. We recommend using @depict-ai/js-ui or @depict-ai/react-ui instead.",
5
5
  "packageManager": "yarn@3.2.2",
6
6
  "sass": "styles.scss",
@@ -236,9 +236,9 @@
236
236
  "@babel/plugin-transform-typescript": "^7.22.9",
237
237
  "@babel/runtime": "latest",
238
238
  "@babel/runtime-corejs3": "^7.22.6",
239
- "@depict-ai/plp-styling": "^4.6.5",
240
- "@depict-ai/types": "^5.6.3",
241
- "@depict-ai/utilishared": "^2.6.3",
239
+ "@depict-ai/plp-styling": "^4.6.6",
240
+ "@depict-ai/types": "^5.6.4",
241
+ "@depict-ai/utilishared": "^2.6.4",
242
242
  "solid-js": "^1.9.10"
243
243
  },
244
244
  "type": "module",
@@ -115,7 +115,7 @@ $parcel$export(module.exports, "BreadCrumbs", () => $335c02c1241a9ca8$export$5b7
115
115
  $parcel$export(module.exports, "QuickLinks", () => $335c02c1241a9ca8$export$de035477d6fef996);
116
116
  $parcel$export(module.exports, "CategoryPage", () => $c10e33c4681f8c9b$export$e2bf8ce7779e827e);
117
117
  /*! Depict.ai search and product listing SDK */
118
- const $aa1938dec50d6c12$export$83d89fbfd8236492 = "4.10.13";
118
+ const $aa1938dec50d6c12$export$83d89fbfd8236492 = "4.10.14";
119
119
  function $3e17e871e9d0911d$export$d9f36cf74e24d595(media_query) {
120
120
  const signal = $3hooq$solidjs.createSignal(false);
121
121
  $3hooq$solidjs.onCleanup($3hooq$depictaiutilishared.javascript_media_query(media_query, _ref => {
@@ -2315,8 +2315,10 @@ var $b0477e4d832f090e$var$_tmpl$ = ["<button", ' type="button" class="', '"', ">
2315
2315
  function $b0477e4d832f090e$export$ca21a16d65b3dd8(_ref) {
2316
2316
  let {
2317
2317
  show_extras_: [get_show_extras, set_show_extras],
2318
- i18n_: i18n_
2318
+ i18n_: i18n_,
2319
+ expanding_container_element_: expanding_container_element_
2319
2320
  } = _ref;
2321
+ let button;
2320
2322
  return $3hooq$solidjsweb.ssr($b0477e4d832f090e$var$_tmpl$, $3hooq$solidjsweb.ssrHydrationKey(), "expand-filter ".concat(get_show_extras() ? "expanded" : ""), $3hooq$solidjsweb.ssrAttribute("aria-expanded", $3hooq$solidjsweb.escape(get_show_extras(), true), false), $3hooq$solidjsweb.escape($3hooq$solidjsweb.createComponent((0, $a904ccf883f60231$export$f21ab0717a89c77f), {})), get_show_extras() ? $3hooq$solidjsweb.escape(i18n_.view_less_()) : $3hooq$solidjsweb.escape(i18n_.view_more_()));
2321
2323
  }
2322
2324
  var $23c3f390dee33ff8$var$_tmpl$ = ["<span", ' class="highlighted-part">', "</span>"],
@@ -2478,7 +2480,8 @@ function $9b54b9c5381716eb$export$dd948f91abc3a1c4(_ref) {
2478
2480
  $3hooq$solidjs.createRenderEffect(() => {
2479
2481
  set_view_more_button_below_group_(togglable_rest() ? $3hooq$solidjsweb.createComponent((0, $b0477e4d832f090e$export$ca21a16d65b3dd8), {
2480
2482
  show_extras_: show_extras_signal,
2481
- i18n_: i18n_
2483
+ i18n_: i18n_,
2484
+ expanding_container_element_: expanding_container_els
2482
2485
  }) : []);
2483
2486
  });
2484
2487
  $3hooq$solidjs.onCleanup(() => set_view_more_button_below_group_());
@@ -3195,7 +3198,8 @@ function $9c1d49181fb3002a$export$a32086fa6616eafd(_ref) {
3195
3198
  $3hooq$solidjs.createRenderEffect(() => {
3196
3199
  set_view_more_button_below_group(some_top_level_are_hidden() ? $3hooq$solidjsweb.createComponent((0, $b0477e4d832f090e$export$ca21a16d65b3dd8), {
3197
3200
  show_extras_: show_extras,
3198
- i18n_: i18n_
3201
+ i18n_: i18n_,
3202
+ expanding_container_element_: expanding_container_els
3199
3203
  }) : []);
3200
3204
  });
3201
3205
  $3hooq$solidjs.onCleanup(() => set_view_more_button_below_group());
@@ -3921,7 +3925,8 @@ function $476a3dc36afc1938$export$82ed4b28ecb67608(_ref) {
3921
3925
  $3hooq$solidjs.createRenderEffect(() => {
3922
3926
  set_view_more_button_below_group_(togglable_rest() ? $3hooq$solidjsweb.createComponent((0, $b0477e4d832f090e$export$ca21a16d65b3dd8), {
3923
3927
  show_extras_: show_extras_signal,
3924
- i18n_: i18n_
3928
+ i18n_: i18n_,
3929
+ expanding_container_element_: expanding_container_els
3925
3930
  }) : []);
3926
3931
  });
3927
3932
  $3hooq$solidjs.onCleanup(() => set_view_more_button_below_group_());
@@ -5004,8 +5009,8 @@ var $ae261a5687fe84f4$var$_tmpl$ = ["<svg", ' xmlns="http://www.w3.org/2000/svg"
5004
5009
  function $ae261a5687fe84f4$export$cb808a3c41736d8e() {
5005
5010
  return $3hooq$solidjsweb.ssr($ae261a5687fe84f4$var$_tmpl$, $3hooq$solidjsweb.ssrHydrationKey());
5006
5011
  }
5007
- var $f70cc6dfcadf0fd5$var$_tmpl$ = ["<div", ' class="filters"><div class="body">', "</div></div>"],
5008
- $f70cc6dfcadf0fd5$var$_tmpl$2 = ["<div", ' class="sorting"><div class="body">', "</div></div>"],
5012
+ var $f70cc6dfcadf0fd5$var$_tmpl$ = ["<section", ' class="filters"', '><div class="body">', "</div></section>"],
5013
+ $f70cc6dfcadf0fd5$var$_tmpl$2 = ["<section", ' class="sorting"', '><div class="body">', "</div></section>"],
5009
5014
  $f70cc6dfcadf0fd5$var$_tmpl$3 = ["<div", ' class="sort-and-filter-buttons"><div class="outer"><div class="inner"><!--$-->', "<!--/--><!--$-->", "<!--/--><!--$-->", "<!--/--></div></div></div>"],
5010
5015
  $f70cc6dfcadf0fd5$var$_tmpl$4 = ["<span", ' class="num-filters" style="', '">', "</span>"],
5011
5016
  $f70cc6dfcadf0fd5$var$_tmpl$5 = ["<div", ' class="open-filters-button-container" style="', '"><!--$-->', "<!--/--><button", ' class="', '" type="button"', ' style="', '"><!--$-->', "<!--/--><span>", "</span></button></div>"],
@@ -5082,6 +5087,27 @@ function $f70cc6dfcadf0fd5$export$d7841e452f2e59a8(_ref) {
5082
5087
  available_sortings_: available_sortings_,
5083
5088
  meta_of_currently_selected_sorting_: meta_of_currently_selected_sorting_
5084
5089
  };
5090
+ // Keyboard accessibility for the desktop panels (rendered after the product grid in the DOM): when the user
5091
+ // opens a panel we move focus into it, and restore focus to the toggle button on close. Intent is tracked with
5092
+ // a plain flag set in the buttons' click handlers - `filters_open`/`sorting_open` also change programmatically
5093
+ // (undo toast, history-state restore, SDK consumers), and those must not steal focus.
5094
+ let user_opened_panel = false;
5095
+ let filter_toggle_button;
5096
+ let sort_toggle_button;
5097
+ let current_panel;
5098
+ let current_panel_toggle_button;
5099
+ const focus_panel_when_in_dom = panel => $3hooq$depictaiutilishared.catchify(async () => {
5100
+ // Bounded wait: if the panel never lands in the DOM (e.g. it's superseded by a rapid re-render before
5101
+ // insertion), the timeout lets this promise resolve instead of keeping `panel` - and the observer
5102
+ // listener it registers - referenced forever.
5103
+ await (0, $3hooq$depictaiutilishared.observer).wait_for_element(panel, 4000);
5104
+ if (panel.isConnected) panel.focus();
5105
+ })();
5106
+ const register_desktop_panel = (el, toggle_button, should_focus) => {
5107
+ current_panel = el;
5108
+ current_panel_toggle_button = toggle_button;
5109
+ if (should_focus) focus_panel_when_in_dom(el);
5110
+ };
5085
5111
  const make_open_filters_button = function () {
5086
5112
  let adhere_to_width = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
5087
5113
  let is_tabbable = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
@@ -5092,7 +5118,9 @@ function $f70cc6dfcadf0fd5$export$d7841e452f2e59a8(_ref) {
5092
5118
  search_sorting_open_: search_sorting_open_,
5093
5119
  number_of_rendered_selected_filters_items_: number_of_rendered_selected_filters_items_,
5094
5120
  filter_button_width_: adhere_to_width ? filter_button_width_ : undefined,
5095
- hide_button_: hide_filters
5121
+ hide_button_: hide_filters,
5122
+ on_user_open_: () => user_opened_panel = true,
5123
+ button_ref_: is_tabbable ? el => filter_toggle_button = el : undefined
5096
5124
  });
5097
5125
  };
5098
5126
  const make_open_sorting_button = function () {
@@ -5106,7 +5134,9 @@ function $f70cc6dfcadf0fd5$export$d7841e452f2e59a8(_ref) {
5106
5134
  search_sorting_open_: search_sorting_open_,
5107
5135
  available_sortings_: available_sortings_,
5108
5136
  sort_button_width_: adhere_to_width ? sort_button_width_ : undefined,
5109
- meta_of_currently_selected_sorting_: meta_of_currently_selected_sorting_
5137
+ meta_of_currently_selected_sorting_: meta_of_currently_selected_sorting_,
5138
+ on_user_open_: () => user_opened_panel = true,
5139
+ button_ref_: is_tabbable ? el => sort_toggle_button = el : undefined
5110
5140
  });
5111
5141
  };
5112
5142
  let open_modal_;
@@ -5126,10 +5156,35 @@ function $f70cc6dfcadf0fd5$export$d7841e452f2e59a8(_ref) {
5126
5156
  grid_is_in_original_state = true;
5127
5157
  }
5128
5158
  });
5159
+ // Restore focus to the relevant toggle button when a desktop panel is torn down while focus is still inside it.
5160
+ const restore_focus_to_toggle_on_close = () => {
5161
+ const button_to_restore = current_panel_toggle_button;
5162
+ const focus_was_in_panel = !!current_panel && current_panel.contains(document.activeElement);
5163
+ current_panel = undefined;
5164
+ current_panel_toggle_button = undefined;
5165
+ if (focus_was_in_panel) button_to_restore === null || button_to_restore === void 0 || button_to_restore.focus();
5166
+ };
5167
+ // `<section>` + `aria-label` so the panel announces itself ("Filters"/"Sort") when we move focus to it; the bare
5168
+ // tabindex=-1 container would otherwise give screen readers nothing to read on focus. A semantic <section> avoids
5169
+ // an ARIA role and the UA styling pitfalls of <fieldset>; the existing CSS targets the `.filters`/`.sorting` class.
5170
+ const FiltersPanel = should_focus => $3hooq$solidjsweb.createComponent((0, $3hooq$solidjs.Show), {
5171
+ get when() {
5172
+ return !hide_filters();
5173
+ },
5174
+ get children() {
5175
+ return $3hooq$solidjsweb.ssr($f70cc6dfcadf0fd5$var$_tmpl$, $3hooq$solidjsweb.ssrHydrationKey(), $3hooq$solidjsweb.ssrAttribute("tabindex", -1, false) + $3hooq$solidjsweb.ssrAttribute("aria-label", $3hooq$solidjsweb.escape(i18n_.filters_(), true), false), $3hooq$solidjsweb.escape($3hooq$solidjsweb.createComponent((0, $164d474fea221d77$export$3f1a388cc0d8fed7), filter_options)));
5176
+ }
5177
+ });
5178
+ const SortingPanel = should_focus => $3hooq$solidjsweb.ssr($f70cc6dfcadf0fd5$var$_tmpl$2, $3hooq$solidjsweb.ssrHydrationKey(), $3hooq$solidjsweb.ssrAttribute("tabindex", -1, false) + $3hooq$solidjsweb.ssrAttribute("aria-label", $3hooq$solidjsweb.escape(i18n_.sorting_text_(), true), false), $3hooq$solidjsweb.escape($3hooq$solidjsweb.createComponent((0, $3bd211c857f81dfd$export$1f1775a58da589b5), sorting_options)));
5129
5179
  $3hooq$solidjs.createEffect(() => {
5180
+ // Consume the user-intent flag once per run, in every branch, so a stale flag can't leak into a later
5181
+ // resize-triggered re-render and steal focus.
5182
+ const should_focus_panel = user_opened_panel;
5183
+ user_opened_panel = false;
5130
5184
  if (!filters_open() && !sorting_open()) {
5131
5185
  var _close_modal_;
5132
5186
  (_close_modal_ = close_modal_) === null || _close_modal_ === void 0 || _close_modal_();
5187
+ restore_focus_to_toggle_on_close();
5133
5188
  set_extra_els_in_results_container_("");
5134
5189
  } else if (isSmall()()) {
5135
5190
  var _open_modal_;
@@ -5139,19 +5194,15 @@ function $f70cc6dfcadf0fd5$export$d7841e452f2e59a8(_ref) {
5139
5194
  set_sorting_open(false);
5140
5195
  return;
5141
5196
  }
5197
+ // The modal manages its own focus; just drop the desktop panel reference.
5198
+ current_panel = undefined;
5199
+ current_panel_toggle_button = undefined;
5142
5200
  (_open_modal_ = open_modal_) === null || _open_modal_ === void 0 || _open_modal_();
5143
5201
  set_extra_els_in_results_container_("");
5144
5202
  } else {
5145
5203
  var _close_modal_2;
5146
5204
  (_close_modal_2 = close_modal_) === null || _close_modal_2 === void 0 || _close_modal_2();
5147
- if (filters_open()) set_extra_els_in_results_container_(() => $3hooq$solidjsweb.createComponent((0, $3hooq$solidjs.Show), {
5148
- get when() {
5149
- return !hide_filters();
5150
- },
5151
- get children() {
5152
- return $3hooq$solidjsweb.ssr($f70cc6dfcadf0fd5$var$_tmpl$, $3hooq$solidjsweb.ssrHydrationKey(), $3hooq$solidjsweb.escape($3hooq$solidjsweb.createComponent((0, $164d474fea221d77$export$3f1a388cc0d8fed7), filter_options)));
5153
- }
5154
- }));else set_extra_els_in_results_container_($3hooq$solidjsweb.ssr($f70cc6dfcadf0fd5$var$_tmpl$2, $3hooq$solidjsweb.ssrHydrationKey(), $3hooq$solidjsweb.escape($3hooq$solidjsweb.createComponent((0, $3bd211c857f81dfd$export$1f1775a58da589b5), sorting_options))));
5205
+ if (filters_open()) set_extra_els_in_results_container_(() => FiltersPanel(should_focus_panel));else set_extra_els_in_results_container_(SortingPanel(should_focus_panel));
5155
5206
  }
5156
5207
  });
5157
5208
  $3hooq$depictaiutilishared.catchify(async () => {
@@ -5202,7 +5253,9 @@ function $f70cc6dfcadf0fd5$var$OpenFiltersButton(_ref3) {
5202
5253
  filter_button_width_: filter_button_width_,
5203
5254
  tabindex_: tabindex_,
5204
5255
  number_of_rendered_selected_filters_items_: [num_selected_filters],
5205
- hide_button_: hide_button_
5256
+ hide_button_: hide_button_,
5257
+ on_user_open_: on_user_open_,
5258
+ button_ref_: button_ref_
5206
5259
  } = _ref3;
5207
5260
  const filters_closed = $3hooq$solidjs.createMemo(() => !search_filters_open_[0]());
5208
5261
  // We assume in embedded_num_products that this is a single HTMLElement so pls change there if you change it here
@@ -5215,7 +5268,7 @@ function $f70cc6dfcadf0fd5$var$OpenFiltersButton(_ref3) {
5215
5268
  get children() {
5216
5269
  return $3hooq$solidjsweb.ssr($f70cc6dfcadf0fd5$var$_tmpl$4, $3hooq$solidjsweb.ssrHydrationKey(), $3hooq$solidjsweb.ssrStyle(filters_closed() ? "" : "opacity:0"), $3hooq$solidjsweb.escape(num_selected_filters()));
5217
5270
  }
5218
- })), $3hooq$solidjsweb.ssrAttribute("tabindex", $3hooq$solidjsweb.escape(tabindex_, true), false), "".concat(!filters_closed() ? "major" : "", " ").concat(filters_closed() ? "minor" : "").concat("filter toggle-button major-minor-transition" + ((0, $3hooq$solidjsweb.isServer) ? " minor" : "")), $3hooq$solidjsweb.ssrAttribute("aria-label", $3hooq$solidjsweb.escape((filters_closed() ? i18n_.open_filters_ : i18n_.close_filters_)(), true), false), $3hooq$solidjsweb.ssrStyle(filter_button_width_ !== null && filter_button_width_ !== void 0 && filter_button_width_() ? {
5271
+ })), $3hooq$solidjsweb.ssrAttribute("tabindex", $3hooq$solidjsweb.escape(tabindex_, true), false), "".concat(!filters_closed() ? "major" : "", " ").concat(filters_closed() ? "minor" : "").concat("filter toggle-button major-minor-transition" + ((0, $3hooq$solidjsweb.isServer) ? " minor" : "")), $3hooq$solidjsweb.ssrAttribute("aria-label", $3hooq$solidjsweb.escape((filters_closed() ? i18n_.open_filters_ : i18n_.close_filters_)(), true), false) + $3hooq$solidjsweb.ssrAttribute("aria-expanded", !filters_closed(), false), $3hooq$solidjsweb.ssrStyle(filter_button_width_ !== null && filter_button_width_ !== void 0 && filter_button_width_() ? {
5219
5272
  width: filter_button_width_() + "px"
5220
5273
  } : {}), $3hooq$solidjsweb.escape($3hooq$solidjsweb.createComponent((0, $3hooq$solidjs.Show), {
5221
5274
  get when() {
@@ -5239,11 +5292,13 @@ function $f70cc6dfcadf0fd5$var$OpenSortingButton(_ref4) {
5239
5292
  search_sorting_open_: search_sorting_open_,
5240
5293
  sort_button_width_: sort_button_width_,
5241
5294
  tabindex_: tabindex_,
5242
- meta_of_currently_selected_sorting_: meta_of_currently_selected_sorting_
5295
+ meta_of_currently_selected_sorting_: meta_of_currently_selected_sorting_,
5296
+ on_user_open_: on_user_open_,
5297
+ button_ref_: button_ref_
5243
5298
  } = _ref4;
5244
5299
  const sorting_closed = $3hooq$solidjs.createMemo(() => !search_sorting_open_[0]());
5245
5300
  // We assume in embedded_num_products that this is a single HTMLElement so pls change there if you change it here
5246
- return $3hooq$solidjsweb.ssr($f70cc6dfcadf0fd5$var$_tmpl$6, $3hooq$solidjsweb.ssrHydrationKey(), "".concat(!sorting_closed() ? "major" : "", " ").concat(sorting_closed() ? "minor" : "", " toggle-button for-sorting major-minor-transition"), $3hooq$solidjsweb.ssrAttribute("tabindex", $3hooq$solidjsweb.escape(tabindex_, true), false) + $3hooq$solidjsweb.ssrAttribute("aria-label", $3hooq$solidjsweb.escape((sorting_closed() ? i18n_.open_sorting_ : i18n_.close_sorting_)(), true), false), $3hooq$solidjsweb.ssrStyle(sort_button_width_ !== null && sort_button_width_ !== void 0 && sort_button_width_() ? {
5301
+ return $3hooq$solidjsweb.ssr($f70cc6dfcadf0fd5$var$_tmpl$6, $3hooq$solidjsweb.ssrHydrationKey(), "".concat(!sorting_closed() ? "major" : "", " ").concat(sorting_closed() ? "minor" : "", " toggle-button for-sorting major-minor-transition"), $3hooq$solidjsweb.ssrAttribute("tabindex", $3hooq$solidjsweb.escape(tabindex_, true), false) + $3hooq$solidjsweb.ssrAttribute("aria-label", $3hooq$solidjsweb.escape((sorting_closed() ? i18n_.open_sorting_ : i18n_.close_sorting_)(), true), false) + $3hooq$solidjsweb.ssrAttribute("aria-expanded", !sorting_closed(), false), $3hooq$solidjsweb.ssrStyle(sort_button_width_ !== null && sort_button_width_ !== void 0 && sort_button_width_() ? {
5247
5302
  width: sort_button_width_() + "px"
5248
5303
  } : {}),
5249
5304
  // Show the title of the currently selected sorting when the sorting is closed, if there's currently a sorting selected
@@ -11,7 +11,7 @@ import { GetListingRequest } from "@depict-ai/types/api/GetListingRequest";
11
11
  import { BaseSearchRequestV3 } from "@depict-ai/types/api/BaseSearchRequestV3";
12
12
  import { FeaturedInDisplay } from "@depict-ai/types/api/FeaturedInResponseV3";
13
13
  import { SearchFilter as _SearchFilter3 } from "@depict-ai/types/api/SearchRequestV2";
14
- export const version = "4.10.13";
14
+ export const version = "4.10.14";
15
15
  /**
16
16
  * Use `javascript_media_query` but return a reactive accessor instead of taking a callback function
17
17
  */