@depict-ai/ui 4.10.19 → 4.10.21

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/ES10/index.js CHANGED
@@ -10,7 +10,7 @@ import $8tj43$babelruntimehelpersclassPrivateFieldGet from "@babel/runtime/helpe
10
10
  /*! Depict.ai search and product listing SDK */
11
11
  import { register_es_version } from "../multi_import_deduplicator.mjs";
12
12
  register_es_version("ui", "ES10");
13
- const $8db9a15135765c11$export$83d89fbfd8236492 = "4.10.19";
13
+ const $8db9a15135765c11$export$83d89fbfd8236492 = "4.10.21";
14
14
  function $00a5b94f0c11efbb$export$d9f36cf74e24d595(media_query) {
15
15
  const signal = $8tj43$createSignal(false);
16
16
  $8tj43$onCleanup($8tj43$javascript_media_query(media_query, _ref => {
@@ -2573,6 +2573,63 @@ function $4711a82d08d2021b$export$fecbb157621501bd(_ref) {
2573
2573
  return outmost_element;
2574
2574
  }
2575
2575
  $8tj43$delegateEvents(["click"]);
2576
+
2577
+ /**
2578
+ * `HTMLElement.focus()` is a **silent no-op** on an element that is not being rendered
2579
+ * (`display: none`, `visibility: hidden`, a collapsed menu). Nothing throws, focus simply
2580
+ * stays where it was, so a caller that does not check believes it restored focus when it
2581
+ * left it on `<body>` — which puts the keyboard user back at the top of the document.
2582
+ *
2583
+ * That is reachable whenever the element which opened a modal stops being rendered while the
2584
+ * modal is open, and the common way for that to happen is the responsive-duplicate header:
2585
+ * a theme renders the same search trigger twice, once for desktop and once for mobile, and
2586
+ * hides one at the current breakpoint. Open the modal from the desktop trigger, cross the
2587
+ * breakpoint (rotate a tablet, resize a window), close the modal, and the remembered trigger
2588
+ * is still `isConnected` but no longer rendered. Verified against a live merchant storefront
2589
+ * on 4.10.19.
2590
+ *
2591
+ * So: verify that focus landed, and when it did not, look for a rendered twin of the same
2592
+ * control — the other half of the responsive pair — and use that instead.
2593
+ */ /**
2594
+ * An element can only take focus if it is actually being rendered.
2595
+ *
2596
+ * Injectable because it is the one part of this module that needs a layout engine: jsdom
2597
+ * reports no client rects for anything, so the specs pass their own predicate to exercise the
2598
+ * matching rules. The real predicate is only exercised in a browser.
2599
+ */
2600
+ const $1c5106dfe72d554c$export$e0652711c614c755 = element => !!element.getClientRects().length;
2601
+ /**
2602
+ * `document.activeElement` is the outermost shadow host when focus is inside a shadow tree,
2603
+ * so ask the element's own root rather than the document — matching how the rest of
2604
+ * modal_opener treats shadow-mounted modals.
2605
+ */
2606
+ const $1c5106dfe72d554c$var$has_focus = element => element.getRootNode().activeElement === element;
2607
+ /**
2608
+ * The accessible-name-ish identity we match twins on. Deliberately narrow: an explicit label
2609
+ * or the trimmed text. Two controls that share a tag and this string are the same control
2610
+ * rendered twice, which is exactly the responsive-duplicate case.
2611
+ */
2612
+ const $1c5106dfe72d554c$var$identity_of = element => (element.getAttribute("aria-label") || element.getAttribute("title") || element.textContent || "").trim().replace(/\s+/g, " ");
2613
+ function $1c5106dfe72d554c$export$5800d9d535a06e96(element) {
2614
+ let rendered = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : $1c5106dfe72d554c$export$e0652711c614c755;
2615
+ const identity = $1c5106dfe72d554c$var$identity_of(element);
2616
+ if (!identity) return; // nothing to match on — an icon-only button with no label
2617
+ const twins = [...element.ownerDocument.querySelectorAll(element.localName)].filter(candidate => candidate !== element && rendered(candidate) && $1c5106dfe72d554c$var$identity_of(candidate) === identity);
2618
+ return twins.length === 1 ? twins[0] : undefined;
2619
+ }
2620
+ function $1c5106dfe72d554c$export$51461d633c351649(element) {
2621
+ let rendered = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : $1c5106dfe72d554c$export$e0652711c614c755;
2622
+ element.focus({
2623
+ preventScroll: true
2624
+ });
2625
+ if ($1c5106dfe72d554c$var$has_focus(element)) return true;
2626
+ const twin = $1c5106dfe72d554c$export$5800d9d535a06e96(element, rendered);
2627
+ if (!twin) return false;
2628
+ twin.focus({
2629
+ preventScroll: true
2630
+ });
2631
+ return $1c5106dfe72d554c$var$has_focus(twin);
2632
+ }
2576
2633
  async function $d5f1e6a0f9117286$export$79b1565500412d9b(search_modal, modal_fn_opts, parent) {
2577
2634
  const body = parent || document.body || (await (0, $8tj43$observer).wait_for_element("body"));
2578
2635
  let dispose_and_remove;
@@ -2604,8 +2661,10 @@ async function $d5f1e6a0f9117286$export$79b1565500412d9b(search_modal, modal_fn_
2604
2661
  const modal_els = $8tj43$createRoot(dispose => {
2605
2662
  let closing_animation;
2606
2663
  let animation_started;
2664
+ let focus_target_after_close;
2607
2665
  dispose_and_remove = () => {
2608
2666
  const actually_close = () => {
2667
+ var _focus_target_after_c;
2609
2668
  dispose();
2610
2669
  on_dispose === null || on_dispose === void 0 || on_dispose();
2611
2670
  const {
@@ -2624,13 +2683,24 @@ async function $d5f1e6a0f9117286$export$79b1565500412d9b(search_modal, modal_fn_
2624
2683
  }
2625
2684
  el.remove();
2626
2685
  });
2627
- if (should_restore_focus && element_focused_before_open !== null && element_focused_before_open !== void 0 && element_focused_before_open.isConnected) {
2686
+ const requested_focus_target = (_focus_target_after_c = focus_target_after_close) === null || _focus_target_after_c === void 0 ? void 0 : _focus_target_after_c();
2687
+ if (should_restore_focus && (requested_focus_target !== null && requested_focus_target !== void 0 && requested_focus_target.isConnected || element_focused_before_open !== null && element_focused_before_open !== void 0 && element_focused_before_open.isConnected)) {
2628
2688
  restoring_focus = true;
2629
2689
  try {
2630
2690
  // preventScroll so this can't re-introduce the safari page-jump the blur() above works around
2631
- element_focused_before_open.focus({
2632
- preventScroll: true
2633
- });
2691
+ let focused = false;
2692
+ if (requested_focus_target !== null && requested_focus_target !== void 0 && requested_focus_target.isConnected) {
2693
+ requested_focus_target.focus({
2694
+ preventScroll: true
2695
+ });
2696
+ focused = requested_focus_target.getRootNode().activeElement === requested_focus_target;
2697
+ }
2698
+ if (!focused && element_focused_before_open !== null && element_focused_before_open !== void 0 && element_focused_before_open.isConnected)
2699
+ // restore_focus_to rather than a bare focus(): the remembered trigger can be
2700
+ // connected but no longer rendered (a responsive-duplicate header whose other
2701
+ // half is showing now), and focus() on an unrendered element silently does
2702
+ // nothing, leaving the keyboard user at the top of the page.
2703
+ $1c5106dfe72d554c$export$51461d633c351649(element_focused_before_open);
2634
2704
  } finally {
2635
2705
  // Cleared on a task instead of synchronously in case a browser delivers the focus event async
2636
2706
  setTimeout(() => restoring_focus = false, 0);
@@ -2650,7 +2720,8 @@ async function $d5f1e6a0f9117286$export$79b1565500412d9b(search_modal, modal_fn_
2650
2720
  ...extra_options_for_modal,
2651
2721
  close_modal_: close_modal_,
2652
2722
  open_modal_: open_modal_,
2653
- register_closing_animation_: animation => closing_animation = animation
2723
+ register_closing_animation_: animation => closing_animation = animation,
2724
+ set_focus_target_after_close_: get_target => focus_target_after_close = get_target
2654
2725
  });
2655
2726
  });
2656
2727
  body.append(...modal_els);
@@ -9672,20 +9743,28 @@ function $ac571292d606f30b$var$_classPrivateMethodGet(receiver, privateSet, fn)
9672
9743
  }
9673
9744
  var $ac571292d606f30b$var$_throwing_on_navigation = /*#__PURE__*/new WeakSet();
9674
9745
  var $ac571292d606f30b$var$_get_navigation_happened_promise = /*#__PURE__*/new WeakSet();
9746
+ var $ac571292d606f30b$var$_watch_for_navigation_to_same_href = /*#__PURE__*/new WeakSet();
9675
9747
  class $ac571292d606f30b$export$7e1297a3a19f10d8 {
9676
9748
  /**
9677
9749
  * Function that will be called when we want to navigate, or a string saying it's not an SPA. You can change this OTG
9678
9750
  */ /**
9679
9751
  * We store listing_id in history.state and do operate on this both here and in js-ui, this is the key to be used which js-ui provides
9680
9752
  */ /**
9681
- * Vue has async router that needs to be awaited (it navigates after a microtask)
9682
- * This standardises waiting for all kinds of routers
9683
- */
9753
+ * Called when a go_to_ didn't change location.href, for example when following a link to the page one is already on. href_change_ipns stays silent then, so whoever waits for a href change to react to a navigation has to listen here too
9754
+ */ /**
9755
+ * Vue has async router that needs to be awaited (it navigates after a microtask)
9756
+ * This standardises waiting for all kinds of routers
9757
+ */ /**
9758
+ * Calls navigation_to_same_href_listeners_ if the navigation we're about to request ends on the href we're already on
9759
+ * @returns function to stop watching, call it when the navigation failed
9760
+ */
9684
9761
  constructor(on_navigation, listing_query_state_key) {
9762
+ $ac571292d606f30b$var$_classPrivateMethodInitSpec(this, $ac571292d606f30b$var$_watch_for_navigation_to_same_href);
9685
9763
  $ac571292d606f30b$var$_classPrivateMethodInitSpec(this, $ac571292d606f30b$var$_get_navigation_happened_promise);
9686
9764
  $ac571292d606f30b$var$_classPrivateMethodInitSpec(this, $ac571292d606f30b$var$_throwing_on_navigation);
9687
9765
  $8tj43$babelruntimehelpersdefineProperty(this, "on_navigation_", void 0);
9688
9766
  $8tj43$babelruntimehelpersdefineProperty(this, "listing_query_state_key", void 0);
9767
+ $8tj43$babelruntimehelpersdefineProperty(this, "navigation_to_same_href_listeners_", new Set());
9689
9768
  $8tj43$babelruntimehelpersdefineProperty(this, "navigate_", {
9690
9769
  /**
9691
9770
  * Call this if you *just* want to replace the state object in history.state
@@ -9727,6 +9806,7 @@ class $ac571292d606f30b$export$7e1297a3a19f10d8 {
9727
9806
  }
9728
9807
  event_ === null || event_ === void 0 || event_.preventDefault();
9729
9808
  const promise = $ac571292d606f30b$var$_classPrivateMethodGet(this, $ac571292d606f30b$var$_get_navigation_happened_promise, $ac571292d606f30b$var$_get_navigation_happened_promise2).call(this, true);
9809
+ const stop_watching_for_same_href = $ac571292d606f30b$var$_classPrivateMethodGet(this, $ac571292d606f30b$var$_watch_for_navigation_to_same_href, $ac571292d606f30b$var$_watch_for_navigation_to_same_href2).call(this, new_url_);
9730
9810
  if (force_spa_navigation_ && wants_hard_navigation) {
9731
9811
  // Don't allow hard navigation if we're forcing SPA navigation, which we do for things where PageReplacer can be used for performance
9732
9812
  const new_state = history.state;
@@ -9740,7 +9820,7 @@ class $ac571292d606f30b$export$7e1297a3a19f10d8 {
9740
9820
  is_replace: is_replace_,
9741
9821
  new_url: new_url_ instanceof URL ? new_url_ : new URL(new_url_, location.href),
9742
9822
  scroll: scroll
9743
- });
9823
+ }, stop_watching_for_same_href);
9744
9824
  await promise;
9745
9825
  })
9746
9826
  });
@@ -9748,15 +9828,16 @@ class $ac571292d606f30b$export$7e1297a3a19f10d8 {
9748
9828
  this.on_navigation_ = on_navigation;
9749
9829
  }
9750
9830
  }
9751
- function $ac571292d606f30b$var$_throwing_on_navigation2() {
9831
+ function $ac571292d606f30b$var$_throwing_on_navigation2(options, on_throw_) {
9752
9832
  const {
9753
9833
  on_navigation_: on_navigation_
9754
9834
  } = this;
9755
9835
  if (typeof on_navigation_ !== "function") throw new Error("on_navigation_ is not a function");
9756
9836
  // make sure that we don't accidentally catchify if the SDK consumer has fucked up
9757
9837
  try {
9758
- return on_navigation_(...arguments);
9838
+ return on_navigation_(options);
9759
9839
  } catch (e) {
9840
+ on_throw_ === null || on_throw_ === void 0 || on_throw_();
9760
9841
  queueMicrotask(() => {
9761
9842
  throw e;
9762
9843
  });
@@ -9773,6 +9854,24 @@ function $ac571292d606f30b$var$_get_navigation_happened_promise2(is_replace) {
9773
9854
  (0, $8tj43$instant_exec_on_suspect_history_change).add(handler);
9774
9855
  });
9775
9856
  }
9857
+ function $ac571292d606f30b$var$_watch_for_navigation_to_same_href2(target_url) {
9858
+ const href_before = location.href;
9859
+ const stop_watching = () => {
9860
+ (0, $8tj43$instant_exec_on_suspect_history_change).delete(on_history_change);
9861
+ clearTimeout(timeout);
9862
+ };
9863
+ const notify_if_href_unchanged = $8tj43$catchify1(() => {
9864
+ stop_watching();
9865
+ if (location.href !== href_before) return;
9866
+ this.navigation_to_same_href_listeners_.forEach(listener => $8tj43$catchify1(listener)());
9867
+ });
9868
+ // The router has acted once it touches history, if the href is still the same then it took us to the page we're on
9869
+ const on_history_change = () => notify_if_href_unchanged();
9870
+ // A router asked to go to the exact href we're on might not touch history at all, so don't wait longer than 500ms for it. For any other target we can't tell a slow navigation from one that goes nowhere, so only stop listening after a while
9871
+ const timeout = target_url.href === href_before ? setTimeout(notify_if_href_unchanged, 500) : setTimeout(stop_watching, 10000);
9872
+ (0, $8tj43$instant_exec_on_suspect_history_change).add(on_history_change);
9873
+ return stop_watching;
9874
+ }
9776
9875
  var $e3efeb558d952696$var$_tmpl$ = /*#__PURE__*/$8tj43$template(`<button class="show-more major"type=button>`),
9777
9876
  $e3efeb558d952696$var$_tmpl$2 = /*#__PURE__*/$8tj43$template(`<h2 class=recs-title>`),
9778
9877
  $e3efeb558d952696$var$_tmpl$3 = /*#__PURE__*/$8tj43$template(`<div class=recommendation-grid><!$><!/><!$><!/>`);
@@ -11317,6 +11416,7 @@ var $584c06c09cf4609d$var$_tmpl$ = /*#__PURE__*/$8tj43$template(`<button class=b
11317
11416
  $584c06c09cf4609d$var$_tmpl$3 = /*#__PURE__*/$8tj43$template(`<div class=spacer>`),
11318
11417
  $584c06c09cf4609d$var$_tmpl$4 = /*#__PURE__*/$8tj43$template(`<button class="submit major"type=button>`),
11319
11418
  $584c06c09cf4609d$var$_tmpl$5 = /*#__PURE__*/$8tj43$template(`<div><!$><!/><!$><!/><div class=field><!$><!/><input class=query tabindex=0 enterkeyhint=search><!$><!/></div><!$><!/><!$><!/>`);
11419
+ const $584c06c09cf4609d$var$keys_not_opening_modal = new Set(["Tab", "Shift", "Control", "Alt", "AltGraph", "Meta", "CapsLock", "Escape", "ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "PageUp", "PageDown", "Home", "End", "Insert", "ContextMenu", "NumLock", "ScrollLock", "Pause", "PrintScreen"]);
11320
11420
  function $584c06c09cf4609d$export$b94867ecbd698f21(_ref) {
11321
11421
  let {
11322
11422
  search_field_value_: [searchFieldValue, setSearchFieldValue],
@@ -11499,7 +11599,7 @@ function $584c06c09cf4609d$export$b94867ecbd698f21(_ref) {
11499
11599
  get onKeyDown() {
11500
11600
  return $8tj43$catchify1(e => {
11501
11601
  if (disabled_) {
11502
- if (e.key !== "Tab" && e.key !== "Shift")
11602
+ if (!$584c06c09cf4609d$var$keys_not_opening_modal.has(e.key) && !/^F\d{1,2}$/.test(e.key))
11503
11603
  // alow tab-selecting the input field and then open the modal when the user start writing but also to move past the field with tab
11504
11604
  input_element.click();
11505
11605
  } else if (e.key === "Enter") {
@@ -11581,11 +11681,17 @@ var $fac58b5610eec6a9$var$_tmpl$ = /*#__PURE__*/$8tj43$template(`<svg xmlns=http
11581
11681
  function $fac58b5610eec6a9$export$8d8893ffd8aca39a() {
11582
11682
  return $8tj43$getNextElement($fac58b5610eec6a9$var$_tmpl$);
11583
11683
  }
11584
- function $a82a41ab7188eda2$export$93d9bfd0c9c1a5b8(close_modal, search_query_url_param_name_) {
11684
+ function $a82a41ab7188eda2$export$93d9bfd0c9c1a5b8(close_modal, search_query_url_param_name_, router_) {
11585
11685
  const [exit_iterable, exitable_iterable] = $8tj43$make_asyncIterable_exiter((0, $8tj43$href_change_ipns));
11686
+ const {
11687
+ navigation_to_same_href_listeners_: navigation_to_same_href_listeners_
11688
+ } = router_;
11586
11689
  let set_initial_values = false;
11587
11690
  let old_pathname;
11588
11691
  let old_param_value;
11692
+ // A card linking to the page one is already on doesn't change the href, close the modal anyway so the click does something
11693
+ navigation_to_same_href_listeners_.add(close_modal);
11694
+ $8tj43$onCleanup(() => navigation_to_same_href_listeners_.delete(close_modal));
11589
11695
  $8tj43$onCleanup($8tj43$catchify1(exit_iterable));
11590
11696
  $8tj43$catchify1(async () => {
11591
11697
  for await (const href of exitable_iterable) {
@@ -11604,6 +11710,33 @@ function $a82a41ab7188eda2$export$93d9bfd0c9c1a5b8(close_modal, search_query_url
11604
11710
  }
11605
11711
  })();
11606
11712
  }
11713
+ function $802b1d7ed155c277$export$9e9e2ae069cf2fe1(_ref) {
11714
+ let {
11715
+ props_search_field_value_: props_search_field_value_,
11716
+ props_submit_query_: props_submit_query_,
11717
+ dont_sync_search_field_value_except_on_submit_: dont_sync_search_field_value_except_on_submit_,
11718
+ set_focus_target_after_close_: set_focus_target_after_close_,
11719
+ get_search_page_input_element_: get_search_page_input_element_
11720
+ } = _ref;
11721
+ const search_field_value_ = dont_sync_search_field_value_except_on_submit_ ? $8tj43$createSignal("") : props_search_field_value_;
11722
+ let submits_in_flight = 0;
11723
+ const submit_query_ = async function () {
11724
+ let new_query = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : $8tj43$untrack(search_field_value_[0]);
11725
+ submits_in_flight++;
11726
+ try {
11727
+ return await props_submit_query_(new_query, () => set_focus_target_after_close_(get_search_page_input_element_));
11728
+ } finally {
11729
+ submits_in_flight--;
11730
+ }
11731
+ };
11732
+ if (dont_sync_search_field_value_except_on_submit_) $8tj43$createEffect($8tj43$on(search_field_value_[0], value => submits_in_flight > 0 && props_search_field_value_[1](value), {
11733
+ defer: true
11734
+ }));
11735
+ return {
11736
+ search_field_value_: search_field_value_,
11737
+ submit_query_: submit_query_
11738
+ };
11739
+ }
11607
11740
  var $40411f2ec772c376$var$_tmpl$ = /*#__PURE__*/$8tj43$template(`<div class=discover-more><button class=major type=button>`),
11608
11741
  $40411f2ec772c376$var$_tmpl$2 = /*#__PURE__*/$8tj43$template(`<b>`),
11609
11742
  $40411f2ec772c376$var$_tmpl$3 = /*#__PURE__*/$8tj43$template(`<div class=depict-search-modal><div class=body role=search aria-label="Search modal with search field, query suggestions and result preview"><!$><!/><div id=depict-suggestions-and-result-preview class=padded><!$><!/><!$><!/><!$><!/></div><!$><!/></div><!$><!/>`),
@@ -11618,6 +11751,8 @@ function $40411f2ec772c376$var$RawClassicSearchModal(_ref) {
11618
11751
  search_query_url_param_name_: search_query_url_param_name_,
11619
11752
  previous_searches_: previous_searches_,
11620
11753
  close_modal_: close_modal_,
11754
+ set_focus_target_after_close_: set_focus_target_after_close_,
11755
+ get_search_page_input_element_: get_search_page_input_element_,
11621
11756
  depict_api_: depict_api_,
11622
11757
  merchant_: merchant_,
11623
11758
  market_: market_,
@@ -11642,15 +11777,16 @@ function $40411f2ec772c376$var$RawClassicSearchModal(_ref) {
11642
11777
  // As per feedback from stronger we sometimes want a modal with the search field value disconnected from the one in the rest of the UI, see https://depictaiworkspace.slack.com/archives/C02J16R9XEH/p1679065878487709.
11643
11778
  // This is desired for when the modal is opened from a UI element that visually does not look connected with the search page or current query
11644
11779
  // Basically the UI signals that the button that opens the modal starts a new search.
11645
- const search_field_value_ = dont_sync_search_field_value_except_on_submit_ ? $8tj43$createSignal("") : props_search_field_value;
11646
- const propagate_search_field_value_back = dont_sync_search_field_value_except_on_submit_ ? () => props_search_field_value[1]($8tj43$untrack(search_field_value_[0])) // Set actual search field value to the throwaway internal one before submitting
11647
- : undefined;
11648
- const submit_query_ = function () {
11649
- // submit_query expects to read the current search field value which is why we have to write the current one to the signal before calling it
11650
- // It will write the old one back and then write the new one after submit
11651
- propagate_search_field_value_back === null || propagate_search_field_value_back === void 0 || propagate_search_field_value_back();
11652
- return props_submit_query(...arguments);
11653
- };
11780
+ const {
11781
+ search_field_value_: search_field_value_,
11782
+ submit_query_: submit_query_
11783
+ } = $802b1d7ed155c277$export$9e9e2ae069cf2fe1({
11784
+ props_search_field_value_: props_search_field_value,
11785
+ props_submit_query_: props_submit_query,
11786
+ dont_sync_search_field_value_except_on_submit_: dont_sync_search_field_value_except_on_submit_,
11787
+ set_focus_target_after_close_: set_focus_target_after_close_,
11788
+ get_search_page_input_element_: get_search_page_input_element_
11789
+ });
11654
11790
  const [input_field, set_input_field] = $8tj43$createSignal();
11655
11791
  const [get_search_field_value_] = search_field_value_;
11656
11792
  // Search field alignment unused in ClassicSearchModal since the search field spans the whole modal
@@ -11716,7 +11852,7 @@ function $40411f2ec772c376$var$RawClassicSearchModal(_ref) {
11716
11852
  return _el$;
11717
11853
  })();
11718
11854
  if (disable_scrolling_) $e56d241d0f33d459$export$fe334901e8bebd57();
11719
- $a82a41ab7188eda2$export$93d9bfd0c9c1a5b8(close_modal_, search_query_url_param_name_);
11855
+ $a82a41ab7188eda2$export$93d9bfd0c9c1a5b8(close_modal_, search_query_url_param_name_, router_);
11720
11856
  window.addEventListener("keydown", close_on_escape_handler);
11721
11857
  $8tj43$onCleanup($8tj43$catchify1(() => window.removeEventListener("keydown", close_on_escape_handler)));
11722
11858
  if (closing_animation_) register_closing_animation_(closing_animation_);
@@ -12482,6 +12618,8 @@ function $06fcd2a345efd24d$var$RawSearchModalV2(_ref) {
12482
12618
  search_query_url_param_name_: search_query_url_param_name_,
12483
12619
  previous_searches_: previous_searches_,
12484
12620
  close_modal_: close_modal_,
12621
+ set_focus_target_after_close_: set_focus_target_after_close_,
12622
+ get_search_page_input_element_: get_search_page_input_element_,
12485
12623
  alignmentSignals_: alignmentSignals_,
12486
12624
  depict_api_: depict_api_,
12487
12625
  merchant_: merchant_,
@@ -12512,15 +12650,16 @@ function $06fcd2a345efd24d$var$RawSearchModalV2(_ref) {
12512
12650
  // As per feedback from stronger we sometimes want a modal with the search field value disconnected from the one in the rest of the UI, see https://depictaiworkspace.slack.com/archives/C02J16R9XEH/p1679065878487709.
12513
12651
  // This is desired for when the modal is opened from a UI element that visually does not look connected with the search page or current query
12514
12652
  // Basically the UI signals that the button that opens the modal starts a new search.
12515
- const search_field_value_ = dont_sync_search_field_value_except_on_submit_ ? $8tj43$createSignal("") : props_search_field_value;
12516
- const propagate_search_field_value_back = dont_sync_search_field_value_except_on_submit_ ? () => props_search_field_value[1]($8tj43$untrack(search_field_value_[0])) // Set actual search field value to the throwaway internal one before submitting
12517
- : undefined;
12518
- const submit_query_ = function () {
12519
- // submit_query expects to read the current search field value which is why we have to write the current one to the signal before calling it
12520
- // It will write the old one back and then write the new one after submit
12521
- propagate_search_field_value_back === null || propagate_search_field_value_back === void 0 || propagate_search_field_value_back();
12522
- return props_submit_query(...arguments);
12523
- };
12653
+ const {
12654
+ search_field_value_: search_field_value_,
12655
+ submit_query_: submit_query_
12656
+ } = $802b1d7ed155c277$export$9e9e2ae069cf2fe1({
12657
+ props_search_field_value_: props_search_field_value,
12658
+ props_submit_query_: props_submit_query,
12659
+ dont_sync_search_field_value_except_on_submit_: dont_sync_search_field_value_except_on_submit_,
12660
+ set_focus_target_after_close_: set_focus_target_after_close_,
12661
+ get_search_page_input_element_: get_search_page_input_element_
12662
+ });
12524
12663
  const [input_field, set_input_field] = $8tj43$createSignal();
12525
12664
  const [searching_for_value_, set_searching_for_value_] = $8tj43$createSignal();
12526
12665
  const [show_stale_content_results_, set_show_stale_content_results_] = $8tj43$createSignal(false);
@@ -12634,7 +12773,7 @@ function $06fcd2a345efd24d$var$RawSearchModalV2(_ref) {
12634
12773
  return (((_get_modal_search_res5 = get_modal_search_results_()) === null || _get_modal_search_res5 === void 0 ? void 0 : _get_modal_search_res5.loading) === false && !suggestions_response_.loading || !!prev) && totalNumberResults() === 0 && previous_searches_matching_query().length === 0;
12635
12774
  });
12636
12775
  if (disable_scrolling_) $e56d241d0f33d459$export$fe334901e8bebd57();
12637
- $a82a41ab7188eda2$export$93d9bfd0c9c1a5b8(close_modal_, search_query_url_param_name_);
12776
+ $a82a41ab7188eda2$export$93d9bfd0c9c1a5b8(close_modal_, search_query_url_param_name_, router_);
12638
12777
  addEventListener("keydown", close_on_escape_handler);
12639
12778
  $8tj43$onCleanup(() => removeEventListener("keydown", close_on_escape_handler));
12640
12779
  $8tj43$createEffect($8tj43$on(get_search_field_value_, () => {
@@ -14838,11 +14977,12 @@ async function $86b0ff0c85e5fc6c$export$e16630ecb9644a1c(_ref) {
14838
14977
  let {
14839
14978
  on_submit_with_unchanged_value_: on_submit_with_unchanged_value_,
14840
14979
  search_param_name_: search_param_name_,
14841
- set_search_field_value_: set_search_field_value_,
14980
+ search_field_value_: search_field_value_,
14842
14981
  get_search_query_: get_search_query_,
14843
14982
  url_transformer_: url_transformer_,
14844
14983
  router_: router_,
14845
14984
  after_submit_: after_submit_,
14985
+ before_navigate_: before_navigate_,
14846
14986
  get_new_query: get_new_query
14847
14987
  } = _ref;
14848
14988
  const new_search_query = get_new_query();
@@ -14850,21 +14990,92 @@ async function $86b0ff0c85e5fc6c$export$e16630ecb9644a1c(_ref) {
14850
14990
  if (previous_query === new_search_query && new URLSearchParams(location.search).has(search_param_name_)) {
14851
14991
  // don't push a history entry / re-search if someone submits a search again
14852
14992
  // do close the modal though
14993
+ search_field_value_.settle_(new_search_query);
14853
14994
  on_submit_with_unchanged_value_ === null || on_submit_with_unchanged_value_ === void 0 || on_submit_with_unchanged_value_();
14854
- return;
14995
+ return false;
14855
14996
  }
14856
- set_search_field_value_(previous_query); // restore the value to the previous query since this one goes to the new history entry
14857
14997
  const target_url = new URL(location.href);
14858
14998
  url_transformer_ === null || url_transformer_ === void 0 || url_transformer_(target_url);
14859
14999
  target_url.searchParams.set(search_param_name_, new_search_query);
14860
- await router_.navigate_.go_to_({
14861
- new_url_: target_url,
14862
- is_replace_: false,
14863
- force_spa_navigation_: true
14864
- });
14865
- set_search_field_value_(new_search_query);
15000
+ const end_submit = search_field_value_.begin_submit_(new_search_query, previous_query);
15001
+ before_navigate_ === null || before_navigate_ === void 0 || before_navigate_();
15002
+ let landed;
15003
+ try {
15004
+ await router_.navigate_.go_to_({
15005
+ new_url_: target_url,
15006
+ is_replace_: false,
15007
+ force_spa_navigation_: true
15008
+ });
15009
+ } finally {
15010
+ landed = end_submit();
15011
+ }
15012
+ if (!landed) return false;
14866
15013
  scrollTo(0, 0);
14867
15014
  after_submit_ === null || after_submit_ === void 0 || after_submit_();
15015
+ return true;
15016
+ }
15017
+ function $8a9827cc2842b300$export$d13a185c53aa5edf(persisted_, get_search_query_) {
15018
+ const [get_persisted, set_persisted] = persisted_;
15019
+ const [get_submitting, set_submitting] = $8tj43$createSignal();
15020
+ const get_value = $8tj43$createMemo(() => {
15021
+ var _get_submitting;
15022
+ return (_get_submitting = get_submitting()) !== null && _get_submitting !== void 0 ? _get_submitting : get_persisted();
15023
+ });
15024
+ const set_value = value => {
15025
+ const new_value = typeof value === "function" ? value($8tj43$untrack(get_value)) : value;
15026
+ if ($8tj43$untrack(get_submitting) === undefined) set_persisted(new_value);else set_submitting(new_value);
15027
+ return new_value;
15028
+ };
15029
+ let current_submit;
15030
+ const end_submit = landed => {
15031
+ current_submit.landed_ = landed;
15032
+ current_submit = undefined;
15033
+ $8tj43$batch(() => {
15034
+ const submitting = $8tj43$untrack(get_submitting);
15035
+ set_submitting(undefined);
15036
+ if (landed && submitting !== undefined) set_persisted(submitting);
15037
+ });
15038
+ };
15039
+ const abort_on_popstate = what_happened => {
15040
+ if (what_happened === "popstate" && current_submit) end_submit(false);
15041
+ };
15042
+ (0, $8tj43$instant_exec_on_suspect_history_change).add(abort_on_popstate);
15043
+ $8tj43$onCleanup(() => (0, $8tj43$instant_exec_on_suspect_history_change).delete(abort_on_popstate));
15044
+ $8tj43$createEffect($8tj43$on(get_search_query_, query => {
15045
+ const token = current_submit;
15046
+ if (!token || query !== token.query_) return;
15047
+ queueMicrotask(() => {
15048
+ if (current_submit === token) end_submit(true);
15049
+ });
15050
+ }, {
15051
+ defer: true
15052
+ }));
15053
+ const begin_submit_ = (submitted_query, query_of_current_history_entry) => {
15054
+ const token = current_submit = {
15055
+ query_: submitted_query,
15056
+ landed_: false
15057
+ };
15058
+ $8tj43$batch(() => {
15059
+ set_submitting(submitted_query);
15060
+ set_persisted(query_of_current_history_entry);
15061
+ });
15062
+ return () => {
15063
+ if (current_submit === token) end_submit(true);
15064
+ return token.landed_;
15065
+ };
15066
+ };
15067
+ const settle_ = query => {
15068
+ if (current_submit) return;
15069
+ $8tj43$batch(() => {
15070
+ set_submitting(undefined);
15071
+ set_persisted(query);
15072
+ });
15073
+ };
15074
+ return {
15075
+ value_: [get_value, set_value],
15076
+ begin_submit_: begin_submit_,
15077
+ settle_: settle_
15078
+ };
14868
15079
  }
14869
15080
  function $96d57a48e7bce64f$export$181cceed5c91919e(callback, alsoRaF, passiveListener) {
14870
15081
  let aligned_this_microtask = false;
@@ -15608,6 +15819,7 @@ function $da279c5a540c6846$export$a54ec244c8863715(_ref) {
15608
15819
  scroll_restoration_data_: scroll_restoration_data_,
15609
15820
  product_card_template_: product_card_template_,
15610
15821
  modalAlignmentSignalsRef_: modalAlignmentSignalsRef_,
15822
+ inputFieldRef_: inputFieldRef_,
15611
15823
  router_: router_,
15612
15824
  content_results_rows_: content_results_rows_,
15613
15825
  content_layout_options_: content_layout_options_,
@@ -15812,6 +16024,8 @@ function $da279c5a540c6846$export$a54ec244c8863715(_ref) {
15812
16024
  if (!search_field) break add_input_field;
15813
16025
  setModalBodyStyle({});
15814
16026
  modalAlignmentSignalsRef_ === null || modalAlignmentSignalsRef_ === void 0 || modalAlignmentSignalsRef_(alignmentSignals_);
16027
+ inputFieldRef_ === null || inputFieldRef_ === void 0 || inputFieldRef_(input_element);
16028
+ $8tj43$onCleanup(() => inputFieldRef_ === null || inputFieldRef_ === void 0 ? void 0 : inputFieldRef_(undefined));
15815
16029
  const [pollAlignment, setPollAlignment_] = $8tj43$createSignal(false);
15816
16030
  const align_position = $8tj43$catchify1((0, $1308a7816c3d4f2d$export$b3ad617e9036868))(alignmentSignals_, search_field, (0, $1308a7816c3d4f2d$export$3f238c96c45e6cc6) | (0, $1308a7816c3d4f2d$export$7895aadd1956b1c7) | (modalVersionUsed_ === 1 ? (0, $1308a7816c3d4f2d$export$902f8b4a7dae5d78) : (0, $1308a7816c3d4f2d$export$6060bc6bee850eb6) | (0, $1308a7816c3d4f2d$export$5097308c5200105a)), true, pollAlignment);
15817
16031
  div_with_field_class.addEventListener("click", $8tj43$catchify1(e => {
@@ -16221,14 +16435,16 @@ class $eb064bc3350276c1$export$ac6237957a15b3f0 {
16221
16435
  set_search_content_results_rows((0, $d53ebed6f63304e4$export$70ceae36059a1036));
16222
16436
  }; // do this every time after we have submitted a new query - otherwise there might already be a saved number of rows in the state
16223
16437
  const on_submit_with_unchanged_value_ = () => this.modal_open = false;
16224
- const [get_search_field_value_, set_search_field_value_] = state_.field_value;
16225
- const configured_submit_query_ = new_query => $86b0ff0c85e5fc6c$export$e16630ecb9644a1c({
16438
+ const search_field_value_ = $8a9827cc2842b300$export$d13a185c53aa5edf(state_.field_value, get_search_query_);
16439
+ const [get_search_field_value_] = search_field_value_.value_;
16440
+ const configured_submit_query_ = (new_query, before_navigate_) => $86b0ff0c85e5fc6c$export$e16630ecb9644a1c({
16226
16441
  on_submit_with_unchanged_value_: on_submit_with_unchanged_value_,
16227
- set_search_field_value_: set_search_field_value_,
16442
+ search_field_value_: search_field_value_,
16228
16443
  get_search_query_: get_search_query_,
16229
16444
  search_param_name_: search_query_url_param_name_,
16230
16445
  after_submit_: after_submit_,
16231
- get_new_query: () => new_query || $8tj43$untrack(get_search_field_value_),
16446
+ before_navigate_: before_navigate_,
16447
+ get_new_query: () => new_query !== null && new_query !== void 0 ? new_query : $8tj43$untrack(get_search_field_value_),
16232
16448
  url_transformer_: url_transformer,
16233
16449
  router_: $8tj43$babelruntimehelpersclassPrivateFieldGet(this, $eb064bc3350276c1$var$_router)
16234
16450
  });
@@ -16247,6 +16463,7 @@ class $eb064bc3350276c1$export$ac6237957a15b3f0 {
16247
16463
  search_query_url_param_name_: search_query_url_param_name_,
16248
16464
  reset_history_state_: reset_history_state_,
16249
16465
  state_: state_,
16466
+ search_field_value_: search_field_value_.value_,
16250
16467
  router_: $8tj43$babelruntimehelpersclassPrivateFieldGet(this, $eb064bc3350276c1$var$_router),
16251
16468
  url_transformer_: url_transformer,
16252
16469
  depict_api_: depict_api_,
@@ -16270,7 +16487,11 @@ class $eb064bc3350276c1$export$ac6237957a15b3f0 {
16270
16487
  $8tj43$onCleanup(() => _this.modal_open = false);
16271
16488
  return searchModalComponent(...arguments);
16272
16489
  }, {
16273
- search_field_value_: state_.field_value,
16490
+ search_field_value_: search_field_value_.value_,
16491
+ get_search_page_input_element_: () => {
16492
+ var _privately_shared_pro2;
16493
+ return (_privately_shared_pro2 = $eb064bc3350276c1$export$dde08b2dca8cc1ce.get(this)) === null || _privately_shared_pro2 === void 0 ? void 0 : _privately_shared_pro2.search_page_input_element_;
16494
+ },
16274
16495
  get_search_query_: get_search_query_,
16275
16496
  search_query_url_param_name_: search_query_url_param_name_,
16276
16497
  previous_searches_: previous_searches,
@@ -16435,6 +16656,7 @@ function $eb064bc3350276c1$export$f2dc7e4e4aa11abb(props) {
16435
16656
  const {
16436
16657
  state_: state_
16437
16658
  } = shared_properties;
16659
+ let registered_input_element;
16438
16660
  const grid_spacing_override = $8tj43$createMemo(() => {
16439
16661
  const {
16440
16662
  grid_spacing: grid_spacing
@@ -16466,7 +16688,7 @@ function $eb064bc3350276c1$export$f2dc7e4e4aa11abb(props) {
16466
16688
  var _depict_search$enable;
16467
16689
  return (_depict_search$enable = depict_search.enable_content_search) !== null && _depict_search$enable !== void 0 ? _depict_search$enable : $eb064bc3350276c1$var$content_search_default;
16468
16690
  },
16469
- search_field_value_: state_.field_value,
16691
+ search_field_value_: shared_properties.search_field_value_,
16470
16692
  get_search_query_: shared_properties.get_search_query_,
16471
16693
  clear_filters_on_next_submit_: shared_properties.clear_filters_on_next_submit_,
16472
16694
  open_modal_: function () {
@@ -16477,6 +16699,16 @@ function $eb064bc3350276c1$export$f2dc7e4e4aa11abb(props) {
16477
16699
  modalVersionUsed_: shared_properties.modalVersionUsed_,
16478
16700
  showSliderArrow_: () => props.showSliderArrow_,
16479
16701
  i18n_: shared_properties.i18n_,
16702
+ inputFieldRef_: input_element => {
16703
+ const shared_info_right_now = $eb064bc3350276c1$export$dde08b2dca8cc1ce.get(depict_search);
16704
+ if (!shared_info_right_now) return;
16705
+ if (input_element === undefined && shared_info_right_now.search_page_input_element_ !== registered_input_element) return;
16706
+ registered_input_element = input_element;
16707
+ $eb064bc3350276c1$export$dde08b2dca8cc1ce.set(depict_search, {
16708
+ ...shared_info_right_now,
16709
+ search_page_input_element_: input_element
16710
+ });
16711
+ },
16480
16712
  modalAlignmentSignalsRef_: style => {
16481
16713
  const shared_info_right_now = $eb064bc3350276c1$export$dde08b2dca8cc1ce.get(depict_search);
16482
16714
  if (!shared_info_right_now) return;
@@ -16923,7 +17155,7 @@ function $a3026fb727bc7550$export$316f6f283ae64765(props) {
16923
17155
  return shared_properties.BackIcon_;
16924
17156
  },
16925
17157
  get search_field_value_() {
16926
- return shared_properties.state_.field_value;
17158
+ return shared_properties.search_field_value_;
16927
17159
  },
16928
17160
  get submit_query_() {
16929
17161
  return shared_properties.configured_submit_query_;
@@ -16966,7 +17198,7 @@ function $a3026fb727bc7550$export$316f6f283ae64765(props) {
16966
17198
  return shared_properties.BackIcon_;
16967
17199
  },
16968
17200
  get search_field_value_() {
16969
- return shared_properties.state_.field_value;
17201
+ return shared_properties.search_field_value_;
16970
17202
  },
16971
17203
  get submit_query_() {
16972
17204
  return shared_properties.configured_submit_query_;