@depict-ai/ui 0.0.65 → 0.0.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.js CHANGED
@@ -18,6 +18,7 @@ $parcel$export(module.exports, "DepictSearch", () => $79fbf145b15af988$export$ac
18
18
  $parcel$export(module.exports, "get_search_query_updating_blocked_signal", () => $79fbf145b15af988$export$bde3eb976dfded9);
19
19
  $parcel$export(module.exports, "SearchPage", () => $79fbf145b15af988$export$f2dc7e4e4aa11abb);
20
20
  $parcel$export(module.exports, "SearchField", () => $79fbf145b15af988$export$316f6f283ae64765);
21
+ $parcel$export(module.exports, "ProductCardError", () => $99a365f2a6c66061$export$aa14a9f43128f61f);
21
22
  $parcel$export(module.exports, "open_modal_with_alignment", () => $9c5a1d57540c06e5$export$d86a33413558014e);
22
23
  $parcel$export(module.exports, "DefaultInstantCardPlaceholder", () => $17c49340edfdbb31$export$ee1733d9a8495996);
23
24
  $parcel$export(module.exports, "align_field", () => $67b60b572b7b7059$export$b3ad617e9036868);
@@ -34,7 +35,7 @@ $parcel$export(module.exports, "solid_format_price", () => $5fc9fc23df1591db$exp
34
35
  $parcel$export(module.exports, "connect_search_field_height_to_aligner_height", () => $246e3e89a097f014$export$828dcdd425fd3231);
35
36
  $parcel$export(module.exports, "PageReplacer", () => $37e96a5ebc768cc7$export$3ccaa27d81dd8556);
36
37
  $parcel$export(module.exports, "version", () => $ae93561d5649a847$export$83d89fbfd8236492);
37
- /*! Depict.ai search and product listing SDK */ const $ae93561d5649a847$export$83d89fbfd8236492 = "0.0.65";
38
+ /*! Depict.ai search and product listing SDK */ const $ae93561d5649a847$export$83d89fbfd8236492 = "0.0.67";
38
39
 
39
40
 
40
41
 
@@ -819,6 +820,55 @@ function $8e863dc22b06b688$export$a2cc176055f8f08() {
819
820
  }
820
821
 
821
822
 
823
+
824
+
825
+
826
+
827
+
828
+
829
+ // Errors caused by SDK consuming code interfacing with the SDK, not the SDK itself or other Depict packages
830
+ class $99a365f2a6c66061$export$e1d52e4f0c7557a1 extends Error {
831
+ }
832
+ class $99a365f2a6c66061$export$aa14a9f43128f61f extends $99a365f2a6c66061$export$e1d52e4f0c7557a1 {
833
+ constructor(templateError){
834
+ super("Uncaught error in product card template", {
835
+ cause: templateError
836
+ });
837
+ }
838
+ }
839
+
840
+
841
+ const $0f2f58dd60b11888$var$_tmpl$ = /*@__PURE__*/ (0, /*@__PURE__*/$46MJV$solidjsweb.template)(`<div></div>`, 2);
842
+ function $0f2f58dd60b11888$export$b69d0d92862de18b(props) {
843
+ return (0, $46MJV$solidjs.ErrorBoundary)({
844
+ fallback (err, retry) {
845
+ const { message_: message_ , severity_: severity_ } = props;
846
+ let message = message_;
847
+ if (err instanceof (0, $99a365f2a6c66061$export$aa14a9f43128f61f)) {
848
+ console.error(err.cause);
849
+ message = `${message}: ${err.message}`;
850
+ } else (0, $46MJV$depictaiutilishared.report)([
851
+ err,
852
+ message_
853
+ ], severity_);
854
+ props.on_error_?.(retry);
855
+ return (()=>{
856
+ const _el$ = $0f2f58dd60b11888$var$_tmpl$.cloneNode(true);
857
+ (0, $46MJV$solidjsweb.insert)(_el$, message);
858
+ (0, $46MJV$solidjsweb.effect)((_$p)=>(0, $46MJV$solidjsweb.classList)(_el$, Object.fromEntries(props.class_list_?.map((c)=>[
859
+ c,
860
+ true
861
+ ]) || []), _$p));
862
+ return _el$;
863
+ })();
864
+ },
865
+ get children () {
866
+ return props.children;
867
+ }
868
+ });
869
+ }
870
+
871
+
822
872
  const $8d94abc871e13baf$var$_tmpl$ = /*@__PURE__*/ (0, /*@__PURE__*/$46MJV$solidjsweb.template)(`<div class="PLP-results"></div>`, 2), $8d94abc871e13baf$var$_tmpl$2 = /*@__PURE__*/ (0, /*@__PURE__*/$46MJV$solidjsweb.template)(`<div class="cards"></div>`, 2);
823
873
  let $8d94abc871e13baf$var$cached_placeholder_element;
824
874
  function $8d94abc871e13baf$export$3925f87b1545cfc6({ plp_results_: plp_results_ , depict_api_: depict_api_ , all_products_loaded_: all_products_loaded_ , min_products_to_fetch_: min_products_to_fetch_ , query_base_: query_base_ , first_result_in_viewport_: first_result_in_viewport_ , last_result_in_viewport_: last_result_in_viewport_ , scroll_restoration_data_: scroll_restoration_data_ , no_results_options_: no_results_options_ , desktop_filter_elements_: desktop_filter_elements_ , sort_or_filter_open_: sort_or_filter_open_ , rr_options_: rr_options_ , layout_options_: layout_options_ , tenant_object_: tenant_object_ , type_for_tracking_: type_for_tracking_ , id_currently_querying_for_: id_currently_querying_for_ }) {
@@ -855,8 +905,7 @@ function $8d94abc871e13baf$export$3925f87b1545cfc6({ plp_results_: plp_results_
855
905
  recs: current_results.displays,
856
906
  ...rr_options_,
857
907
  ...typeof rr_options_.template === "function" ? {
858
- template: (...args)=>(0, $46MJV$solidjs.runWithOwner)(owner_for_cards, ()=>// give template the possibility to know when it gets removed from the DOM by using solid-js onCleanup
859
- rr_options_.template(...args))
908
+ template: $8d94abc871e13baf$var$wrap_template_to_throw_into_error_boundary(rr_options_.template, owner_for_cards)
860
909
  } : {},
861
910
  post_processors: [
862
911
  ...rr_options_.post_processors || [],
@@ -901,86 +950,101 @@ function $8d94abc871e13baf$export$3925f87b1545cfc6({ plp_results_: plp_results_
901
950
  return (0, $46MJV$solidjsweb.createComponent)((0, $2b4e3538e183d885$export$ef6006467f04ee41), no_results_options_);
902
951
  },
903
952
  get children () {
904
- return (()=>{
905
- const random_id = (0, $46MJV$depictaiutilishared.make_random_classname)();
906
- const selector_beginning = `.depict.plp #${random_id}>`;
907
- const cards = (()=>{
908
- const _el$2 = $8d94abc871e13baf$var$_tmpl$2.cloneNode(true);
909
- (0, $46MJV$solidjsweb.setAttribute)(_el$2, "id", random_id);
910
- return _el$2;
911
- })();
912
- const style = document.createElement("style");
913
- (0, $46MJV$solidjs.createRenderEffect)(()=>{
914
- // Add grid styling that changes when filters get opened/closed
915
- const when_filters_closed_cols = layout_options_.cols_at_size;
916
- const cols_at_size = sort_or_filter_open_() ? when_filters_closed_cols.map((row)=>{
917
- const [num_cols_default, , , , override_cols] = row;
918
- const cloned_row = [
919
- ...row
920
- ];
921
- // @ts-ignore
922
- cloned_row[0] = num_cols_default - 1;
923
- if (override_cols) // @ts-ignore
924
- cloned_row[4] = {
925
- overrides: Object.fromEntries(Object.entries(override_cols.overrides).map(([row, column])=>[
926
- row,
927
- column - 1
928
- ]))
929
- };
930
- return cloned_row;
931
- }) : when_filters_closed_cols;
932
- const css = (0, $46MJV$depictaiutilishared.n_col_styling_with_dist)(selector_beginning, layout_options_.grid_spacing, cols_at_size, "grid", layout_options_.override_vertical_spacing);
933
- style.replaceChildren(css);
934
- });
935
- (0, $46MJV$solidjs.createRenderEffect)(// render placeholders / product cards
936
- (0, $46MJV$depictaiutilishared.catchify)(async ()=>{
937
- const owner_ = (0, $46MJV$solidjs.getOwner)();
938
- if (is_loading()) await $8d94abc871e13baf$var$insert_placeholders({
939
- scroll_restoration_data_: scroll_restoration_data_,
940
- id_currently_querying_for_: id_currently_querying_for_,
941
- rr_options_: rr_options_,
942
- tenant_object_: tenant_object_,
943
- min_products_to_fetch_: min_products_to_fetch_,
944
- owner_: owner_,
945
- cards_element_: cards
946
- });
947
- else if (!has_no_results_or_failed()) {
948
- plp_results_(); // re-run render_and_insert_results when results change
949
- render_and_insert_results(cards, owner_);
950
- }
951
- }));
952
- // copied from RecommendationGrid
953
- // convoluted lazy loading that
954
- // when the elements are in the DOM starts IntersectionObserver on whole grid
955
- // when grid intersects starts Lazyfier
956
- // this is because Lazyfier is fucking stupid
957
- (0, $46MJV$depictaiutilishared.observer).wait_for_element(cards).then((0, $46MJV$depictaiutilishared.catchify)((element)=>{
958
- let start_lazy_loading;
959
- const lazy_loading_promise = new Promise((r)=>start_lazy_loading = r);
960
- const lf = new (0, $46MJV$depictaiutilishared.Lazyfier)({
961
- only_load_intersecting: true,
962
- wait_for_dominsertion: lazy_loading_promise,
963
- ignore_data_urls: true,
964
- lazyfinder: {
965
- unload () {}
966
- }
953
+ return (0, $0f2f58dd60b11888$export$b69d0d92862de18b)({
954
+ severity_: "error",
955
+ // More granular error handling
956
+ // This _also_ fails when a product card rendering fails due to the runWithOwner with a root that was created inside the "root"/"context" of this ErrorBoundary
957
+ on_error_: (retry)=>{
958
+ // re-try / reset ErrorBoundary next time we're getting product cards
959
+ const track = (0, $46MJV$solidjs.createReaction)(retry);
960
+ track(plp_results_);
961
+ },
962
+ class_list_: [
963
+ "cards"
964
+ ],
965
+ // So that the styling looks pretty when we've failed
966
+ message_: "Result rendering failed",
967
+ get children () {
968
+ const random_id = (0, $46MJV$depictaiutilishared.make_random_classname)();
969
+ const selector_beginning = `.depict.plp #${random_id}>`;
970
+ const cards = (()=>{
971
+ const _el$2 = $8d94abc871e13baf$var$_tmpl$2.cloneNode(true);
972
+ (0, $46MJV$solidjsweb.setAttribute)(_el$2, "id", random_id);
973
+ return _el$2;
974
+ })();
975
+ const style = document.createElement("style");
976
+ (0, $46MJV$solidjs.createRenderEffect)(()=>{
977
+ // Add grid styling that changes when filters get opened/closed
978
+ const when_filters_closed_cols = layout_options_.cols_at_size;
979
+ const cols_at_size = sort_or_filter_open_() ? when_filters_closed_cols.map((row)=>{
980
+ const [num_cols_default, , , , override_cols] = row;
981
+ const cloned_row = [
982
+ ...row
983
+ ];
984
+ // @ts-ignore
985
+ cloned_row[0] = num_cols_default - 1;
986
+ if (override_cols) // @ts-ignore
987
+ cloned_row[4] = {
988
+ overrides: Object.fromEntries(Object.entries(override_cols.overrides).map(([row, column])=>[
989
+ row,
990
+ column - 1
991
+ ]))
992
+ };
993
+ return cloned_row;
994
+ }) : when_filters_closed_cols;
995
+ const css = (0, $46MJV$depictaiutilishared.n_col_styling_with_dist)(selector_beginning, layout_options_.grid_spacing, cols_at_size, "grid", layout_options_.override_vertical_spacing);
996
+ style.replaceChildren(css);
967
997
  });
968
- lf.start_observing_for_new_children_(element);
969
- const i_o = new IntersectionObserver((0, $46MJV$depictaiutilishared.catchify)((records)=>{
970
- for (const record of records)if (record.intersectionRatio > 0) {
971
- start_lazy_loading();
972
- i_o.disconnect();
973
- return;
998
+ (0, $46MJV$solidjs.createRenderEffect)(// render placeholders / product cards
999
+ (0, $46MJV$depictaiutilishared.catchify)(async ()=>{
1000
+ const owner_ = (0, $46MJV$solidjs.getOwner)();
1001
+ if (is_loading()) await $8d94abc871e13baf$var$insert_placeholders({
1002
+ scroll_restoration_data_: scroll_restoration_data_,
1003
+ id_currently_querying_for_: id_currently_querying_for_,
1004
+ rr_options_: rr_options_,
1005
+ tenant_object_: tenant_object_,
1006
+ min_products_to_fetch_: min_products_to_fetch_,
1007
+ owner_: owner_,
1008
+ cards_element_: cards
1009
+ });
1010
+ else if (!has_no_results_or_failed()) {
1011
+ plp_results_(); // re-run render_and_insert_results when results change
1012
+ render_and_insert_results(cards, owner_);
974
1013
  }
975
1014
  }));
976
- i_o.observe(cards);
977
- }));
978
- return [
979
- (0, $8e863dc22b06b688$export$a2cc176055f8f08)(),
980
- cards,
981
- style
982
- ];
983
- })();
1015
+ // copied from RecommendationGrid
1016
+ // convoluted lazy loading that
1017
+ // when the elements are in the DOM starts IntersectionObserver on whole grid
1018
+ // when grid intersects starts Lazyfier
1019
+ // this is because Lazyfier is fucking stupid
1020
+ (0, $46MJV$depictaiutilishared.observer).wait_for_element(cards).then((0, $46MJV$depictaiutilishared.catchify)((element)=>{
1021
+ let start_lazy_loading;
1022
+ const lazy_loading_promise = new Promise((r)=>start_lazy_loading = r);
1023
+ const lf = new (0, $46MJV$depictaiutilishared.Lazyfier)({
1024
+ only_load_intersecting: true,
1025
+ wait_for_dominsertion: lazy_loading_promise,
1026
+ ignore_data_urls: true,
1027
+ lazyfinder: {
1028
+ unload () {}
1029
+ }
1030
+ });
1031
+ lf.start_observing_for_new_children_(element);
1032
+ const i_o = new IntersectionObserver((0, $46MJV$depictaiutilishared.catchify)((records)=>{
1033
+ for (const record of records)if (record.intersectionRatio > 0) {
1034
+ start_lazy_loading();
1035
+ i_o.disconnect();
1036
+ return;
1037
+ }
1038
+ }));
1039
+ i_o.observe(cards);
1040
+ }));
1041
+ return [
1042
+ (0, $8e863dc22b06b688$export$a2cc176055f8f08)(),
1043
+ cards,
1044
+ style
1045
+ ];
1046
+ }
1047
+ });
984
1048
  }
985
1049
  }), null);
986
1050
  (0, $46MJV$solidjsweb.insert)(_el$, desktop_filter_elements_, null);
@@ -997,19 +1061,18 @@ async function $8d94abc871e13baf$var$insert_placeholders({ scroll_restoration_da
997
1061
  let existing_num = 0;
998
1062
  let removed_old_children = false;
999
1063
  if (!$8d94abc871e13baf$var$cached_placeholder_element) {
1064
+ const [dispose_card, root_in_root] = (0, $46MJV$solidjs.createRoot)((dispose)=>[
1065
+ dispose,
1066
+ (0, $46MJV$solidjs.getOwner)()
1067
+ ]);
1000
1068
  const { elements: elements } = await (0, $46MJV$depictaiutilishared.default_rr)(tenant_object_, {
1001
1069
  ...rr_options_,
1002
1070
  type: "placeholder",
1003
1071
  pre_processors: [],
1004
1072
  post_processors: [],
1005
1073
  ...typeof rr_options_.template === "function" ? {
1006
- template: (...args)=>(0, $46MJV$solidjs.createRoot)(async (dispose)=>{
1007
- try {
1008
- return await rr_options_.template(...args);
1009
- } finally{
1010
- (0, $46MJV$depictaiutilishared.queueMacroTask)((0, $46MJV$depictaiutilishared.catchify)(dispose)); // we just want it cloned and dead
1011
- }
1012
- })
1074
+ template: $8d94abc871e13baf$var$wrap_template_to_throw_into_error_boundary(rr_options_.template, root_in_root, ()=>(0, $46MJV$depictaiutilishared.queueMacroTask)((0, $46MJV$depictaiutilishared.catchify)(dispose_card)) // we just want it cloned and dead
1075
+ )
1013
1076
  } : {},
1014
1077
  recs: [
1015
1078
  {
@@ -1025,13 +1088,28 @@ async function $8d94abc871e13baf$var$insert_placeholders({ scroll_restoration_da
1025
1088
  const to_add = num_placeholders() - existing_num;
1026
1089
  if (to_add <= 0) return;
1027
1090
  // We don't need to remove placeholders, only need to add. The reason for that is that chrome restores the scroll position once all tasks queued as reaction of the "popstate" events have been completed in the task queue. That means that we need to get the placeholders in fast, or we might lose scroll position if the previous site was shorter.
1028
- // The query id and the amount might update in separate tasks because one comes from href_change_ipns and the other one from another "popstate" listener. Therefore, we need to be able to dynamically add more placeholders. I'm not entirely sure about this anymore though, since we have the scroll position on a per-id basis it might work anyways but THIS WORKS and I've been working on this bug for 3 hours so let's just keep it this way.
1091
+ // The query id and the amount might update in separate tasks because one comes from href_change_ipns and the other one from another "popstate" listener. Therefore, we need to be able to dynamically add more placeholders. I'm not entirely sure about this anymore though, since we have the scroll position on a per-id basis it might work anyway but THIS WORKS, and I've been working on this bug for 3 hours so let's just keep it this way.
1029
1092
  cards_element_[removed_old_children ? "append" : (removed_old_children = true, "replaceChildren")](...Array.from({
1030
1093
  length: to_add
1031
1094
  }).map(()=>$8d94abc871e13baf$var$cached_placeholder_element.cloneNode(true)));
1032
1095
  existing_num += to_add;
1033
1096
  }));
1034
1097
  }
1098
+ function $8d94abc871e13baf$var$wrap_template_to_throw_into_error_boundary(template, root_in_root, on_finally) {
1099
+ return async (...args)=>{
1100
+ try {
1101
+ return await (0, $46MJV$solidjs.runWithOwner)(root_in_root, ()=>template(...args)) || [];
1102
+ } catch (e) {
1103
+ (0, $46MJV$solidjs.runWithOwner)(root_in_root, ()=>{
1104
+ // Throw in case of promise rejection, ultimately into ErrorBoundary
1105
+ throw e;
1106
+ });
1107
+ return [];
1108
+ } finally{
1109
+ on_finally?.();
1110
+ }
1111
+ };
1112
+ }
1035
1113
 
1036
1114
 
1037
1115
 
@@ -2667,7 +2745,7 @@ function $cd6cdf2099e918a4$export$82ed4b28ecb67608({ filter_: filter_ , selected
2667
2745
  // lighten or darken (+/- 10) depending on it's over or under 50 lightness
2668
2746
  // lighten under 25 lightness by 20
2669
2747
  const target_lightness = is_hovered ? is_light ? lightness() - 10 : lightness() < 25 ? lightness() + 20 : lightness() + 10 : lightness();
2670
- classList.toggle("check-dark", lightness() > 75); // dark checkmark for bright colors
2748
+ classList.toggle("check-dark", $cd6cdf2099e918a4$var$black_contrast_better(hue(), saturation(), lightness())); // Decide between black/white checkmark based on which one has better contrast according to WCAG contrast guidelines
2671
2749
  style.backgroundColor = `hsl(${hue()}, ${saturation()}%, ${target_lightness}%)`;
2672
2750
  }
2673
2751
  });
@@ -2764,6 +2842,15 @@ function $cd6cdf2099e918a4$export$82ed4b28ecb67608({ filter_: filter_ , selected
2764
2842
  return _el$;
2765
2843
  })();
2766
2844
  }
2845
+ function $cd6cdf2099e918a4$var$black_contrast_better(hue, saturation, lightness) {
2846
+ const as_rgb = (0, $46MJV$depictaiutilishared.hsl_to_rgb)(hue, saturation, lightness);
2847
+ const luminance_color = (0, $46MJV$depictaiutilishared.relative_luminance_from_rgb)(...as_rgb);
2848
+ const luminance_white = 1;
2849
+ const luminance_black = 0;
2850
+ const contrast_ratio_if_white = (luminance_white + 0.05) / (luminance_color + 0.05);
2851
+ const contrast_ratio_if_black = (luminance_color + 0.05) / (luminance_black + 0.05);
2852
+ return contrast_ratio_if_black > contrast_ratio_if_white;
2853
+ }
2767
2854
 
2768
2855
 
2769
2856
  var $6865c7388a79e957$export$2e2bcd8739ae039 = {
@@ -3045,31 +3132,6 @@ function $5804fd6cbfb7160f$export$ab34afce88557c0e(props) {
3045
3132
 
3046
3133
 
3047
3134
 
3048
-
3049
-
3050
- const $0f2f58dd60b11888$var$_tmpl$ = /*@__PURE__*/ (0, /*@__PURE__*/$46MJV$solidjsweb.template)(`<div></div>`, 2);
3051
- function $0f2f58dd60b11888$export$b69d0d92862de18b(props) {
3052
- return (0, $46MJV$solidjs.ErrorBoundary)({
3053
- fallback (err) {
3054
- const { message_: message_ , severity_: severity_ } = props;
3055
- (0, $46MJV$depictaiutilishared.report)([
3056
- err,
3057
- message_
3058
- ], severity_);
3059
- return (()=>{
3060
- const _el$ = $0f2f58dd60b11888$var$_tmpl$.cloneNode(true);
3061
- (0, $46MJV$solidjsweb.insert)(_el$, message_);
3062
- return _el$;
3063
- })();
3064
- },
3065
- get children () {
3066
- return props.children;
3067
- }
3068
- });
3069
- }
3070
-
3071
-
3072
-
3073
3135
  const $1587765bd31f3722$var$_tmpl$ = /*@__PURE__*/ (0, /*@__PURE__*/$46MJV$solidjsweb.template)(`<div class="filter-collapsible"></div>`, 2), $1587765bd31f3722$var$_tmpl$2 = /*@__PURE__*/ (0, /*@__PURE__*/$46MJV$solidjsweb.template)(`<button class="clear-group"><span></span></button>`, 4), $1587765bd31f3722$var$_tmpl$3 = /*@__PURE__*/ (0, /*@__PURE__*/$46MJV$solidjsweb.template)(`<div class="view-more-clear"></div>`, 2), $1587765bd31f3722$var$_tmpl$4 = /*@__PURE__*/ (0, /*@__PURE__*/$46MJV$solidjsweb.template)(`<div class="filter-collapsible-body"><div class="filter-part"></div></div>`, 4), $1587765bd31f3722$var$_tmpl$5 = /*@__PURE__*/ (0, /*@__PURE__*/$46MJV$solidjsweb.template)(`<details class="filter-collapsible"></details>`, 2), $1587765bd31f3722$var$_tmpl$6 = /*@__PURE__*/ (0, /*@__PURE__*/$46MJV$solidjsweb.template)(`<summary class="filter-group-summary"><div class="summary"><span></span><div class="selected-w-sign"></div></div></summary>`, 8), $1587765bd31f3722$var$_tmpl$7 = /*@__PURE__*/ (0, /*@__PURE__*/$46MJV$solidjsweb.template)(`<div class="ungrouped"></div>`, 2), $1587765bd31f3722$var$_tmpl$8 = /*@__PURE__*/ (0, /*@__PURE__*/$46MJV$solidjsweb.template)(`<button class="clear-all-filters major"></button>`, 2);
3074
3136
  function $1587765bd31f3722$export$3f1a388cc0d8fed7(props) {
3075
3137
  // Split like this to make placeholder wrapping more visible & this component is exported and used in MobileModal
@@ -5328,14 +5390,18 @@ function $67892c03cd3dfa66$export$d757d54550ebfb3d({ category_suggestion_: categ
5328
5390
 
5329
5391
 
5330
5392
  const $2989e355f64e18e1$var$_tmpl$ = /*@__PURE__*/ (0, /*@__PURE__*/$46MJV$solidjsweb.template)(`<button class="back" type="button"></button>`, 2), $2989e355f64e18e1$var$_tmpl$2 = /*@__PURE__*/ (0, /*@__PURE__*/$46MJV$solidjsweb.template)(`<div class="search-field"><div class="field"><input class="query" tabindex="0"><button type="button" class="clear"></button></div><button class="submit major" type="button"></button></div>`, 9);
5331
- function $2989e355f64e18e1$export$b94867ecbd698f21({ search_field_value_: search_field_value_ , input_field_ref_: input_field_ref_ , field_element_ref_: field_element_ref_ , submit_query_: submit_query_ , override_on_enter_: override_on_enter_ , clear_filters_: clear_filters_ , disabled_: disabled_ = false , on_back_: on_back_ , i18n_: i18n_ }) {
5332
- let input_field;
5393
+ function $2989e355f64e18e1$export$b94867ecbd698f21({ search_field_value_: search_field_value_ , input_field_ref_: input_field_ref_ , field_element_ref_: field_element_ref_ , submit_query_: submit_query_ , override_on_enter_: override_on_enter_ , clear_filters_: clear_filters_ , disabled_: disabled_ = false , on_back_: on_back_ , i18n_: i18n_ , after_focusing_: after_focusing_ }) {
5394
+ let input_element;
5395
+ // This is the div where we recommend (and ourselves do) attach the event listener to that opens the search modal.
5396
+ let field_div;
5333
5397
  (0, $46MJV$solidjs.createEffect)((0, $46MJV$depictaiutilishared.catchify)(async ()=>{
5334
5398
  if (disabled_) return;
5335
5399
  // we aren't in DOM yet unfortunately, wouldn't even be with onMount
5336
- await (0, $46MJV$depictaiutilishared.observer).wait_for_element(input_field);
5337
- input_field.focus();
5400
+ await (0, $46MJV$depictaiutilishared.observer).wait_for_element(input_element);
5401
+ input_element.focus();
5402
+ after_focusing_?.(input_element);
5338
5403
  })); // focus field on render
5404
+ const owner_of_field_element = (0, $46MJV$solidjs.getOwner)();
5339
5405
  return (()=>{
5340
5406
  const _el$ = $2989e355f64e18e1$var$_tmpl$2.cloneNode(true), _el$3 = _el$.firstChild, _el$4 = _el$3.firstChild, _el$5 = _el$4.nextSibling, _el$6 = _el$3.nextSibling;
5341
5407
  (0, $46MJV$solidjsweb.insert)(_el$, (0, $46MJV$solidjsweb.createComponent)((0, $46MJV$solidjs.Show), {
@@ -5348,38 +5414,47 @@ function $2989e355f64e18e1$export$b94867ecbd698f21({ search_field_value_: search
5348
5414
  return _el$2;
5349
5415
  }
5350
5416
  }), _el$3);
5351
- (0, $46MJV$solidjsweb.use)((el)=>field_element_ref_?.(el), _el$3);
5352
- (0, $46MJV$solidjsweb.addEventListener)(_el$4, "select", (0, $46MJV$depictaiutilishared.catchify)((e)=>{
5353
- if (!disabled_) // just in case. The field not actually being disabled when being disabled_ is so that you can focus it and open the modal. We don't want any of the other input-field-interaction features to work
5354
- {
5355
- if (input_field.selectionStart === 0 && input_field.selectionEnd === input_field.value.length) // everything was selected, clear filters on next submit on next input
5356
- input_field.addEventListener("input", (0, $46MJV$depictaiutilishared.catchify)(clear_filters_), {
5417
+ (0, $46MJV$solidjsweb.use)((el)=>{
5418
+ field_div = el;
5419
+ field_element_ref_?.(el);
5420
+ }, _el$3);
5421
+ _el$4.$$pointerdown = ({ pointerType: pointerType })=>{
5422
+ // When selecting text with a mouse we want a SearchField to be focussed even when releasing the mouse outside the .field element (we assume the event listener which opens the modal is attached to that).
5423
+ if (pointerType === "mouse") {
5424
+ const handler = (0, $46MJV$depictaiutilishared.catchify)(({ pointerType: pointerType , target: target })=>{
5425
+ if (pointerType !== "mouse" || !(target instanceof Node) || target === field_div || field_div.contains(target)) return;
5426
+ input_element.click();
5427
+ });
5428
+ window.addEventListener("pointerup", handler, {
5357
5429
  once: true
5358
5430
  });
5431
+ if (owner_of_field_element) (0, $46MJV$solidjs.runWithOwner)(owner_of_field_element, ()=>(0, $46MJV$solidjs.onCleanup)(()=>window.removeEventListener("pointerup", handler)));
5359
5432
  }
5433
+ };
5434
+ (0, $46MJV$solidjsweb.addEventListener)(_el$4, "select", (0, $46MJV$depictaiutilishared.catchify)(()=>{
5435
+ if (disabled_) // just in case. The field not actually being disabled when being disabled_ is so that you can focus it and open the modal. We don't want any of the other input-field-interaction features to work
5436
+ return;
5437
+ if (input_element.selectionStart === 0 && input_element.selectionEnd === input_element.value.length) // everything was selected, clear filters on next submit on next input
5438
+ input_element.addEventListener("input", (0, $46MJV$depictaiutilishared.catchify)(clear_filters_), {
5439
+ once: true
5440
+ });
5360
5441
  }));
5361
5442
  (0, $46MJV$solidjsweb.addEventListener)(_el$4, "input", (0, $46MJV$depictaiutilishared.catchify)(()=>{
5362
- const { value: value } = input_field;
5443
+ const { value: value } = input_element;
5363
5444
  if (!disabled_ && !value.length) clear_filters_(); // if the user clears the whole field, reset filters on next submit
5364
5445
  search_field_value_[1](value);
5365
5446
  }), true);
5366
5447
  (0, $46MJV$solidjsweb.addEventListener)(_el$4, "keydown", (0, $46MJV$depictaiutilishared.catchify)((e)=>{
5367
5448
  if (disabled_) {
5368
5449
  if (e.key !== "Tab" && e.key !== "Shift") // 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
5369
- input_field.click();
5450
+ input_element.click();
5370
5451
  } else if (e.key === "Enter") {
5371
5452
  const dont_submit = override_on_enter_?.(e);
5372
5453
  if (!dont_submit) submit_query_();
5373
5454
  }
5374
5455
  }), true);
5375
- (0, $46MJV$solidjsweb.addEventListener)(_el$4, "focus", (0, $46MJV$depictaiutilishared.catchify)(()=>{
5376
- if (disabled_) {
5377
- const last_pos = input_field.value.length;
5378
- input_field.setSelectionRange(last_pos, last_pos);
5379
- }
5380
- }));
5381
5456
  const _ref$ = (0, $46MJV$depictaiutilishared.catchify)((el)=>{
5382
- input_field = el;
5457
+ input_element = el;
5383
5458
  input_field_ref_?.(el);
5384
5459
  });
5385
5460
  typeof _ref$ === "function" && (0, $46MJV$solidjsweb.use)(_ref$, _el$4);
@@ -5387,8 +5462,7 @@ function $2989e355f64e18e1$export$b94867ecbd698f21({ search_field_value_: search
5387
5462
  (0, $46MJV$solidjsweb.addEventListener)(_el$5, "click", (0, $46MJV$depictaiutilishared.catchify)(()=>{
5388
5463
  search_field_value_[1]("");
5389
5464
  clear_filters_();
5390
- if (disabled_) return;
5391
- input_field.focus();
5465
+ if (!disabled_) input_element.focus();
5392
5466
  }), true);
5393
5467
  (0, $46MJV$solidjsweb.insert)(_el$5, (0, $46MJV$solidjsweb.createComponent)((0, $46MJV$depictaiutilishared.CrossIcon), {}));
5394
5468
  (0, $46MJV$solidjsweb.addEventListener)(_el$6, "click", (0, $46MJV$depictaiutilishared.catchify)(()=>submit_query_()), true);
@@ -5415,7 +5489,8 @@ function $2989e355f64e18e1$export$b94867ecbd698f21({ search_field_value_: search
5415
5489
  (0, $46MJV$solidjsweb.delegateEvents)([
5416
5490
  "click",
5417
5491
  "keydown",
5418
- "input"
5492
+ "input",
5493
+ "pointerdown"
5419
5494
  ]);
5420
5495
 
5421
5496
 
@@ -5767,7 +5842,7 @@ function $690220645373c65e$export$2542ffb77b620b02(params_to_default_value) {
5767
5842
 
5768
5843
 
5769
5844
  const $1bf0125991f2d39b$var$_tmpl$ = /*@__PURE__*/ (0, /*@__PURE__*/$46MJV$solidjsweb.template)(`<span class="orig price"></span>`, 2), $1bf0125991f2d39b$var$_tmpl$2 = /*@__PURE__*/ (0, /*@__PURE__*/$46MJV$solidjsweb.template)(`<a class="instant-card"><div class="img-part"></div><div class="right-part"><div class="title-brand-tagline"><span class="brand"></span><span class="title"></span></div><div class="price-container"><span class="price"></span></div></div></a>`, 16), $1bf0125991f2d39b$var$_tmpl$3 = /*@__PURE__*/ (0, /*@__PURE__*/$46MJV$solidjsweb.template)(`<div class="tagline"></div>`, 2);
5770
- const $1bf0125991f2d39b$export$b05c0ae390cf3e06 = (display_or_variant_container, { i18n: i18n })=>{
5845
+ const $1bf0125991f2d39b$export$b05c0ae390cf3e06 = (display_or_variant_container, { i18n: i18n , market: market })=>{
5771
5846
  const display = (0, $46MJV$solidjs.createMemo)(()=>{
5772
5847
  const display = display_or_variant_container();
5773
5848
  // Support for backend's new display format
@@ -5779,7 +5854,12 @@ const $1bf0125991f2d39b$export$b05c0ae390cf3e06 = (display_or_variant_container,
5779
5854
  };
5780
5855
  }
5781
5856
  if (display.page_url) return display;
5782
- // Support for Spendrups displays, should probably be in the Spendrups script
5857
+ // Support for post-migration (but still old basic format) Stronger displays, with slug but without page_url
5858
+ if (display.slug) {
5859
+ display.page_url = `/${market}/` + display.slug;
5860
+ return display;
5861
+ }
5862
+ // Support for Spendrups displays, used by our frontend script and Spendrups coming react-ui integration.
5783
5863
  if (!display?.variants?.length) return;
5784
5864
  return display.variants.filter((v)=>v.product_id == display.product_id)[0];
5785
5865
  });
@@ -6766,7 +6846,7 @@ function $4a976b492943589f$export$f021bdedd3ec901a(props) {
6766
6846
 
6767
6847
 
6768
6848
  const $121d25ca6af2898f$var$_tmpl$ = /*@__PURE__*/ (0, /*@__PURE__*/$46MJV$solidjsweb.template)(`<div class="discover-more"><button class="major" type="button"></button></div>`, 4), $121d25ca6af2898f$var$_tmpl$2 = /*@__PURE__*/ (0, /*@__PURE__*/$46MJV$solidjsweb.template)(`<b></b>`, 2), $121d25ca6af2898f$var$_tmpl$3 = /*@__PURE__*/ (0, /*@__PURE__*/$46MJV$solidjsweb.template)(`<div class="depict-search-modal"><div class="body"><div class="padded"></div></div></div>`, 6), $121d25ca6af2898f$var$_tmpl$4 = /*@__PURE__*/ (0, /*@__PURE__*/$46MJV$solidjsweb.template)(`<div class="depict plp search"><div class="depict-search-modal-backdrop"></div></div>`, 4);
6769
- function $121d25ca6af2898f$export$1c593cbd6f1e10bc({ search_field_value_: search_field_value_ , search_query_: search_query_ , search_page_url_param_name_: search_page_url_param_name_ , previous_searches_: previous_searches_ , close_modal_: close_modal_ , style_props_: style_props_ = (0, $46MJV$solidjs.createSignal)({}) , depict_api_: depict_api_ , tenant_: tenant_ , market_: market_ , submit_query_: submit_query_ , instant_results_options_: instant_results_options_ , register_closing_animation_: register_closing_animation_ , url_transformer_: url_transformer_ , closing_animation_: closing_animation_ , alternative_query_submitter_for_spas_: alternative_query_submitter_for_spas_ , clear_filters_: clear_filters_ , i18n_: i18n_ , disable_scrolling_: disable_scrolling_ = true , enable_category_suggestions_: enable_category_suggestions_ , class_list_: class_list_ , after_submit_: after_submit_ , bottom_distance_under_modal_: bottom_distance_under_modal_ , navigate_page_to_href_: navigate_page_to_href_ , on_submit_with_unchanged_value_: on_submit_with_unchanged_value_ }) {
6849
+ function $121d25ca6af2898f$export$1c593cbd6f1e10bc({ search_field_value_: search_field_value_ , search_query_: search_query_ , search_page_url_param_name_: search_page_url_param_name_ , previous_searches_: previous_searches_ , close_modal_: close_modal_ , style_props_: style_props_ = (0, $46MJV$solidjs.createSignal)({}) , depict_api_: depict_api_ , tenant_: tenant_ , market_: market_ , submit_query_: submit_query_ , instant_results_options_: instant_results_options_ , register_closing_animation_: register_closing_animation_ , url_transformer_: url_transformer_ , closing_animation_: closing_animation_ , alternative_query_submitter_for_spas_: alternative_query_submitter_for_spas_ , clear_filters_: clear_filters_ , i18n_: i18n_ , disable_scrolling_: disable_scrolling_ = true , enable_category_suggestions_: enable_category_suggestions_ , class_list_: class_list_ , after_submit_: after_submit_ , bottom_distance_under_modal_: bottom_distance_under_modal_ , navigate_page_to_href_: navigate_page_to_href_ , on_submit_with_unchanged_value_: on_submit_with_unchanged_value_ , selected_text_range_: selected_text_range_ }) {
6770
6850
  let on_enter_in_search_field_function;
6771
6851
  const [input_field, set_input_field] = (0, $46MJV$solidjs.createSignal)();
6772
6852
  const [get_search_field_value_] = search_field_value_;
@@ -6828,7 +6908,14 @@ function $121d25ca6af2898f$export$1c593cbd6f1e10bc({ search_field_value_: search
6828
6908
  search_field_value_: search_field_value_,
6829
6909
  submit_query_: submit_query_,
6830
6910
  clear_filters_: clear_filters_,
6831
- i18n_: i18n_
6911
+ i18n_: i18n_,
6912
+ after_focusing_: (input_el)=>{
6913
+ // Restore the selection range from the SearchField that was used to open the modal, if it was saved.
6914
+ if (!selected_text_range_) return;
6915
+ const [start, end] = selected_text_range_;
6916
+ if (start === null || end === null) return;
6917
+ input_el.setSelectionRange(start, end);
6918
+ }
6832
6919
  });
6833
6920
  search_field.classList.add("in-modal");
6834
6921
  const modal_element = (()=>{
@@ -7098,28 +7185,38 @@ function $93779a41dce11249$export$a54ec244c8863715(opts) {
7098
7185
  })));
7099
7186
  const available_filters_ = (0, $46MJV$solidjs.createMemo)(()=>search_results_()?.filters);
7100
7187
  const modal_body_style = (0, $46MJV$solidjs.createSignal)({});
7101
- let input_field;
7188
+ let search_field;
7102
7189
  if (include_input_field_) {
7103
7190
  const SafeSearchField = (0, $46MJV$depictaiutilishared.catchify)((0, $2989e355f64e18e1$export$b94867ecbd698f21));
7104
- input_field = (0, $46MJV$solidjsweb.createComponent)(SafeSearchField, {
7191
+ let input_element;
7192
+ let div_with_field_class;
7193
+ search_field = SafeSearchField({
7105
7194
  i18n_: i18n_,
7106
- disabled_: true,
7107
7195
  search_query_: search_query_,
7108
7196
  search_field_value_: search_field_value_,
7109
7197
  submit_query_: submit_query_,
7110
- clear_filters_: clear_filters_on_next_submit_
7198
+ clear_filters_: clear_filters_on_next_submit_,
7199
+ input_field_ref_: (el)=>input_element = el,
7200
+ field_element_ref_: (el)=>div_with_field_class = el,
7201
+ disabled_: true
7111
7202
  });
7112
- if (input_field) {
7203
+ if (search_field) {
7113
7204
  opts?.modal_body_style_ref_?.(modal_body_style);
7114
- const align_position = (0, $46MJV$depictaiutilishared.catchify)((0, $67b60b572b7b7059$export$b3ad617e9036868))(modal_body_style, input_field, undefined, true);
7115
- input_field.addEventListener("click", (0, $46MJV$depictaiutilishared.catchify)((e)=>{
7205
+ const align_position = (0, $46MJV$depictaiutilishared.catchify)((0, $67b60b572b7b7059$export$b3ad617e9036868))(modal_body_style, search_field, undefined, true);
7206
+ div_with_field_class.addEventListener("click", (0, $46MJV$depictaiutilishared.catchify)((e)=>{
7116
7207
  const target = e.target;
7117
7208
  const sel = ".submit";
7118
7209
  if (target?.matches?.(sel) || target?.closest?.(sel)) // the search button is just decor, don't do anything when clicked
7119
7210
  return;
7211
+ // When selecting text in the SearchField that's in the page we want the same selection to persist. It doesn't by itself, since the SearchModal has an entirely different SearchField. Therefore, we manually copy the selection over.
7212
+ const selected_text_range_ = [
7213
+ input_element.selectionStart,
7214
+ input_element.selectionEnd
7215
+ ];
7120
7216
  align_position?.();
7121
7217
  open_modal_({
7122
- style_props_: modal_body_style
7218
+ style_props_: modal_body_style,
7219
+ selected_text_range_: selected_text_range_
7123
7220
  }, ()=>include_input_field_?.on_close_?.());
7124
7221
  include_input_field_?.on_open_?.();
7125
7222
  }));
@@ -7195,7 +7292,7 @@ function $93779a41dce11249$export$a54ec244c8863715(opts) {
7195
7292
  document.createComment("Search page based on Depict SDK"),
7196
7293
  (()=>{
7197
7294
  const _el$2 = $93779a41dce11249$var$_tmpl$2.cloneNode(true), _el$3 = _el$2.firstChild;
7198
- (0, $46MJV$solidjsweb.insert)(_el$3, input_field, null);
7295
+ (0, $46MJV$solidjsweb.insert)(_el$3, search_field, null);
7199
7296
  (0, $46MJV$solidjsweb.insert)(_el$3, make_category_suggestion_card_ ? (0, $46MJV$solidjsweb.createComponent)((0, $0f2f58dd60b11888$export$b69d0d92862de18b), {
7200
7297
  severity_: "error",
7201
7298
  message_: "Category suggestions failed",
@@ -7652,7 +7749,8 @@ function $79fbf145b15af988$export$f2dc7e4e4aa11abb({ depict_search: depict_searc
7652
7749
  function $79fbf145b15af988$export$316f6f283ae64765({ depict_search: depict_search , modal_dispose_handler: modal_dispose_handler , click_handler: click_handler , aligner_ref: aligner_ref }) {
7653
7750
  const shared_properties = $79fbf145b15af988$var$get_shared_properties(depict_search);
7654
7751
  return (0, $f27b0b326e0a87e2$export$23fca46f3143581f)(()=>{
7655
- const input = (0, $46MJV$solidjsweb.createComponent)((0, $2989e355f64e18e1$export$b94867ecbd698f21), {
7752
+ let input_element;
7753
+ const search_field = (0, $46MJV$solidjsweb.createComponent)((0, $2989e355f64e18e1$export$b94867ecbd698f21), {
7656
7754
  get search_query_ () {
7657
7755
  return shared_properties.search_query_signal_;
7658
7756
  },
@@ -7669,35 +7767,40 @@ function $79fbf145b15af988$export$316f6f283ae64765({ depict_search: depict_searc
7669
7767
  return shared_properties.i18n_;
7670
7768
  },
7671
7769
  disabled_: true,
7770
+ input_field_ref_: (el)=>input_element = el,
7672
7771
  field_element_ref_: (field)=>{
7673
7772
  const style_props_ = (0, $46MJV$solidjs.createSignal)({
7674
7773
  position: "fixed"
7675
7774
  });
7676
7775
  const defaultHandler = (0, $46MJV$depictaiutilishared.catchify)(()=>{
7677
- const { cleanup: cleanup } = $79fbf145b15af988$var$align_field_modal(style_props_, input, aligner_ref);
7776
+ // When selecting text in the SearchField that's in the page we want the same selection to persist. It doesn't by itself, since the SearchModal has an entirely different SearchField. Therefore, we manually copy the selection over.
7777
+ const selected_text_range_ = [
7778
+ input_element.selectionStart,
7779
+ input_element.selectionEnd
7780
+ ];
7781
+ const { cleanup: cleanup } = $79fbf145b15af988$var$align_field_modal(style_props_, search_field, aligner_ref);
7678
7782
  const complete_modal_dispose_handler = ()=>{
7679
7783
  modal_dispose_handler?.();
7680
7784
  cleanup();
7681
7785
  };
7682
7786
  depict_search.modal_open = [
7683
7787
  {
7684
- style_props_: style_props_
7788
+ style_props_: style_props_,
7789
+ selected_text_range_: selected_text_range_
7685
7790
  },
7686
7791
  complete_modal_dispose_handler
7687
7792
  ];
7688
7793
  });
7689
7794
  const handler = click_handler ?? defaultHandler;
7690
7795
  field.addEventListener("click", handler);
7691
- (0, $46MJV$solidjs.onCleanup)(()=>{
7692
- field.removeEventListener("click", handler);
7693
- });
7796
+ (0, $46MJV$solidjs.onCleanup)(()=>field.removeEventListener("click", handler));
7694
7797
  }
7695
7798
  });
7696
7799
  // We assume this to be an array containing exactly on div in js-ui
7697
7800
  return [
7698
7801
  (()=>{
7699
7802
  const _el$ = $79fbf145b15af988$var$_tmpl$.cloneNode(true);
7700
- (0, $46MJV$solidjsweb.insert)(_el$, input);
7803
+ (0, $46MJV$solidjsweb.insert)(_el$, search_field);
7701
7804
  return _el$;
7702
7805
  })()
7703
7806
  ];
@@ -7727,6 +7830,7 @@ function $79fbf145b15af988$var$align_field_modal(style_props_, input, aligner_re
7727
7830
 
7728
7831
 
7729
7832
 
7833
+
7730
7834
  const $9c5a1d57540c06e5$export$d86a33413558014e = (openModalParams)=>{
7731
7835
  const { search: search } = openModalParams;
7732
7836
  openModalParams.location ||= "centered";