@depict-ai/ui 2.0.26 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/latest/index.cjs CHANGED
@@ -1,6 +1,7 @@
1
1
  var $gVhhF$depictaiutilishared = require("@depict-ai/utilishared/latest");
2
2
  var $gVhhF$solidjsweb = require("solid-js/web");
3
3
  var $gVhhF$solidjs = require("solid-js");
4
+ var $gVhhF$solidjsstore = require("solid-js/store");
4
5
  require("../multi_import_deduplicator.cjs").register_es_version("ui", "latest");
5
6
  function $parcel$export(e, n, v, s) {
6
7
  Object.defineProperty(e, n, {
@@ -69,7 +70,7 @@ $parcel$export(module.exports, "defaultColsAtSize", () => $a3280f0aad997933$expo
69
70
  $parcel$export(module.exports, "defaultCategoryTitlePlugin", () => $a3280f0aad997933$export$7bf543b9d9be2c22);
70
71
  $parcel$export(module.exports, "version", () => $b757f75811f3261f$export$83d89fbfd8236492);
71
72
  /*! Depict.ai search and product listing SDK */
72
- const $b757f75811f3261f$export$83d89fbfd8236492 = "2.0.26";
73
+ const $b757f75811f3261f$export$83d89fbfd8236492 = "2.1.0";
73
74
  const $1ab22f2cd39b3061$var$fallback_operator = "in";
74
75
  const $1ab22f2cd39b3061$var$fallback_token = "";
75
76
  const $1ab22f2cd39b3061$var$legacy_filter_prefix = "filter_";
@@ -484,7 +485,7 @@ const $4e04be41243c3d80$export$6daf8749b65a1b77 = cols_at_size => {
484
485
  return $4e04be41243c3d80$var$transform_elements(sorted_cols_at_size);
485
486
  };
486
487
  function $fc23d7668ae0011d$export$a2cc176055f8f08() {
487
- const text = "Please try setting `columnsAtSize` on the `SearchPage`/`CategoryPage` components to change the grid before setting it with CSS. If you do with CSS, set `columnsAtSize` to an empty array to ensure no declarations created by the SDK leak through.";
488
+ const text = "Please try setting `columnsAtSize`/`gridSpacing` on the `SearchPage`/`CategoryPage` components to change the grid before setting it with CSS. If you do with CSS, set `columnsAtSize` to an empty array to ensure no declarations created by the SDK leak through.";
488
489
  return (0, $gVhhF$solidjsweb.isServer) ? {
489
490
  t: `<!-- ${text} -->`
490
491
  } : document.createComment(text);
@@ -505,12 +506,13 @@ let $0caf87eaa19079da$var$cached_placeholder_element;
505
506
  let $0caf87eaa19079da$var$rendering_cached_placeholder_element;
506
507
  function $0caf87eaa19079da$export$f33414a4df0afd3f({
507
508
  product_card_template_: product_card_template_,
508
- num_placeholders_: num_placeholders_
509
+ num_placeholders_: num_placeholders_,
510
+ content_blocks_: content_blocks_
509
511
  }) {
510
- const [get_elements, set_elements] = $gVhhF$solidjs.createSignal([]);
511
- let existing_num = 0;
512
+ const [num_to_actually_show, set_num_to_actually_show] = $gVhhF$solidjs.createSignal($gVhhF$solidjs.untrack(num_placeholders_));
512
513
  if (0, $gVhhF$solidjsweb.isServer)
513
514
  // want to render simple placeholders on server, effects don't run there
515
+ // FIXME when adding proper SSR: also SSR content blocks
514
516
  return $gVhhF$solidjs.createMemo(() => Array.from({
515
517
  length: num_placeholders_()
516
518
  }).map(() => {
@@ -519,19 +521,30 @@ function $0caf87eaa19079da$export$f33414a4df0afd3f({
519
521
  if (typeof template_result?.then !== "function") return template_result;
520
522
  }));
521
523
  $gVhhF$solidjs.createRenderEffect(() => {
524
+ const existing_num = num_to_actually_show();
522
525
  const to_add = num_placeholders_() - existing_num;
523
526
  if (to_add <= 0) return;
524
527
  // Below comment is from when we used recommendation renderer and manual DOM manipulation for this, but I'm still scared to remove placeholders and mess up scroll restoration, so I'm keeping the way it worked. Otherwise, <Index> could be used which would be far more elegant.
525
528
  // 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.
526
529
  // 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.
527
- set_elements(prev => [...prev, ...Array.from({
528
- length: to_add
529
- }).map(() => $0caf87eaa19079da$var$Placeholder({
530
- product_card_template_: product_card_template_
531
- }))]);
532
- existing_num += to_add;
530
+ // Above comments were from when we added elements in this createRenderEffect. Now I changed it to just increment the number and render them from an <Index> instead, so I can add content blocks better
531
+ // Functionality should be the same
532
+ set_num_to_actually_show(existing_num + to_add);
533
+ });
534
+ return $gVhhF$solidjsweb.createComponent((0, $gVhhF$solidjs.Index), {
535
+ get each() {
536
+ return Array.from({
537
+ length: num_to_actually_show()
538
+ });
539
+ },
540
+ children: (_item, index) => {
541
+ const possible_content_block = $gVhhF$solidjs.createMemo(() => content_blocks_?.()?.()?.[index]);
542
+ // Show content block before product card, so it's *at* that index
543
+ return [possible_content_block, $0caf87eaa19079da$var$Placeholder({
544
+ product_card_template_: product_card_template_
545
+ })]; // https://github.com/solidjs/solid/releases/tag/v1.7.0
546
+ }
533
547
  });
534
- return get_elements; // https://github.com/solidjs/solid/releases/tag/v1.7.0
535
548
  }
536
549
  /**
537
550
  * Get one placeholder element. It will be cloned for each placeholder for ultimate performance even when solid-js isn't rendering the placeholders.
@@ -616,7 +629,8 @@ function $a73063cc642f3e5f$export$43f0fb951fcb0c54({
616
629
  merchant_: merchant_,
617
630
  market_: market_,
618
631
  product_card_template_: product_card_template_,
619
- do_per_elements_: do_per_elements_
632
+ do_per_elements_: do_per_elements_,
633
+ content_blocks_: content_blocks_
620
634
  }) {
621
635
  return $gVhhF$solidjsweb.createComponent((0, $gVhhF$solidjs.For), {
622
636
  get each() {
@@ -624,6 +638,7 @@ function $a73063cc642f3e5f$export$43f0fb951fcb0c54({
624
638
  },
625
639
  children: (product_id, index) => {
626
640
  const owner = $gVhhF$solidjs.getOwner();
641
+ const possible_content_block = $gVhhF$solidjs.createMemo(() => content_blocks_?.()?.()?.[index()]);
627
642
  const display_accessor = $gVhhF$solidjs.createMemo(prev => {
628
643
  const new_display = displays_by_key_().get(product_id);
629
644
  if (prev && $a73063cc642f3e5f$var$deep_equal(prev, new_display))
@@ -676,7 +691,9 @@ function $a73063cc642f3e5f$export$43f0fb951fcb0c54({
676
691
  }
677
692
  do_per_elements_?.(elements, index);
678
693
  });
679
- return product_card_resource; // https://github.com/solidjs/solid/releases/tag/v1.7.0
694
+ return [
695
+ // Show content block before product card, so it's *at* that index
696
+ possible_content_block, product_card_resource]; // https://github.com/solidjs/solid/releases/tag/v1.7.0
680
697
  }
681
698
  });
682
699
  }
@@ -4616,7 +4633,9 @@ function $ac167f6af6a48fc3$export$a1fd619a4743ca08({
4616
4633
  min_products_to_fetch_: min_products_to_fetch_,
4617
4634
  query_base_: query_base_,
4618
4635
  depict_api_: depict_api_,
4619
- is_loading_: is_loading_
4636
+ is_loading_: is_loading_,
4637
+ content_blocks_: content_blocks_,
4638
+ set_number_loaded_displays_: set_number_loaded_displays_
4620
4639
  }) {
4621
4640
  // The following sets up an intersection observer to determine which results are in the viewport, used for the ScrollStatus indicator and knowing when to load more
4622
4641
  const target_to_index_map = new Map();
@@ -4660,11 +4679,13 @@ function $ac167f6af6a48fc3$export$a1fd619a4743ca08({
4660
4679
  query_base_: query_base_,
4661
4680
  depict_api_: depict_api_
4662
4681
  });
4682
+ $gVhhF$solidjs.createComputed(() => set_number_loaded_displays_(displays_by_key_().size));
4663
4683
  return $a73063cc642f3e5f$export$43f0fb951fcb0c54({
4664
4684
  displays_by_key_: displays_by_key_,
4665
4685
  merchant_: merchant_,
4666
4686
  market_: market_,
4667
4687
  product_card_template_: product_card_template_,
4688
+ content_blocks_: content_blocks_,
4668
4689
  do_per_elements_: (elements, index_accessor) =>
4669
4690
  // Adds/removes elements from the "results in viewport" intersection observer above
4670
4691
  $gVhhF$solidjs.createEffect(() => {
@@ -4686,6 +4707,343 @@ function $ac167f6af6a48fc3$export$a1fd619a4743ca08({
4686
4707
  })
4687
4708
  });
4688
4709
  }
4710
+ const $75777da1687ba3f6$var$_tmpl$ = /*#__PURE__*/$gVhhF$solidjsweb.template(`<div></div>`, 2),
4711
+ $75777da1687ba3f6$var$_tmpl$2 = /*#__PURE__*/$gVhhF$solidjsweb.template(`<style type="text/css"></style>`, 2);
4712
+ const $75777da1687ba3f6$export$c500183c31c2b22e = "--spans-columns";
4713
+ function $75777da1687ba3f6$export$ab6b147eec64fea5(props) {
4714
+ const container_class = "x" + $gVhhF$solidjs.createUniqueId();
4715
+ const container_element_ = (() => {
4716
+ const _el$ = $gVhhF$solidjsweb.getNextElement($75777da1687ba3f6$var$_tmpl$);
4717
+ $gVhhF$solidjsweb.spread(_el$, $gVhhF$solidjsweb.mergeProps(() => props.element_attributes, {
4718
+ "classList": {
4719
+ [container_class]: true
4720
+ }
4721
+ }), false, true);
4722
+ $gVhhF$solidjsweb.insert(_el$, () => props.children);
4723
+ $gVhhF$solidjsweb.runHydrationEvents();
4724
+ return _el$;
4725
+ })(); // Don't want this in the error boundary below, it should only be for the actual layouting
4726
+ return $gVhhF$solidjsweb.createComponent((0, $edafe91daf3091d7$export$b69d0d92862de18b), {
4727
+ message_: "Failed calculating css grid layout",
4728
+ severity_: "error",
4729
+ get children() {
4730
+ return $75777da1687ba3f6$export$e2f22da34aaf310a(props, container_element_, false, container_class);
4731
+ }
4732
+ });
4733
+ }
4734
+ function $75777da1687ba3f6$export$e2f22da34aaf310a(props, container_element, insert_after_container = false, container_class) {
4735
+ if (!container_class) {
4736
+ // only try to add if it wasn't provided, so that we have a code path without classList when doing SSR
4737
+ container_class = $gVhhF$depictaiutilishared.make_random_classname();
4738
+ container_element.classList.add(container_class);
4739
+ }
4740
+ const container_selector = `.depict .${container_class}`; // class so ppl can have id if needed
4741
+ const col_styling = $gVhhF$solidjs.createMemo(() => $75777da1687ba3f6$var$generate_media_queried_declarations({
4742
+ container_selector_: container_selector,
4743
+ default_grid_spacing_text: props.grid_spacing,
4744
+ cols_at_size_: props.cols_at_size,
4745
+ override_vertical_spacing_: props.override_vertical_spacing,
4746
+ top_row_shortened_by_: props.top_row_shortened_by_()
4747
+ }));
4748
+ const base_styling = $gVhhF$solidjs.createMemo(() => {
4749
+ return `${container_selector}{display:grid;}`;
4750
+ });
4751
+ const get_styling = $gVhhF$solidjs.createMemo(() => base_styling() + col_styling());
4752
+ const style_element = (() => {
4753
+ const _el$2 = $gVhhF$solidjsweb.getNextElement($75777da1687ba3f6$var$_tmpl$2);
4754
+ $gVhhF$solidjsweb.insert(_el$2, get_styling);
4755
+ return _el$2;
4756
+ })(); // need to create this after set_styling has been called or else there will be no styling in the SSR'd output
4757
+ if (insert_after_container) container_element.after(style_element);
4758
+ return [container_element, style_element];
4759
+ }
4760
+ function $75777da1687ba3f6$var$generate_media_queried_declarations({
4761
+ container_selector_: container_selector_,
4762
+ default_grid_spacing_text: default_grid_spacing_text,
4763
+ cols_at_size_: cols_at_size_,
4764
+ override_vertical_spacing_: override_vertical_spacing_,
4765
+ top_row_shortened_by_: top_row_shortened_by_
4766
+ }) {
4767
+ return cols_at_size_.map(options => {
4768
+ const [n_cols, min, max, grid_spacing_for_size] = options;
4769
+ const spacing_to_use = grid_spacing_for_size || default_grid_spacing_text;
4770
+ // See comment in else block below
4771
+ const can_use_gap = $75777da1687ba3f6$var$can_use_gap_for_unit(spacing_to_use) && (!override_vertical_spacing_ || $75777da1687ba3f6$var$can_use_gap_for_unit(override_vertical_spacing_));
4772
+ let spacing_styling;
4773
+ let additional_styling = ""; // outside the media query
4774
+ if (can_use_gap) spacing_styling = `gap:${spacing_to_use};${override_vertical_spacing_ ? `row-gap:${override_vertical_spacing_};` : ``}`;else {
4775
+ // When using percent units, which our default styling does (because convenient) and our interface relies on (hard to specify different gaps for different screen sizes)
4776
+ // row gaps in grids are relative to the whole height of the grid, maybe see also https://stackoverflow.com/a/53563865. The issue with that is that as we load more products, the gap grows. Also, it breaks existing integrations.
4777
+ // Logical thought: use margins for the vertical spacing. But margins in grids are apparently relative to the size of the individual items in grids.
4778
+ // Given that, and that content blocks can be of different width, we have to do some complicated calculations to convert the provided gap, which is in gap of the total container width, to a margin of the individual items.
4779
+ const width_multiplier = `var(${$75777da1687ba3f6$export$c500183c31c2b22e}, 1)`; // How many cards wide the current item is (needed because content blocks)
4780
+ const one_item_width_exclusing_gaps = `calc(calc(100 / ${n_cols}) - calc(calc(${n_cols * 2 - 2} * calc(${$75777da1687ba3f6$var$strip_percent_unit(spacing_to_use)} / 2)) / ${n_cols}))`; // Width of one item in percent of the whole
4781
+ // Equation from layout.tsx, also used in CheckboxGrid. Needs half spacing for some reason
4782
+ const this_item_width_meat = `calc(${one_item_width_exclusing_gaps} * ${width_multiplier})`; // Width of just the card
4783
+ const this_item_width_gaps = `calc(calc(${width_multiplier} - 1) * ${$75777da1687ba3f6$var$strip_percent_unit(spacing_to_use)})`; // Width of the gaps
4784
+ const this_item_width = `calc(${this_item_width_meat} + ${this_item_width_gaps})`; // Width of this item including gaps
4785
+ // this_item_width needs to be unitless, and since plain css can't do calc(40% / 5%) which would become unitless we need to strip all units in the calculations before
4786
+ const convert_top_spacing_to_item_width_percentage = spacing => `calc(calc(100 / ${this_item_width}) * ${spacing})`; // Now finally we can convert the desired spacing to a percentage of this individual item's width (including gaps that would be there but aren't because content blocks span them)
4787
+ spacing_styling = `column-gap:${spacing_to_use};`; // Still use gaps in the horizontal direction because that works flawlessly
4788
+ // Re-use old layout code to get the correct :nth-child declarations for the top margins
4789
+ additional_styling = $gVhhF$depictaiutilishared.n_col_styling_with_dist(container_selector_ + ">", convert_top_spacing_to_item_width_percentage(default_grid_spacing_text), [[n_cols, min, max, grid_spacing_for_size ? convert_top_spacing_to_item_width_percentage(grid_spacing_for_size) : null]], "grid", override_vertical_spacing_ ? convert_top_spacing_to_item_width_percentage(override_vertical_spacing_) : override_vertical_spacing_, top_row_shortened_by_);
4790
+ }
4791
+ const media_query_body = `${container_selector_}{${spacing_styling}grid-template-columns:repeat(${n_cols},minmax(0,1fr));}`;
4792
+ return `${$gVhhF$depictaiutilishared.layout_media_query_header(min, max)}{${media_query_body}}${additional_styling}`;
4793
+ }).join("");
4794
+ }
4795
+ function $75777da1687ba3f6$var$can_use_gap_for_unit(spacing) {
4796
+ const trimmed_spacing = spacing.trim();
4797
+ return !trimmed_spacing.includes("%");
4798
+ }
4799
+ function $75777da1687ba3f6$var$strip_percent_unit(css_value) {
4800
+ return css_value.replaceAll("%", "");
4801
+ }
4802
+ function $738c3a81fc46a340$export$cb5808ba002cdeed({
4803
+ layout_options_: layout_options_,
4804
+ sort_or_filter_open_: sort_or_filter_open_
4805
+ }) {
4806
+ return $gVhhF$solidjs.createMemo(() => {
4807
+ const layout_options = layout_options_();
4808
+ // Add grid styling that changes when filters get opened/closed
4809
+ const when_filters_closed_cols = layout_options.cols_at_size;
4810
+ return sort_or_filter_open_() ? when_filters_closed_cols.map(row => {
4811
+ const [num_cols_default,,,, override_cols] = row;
4812
+ const cloned_row = [...row];
4813
+ // @ts-ignore
4814
+ cloned_row[0] = num_cols_default - 1;
4815
+ if (override_cols)
4816
+ // @ts-ignore
4817
+ cloned_row[4] = {
4818
+ overrides: Object.fromEntries(Object.entries(override_cols.overrides).map(([row, column]) => [row, column - 1]))
4819
+ };
4820
+ return cloned_row;
4821
+ }) : when_filters_closed_cols;
4822
+ });
4823
+ }
4824
+ function $055384b985678603$export$a79e666719b3647c(cols_at_size_) {
4825
+ const size_active = $gVhhF$solidjs.createMemo(() => cols_at_size_().map(([n_cols, min_width, max_width]) => {
4826
+ const media_query = $gVhhF$depictaiutilishared.layout_media_query_header(min_width, max_width).replaceAll("@media", "");
4827
+ const matches = $b54e6192d0caa293$export$d9f36cf74e24d595(media_query);
4828
+ return [matches, n_cols];
4829
+ }));
4830
+ const n_cols_currently_showing = $gVhhF$solidjs.createMemo(() => {
4831
+ try {
4832
+ const [, n_cols_currently_showing] = size_active().find(([media_query]) => media_query());
4833
+ return n_cols_currently_showing;
4834
+ } catch (e) {
4835
+ $gVhhF$depictaiutilishared.dwarn("No active size found in columnsAtSize - can't render content blocks");
4836
+ return null;
4837
+ }
4838
+ });
4839
+ return n_cols_currently_showing;
4840
+ }
4841
+ function $3bc4a89b971a3af5$export$3f37af283f8fb843(props) {
4842
+ const style = $gVhhF$solidjs.createMemo(() => {
4843
+ const {
4844
+ style: style,
4845
+ height: height,
4846
+ width: width,
4847
+ aspectRatio: aspectRatio
4848
+ } = props;
4849
+ const is_image = aspectRatio != undefined;
4850
+ const size_data = is_image ? {
4851
+ width: "100%",
4852
+ "padding-bottom": 1 / aspectRatio * 100 + "%"
4853
+ } : {
4854
+ width: width,
4855
+ height: height
4856
+ };
4857
+ return {
4858
+ display: "block",
4859
+ ...(style || {}),
4860
+ ...size_data
4861
+ };
4862
+ });
4863
+ return $gVhhF$solidjsweb.createComponent((0, $9fe9883b1d8ecccc$export$acb3eaade4b23afd), {
4864
+ get style() {
4865
+ return style();
4866
+ },
4867
+ get ["class"]() {
4868
+ return props.class;
4869
+ }
4870
+ });
4871
+ }
4872
+ const $d92f338ba8f9da9b$var$_tmpl$ = /*#__PURE__*/$gVhhF$solidjsweb.template(`<div class="content-block-wrapper"></div>`, 2);
4873
+ function $d92f338ba8f9da9b$export$791ef57e62e21c3f({
4874
+ content_blocks_: incoming_content_blocks,
4875
+ cols_at_size_: cols_at_size_,
4876
+ number_of_items_shown_: number_of_items_shown_,
4877
+ set_top_row_shortened_by_: set_top_row_shortened_by_
4878
+ }) {
4879
+ // these are by row
4880
+ const [content_blocks, set_content_blocks] = $gVhhF$solidjsstore.createStore([]);
4881
+ const n_cols_currently_showing_ = $055384b985678603$export$a79e666719b3647c(cols_at_size_);
4882
+ const products_to_rows = products => {
4883
+ const cols_currently_showing = n_cols_currently_showing_();
4884
+ if (cols_currently_showing === null) return 0;
4885
+ return Math.ceil(products / cols_currently_showing);
4886
+ };
4887
+ const showing_rows = $gVhhF$solidjs.createMemo(() => products_to_rows(number_of_items_shown_()));
4888
+ $gVhhF$solidjs.createEffect(() => {
4889
+ const incoming_value = incoming_content_blocks();
4890
+ if (!incoming_value) {
4891
+ set_content_blocks([]);
4892
+ return;
4893
+ }
4894
+ const capped_value = incoming_value.slice(0, showing_rows()); // Don't show more content blocks than we have rows
4895
+ set_content_blocks($gVhhF$solidjsstore.reconcile(capped_value));
4896
+ });
4897
+ const get_wrapped_blocks_ = $d92f338ba8f9da9b$var$wrap_blocks_in_div(content_blocks, n_cols_currently_showing_);
4898
+ $gVhhF$solidjs.createComputed(() => {
4899
+ // Update our styling if a content block forces some items that should be in the top row into a lower one, so we can generate margin-top declarations for them
4900
+ const top_row_block = get_wrapped_blocks_()[0];
4901
+ const blocks_in_top_row_taken = top_row_block?.span_columns;
4902
+ if (blocks_in_top_row_taken == undefined) {
4903
+ // Fall back to zero if no content block in top row, since then no blocks in top row are taken
4904
+ set_top_row_shortened_by_(0);
4905
+ return;
4906
+ }
4907
+ set_top_row_shortened_by_(blocks_in_top_row_taken - 1); // minus one because the content block wrapper also is an element
4908
+ });
4909
+
4910
+ return $d92f338ba8f9da9b$var$remap_blocks_to_index({
4911
+ get_wrapped_blocks_: get_wrapped_blocks_,
4912
+ n_cols_currently_showing_: n_cols_currently_showing_
4913
+ });
4914
+ }
4915
+ /**
4916
+ * Calculate where to put each of the finished wrapped content blocks. Also limit blocks' max width.
4917
+ * @returns an array where index is index of the blocks in the "displays array" and value is the content block (elements) to show at that index
4918
+ */
4919
+ function $d92f338ba8f9da9b$var$remap_blocks_to_index({
4920
+ get_wrapped_blocks_: get_wrapped_blocks_,
4921
+ n_cols_currently_showing_: n_cols_currently_showing_
4922
+ }) {
4923
+ return $gVhhF$solidjs.createMemo(() => {
4924
+ // This computation should be quite cheap since it just moves around things into an array
4925
+ const content_blocks_by_index = [];
4926
+ const constructed_block_arrays = new WeakSet();
4927
+ const wrapped_blocks = get_wrapped_blocks_();
4928
+ const cols_showing = n_cols_currently_showing_();
4929
+ // Need to keep track of products displaced by blocks above when mapping rows to indexes in the actual grid
4930
+ const displaced_products = []; // undefined = is product, true = is content block if number instead of tuple number indicates content blocks in that row. Index in first array is row, index in second array is column
4931
+ for (let i = 0; i < wrapped_blocks.length; i++) {
4932
+ // i = row to show at
4933
+ const block = wrapped_blocks[i];
4934
+ if (!block) continue; // Array can have holes/not defined places
4935
+ const index_of_first_item_in_row = i * cols_showing;
4936
+ const index_of_last_item_in_row = index_of_first_item_in_row + cols_showing;
4937
+ const {
4938
+ span_rows: span_rows,
4939
+ position: position,
4940
+ span_columns: span_columns
4941
+ } = block; // span columns is already capped in the block wrapping step (wrap_blocks_in_div)
4942
+ let target_index;
4943
+ if (position === "left") target_index = index_of_first_item_in_row;else if (position === "right") target_index = index_of_last_item_in_row - span_columns;else if (position === "center") target_index = index_of_first_item_in_row + Math.floor((cols_showing - span_columns) / 2);else throw new Error("Invalid position for content block - must be left, right or center: " + JSON.stringify(position));
4944
+ // Calculate displacement of us by content blocks above us
4945
+ let displacement_by_added_blocks = 0;
4946
+ for (let j = 0; j < i; j++) {
4947
+ const row = displaced_products[j];
4948
+ if (row === undefined) continue; // there were no blocks in this row
4949
+ let items_in_row;
4950
+ if (typeof row === "number") items_in_row = row;else {
4951
+ items_in_row = row.filter(item => item).length;
4952
+ displaced_products[j] = items_in_row;
4953
+ }
4954
+ displacement_by_added_blocks += items_in_row;
4955
+ }
4956
+ const index_of_us_in_row = target_index - index_of_first_item_in_row;
4957
+ for (let j = 0; j < index_of_us_in_row; j++) if (displaced_products[i]?.[j])
4958
+ // Add blocks in our *current* row to the displacement, but only the ones to our left
4959
+ displacement_by_added_blocks++;
4960
+ // Add block to output array at the correct index
4961
+ const final_target_index = target_index - displacement_by_added_blocks;
4962
+ const existing_block = content_blocks_by_index[final_target_index];
4963
+ const block_content = block.content;
4964
+ // If two blocks want to exist at the same location (can happen, for example if one block wants to be at the end of a row and the other one at the start of the next row) add an array with both
4965
+ if (existing_block) {
4966
+ if (constructed_block_arrays.has(existing_block))
4967
+ // Only push to arrays we have created to not create funky bugs when there's an array in JSX.Element
4968
+ existing_block.push(block_content);else {
4969
+ const array = [existing_block, block_content];
4970
+ constructed_block_arrays.add(array);
4971
+ content_blocks_by_index[final_target_index] = array;
4972
+ }
4973
+ } else content_blocks_by_index[final_target_index] = block_content;
4974
+ // Update displacement
4975
+ for (let j = 0; j < span_rows; j++) {
4976
+ const row = displaced_products[i + j] ||= [];
4977
+ for (let k = index_of_us_in_row; k < index_of_us_in_row + span_columns; k++) row[k] = true;
4978
+ }
4979
+ }
4980
+ return content_blocks_by_index;
4981
+ });
4982
+ }
4983
+ /**
4984
+ * Takes a store that contains an array from where index is number of row and value is the result of executing the content block rendering function.
4985
+ * Then renders the content and wraps it into a div with the correct styling.
4986
+ * Also caps span_columns to max available columns
4987
+ */
4988
+ function $d92f338ba8f9da9b$var$wrap_blocks_in_div(rendered_content_blocks, max_span_columns) {
4989
+ const get_wrapped_blocks = $gVhhF$solidjs.mapArray(() => rendered_content_blocks, block => {
4990
+ if (!block) return;
4991
+ const get_span_columns = () => Math.min(block.span_columns, max_span_columns() ?? Infinity);
4992
+ return $gVhhF$solidjs.mergeProps(block, {
4993
+ // Create content divs for the blocks with as much fine-grained diffing as possible?
4994
+ content: (() => {
4995
+ const _el$ = $gVhhF$solidjsweb.getNextElement($d92f338ba8f9da9b$var$_tmpl$);
4996
+ $gVhhF$solidjsweb.insert(_el$, $gVhhF$solidjsweb.createComponent($d92f338ba8f9da9b$var$RenderContent, {
4997
+ get content() {
4998
+ return block.content;
4999
+ }
5000
+ }));
5001
+ $gVhhF$solidjsweb.effect(_p$ => {
5002
+ const _v$ = {
5003
+ [(0, $75777da1687ba3f6$export$c500183c31c2b22e)]: get_span_columns()
5004
+ },
5005
+ _v$2 = `span ${get_span_columns()}`,
5006
+ _v$3 = `span ${block.span_rows}`;
5007
+ _p$._v$ = $gVhhF$solidjsweb.style(_el$, _v$, _p$._v$);
5008
+ _v$2 !== _p$._v$2 && _el$.style.setProperty("grid-column", _p$._v$2 = _v$2);
5009
+ _v$3 !== _p$._v$3 && _el$.style.setProperty("grid-row", _p$._v$3 = _v$3);
5010
+ return _p$;
5011
+ }, {
5012
+ _v$: undefined,
5013
+ _v$2: undefined,
5014
+ _v$3: undefined
5015
+ });
5016
+ return _el$;
5017
+ })(),
5018
+ get span_columns() {
5019
+ // Cap max width of block to the number of columns available, for everyone downstream
5020
+ return get_span_columns();
5021
+ }
5022
+ });
5023
+ });
5024
+ return get_wrapped_blocks;
5025
+ }
5026
+ /**
5027
+ * Basically adds support for async content block functions and shows a rudimentary placeholder if rendering is delayed. Required due to react having a rendering delay.
5028
+ */
5029
+ function $d92f338ba8f9da9b$var$RenderContent(props) {
5030
+ const [resource] = $gVhhF$solidjs.createResource(() => props.content,
5031
+ // Could be reactive
5032
+ fn => fn());
5033
+ $gVhhF$solidjs.createEffect(() => {
5034
+ if (resource.error) console.error("Error in content block rendering", resource.error);
5035
+ });
5036
+ // The suspense is for when there's an async content block (which we have to support due to react having a rendering delay) so that we can show some height while it's loading (should kinda never be visible)
5037
+ return $gVhhF$solidjsweb.createComponent((0, $gVhhF$solidjs.Suspense), {
5038
+ get fallback() {
5039
+ return $gVhhF$solidjsweb.createComponent((0, $3bc4a89b971a3af5$export$3f37af283f8fb843), {
5040
+ width: "100%",
5041
+ height: "max(100%, 400px)"
5042
+ });
5043
+ },
5044
+ children: resource
5045
+ });
5046
+ }
4689
5047
  const $fe76fb463cc60b89$var$_tmpl$ = /*#__PURE__*/$gVhhF$solidjsweb.template(`<div class="PLP-results"><!#><!/><!#><!/></div>`, 6);
4690
5048
  function $fe76fb463cc60b89$export$3925f87b1545cfc6({
4691
5049
  plp_results_: plp_results_,
@@ -4701,7 +5059,8 @@ function $fe76fb463cc60b89$export$3925f87b1545cfc6({
4701
5059
  sort_or_filter_open_: sort_or_filter_open_,
4702
5060
  product_card_template_: product_card_template_,
4703
5061
  layout_options_: layout_options_,
4704
- id_currently_querying_for_: id_currently_querying_for_
5062
+ id_currently_querying_for_: id_currently_querying_for_,
5063
+ content_blocks_by_row_: content_blocks_by_row_
4705
5064
  }) {
4706
5065
  // The plp_results_ resource will be delayed because we're using createBatchedMemo to not make triplicate API requests, but we need to show the placeholders before already to match Chrome and Firefox's "content has to be there, ready for scroll restoration, before all popstate tasks have been completed"-requirement
4707
5066
  const is_loading_ = $gVhhF$solidjs.createMemo(() => plp_results_.loading || query_base_.loading);
@@ -4748,20 +5107,33 @@ function $fe76fb463cc60b89$export$3925f87b1545cfc6({
4748
5107
  let is_just_after_plp_results_update = false;
4749
5108
  let fallback_is_alive = false;
4750
5109
  const [get_should_have_placeholders_rendered, set_should_have_placeholders_rendered] = $gVhhF$solidjs.createSignal(true);
5110
+ const [top_row_shortened_by_, set_top_row_shortened_by_] = $gVhhF$solidjs.createSignal(0);
5111
+ const [product_card_suspense_is_in_fallback, set_product_card_suspense_is_in_fallback] = $gVhhF$solidjs.createSignal(false);
5112
+ const [number_loaded_displays, set_number_loaded_displays_] = $gVhhF$solidjs.createSignal(0);
5113
+ const modified_cols_at_size = $738c3a81fc46a340$export$cb5808ba002cdeed({
5114
+ layout_options_: layout_options_,
5115
+ sort_or_filter_open_: sort_or_filter_open_
5116
+ });
5117
+ const num_placeholders_ = $gVhhF$solidjs.createMemo(() => {
5118
+ // Can't use the data out of request_base for the id because request_base is too late, we need the correct amount of placeholders before the browser has restored the scroll state after processing all popstate events
5119
+ return (0, $aec24316ed262dc0$export$6c9030e511152266) + (get_scroll_restoration_data().find(({
5120
+ for_id: for_id
5121
+ }) => for_id === id_currently_querying_for_())?.min_results_loaded ?? min_products_to_fetch_);
5122
+ });
5123
+ const number_of_items_shown_ = $gVhhF$solidjs.createMemo(() => is_loading_() || product_card_suspense_is_in_fallback() ? num_placeholders_() : number_loaded_displays());
5124
+ const doesnt_have_content_blocks = $gVhhF$solidjs.createMemo(() => !content_blocks_by_row_());
5125
+ const content_blocks_ = $gVhhF$solidjs.createMemo(() => doesnt_have_content_blocks() ? () => [] : $d92f338ba8f9da9b$export$791ef57e62e21c3f({
5126
+ content_blocks_: content_blocks_by_row_,
5127
+ cols_at_size_: modified_cols_at_size,
5128
+ number_of_items_shown_: number_of_items_shown_,
5129
+ set_top_row_shortened_by_: set_top_row_shortened_by_
5130
+ }));
4751
5131
  const rendered_placeholders = $gVhhF$solidjs.createMemo(() => get_should_have_placeholders_rendered() ? $0caf87eaa19079da$export$f33414a4df0afd3f({
5132
+ content_blocks_: content_blocks_,
4752
5133
  product_card_template_: product_card_template_,
4753
- num_placeholders_: $gVhhF$solidjs.createMemo(() => {
4754
- // Can't use the data out of request_base for the id because request_base is too late, we need the correct amount of placeholders before the browser has restored the scroll state after processing all popstate events
4755
- return (0, $aec24316ed262dc0$export$6c9030e511152266) + (get_scroll_restoration_data().find(({
4756
- for_id: for_id
4757
- }) => for_id === id_currently_querying_for_())?.min_results_loaded ?? min_products_to_fetch_);
4758
- })
5134
+ num_placeholders_: num_placeholders_
4759
5135
  }) : undefined);
4760
5136
  const [get_suspense_is_blocked, set_suspense_is_blocked] = $gVhhF$solidjs.createSignal(false);
4761
- const modified_cols_at_size = $fe76fb463cc60b89$var$make_modified_cols_at_size({
4762
- layout_options_: layout_options_,
4763
- sort_or_filter_open_: sort_or_filter_open_
4764
- });
4765
5137
  const block_suspense_if_needed = () => {
4766
5138
  if (!is_just_after_plp_results_update) return;
4767
5139
  is_just_after_plp_results_update = false;
@@ -4794,6 +5166,8 @@ function $fe76fb463cc60b89$export$3925f87b1545cfc6({
4794
5166
  return (() => {
4795
5167
  fallback_is_alive = true;
4796
5168
  $gVhhF$solidjs.onCleanup(block_suspense_if_needed); // Block suspense after initial run every time after we fetch
5169
+ set_product_card_suspense_is_in_fallback(true); // Here for the content block code that needs to know how many items we're displaying
5170
+ $gVhhF$solidjs.onCleanup(() => set_product_card_suspense_is_in_fallback(false));
4797
5171
  return $gVhhF$solidjs.createMemo(() => {
4798
5172
  // We need to be able to block the suspense since when async product cards are *rendering* we want to show the placeholders on initial load but not when loading more
4799
5173
  // In future we could have individual suspense's for each product card, but that's too much for now
@@ -4818,37 +5192,64 @@ function $fe76fb463cc60b89$export$3925f87b1545cfc6({
4818
5192
  min_products_to_fetch_: min_products_to_fetch_,
4819
5193
  query_base_: query_base_,
4820
5194
  depict_api_: depict_api_,
4821
- is_loading_: is_loading_
5195
+ is_loading_: is_loading_,
5196
+ content_blocks_: content_blocks_,
5197
+ set_number_loaded_displays_: set_number_loaded_displays_
4822
5198
  });
4823
5199
  $gVhhF$solidjs.onCleanup(() => suspense_contents = undefined);
4824
5200
  return suspense_contents;
4825
5201
  })();
4826
5202
  }
4827
5203
  });
4828
- return [$gVhhF$solidjsweb.memo((0, $fc23d7668ae0011d$export$a2cc176055f8f08)), $gVhhF$solidjsweb.createComponent((0, $f48d0fbb00835aaa$export$d21e32dfedac04be), {
4829
- get cols_at_size() {
4830
- return modified_cols_at_size();
5204
+ /* This Show is so that we show placeholders while query_base is loading and because it's cumbersome to ensure that everything that directly accesses the plp_results_ resource is within the <Suspense> boundary */
5205
+ const listing_contents = $gVhhF$solidjsweb.createComponent((0, $gVhhF$solidjs.Show), {
5206
+ get when() {
5207
+ return !is_loading_();
4831
5208
  },
4832
- get override_vertical_spacing() {
4833
- return layout_options_().override_vertical_spacing;
5209
+ get fallback() {
5210
+ return rendered_placeholders();
4834
5211
  },
4835
- get grid_spacing() {
4836
- return layout_options_().grid_spacing;
5212
+ children: product_cards_when_data
5213
+ });
5214
+ return [$gVhhF$solidjsweb.memo((0, $fc23d7668ae0011d$export$a2cc176055f8f08)), $gVhhF$solidjsweb.createComponent((0, $gVhhF$solidjs.Show), {
5215
+ get when() {
5216
+ return doesnt_have_content_blocks();
4837
5217
  },
4838
- rows: "all",
4839
- layout: "grid",
4840
- element_attributes: {
4841
- class: "cards"
5218
+ get fallback() {
5219
+ return $gVhhF$solidjsweb.createComponent((0, $75777da1687ba3f6$export$ab6b147eec64fea5), {
5220
+ get cols_at_size() {
5221
+ return modified_cols_at_size();
5222
+ },
5223
+ get override_vertical_spacing() {
5224
+ return layout_options_().override_vertical_spacing;
5225
+ },
5226
+ get grid_spacing() {
5227
+ return layout_options_().grid_spacing;
5228
+ },
5229
+ element_attributes: {
5230
+ class: "cards css-grid"
5231
+ },
5232
+ top_row_shortened_by_: top_row_shortened_by_,
5233
+ children: listing_contents
5234
+ });
4842
5235
  },
4843
5236
  get children() {
4844
- return $gVhhF$solidjsweb.createComponent((0, $gVhhF$solidjs.Show), {
4845
- get when() {
4846
- return !is_loading_();
5237
+ return $gVhhF$solidjsweb.createComponent((0, $f48d0fbb00835aaa$export$d21e32dfedac04be), {
5238
+ get cols_at_size() {
5239
+ return modified_cols_at_size();
5240
+ },
5241
+ get override_vertical_spacing() {
5242
+ return layout_options_().override_vertical_spacing;
4847
5243
  },
4848
- get fallback() {
4849
- return rendered_placeholders();
5244
+ get grid_spacing() {
5245
+ return layout_options_().grid_spacing;
4850
5246
  },
4851
- children: product_cards_when_data
5247
+ rows: "all",
5248
+ layout: "grid",
5249
+ element_attributes: {
5250
+ class: "cards"
5251
+ },
5252
+ children: listing_contents
4852
5253
  });
4853
5254
  }
4854
5255
  })];
@@ -4861,32 +5262,6 @@ function $fe76fb463cc60b89$export$3925f87b1545cfc6({
4861
5262
  return _el$;
4862
5263
  })();
4863
5264
  }
4864
- /**
4865
- * Changes cols_at_size depending on if filters are open or not so one card less is shown when the filters are open
4866
- * This function is special to the actual PLPResults.
4867
- */
4868
- function $fe76fb463cc60b89$var$make_modified_cols_at_size({
4869
- layout_options_: layout_options_,
4870
- sort_or_filter_open_: sort_or_filter_open_
4871
- }) {
4872
- return $gVhhF$solidjs.createMemo(() => {
4873
- const layout_options = layout_options_();
4874
- // Add grid styling that changes when filters get opened/closed
4875
- const when_filters_closed_cols = layout_options.cols_at_size;
4876
- return sort_or_filter_open_() ? when_filters_closed_cols.map(row => {
4877
- const [num_cols_default,,,, override_cols] = row;
4878
- const cloned_row = [...row];
4879
- // @ts-ignore
4880
- cloned_row[0] = num_cols_default - 1;
4881
- if (override_cols)
4882
- // @ts-ignore
4883
- cloned_row[4] = {
4884
- overrides: Object.fromEntries(Object.entries(override_cols.overrides).map(([row, column]) => [row, column - 1]))
4885
- };
4886
- return cloned_row;
4887
- }) : when_filters_closed_cols;
4888
- });
4889
- }
4890
5265
  const $be89be42ce9ea60f$var$_tmpl$ = /*#__PURE__*/$gVhhF$solidjsweb.template(`<div class="sorting-attributes"></div>`, 2),
4891
5266
  $be89be42ce9ea60f$var$_tmpl$2 = /*#__PURE__*/$gVhhF$solidjsweb.template(`<div class="sorting-direction"></div>`, 2),
4892
5267
  $be89be42ce9ea60f$var$_tmpl$3 = /*#__PURE__*/$gVhhF$solidjsweb.template(`<div><div class="input-row"><input type="radio"><span class="custom-indicator"></span><!#><!/></div></div>`, 9),
@@ -6420,7 +6795,8 @@ function $840d88a04b2d22a7$export$f7d2f673fc2f091d({
6420
6795
  product_card_template_: product_card_template_,
6421
6796
  sideways_filter_clearing_flag_: sideways_filter_clearing_flag_,
6422
6797
  sorting_query_param_: sorting_query_param_,
6423
- filter_query_param_prefix_: filter_query_param_prefix_
6798
+ filter_query_param_prefix_: filter_query_param_prefix_,
6799
+ content_blocks_by_row_: content_blocks_by_row_
6424
6800
  }) {
6425
6801
  let results_for;
6426
6802
  let only_show_filters_opener_;
@@ -6712,6 +7088,7 @@ function $840d88a04b2d22a7$export$f7d2f673fc2f091d({
6712
7088
  product_card_template_: product_card_template_,
6713
7089
  sort_or_filter_open_: sort_or_filter_open_,
6714
7090
  desktop_filter_elements_: desktop_filter_elements_,
7091
+ content_blocks_by_row_: content_blocks_by_row_,
6715
7092
  id_currently_querying_for_: query_id_,
6716
7093
  no_results_options_: {
6717
7094
  selected_filters_: selected_filters_,
@@ -7221,6 +7598,7 @@ function $48567ac5b39bac56$export$e2bf8ce7779e827e(props) {
7221
7598
  expanded_hierarchical_filters_: expanded_hierarchical_filters_,
7222
7599
  selected_filters_: selected_filters_,
7223
7600
  sideways_filter_clearing_flag_: sideways_filter_clearing_flag_,
7601
+ content_blocks_by_row_: () => props.content_blocks_by_row,
7224
7602
  scroll_restoration_data_: scroll_restoration_data_,
7225
7603
  layout_options_: $gVhhF$solidjs.createMemo(() => ({
7226
7604
  cols_at_size: $4e04be41243c3d80$export$6daf8749b65a1b77(props.cols_at_size),
@@ -7471,37 +7849,6 @@ async function $63b10c9f461e0ef6$var$download_categories(tenant, market, type) {
7471
7849
  return [];
7472
7850
  }
7473
7851
  }
7474
- function $3bc4a89b971a3af5$export$3f37af283f8fb843(props) {
7475
- const style = $gVhhF$solidjs.createMemo(() => {
7476
- const {
7477
- style: style,
7478
- height: height,
7479
- width: width,
7480
- aspectRatio: aspectRatio
7481
- } = props;
7482
- const is_image = aspectRatio != undefined;
7483
- const size_data = is_image ? {
7484
- width: "100%",
7485
- "padding-bottom": 1 / aspectRatio * 100 + "%"
7486
- } : {
7487
- width: width,
7488
- height: height
7489
- };
7490
- return {
7491
- display: "block",
7492
- ...(style || {}),
7493
- ...size_data
7494
- };
7495
- });
7496
- return $gVhhF$solidjsweb.createComponent((0, $9fe9883b1d8ecccc$export$acb3eaade4b23afd), {
7497
- get style() {
7498
- return style();
7499
- },
7500
- get ["class"]() {
7501
- return props.class;
7502
- }
7503
- });
7504
- }
7505
7852
  const $6f604560873e4f69$var$_tmpl$ = /*#__PURE__*/$gVhhF$solidjsweb.template(`<div class="instant-card"><div class="img-part"></div><div class="right-part"><div class="title-brand-tagline"><span class="title"></span></div></div></div>`, 10);
7506
7853
  function $6f604560873e4f69$export$ee1733d9a8495996() {
7507
7854
  return (() => {
@@ -9927,7 +10274,8 @@ function $f1d7cb69f839a526$export$a54ec244c8863715({
9927
10274
  router_: router_,
9928
10275
  content_results_rows_: content_results_rows_,
9929
10276
  content_layout_options_: content_layout_options_,
9930
- content_search_enabled_: content_search_enabled_
10277
+ content_search_enabled_: content_search_enabled_,
10278
+ content_blocks_by_row_: content_blocks_by_row_
9931
10279
  }) {
9932
10280
  const [get_sorting] = current_sorting_;
9933
10281
  const all_products_loaded_ = $gVhhF$solidjs.createSignal(false);
@@ -10206,6 +10554,7 @@ function $f1d7cb69f839a526$export$a54ec244c8863715({
10206
10554
  layout_options_: layout_options_,
10207
10555
  sort_or_filter_open_: sort_or_filter_open_,
10208
10556
  id_currently_querying_for_: get_search_query_,
10557
+ content_blocks_by_row_: content_blocks_by_row_,
10209
10558
  no_results_options_: {
10210
10559
  selected_filters_: selected_filters_,
10211
10560
  expanded_hierarchical_filters_: expanded_hierarchical_filters_,
@@ -10651,6 +11000,7 @@ function $2c61e4cd8229c49a$export$f2dc7e4e4aa11abb(props) {
10651
11000
  search_sorting_open_: state_.sorting_open,
10652
11001
  expanded_filters_: state_.expanded_filters,
10653
11002
  content_results_rows_: state_.content_results_rows,
11003
+ content_blocks_by_row_: () => props.content_blocks_by_row,
10654
11004
  router_: shared_properties.router_,
10655
11005
  make_category_suggestion_card_: shared_properties.enable_category_suggestions_ ? category_suggestion_ => {
10656
11006
  return $dae23104ba8bb78c$export$d757d54550ebfb3d({