@depict-ai/ui 4.10.21 → 4.10.22

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.cjs CHANGED
@@ -115,7 +115,7 @@ $parcel$export(module.exports, "BreadCrumbs", () => $335c02c1241a9ca8$export$5b7
115
115
  $parcel$export(module.exports, "QuickLinks", () => $335c02c1241a9ca8$export$de035477d6fef996);
116
116
  $parcel$export(module.exports, "CategoryPage", () => $c10e33c4681f8c9b$export$e2bf8ce7779e827e);
117
117
  /*! Depict.ai search and product listing SDK */
118
- const $aa1938dec50d6c12$export$83d89fbfd8236492 = "4.10.21";
118
+ const $aa1938dec50d6c12$export$83d89fbfd8236492 = "4.10.22";
119
119
  function $3e17e871e9d0911d$export$d9f36cf74e24d595(media_query) {
120
120
  const signal = $52FdA$solidjs.createSignal(false);
121
121
  $52FdA$solidjs.onCleanup($52FdA$depictaiutilishared.javascript_media_query(media_query, _ref => {
@@ -1284,8 +1284,15 @@ function $0d3ee7000f047e67$export$a1fd619a4743ca08(_ref) {
1284
1284
  setFirstResultInViewport(Math.min(...intersecting) + 1); // +1 because we want to start counting at 1
1285
1285
  setLastResultsInViewport(Math.max(...intersecting) + 1);
1286
1286
  });
1287
- return renderedDisplays_;
1287
+ // Content blocks placed after the last product (but still in its row) have no product card to render in front of, so render them after the cards once there are no more products to load
1288
+ const trailingContentBlocks_ = $52FdA$solidjs.createMemo(() => {
1289
+ var _content_blocks_, _content_blocks_$trai;
1290
+ if (!all_products_loaded_[0]()) return [];
1291
+ return (content_blocks_ === null || content_blocks_ === void 0 ? void 0 : (_content_blocks_ = content_blocks_()) === null || _content_blocks_ === void 0 ? void 0 : (_content_blocks_$trai = _content_blocks_.trailing_) === null || _content_blocks_$trai === void 0 ? void 0 : _content_blocks_$trai.call(_content_blocks_, displays_by_key_().size)) || [];
1292
+ });
1293
+ return [renderedDisplays_, trailingContentBlocks_]; // Regarding the as unknown: https://github.com/solidjs/solid/releases/tag/v1.7.0
1288
1294
  }
1295
+
1289
1296
  var $6c2c739b113a8ddf$var$_tmpl$ = /*#__PURE__*/$52FdA$solidjsweb.template(`<div>`),
1290
1297
  $6c2c739b113a8ddf$var$_tmpl$2 = /*#__PURE__*/$52FdA$solidjsweb.template(`<style type=text/css>`);
1291
1298
  function $6c2c739b113a8ddf$export$d21e32dfedac04be(props) {
@@ -1658,10 +1665,18 @@ function $f8f375d6245ffff2$export$791ef57e62e21c3f(_ref) {
1658
1665
  set_top_row_shortened_by_(blocks_in_top_row_taken - 1); // minus one because the content block wrapper also is an element
1659
1666
  });
1660
1667
 
1661
- return $52FdA$solidjs.createMemo(() => $f8f375d6245ffff2$export$92aa5d691d588f3f({
1668
+ const remapped_ = $52FdA$solidjs.createMemo(() => $f8f375d6245ffff2$export$92aa5d691d588f3f({
1662
1669
  wrapped_blocks_: get_wrapped_blocks_(),
1663
1670
  n_cols_currently_showing_: n_cols_currently_showing_()
1664
- }).content_blocks_by_index_);
1671
+ }));
1672
+ const content_blocks_by_index_ = $52FdA$solidjs.createMemo(() => remapped_().content_blocks_by_index_);
1673
+ return Object.assign(content_blocks_by_index_, {
1674
+ trailing_: product_count => $f8f375d6245ffff2$export$b94605e5b3ce01c({
1675
+ ...remapped_(),
1676
+ n_cols_currently_showing_: n_cols_currently_showing_(),
1677
+ product_count: product_count
1678
+ })
1679
+ });
1665
1680
  }
1666
1681
  function $f8f375d6245ffff2$export$92aa5d691d588f3f(_ref2) {
1667
1682
  let {
@@ -1670,13 +1685,16 @@ function $f8f375d6245ffff2$export$92aa5d691d588f3f(_ref2) {
1670
1685
  } = _ref2;
1671
1686
  // This computation should be quite cheap since it just moves around things into an array
1672
1687
  const content_blocks_by_index_ = [];
1688
+ const rows_by_index_ = []; // the row of each block at each index of content_blocks_by_index_, in the same order
1673
1689
  const constructed_block_arrays = new WeakSet();
1674
1690
  // Need to keep track of products displaced by blocks above when mapping rows to indexes in the actual grid
1675
1691
  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
1676
1692
  if (!n_cols_currently_showing_)
1677
1693
  // Nope out of here if we don't know how many columns are showing
1678
1694
  return {
1679
- content_blocks_by_index_: content_blocks_by_index_
1695
+ content_blocks_by_index_: content_blocks_by_index_,
1696
+ rows_by_index_: rows_by_index_,
1697
+ displaced_products_: displaced_products_
1680
1698
  };
1681
1699
  for (let i = 0; i < wrapped_blocks_.length; i++) {
1682
1700
  // i = row to show at
@@ -1724,6 +1742,7 @@ function $f8f375d6245ffff2$export$92aa5d691d588f3f(_ref2) {
1724
1742
  content_blocks_by_index_[final_target_index] = array;
1725
1743
  }
1726
1744
  } else content_blocks_by_index_[final_target_index] = block_content;
1745
+ (rows_by_index_[final_target_index] || (rows_by_index_[final_target_index] = [])).push(i);
1727
1746
  // Update displacement
1728
1747
  for (let j = 0; j < span_rows; j++) {
1729
1748
  var _ref3;
@@ -1733,9 +1752,46 @@ function $f8f375d6245ffff2$export$92aa5d691d588f3f(_ref2) {
1733
1752
  }
1734
1753
  return {
1735
1754
  content_blocks_by_index_: content_blocks_by_index_,
1755
+ rows_by_index_: rows_by_index_,
1736
1756
  displaced_products_: displaced_products_
1737
1757
  };
1738
1758
  }
1759
+ function $f8f375d6245ffff2$export$b94605e5b3ce01c(_ref4) {
1760
+ let {
1761
+ content_blocks_by_index_: content_blocks_by_index_,
1762
+ rows_by_index_: rows_by_index_,
1763
+ displaced_products_: displaced_products_,
1764
+ n_cols_currently_showing_: n_cols_currently_showing_,
1765
+ product_count: product_count
1766
+ } = _ref4;
1767
+ const trailing = [];
1768
+ if (!n_cols_currently_showing_ || product_count <= 0) return trailing;
1769
+ // Find the row the last product lands in: each row has room for the columns that blocks don't take up
1770
+ let last_product_row = 0;
1771
+ for (let seen_products = 0;; last_product_row++) {
1772
+ const row = displaced_products_[last_product_row];
1773
+ const taken_by_blocks = typeof row === "number" ? row : row ? row.filter(item => item).length : 0;
1774
+ seen_products += Math.max(0, n_cols_currently_showing_ - taken_by_blocks);
1775
+ if (seen_products >= product_count) break;
1776
+ // Rows past the ones blocks take up all have room for products, so we're done by then at the latest
1777
+ if (last_product_row >= displaced_products_.length + product_count) break;
1778
+ }
1779
+ for (let i = product_count; i < content_blocks_by_index_.length; i++) {
1780
+ var _rows$;
1781
+ const block = content_blocks_by_index_[i];
1782
+ if (block === undefined) continue;
1783
+ const rows = rows_by_index_[i] || [];
1784
+ if (Array.isArray(block) && rows.length > 1) {
1785
+ // Several blocks share this index (e.g. the end of one row and the start of the next): keep the ones in the last product's row
1786
+ const in_last_row = block.filter((_, j) => rows[j] <= last_product_row);
1787
+ if (in_last_row.length) trailing.push(in_last_row);
1788
+ continue;
1789
+ }
1790
+ if (((_rows$ = rows[0]) !== null && _rows$ !== void 0 ? _rows$ : Infinity) > last_product_row) continue; // a row below the last product's row: keep it hidden
1791
+ trailing.push(block);
1792
+ }
1793
+ return trailing;
1794
+ }
1739
1795
  /**
1740
1796
  * 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.
1741
1797
  * Then renders the content and wraps it into a div with the correct styling.
@@ -1788,6 +1844,7 @@ function $f8f375d6245ffff2$var$wrap_blocks_in_div(rendered_content_blocks, max_s
1788
1844
  content: () => {
1789
1845
  // Sneaky on-demand rendering, so we don't render more blocks than we can show: we have the rendered value here and don't return a function that renders because if our block would be moved around we'd be guaranteed to re-render
1790
1846
  // However, no need to count products to know if we should render: the <For> loops in Placeholders and render_displays will only call this function if there's actually a product here that wants to display this block
1847
+ // (or, once all products have loaded, ResultsProductCards renders the blocks placed after the last product)
1791
1848
  set_rendering_delayed_(false);
1792
1849
  return content;
1793
1850
  },
package/ES10/index.d.ts CHANGED
@@ -11,7 +11,7 @@ import { GetListingRequest } from "@depict-ai/types/api/GetListingRequest";
11
11
  import { BaseSearchRequestV3 } from "@depict-ai/types/api/BaseSearchRequestV3";
12
12
  import { FeaturedInDisplay } from "@depict-ai/types/api/FeaturedInResponseV3";
13
13
  import { SearchFilter as _SearchFilter3 } from "@depict-ai/types/api/SearchRequestV2";
14
- export const version = "4.10.21";
14
+ export const version = "4.10.22";
15
15
  /**
16
16
  * Use `javascript_media_query` but return a reactive accessor instead of taking a callback function
17
17
  */
@@ -425,10 +425,8 @@ export function remap_blocks_to_index<T = () => JSX.Element | Promise<JSX.Elemen
425
425
  })[];
426
426
  n_cols_currently_showing_: number | null;
427
427
  }): {
428
- content_blocks_by_index_: (Awaited<T> | T[])[];
429
- readonly displaced_products_?: undefined;
430
- } | {
431
428
  readonly content_blocks_by_index_: (Awaited<T> | T[])[];
429
+ readonly rows_by_index_: number[][];
432
430
  readonly displaced_products_: (number | (true | undefined)[])[];
433
431
  };
434
432
  /** @jsxImportSource solid-js */
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.21";
13
+ const $8db9a15135765c11$export$83d89fbfd8236492 = "4.10.22";
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 => {
@@ -1179,8 +1179,15 @@ function $45a8953d760b5e58$export$a1fd619a4743ca08(_ref) {
1179
1179
  setFirstResultInViewport(Math.min(...intersecting) + 1); // +1 because we want to start counting at 1
1180
1180
  setLastResultsInViewport(Math.max(...intersecting) + 1);
1181
1181
  });
1182
- return renderedDisplays_;
1182
+ // Content blocks placed after the last product (but still in its row) have no product card to render in front of, so render them after the cards once there are no more products to load
1183
+ const trailingContentBlocks_ = $8tj43$createMemo(() => {
1184
+ var _content_blocks_, _content_blocks_$trai;
1185
+ if (!all_products_loaded_[0]()) return [];
1186
+ return (content_blocks_ === null || content_blocks_ === void 0 ? void 0 : (_content_blocks_ = content_blocks_()) === null || _content_blocks_ === void 0 ? void 0 : (_content_blocks_$trai = _content_blocks_.trailing_) === null || _content_blocks_$trai === void 0 ? void 0 : _content_blocks_$trai.call(_content_blocks_, displays_by_key_().size)) || [];
1187
+ });
1188
+ return [renderedDisplays_, trailingContentBlocks_]; // Regarding the as unknown: https://github.com/solidjs/solid/releases/tag/v1.7.0
1183
1189
  }
1190
+
1184
1191
  var $63f1f8dbcd07d3b0$var$_tmpl$ = /*#__PURE__*/$8tj43$template(`<div>`),
1185
1192
  $63f1f8dbcd07d3b0$var$_tmpl$2 = /*#__PURE__*/$8tj43$template(`<style type=text/css>`);
1186
1193
  function $63f1f8dbcd07d3b0$export$d21e32dfedac04be(props) {
@@ -1553,10 +1560,18 @@ function $ff7feae4dddd6073$export$791ef57e62e21c3f(_ref) {
1553
1560
  set_top_row_shortened_by_(blocks_in_top_row_taken - 1); // minus one because the content block wrapper also is an element
1554
1561
  });
1555
1562
 
1556
- return $8tj43$createMemo(() => $ff7feae4dddd6073$export$92aa5d691d588f3f({
1563
+ const remapped_ = $8tj43$createMemo(() => $ff7feae4dddd6073$export$92aa5d691d588f3f({
1557
1564
  wrapped_blocks_: get_wrapped_blocks_(),
1558
1565
  n_cols_currently_showing_: n_cols_currently_showing_()
1559
- }).content_blocks_by_index_);
1566
+ }));
1567
+ const content_blocks_by_index_ = $8tj43$createMemo(() => remapped_().content_blocks_by_index_);
1568
+ return Object.assign(content_blocks_by_index_, {
1569
+ trailing_: product_count => $ff7feae4dddd6073$export$b94605e5b3ce01c({
1570
+ ...remapped_(),
1571
+ n_cols_currently_showing_: n_cols_currently_showing_(),
1572
+ product_count: product_count
1573
+ })
1574
+ });
1560
1575
  }
1561
1576
  function $ff7feae4dddd6073$export$92aa5d691d588f3f(_ref2) {
1562
1577
  let {
@@ -1565,13 +1580,16 @@ function $ff7feae4dddd6073$export$92aa5d691d588f3f(_ref2) {
1565
1580
  } = _ref2;
1566
1581
  // This computation should be quite cheap since it just moves around things into an array
1567
1582
  const content_blocks_by_index_ = [];
1583
+ const rows_by_index_ = []; // the row of each block at each index of content_blocks_by_index_, in the same order
1568
1584
  const constructed_block_arrays = new WeakSet();
1569
1585
  // Need to keep track of products displaced by blocks above when mapping rows to indexes in the actual grid
1570
1586
  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
1571
1587
  if (!n_cols_currently_showing_)
1572
1588
  // Nope out of here if we don't know how many columns are showing
1573
1589
  return {
1574
- content_blocks_by_index_: content_blocks_by_index_
1590
+ content_blocks_by_index_: content_blocks_by_index_,
1591
+ rows_by_index_: rows_by_index_,
1592
+ displaced_products_: displaced_products_
1575
1593
  };
1576
1594
  for (let i = 0; i < wrapped_blocks_.length; i++) {
1577
1595
  // i = row to show at
@@ -1619,6 +1637,7 @@ function $ff7feae4dddd6073$export$92aa5d691d588f3f(_ref2) {
1619
1637
  content_blocks_by_index_[final_target_index] = array;
1620
1638
  }
1621
1639
  } else content_blocks_by_index_[final_target_index] = block_content;
1640
+ (rows_by_index_[final_target_index] || (rows_by_index_[final_target_index] = [])).push(i);
1622
1641
  // Update displacement
1623
1642
  for (let j = 0; j < span_rows; j++) {
1624
1643
  var _ref3;
@@ -1628,9 +1647,46 @@ function $ff7feae4dddd6073$export$92aa5d691d588f3f(_ref2) {
1628
1647
  }
1629
1648
  return {
1630
1649
  content_blocks_by_index_: content_blocks_by_index_,
1650
+ rows_by_index_: rows_by_index_,
1631
1651
  displaced_products_: displaced_products_
1632
1652
  };
1633
1653
  }
1654
+ function $ff7feae4dddd6073$export$b94605e5b3ce01c(_ref4) {
1655
+ let {
1656
+ content_blocks_by_index_: content_blocks_by_index_,
1657
+ rows_by_index_: rows_by_index_,
1658
+ displaced_products_: displaced_products_,
1659
+ n_cols_currently_showing_: n_cols_currently_showing_,
1660
+ product_count: product_count
1661
+ } = _ref4;
1662
+ const trailing = [];
1663
+ if (!n_cols_currently_showing_ || product_count <= 0) return trailing;
1664
+ // Find the row the last product lands in: each row has room for the columns that blocks don't take up
1665
+ let last_product_row = 0;
1666
+ for (let seen_products = 0;; last_product_row++) {
1667
+ const row = displaced_products_[last_product_row];
1668
+ const taken_by_blocks = typeof row === "number" ? row : row ? row.filter(item => item).length : 0;
1669
+ seen_products += Math.max(0, n_cols_currently_showing_ - taken_by_blocks);
1670
+ if (seen_products >= product_count) break;
1671
+ // Rows past the ones blocks take up all have room for products, so we're done by then at the latest
1672
+ if (last_product_row >= displaced_products_.length + product_count) break;
1673
+ }
1674
+ for (let i = product_count; i < content_blocks_by_index_.length; i++) {
1675
+ var _rows$;
1676
+ const block = content_blocks_by_index_[i];
1677
+ if (block === undefined) continue;
1678
+ const rows = rows_by_index_[i] || [];
1679
+ if (Array.isArray(block) && rows.length > 1) {
1680
+ // Several blocks share this index (e.g. the end of one row and the start of the next): keep the ones in the last product's row
1681
+ const in_last_row = block.filter((_, j) => rows[j] <= last_product_row);
1682
+ if (in_last_row.length) trailing.push(in_last_row);
1683
+ continue;
1684
+ }
1685
+ if (((_rows$ = rows[0]) !== null && _rows$ !== void 0 ? _rows$ : Infinity) > last_product_row) continue; // a row below the last product's row: keep it hidden
1686
+ trailing.push(block);
1687
+ }
1688
+ return trailing;
1689
+ }
1634
1690
  /**
1635
1691
  * 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.
1636
1692
  * Then renders the content and wraps it into a div with the correct styling.
@@ -1683,6 +1739,7 @@ function $ff7feae4dddd6073$var$wrap_blocks_in_div(rendered_content_blocks, max_s
1683
1739
  content: () => {
1684
1740
  // Sneaky on-demand rendering, so we don't render more blocks than we can show: we have the rendered value here and don't return a function that renders because if our block would be moved around we'd be guaranteed to re-render
1685
1741
  // However, no need to count products to know if we should render: the <For> loops in Placeholders and render_displays will only call this function if there's actually a product here that wants to display this block
1742
+ // (or, once all products have loaded, ResultsProductCards renders the blocks placed after the last product)
1686
1743
  set_rendering_delayed_(false);
1687
1744
  return content;
1688
1745
  },
package/latest/index.cjs CHANGED
@@ -109,7 +109,7 @@ $parcel$export(module.exports, "BreadCrumbs", () => $1f4925833f07df29$export$5b7
109
109
  $parcel$export(module.exports, "QuickLinks", () => $1f4925833f07df29$export$de035477d6fef996);
110
110
  $parcel$export(module.exports, "CategoryPage", () => $14f289047713d67a$export$e2bf8ce7779e827e);
111
111
  /*! Depict.ai search and product listing SDK */
112
- const $b757f75811f3261f$export$83d89fbfd8236492 = "4.10.21";
112
+ const $b757f75811f3261f$export$83d89fbfd8236492 = "4.10.22";
113
113
  function $b54e6192d0caa293$export$d9f36cf74e24d595(media_query) {
114
114
  const signal = $gVhhF$solidjs.createSignal(false);
115
115
  $gVhhF$solidjs.onCleanup($gVhhF$depictaiutilishared.javascript_media_query(media_query, ({
@@ -1232,8 +1232,14 @@ function $ac167f6af6a48fc3$export$a1fd619a4743ca08({
1232
1232
  setFirstResultInViewport(Math.min(...intersecting) + 1); // +1 because we want to start counting at 1
1233
1233
  setLastResultsInViewport(Math.max(...intersecting) + 1);
1234
1234
  });
1235
- return renderedDisplays_;
1235
+ // Content blocks placed after the last product (but still in its row) have no product card to render in front of, so render them after the cards once there are no more products to load
1236
+ const trailingContentBlocks_ = $gVhhF$solidjs.createMemo(() => {
1237
+ if (!all_products_loaded_[0]()) return [];
1238
+ return content_blocks_?.()?.trailing_?.(displays_by_key_().size) || [];
1239
+ });
1240
+ return [renderedDisplays_, trailingContentBlocks_]; // Regarding the as unknown: https://github.com/solidjs/solid/releases/tag/v1.7.0
1236
1241
  }
1242
+
1237
1243
  var $f48d0fbb00835aaa$var$_tmpl$ = /*#__PURE__*/$gVhhF$solidjsweb.template(`<div>`),
1238
1244
  $f48d0fbb00835aaa$var$_tmpl$2 = /*#__PURE__*/$gVhhF$solidjsweb.template(`<style type=text/css>`);
1239
1245
  function $f48d0fbb00835aaa$export$d21e32dfedac04be(props) {
@@ -1583,10 +1589,18 @@ function $d92f338ba8f9da9b$export$791ef57e62e21c3f({
1583
1589
  set_top_row_shortened_by_(blocks_in_top_row_taken - 1); // minus one because the content block wrapper also is an element
1584
1590
  });
1585
1591
 
1586
- return $gVhhF$solidjs.createMemo(() => $d92f338ba8f9da9b$export$92aa5d691d588f3f({
1592
+ const remapped_ = $gVhhF$solidjs.createMemo(() => $d92f338ba8f9da9b$export$92aa5d691d588f3f({
1587
1593
  wrapped_blocks_: get_wrapped_blocks_(),
1588
1594
  n_cols_currently_showing_: n_cols_currently_showing_()
1589
- }).content_blocks_by_index_);
1595
+ }));
1596
+ const content_blocks_by_index_ = $gVhhF$solidjs.createMemo(() => remapped_().content_blocks_by_index_);
1597
+ return Object.assign(content_blocks_by_index_, {
1598
+ trailing_: product_count => $d92f338ba8f9da9b$export$b94605e5b3ce01c({
1599
+ ...remapped_(),
1600
+ n_cols_currently_showing_: n_cols_currently_showing_(),
1601
+ product_count: product_count
1602
+ })
1603
+ });
1590
1604
  }
1591
1605
  function $d92f338ba8f9da9b$export$92aa5d691d588f3f({
1592
1606
  wrapped_blocks_: wrapped_blocks_,
@@ -1594,13 +1608,16 @@ function $d92f338ba8f9da9b$export$92aa5d691d588f3f({
1594
1608
  }) {
1595
1609
  // This computation should be quite cheap since it just moves around things into an array
1596
1610
  const content_blocks_by_index_ = [];
1611
+ const rows_by_index_ = []; // the row of each block at each index of content_blocks_by_index_, in the same order
1597
1612
  const constructed_block_arrays = new WeakSet();
1598
1613
  // Need to keep track of products displaced by blocks above when mapping rows to indexes in the actual grid
1599
1614
  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
1600
1615
  if (!n_cols_currently_showing_)
1601
1616
  // Nope out of here if we don't know how many columns are showing
1602
1617
  return {
1603
- content_blocks_by_index_: content_blocks_by_index_
1618
+ content_blocks_by_index_: content_blocks_by_index_,
1619
+ rows_by_index_: rows_by_index_,
1620
+ displaced_products_: displaced_products_
1604
1621
  };
1605
1622
  for (let i = 0; i < wrapped_blocks_.length; i++) {
1606
1623
  // i = row to show at
@@ -1645,6 +1662,7 @@ function $d92f338ba8f9da9b$export$92aa5d691d588f3f({
1645
1662
  content_blocks_by_index_[final_target_index] = array;
1646
1663
  }
1647
1664
  } else content_blocks_by_index_[final_target_index] = block_content;
1665
+ (rows_by_index_[final_target_index] ||= []).push(i);
1648
1666
  // Update displacement
1649
1667
  for (let j = 0; j < span_rows; j++) {
1650
1668
  const row = displaced_products_[i + j] ||= [];
@@ -1653,9 +1671,44 @@ function $d92f338ba8f9da9b$export$92aa5d691d588f3f({
1653
1671
  }
1654
1672
  return {
1655
1673
  content_blocks_by_index_: content_blocks_by_index_,
1674
+ rows_by_index_: rows_by_index_,
1656
1675
  displaced_products_: displaced_products_
1657
1676
  };
1658
1677
  }
1678
+ function $d92f338ba8f9da9b$export$b94605e5b3ce01c({
1679
+ content_blocks_by_index_: content_blocks_by_index_,
1680
+ rows_by_index_: rows_by_index_,
1681
+ displaced_products_: displaced_products_,
1682
+ n_cols_currently_showing_: n_cols_currently_showing_,
1683
+ product_count: product_count
1684
+ }) {
1685
+ const trailing = [];
1686
+ if (!n_cols_currently_showing_ || product_count <= 0) return trailing;
1687
+ // Find the row the last product lands in: each row has room for the columns that blocks don't take up
1688
+ let last_product_row = 0;
1689
+ for (let seen_products = 0;; last_product_row++) {
1690
+ const row = displaced_products_[last_product_row];
1691
+ const taken_by_blocks = typeof row === "number" ? row : row ? row.filter(item => item).length : 0;
1692
+ seen_products += Math.max(0, n_cols_currently_showing_ - taken_by_blocks);
1693
+ if (seen_products >= product_count) break;
1694
+ // Rows past the ones blocks take up all have room for products, so we're done by then at the latest
1695
+ if (last_product_row >= displaced_products_.length + product_count) break;
1696
+ }
1697
+ for (let i = product_count; i < content_blocks_by_index_.length; i++) {
1698
+ const block = content_blocks_by_index_[i];
1699
+ if (block === undefined) continue;
1700
+ const rows = rows_by_index_[i] || [];
1701
+ if (Array.isArray(block) && rows.length > 1) {
1702
+ // Several blocks share this index (e.g. the end of one row and the start of the next): keep the ones in the last product's row
1703
+ const in_last_row = block.filter((_, j) => rows[j] <= last_product_row);
1704
+ if (in_last_row.length) trailing.push(in_last_row);
1705
+ continue;
1706
+ }
1707
+ if ((rows[0] ?? Infinity) > last_product_row) continue; // a row below the last product's row: keep it hidden
1708
+ trailing.push(block);
1709
+ }
1710
+ return trailing;
1711
+ }
1659
1712
  /**
1660
1713
  * 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.
1661
1714
  * Then renders the content and wraps it into a div with the correct styling.
@@ -1705,6 +1758,7 @@ function $d92f338ba8f9da9b$var$wrap_blocks_in_div(rendered_content_blocks, max_s
1705
1758
  content: () => {
1706
1759
  // Sneaky on-demand rendering, so we don't render more blocks than we can show: we have the rendered value here and don't return a function that renders because if our block would be moved around we'd be guaranteed to re-render
1707
1760
  // However, no need to count products to know if we should render: the <For> loops in Placeholders and render_displays will only call this function if there's actually a product here that wants to display this block
1761
+ // (or, once all products have loaded, ResultsProductCards renders the blocks placed after the last product)
1708
1762
  set_rendering_delayed_(false);
1709
1763
  return content;
1710
1764
  },
package/latest/index.d.ts CHANGED
@@ -11,7 +11,7 @@ import { GetListingRequest } from "@depict-ai/types/api/GetListingRequest";
11
11
  import { BaseSearchRequestV3 } from "@depict-ai/types/api/BaseSearchRequestV3";
12
12
  import { FeaturedInDisplay } from "@depict-ai/types/api/FeaturedInResponseV3";
13
13
  import { SearchFilter as _SearchFilter3 } from "@depict-ai/types/api/SearchRequestV2";
14
- export const version = "4.10.21";
14
+ export const version = "4.10.22";
15
15
  /**
16
16
  * Use `javascript_media_query` but return a reactive accessor instead of taking a callback function
17
17
  */
@@ -425,10 +425,8 @@ export function remap_blocks_to_index<T = () => JSX.Element | Promise<JSX.Elemen
425
425
  })[];
426
426
  n_cols_currently_showing_: number | null;
427
427
  }): {
428
- content_blocks_by_index_: (Awaited<T> | T[])[];
429
- readonly displaced_products_?: undefined;
430
- } | {
431
428
  readonly content_blocks_by_index_: (Awaited<T> | T[])[];
429
+ readonly rows_by_index_: number[][];
432
430
  readonly displaced_products_: (number | (true | undefined)[])[];
433
431
  };
434
432
  /** @jsxImportSource solid-js */
package/latest/index.js CHANGED
@@ -7,7 +7,7 @@ import { createStore as $9HbP8$createStore, reconcile as $9HbP8$reconcile } from
7
7
  /*! Depict.ai search and product listing SDK */
8
8
  import { register_es_version } from "../multi_import_deduplicator.mjs";
9
9
  register_es_version("ui", "latest");
10
- const $ec291e0010116877$export$83d89fbfd8236492 = "4.10.21";
10
+ const $ec291e0010116877$export$83d89fbfd8236492 = "4.10.22";
11
11
  function $dc9262ef6f786812$export$d9f36cf74e24d595(media_query) {
12
12
  const signal = $9HbP8$createSignal(false);
13
13
  $9HbP8$onCleanup($9HbP8$javascript_media_query(media_query, ({
@@ -1130,8 +1130,14 @@ function $0449e7d49398c077$export$a1fd619a4743ca08({
1130
1130
  setFirstResultInViewport(Math.min(...intersecting) + 1); // +1 because we want to start counting at 1
1131
1131
  setLastResultsInViewport(Math.max(...intersecting) + 1);
1132
1132
  });
1133
- return renderedDisplays_;
1133
+ // Content blocks placed after the last product (but still in its row) have no product card to render in front of, so render them after the cards once there are no more products to load
1134
+ const trailingContentBlocks_ = $9HbP8$createMemo(() => {
1135
+ if (!all_products_loaded_[0]()) return [];
1136
+ return content_blocks_?.()?.trailing_?.(displays_by_key_().size) || [];
1137
+ });
1138
+ return [renderedDisplays_, trailingContentBlocks_]; // Regarding the as unknown: https://github.com/solidjs/solid/releases/tag/v1.7.0
1134
1139
  }
1140
+
1135
1141
  var $c8d5ff4524619fcd$var$_tmpl$ = /*#__PURE__*/$9HbP8$template(`<div>`),
1136
1142
  $c8d5ff4524619fcd$var$_tmpl$2 = /*#__PURE__*/$9HbP8$template(`<style type=text/css>`);
1137
1143
  function $c8d5ff4524619fcd$export$d21e32dfedac04be(props) {
@@ -1481,10 +1487,18 @@ function $e7a7eb102ddc0c79$export$791ef57e62e21c3f({
1481
1487
  set_top_row_shortened_by_(blocks_in_top_row_taken - 1); // minus one because the content block wrapper also is an element
1482
1488
  });
1483
1489
 
1484
- return $9HbP8$createMemo(() => $e7a7eb102ddc0c79$export$92aa5d691d588f3f({
1490
+ const remapped_ = $9HbP8$createMemo(() => $e7a7eb102ddc0c79$export$92aa5d691d588f3f({
1485
1491
  wrapped_blocks_: get_wrapped_blocks_(),
1486
1492
  n_cols_currently_showing_: n_cols_currently_showing_()
1487
- }).content_blocks_by_index_);
1493
+ }));
1494
+ const content_blocks_by_index_ = $9HbP8$createMemo(() => remapped_().content_blocks_by_index_);
1495
+ return Object.assign(content_blocks_by_index_, {
1496
+ trailing_: product_count => $e7a7eb102ddc0c79$export$b94605e5b3ce01c({
1497
+ ...remapped_(),
1498
+ n_cols_currently_showing_: n_cols_currently_showing_(),
1499
+ product_count: product_count
1500
+ })
1501
+ });
1488
1502
  }
1489
1503
  function $e7a7eb102ddc0c79$export$92aa5d691d588f3f({
1490
1504
  wrapped_blocks_: wrapped_blocks_,
@@ -1492,13 +1506,16 @@ function $e7a7eb102ddc0c79$export$92aa5d691d588f3f({
1492
1506
  }) {
1493
1507
  // This computation should be quite cheap since it just moves around things into an array
1494
1508
  const content_blocks_by_index_ = [];
1509
+ const rows_by_index_ = []; // the row of each block at each index of content_blocks_by_index_, in the same order
1495
1510
  const constructed_block_arrays = new WeakSet();
1496
1511
  // Need to keep track of products displaced by blocks above when mapping rows to indexes in the actual grid
1497
1512
  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
1498
1513
  if (!n_cols_currently_showing_)
1499
1514
  // Nope out of here if we don't know how many columns are showing
1500
1515
  return {
1501
- content_blocks_by_index_: content_blocks_by_index_
1516
+ content_blocks_by_index_: content_blocks_by_index_,
1517
+ rows_by_index_: rows_by_index_,
1518
+ displaced_products_: displaced_products_
1502
1519
  };
1503
1520
  for (let i = 0; i < wrapped_blocks_.length; i++) {
1504
1521
  // i = row to show at
@@ -1543,6 +1560,7 @@ function $e7a7eb102ddc0c79$export$92aa5d691d588f3f({
1543
1560
  content_blocks_by_index_[final_target_index] = array;
1544
1561
  }
1545
1562
  } else content_blocks_by_index_[final_target_index] = block_content;
1563
+ (rows_by_index_[final_target_index] ||= []).push(i);
1546
1564
  // Update displacement
1547
1565
  for (let j = 0; j < span_rows; j++) {
1548
1566
  const row = displaced_products_[i + j] ||= [];
@@ -1551,9 +1569,44 @@ function $e7a7eb102ddc0c79$export$92aa5d691d588f3f({
1551
1569
  }
1552
1570
  return {
1553
1571
  content_blocks_by_index_: content_blocks_by_index_,
1572
+ rows_by_index_: rows_by_index_,
1554
1573
  displaced_products_: displaced_products_
1555
1574
  };
1556
1575
  }
1576
+ function $e7a7eb102ddc0c79$export$b94605e5b3ce01c({
1577
+ content_blocks_by_index_: content_blocks_by_index_,
1578
+ rows_by_index_: rows_by_index_,
1579
+ displaced_products_: displaced_products_,
1580
+ n_cols_currently_showing_: n_cols_currently_showing_,
1581
+ product_count: product_count
1582
+ }) {
1583
+ const trailing = [];
1584
+ if (!n_cols_currently_showing_ || product_count <= 0) return trailing;
1585
+ // Find the row the last product lands in: each row has room for the columns that blocks don't take up
1586
+ let last_product_row = 0;
1587
+ for (let seen_products = 0;; last_product_row++) {
1588
+ const row = displaced_products_[last_product_row];
1589
+ const taken_by_blocks = typeof row === "number" ? row : row ? row.filter(item => item).length : 0;
1590
+ seen_products += Math.max(0, n_cols_currently_showing_ - taken_by_blocks);
1591
+ if (seen_products >= product_count) break;
1592
+ // Rows past the ones blocks take up all have room for products, so we're done by then at the latest
1593
+ if (last_product_row >= displaced_products_.length + product_count) break;
1594
+ }
1595
+ for (let i = product_count; i < content_blocks_by_index_.length; i++) {
1596
+ const block = content_blocks_by_index_[i];
1597
+ if (block === undefined) continue;
1598
+ const rows = rows_by_index_[i] || [];
1599
+ if (Array.isArray(block) && rows.length > 1) {
1600
+ // Several blocks share this index (e.g. the end of one row and the start of the next): keep the ones in the last product's row
1601
+ const in_last_row = block.filter((_, j) => rows[j] <= last_product_row);
1602
+ if (in_last_row.length) trailing.push(in_last_row);
1603
+ continue;
1604
+ }
1605
+ if ((rows[0] ?? Infinity) > last_product_row) continue; // a row below the last product's row: keep it hidden
1606
+ trailing.push(block);
1607
+ }
1608
+ return trailing;
1609
+ }
1557
1610
  /**
1558
1611
  * 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.
1559
1612
  * Then renders the content and wraps it into a div with the correct styling.
@@ -1603,6 +1656,7 @@ function $e7a7eb102ddc0c79$var$wrap_blocks_in_div(rendered_content_blocks, max_s
1603
1656
  content: () => {
1604
1657
  // Sneaky on-demand rendering, so we don't render more blocks than we can show: we have the rendered value here and don't return a function that renders because if our block would be moved around we'd be guaranteed to re-render
1605
1658
  // However, no need to count products to know if we should render: the <For> loops in Placeholders and render_displays will only call this function if there's actually a product here that wants to display this block
1659
+ // (or, once all products have loaded, ResultsProductCards renders the blocks placed after the last product)
1606
1660
  set_rendering_delayed_(false);
1607
1661
  return content;
1608
1662
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@depict-ai/ui",
3
- "version": "4.10.21",
3
+ "version": "4.10.22",
4
4
  "description": "Base package containing the actual UI of Depict UI along with translations, with a not-simplified API. We recommend using @depict-ai/js-ui or @depict-ai/react-ui instead.",
5
5
  "packageManager": "yarn@3.2.2",
6
6
  "sass": "styles.scss",
@@ -236,9 +236,9 @@
236
236
  "@babel/plugin-transform-typescript": "^7.22.9",
237
237
  "@babel/runtime": "^7.22.6",
238
238
  "@babel/runtime-corejs3": "^7.22.6",
239
- "@depict-ai/plp-styling": "^4.6.13",
240
- "@depict-ai/types": "^5.6.11",
241
- "@depict-ai/utilishared": "^2.6.11",
239
+ "@depict-ai/plp-styling": "^4.6.14",
240
+ "@depict-ai/types": "^5.6.12",
241
+ "@depict-ai/utilishared": "^2.6.12",
242
242
  "solid-js": "^1.9.10"
243
243
  },
244
244
  "type": "module",
@@ -115,7 +115,7 @@ $parcel$export(module.exports, "BreadCrumbs", () => $335c02c1241a9ca8$export$5b7
115
115
  $parcel$export(module.exports, "QuickLinks", () => $335c02c1241a9ca8$export$de035477d6fef996);
116
116
  $parcel$export(module.exports, "CategoryPage", () => $c10e33c4681f8c9b$export$e2bf8ce7779e827e);
117
117
  /*! Depict.ai search and product listing SDK */
118
- const $aa1938dec50d6c12$export$83d89fbfd8236492 = "4.10.21";
118
+ const $aa1938dec50d6c12$export$83d89fbfd8236492 = "4.10.22";
119
119
  function $3e17e871e9d0911d$export$d9f36cf74e24d595(media_query) {
120
120
  const signal = $3hooq$solidjs.createSignal(false);
121
121
  $3hooq$solidjs.onCleanup($3hooq$depictaiutilishared.javascript_media_query(media_query, _ref => {
@@ -1046,8 +1046,15 @@ function $0d3ee7000f047e67$export$a1fd619a4743ca08(_ref) {
1046
1046
  setFirstResultInViewport(Math.min(...intersecting) + 1); // +1 because we want to start counting at 1
1047
1047
  setLastResultsInViewport(Math.max(...intersecting) + 1);
1048
1048
  });
1049
- return renderedDisplays_;
1049
+ // Content blocks placed after the last product (but still in its row) have no product card to render in front of, so render them after the cards once there are no more products to load
1050
+ const trailingContentBlocks_ = $3hooq$solidjs.createMemo(() => {
1051
+ var _content_blocks_, _content_blocks_$trai;
1052
+ if (!all_products_loaded_[0]()) return [];
1053
+ return (content_blocks_ === null || content_blocks_ === void 0 ? void 0 : (_content_blocks_ = content_blocks_()) === null || _content_blocks_ === void 0 ? void 0 : (_content_blocks_$trai = _content_blocks_.trailing_) === null || _content_blocks_$trai === void 0 ? void 0 : _content_blocks_$trai.call(_content_blocks_, displays_by_key_().size)) || [];
1054
+ });
1055
+ return [renderedDisplays_, trailingContentBlocks_]; // Regarding the as unknown: https://github.com/solidjs/solid/releases/tag/v1.7.0
1050
1056
  }
1057
+
1051
1058
  var $6c2c739b113a8ddf$var$_tmpl$ = ["<div", ' class="', '">', "</div>"],
1052
1059
  $6c2c739b113a8ddf$var$_tmpl$2 = ["<style", ' type="text/css">', "</style>"];
1053
1060
  function $6c2c739b113a8ddf$export$d21e32dfedac04be(props) {
@@ -1365,10 +1372,18 @@ function $f8f375d6245ffff2$export$791ef57e62e21c3f(_ref) {
1365
1372
  set_top_row_shortened_by_(blocks_in_top_row_taken - 1); // minus one because the content block wrapper also is an element
1366
1373
  });
1367
1374
 
1368
- return $3hooq$solidjs.createMemo(() => $f8f375d6245ffff2$export$92aa5d691d588f3f({
1375
+ const remapped_ = $3hooq$solidjs.createMemo(() => $f8f375d6245ffff2$export$92aa5d691d588f3f({
1369
1376
  wrapped_blocks_: get_wrapped_blocks_(),
1370
1377
  n_cols_currently_showing_: n_cols_currently_showing_()
1371
- }).content_blocks_by_index_);
1378
+ }));
1379
+ const content_blocks_by_index_ = $3hooq$solidjs.createMemo(() => remapped_().content_blocks_by_index_);
1380
+ return Object.assign(content_blocks_by_index_, {
1381
+ trailing_: product_count => $f8f375d6245ffff2$export$b94605e5b3ce01c({
1382
+ ...remapped_(),
1383
+ n_cols_currently_showing_: n_cols_currently_showing_(),
1384
+ product_count: product_count
1385
+ })
1386
+ });
1372
1387
  }
1373
1388
  function $f8f375d6245ffff2$export$92aa5d691d588f3f(_ref2) {
1374
1389
  let {
@@ -1377,13 +1392,16 @@ function $f8f375d6245ffff2$export$92aa5d691d588f3f(_ref2) {
1377
1392
  } = _ref2;
1378
1393
  // This computation should be quite cheap since it just moves around things into an array
1379
1394
  const content_blocks_by_index_ = [];
1395
+ const rows_by_index_ = []; // the row of each block at each index of content_blocks_by_index_, in the same order
1380
1396
  const constructed_block_arrays = new WeakSet();
1381
1397
  // Need to keep track of products displaced by blocks above when mapping rows to indexes in the actual grid
1382
1398
  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
1383
1399
  if (!n_cols_currently_showing_)
1384
1400
  // Nope out of here if we don't know how many columns are showing
1385
1401
  return {
1386
- content_blocks_by_index_: content_blocks_by_index_
1402
+ content_blocks_by_index_: content_blocks_by_index_,
1403
+ rows_by_index_: rows_by_index_,
1404
+ displaced_products_: displaced_products_
1387
1405
  };
1388
1406
  for (let i = 0; i < wrapped_blocks_.length; i++) {
1389
1407
  // i = row to show at
@@ -1431,6 +1449,7 @@ function $f8f375d6245ffff2$export$92aa5d691d588f3f(_ref2) {
1431
1449
  content_blocks_by_index_[final_target_index] = array;
1432
1450
  }
1433
1451
  } else content_blocks_by_index_[final_target_index] = block_content;
1452
+ (rows_by_index_[final_target_index] || (rows_by_index_[final_target_index] = [])).push(i);
1434
1453
  // Update displacement
1435
1454
  for (let j = 0; j < span_rows; j++) {
1436
1455
  var _ref3;
@@ -1440,9 +1459,46 @@ function $f8f375d6245ffff2$export$92aa5d691d588f3f(_ref2) {
1440
1459
  }
1441
1460
  return {
1442
1461
  content_blocks_by_index_: content_blocks_by_index_,
1462
+ rows_by_index_: rows_by_index_,
1443
1463
  displaced_products_: displaced_products_
1444
1464
  };
1445
1465
  }
1466
+ function $f8f375d6245ffff2$export$b94605e5b3ce01c(_ref4) {
1467
+ let {
1468
+ content_blocks_by_index_: content_blocks_by_index_,
1469
+ rows_by_index_: rows_by_index_,
1470
+ displaced_products_: displaced_products_,
1471
+ n_cols_currently_showing_: n_cols_currently_showing_,
1472
+ product_count: product_count
1473
+ } = _ref4;
1474
+ const trailing = [];
1475
+ if (!n_cols_currently_showing_ || product_count <= 0) return trailing;
1476
+ // Find the row the last product lands in: each row has room for the columns that blocks don't take up
1477
+ let last_product_row = 0;
1478
+ for (let seen_products = 0;; last_product_row++) {
1479
+ const row = displaced_products_[last_product_row];
1480
+ const taken_by_blocks = typeof row === "number" ? row : row ? row.filter(item => item).length : 0;
1481
+ seen_products += Math.max(0, n_cols_currently_showing_ - taken_by_blocks);
1482
+ if (seen_products >= product_count) break;
1483
+ // Rows past the ones blocks take up all have room for products, so we're done by then at the latest
1484
+ if (last_product_row >= displaced_products_.length + product_count) break;
1485
+ }
1486
+ for (let i = product_count; i < content_blocks_by_index_.length; i++) {
1487
+ var _rows$;
1488
+ const block = content_blocks_by_index_[i];
1489
+ if (block === undefined) continue;
1490
+ const rows = rows_by_index_[i] || [];
1491
+ if (Array.isArray(block) && rows.length > 1) {
1492
+ // Several blocks share this index (e.g. the end of one row and the start of the next): keep the ones in the last product's row
1493
+ const in_last_row = block.filter((_, j) => rows[j] <= last_product_row);
1494
+ if (in_last_row.length) trailing.push(in_last_row);
1495
+ continue;
1496
+ }
1497
+ if (((_rows$ = rows[0]) !== null && _rows$ !== void 0 ? _rows$ : Infinity) > last_product_row) continue; // a row below the last product's row: keep it hidden
1498
+ trailing.push(block);
1499
+ }
1500
+ return trailing;
1501
+ }
1446
1502
  /**
1447
1503
  * 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.
1448
1504
  * Then renders the content and wraps it into a div with the correct styling.
@@ -1475,6 +1531,7 @@ function $f8f375d6245ffff2$var$wrap_blocks_in_div(rendered_content_blocks, max_s
1475
1531
  content: () => {
1476
1532
  // Sneaky on-demand rendering, so we don't render more blocks than we can show: we have the rendered value here and don't return a function that renders because if our block would be moved around we'd be guaranteed to re-render
1477
1533
  // However, no need to count products to know if we should render: the <For> loops in Placeholders and render_displays will only call this function if there's actually a product here that wants to display this block
1534
+ // (or, once all products have loaded, ResultsProductCards renders the blocks placed after the last product)
1478
1535
  set_rendering_delayed_(false);
1479
1536
  return content;
1480
1537
  },
@@ -11,7 +11,7 @@ import { GetListingRequest } from "@depict-ai/types/api/GetListingRequest";
11
11
  import { BaseSearchRequestV3 } from "@depict-ai/types/api/BaseSearchRequestV3";
12
12
  import { FeaturedInDisplay } from "@depict-ai/types/api/FeaturedInResponseV3";
13
13
  import { SearchFilter as _SearchFilter3 } from "@depict-ai/types/api/SearchRequestV2";
14
- export const version = "4.10.21";
14
+ export const version = "4.10.22";
15
15
  /**
16
16
  * Use `javascript_media_query` but return a reactive accessor instead of taking a callback function
17
17
  */
@@ -425,10 +425,8 @@ export function remap_blocks_to_index<T = () => JSX.Element | Promise<JSX.Elemen
425
425
  })[];
426
426
  n_cols_currently_showing_: number | null;
427
427
  }): {
428
- content_blocks_by_index_: (Awaited<T> | T[])[];
429
- readonly displaced_products_?: undefined;
430
- } | {
431
428
  readonly content_blocks_by_index_: (Awaited<T> | T[])[];
429
+ readonly rows_by_index_: number[][];
432
430
  readonly displaced_products_: (number | (true | undefined)[])[];
433
431
  };
434
432
  /** @jsxImportSource solid-js */
@@ -10,7 +10,7 @@ import $b8hua$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.21";
13
+ const $8db9a15135765c11$export$83d89fbfd8236492 = "4.10.22";
14
14
  function $00a5b94f0c11efbb$export$d9f36cf74e24d595(media_query) {
15
15
  const signal = $b8hua$createSignal(false);
16
16
  $b8hua$onCleanup($b8hua$javascript_media_query(media_query, _ref => {
@@ -941,8 +941,15 @@ function $45a8953d760b5e58$export$a1fd619a4743ca08(_ref) {
941
941
  setFirstResultInViewport(Math.min(...intersecting) + 1); // +1 because we want to start counting at 1
942
942
  setLastResultsInViewport(Math.max(...intersecting) + 1);
943
943
  });
944
- return renderedDisplays_;
944
+ // Content blocks placed after the last product (but still in its row) have no product card to render in front of, so render them after the cards once there are no more products to load
945
+ const trailingContentBlocks_ = $b8hua$createMemo(() => {
946
+ var _content_blocks_, _content_blocks_$trai;
947
+ if (!all_products_loaded_[0]()) return [];
948
+ return (content_blocks_ === null || content_blocks_ === void 0 ? void 0 : (_content_blocks_ = content_blocks_()) === null || _content_blocks_ === void 0 ? void 0 : (_content_blocks_$trai = _content_blocks_.trailing_) === null || _content_blocks_$trai === void 0 ? void 0 : _content_blocks_$trai.call(_content_blocks_, displays_by_key_().size)) || [];
949
+ });
950
+ return [renderedDisplays_, trailingContentBlocks_]; // Regarding the as unknown: https://github.com/solidjs/solid/releases/tag/v1.7.0
945
951
  }
952
+
946
953
  var $63f1f8dbcd07d3b0$var$_tmpl$ = ["<div", ' class="', '">', "</div>"],
947
954
  $63f1f8dbcd07d3b0$var$_tmpl$2 = ["<style", ' type="text/css">', "</style>"];
948
955
  function $63f1f8dbcd07d3b0$export$d21e32dfedac04be(props) {
@@ -1260,10 +1267,18 @@ function $ff7feae4dddd6073$export$791ef57e62e21c3f(_ref) {
1260
1267
  set_top_row_shortened_by_(blocks_in_top_row_taken - 1); // minus one because the content block wrapper also is an element
1261
1268
  });
1262
1269
 
1263
- return $b8hua$createMemo(() => $ff7feae4dddd6073$export$92aa5d691d588f3f({
1270
+ const remapped_ = $b8hua$createMemo(() => $ff7feae4dddd6073$export$92aa5d691d588f3f({
1264
1271
  wrapped_blocks_: get_wrapped_blocks_(),
1265
1272
  n_cols_currently_showing_: n_cols_currently_showing_()
1266
- }).content_blocks_by_index_);
1273
+ }));
1274
+ const content_blocks_by_index_ = $b8hua$createMemo(() => remapped_().content_blocks_by_index_);
1275
+ return Object.assign(content_blocks_by_index_, {
1276
+ trailing_: product_count => $ff7feae4dddd6073$export$b94605e5b3ce01c({
1277
+ ...remapped_(),
1278
+ n_cols_currently_showing_: n_cols_currently_showing_(),
1279
+ product_count: product_count
1280
+ })
1281
+ });
1267
1282
  }
1268
1283
  function $ff7feae4dddd6073$export$92aa5d691d588f3f(_ref2) {
1269
1284
  let {
@@ -1272,13 +1287,16 @@ function $ff7feae4dddd6073$export$92aa5d691d588f3f(_ref2) {
1272
1287
  } = _ref2;
1273
1288
  // This computation should be quite cheap since it just moves around things into an array
1274
1289
  const content_blocks_by_index_ = [];
1290
+ const rows_by_index_ = []; // the row of each block at each index of content_blocks_by_index_, in the same order
1275
1291
  const constructed_block_arrays = new WeakSet();
1276
1292
  // Need to keep track of products displaced by blocks above when mapping rows to indexes in the actual grid
1277
1293
  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
1278
1294
  if (!n_cols_currently_showing_)
1279
1295
  // Nope out of here if we don't know how many columns are showing
1280
1296
  return {
1281
- content_blocks_by_index_: content_blocks_by_index_
1297
+ content_blocks_by_index_: content_blocks_by_index_,
1298
+ rows_by_index_: rows_by_index_,
1299
+ displaced_products_: displaced_products_
1282
1300
  };
1283
1301
  for (let i = 0; i < wrapped_blocks_.length; i++) {
1284
1302
  // i = row to show at
@@ -1326,6 +1344,7 @@ function $ff7feae4dddd6073$export$92aa5d691d588f3f(_ref2) {
1326
1344
  content_blocks_by_index_[final_target_index] = array;
1327
1345
  }
1328
1346
  } else content_blocks_by_index_[final_target_index] = block_content;
1347
+ (rows_by_index_[final_target_index] || (rows_by_index_[final_target_index] = [])).push(i);
1329
1348
  // Update displacement
1330
1349
  for (let j = 0; j < span_rows; j++) {
1331
1350
  var _ref3;
@@ -1335,9 +1354,46 @@ function $ff7feae4dddd6073$export$92aa5d691d588f3f(_ref2) {
1335
1354
  }
1336
1355
  return {
1337
1356
  content_blocks_by_index_: content_blocks_by_index_,
1357
+ rows_by_index_: rows_by_index_,
1338
1358
  displaced_products_: displaced_products_
1339
1359
  };
1340
1360
  }
1361
+ function $ff7feae4dddd6073$export$b94605e5b3ce01c(_ref4) {
1362
+ let {
1363
+ content_blocks_by_index_: content_blocks_by_index_,
1364
+ rows_by_index_: rows_by_index_,
1365
+ displaced_products_: displaced_products_,
1366
+ n_cols_currently_showing_: n_cols_currently_showing_,
1367
+ product_count: product_count
1368
+ } = _ref4;
1369
+ const trailing = [];
1370
+ if (!n_cols_currently_showing_ || product_count <= 0) return trailing;
1371
+ // Find the row the last product lands in: each row has room for the columns that blocks don't take up
1372
+ let last_product_row = 0;
1373
+ for (let seen_products = 0;; last_product_row++) {
1374
+ const row = displaced_products_[last_product_row];
1375
+ const taken_by_blocks = typeof row === "number" ? row : row ? row.filter(item => item).length : 0;
1376
+ seen_products += Math.max(0, n_cols_currently_showing_ - taken_by_blocks);
1377
+ if (seen_products >= product_count) break;
1378
+ // Rows past the ones blocks take up all have room for products, so we're done by then at the latest
1379
+ if (last_product_row >= displaced_products_.length + product_count) break;
1380
+ }
1381
+ for (let i = product_count; i < content_blocks_by_index_.length; i++) {
1382
+ var _rows$;
1383
+ const block = content_blocks_by_index_[i];
1384
+ if (block === undefined) continue;
1385
+ const rows = rows_by_index_[i] || [];
1386
+ if (Array.isArray(block) && rows.length > 1) {
1387
+ // Several blocks share this index (e.g. the end of one row and the start of the next): keep the ones in the last product's row
1388
+ const in_last_row = block.filter((_, j) => rows[j] <= last_product_row);
1389
+ if (in_last_row.length) trailing.push(in_last_row);
1390
+ continue;
1391
+ }
1392
+ if (((_rows$ = rows[0]) !== null && _rows$ !== void 0 ? _rows$ : Infinity) > last_product_row) continue; // a row below the last product's row: keep it hidden
1393
+ trailing.push(block);
1394
+ }
1395
+ return trailing;
1396
+ }
1341
1397
  /**
1342
1398
  * 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.
1343
1399
  * Then renders the content and wraps it into a div with the correct styling.
@@ -1370,6 +1426,7 @@ function $ff7feae4dddd6073$var$wrap_blocks_in_div(rendered_content_blocks, max_s
1370
1426
  content: () => {
1371
1427
  // Sneaky on-demand rendering, so we don't render more blocks than we can show: we have the rendered value here and don't return a function that renders because if our block would be moved around we'd be guaranteed to re-render
1372
1428
  // However, no need to count products to know if we should render: the <For> loops in Placeholders and render_displays will only call this function if there's actually a product here that wants to display this block
1429
+ // (or, once all products have loaded, ResultsProductCards renders the blocks placed after the last product)
1373
1430
  set_rendering_delayed_(false);
1374
1431
  return content;
1375
1432
  },
@@ -109,7 +109,7 @@ $parcel$export(module.exports, "BreadCrumbs", () => $1f4925833f07df29$export$5b7
109
109
  $parcel$export(module.exports, "QuickLinks", () => $1f4925833f07df29$export$de035477d6fef996);
110
110
  $parcel$export(module.exports, "CategoryPage", () => $14f289047713d67a$export$e2bf8ce7779e827e);
111
111
  /*! Depict.ai search and product listing SDK */
112
- const $b757f75811f3261f$export$83d89fbfd8236492 = "4.10.21";
112
+ const $b757f75811f3261f$export$83d89fbfd8236492 = "4.10.22";
113
113
  function $b54e6192d0caa293$export$d9f36cf74e24d595(media_query) {
114
114
  const signal = $5vyXB$solidjs.createSignal(false);
115
115
  $5vyXB$solidjs.onCleanup($5vyXB$depictaiutilishared.javascript_media_query(media_query, ({
@@ -1001,8 +1001,14 @@ function $ac167f6af6a48fc3$export$a1fd619a4743ca08({
1001
1001
  setFirstResultInViewport(Math.min(...intersecting) + 1); // +1 because we want to start counting at 1
1002
1002
  setLastResultsInViewport(Math.max(...intersecting) + 1);
1003
1003
  });
1004
- return renderedDisplays_;
1004
+ // Content blocks placed after the last product (but still in its row) have no product card to render in front of, so render them after the cards once there are no more products to load
1005
+ const trailingContentBlocks_ = $5vyXB$solidjs.createMemo(() => {
1006
+ if (!all_products_loaded_[0]()) return [];
1007
+ return content_blocks_?.()?.trailing_?.(displays_by_key_().size) || [];
1008
+ });
1009
+ return [renderedDisplays_, trailingContentBlocks_]; // Regarding the as unknown: https://github.com/solidjs/solid/releases/tag/v1.7.0
1005
1010
  }
1011
+
1006
1012
  var $f48d0fbb00835aaa$var$_tmpl$ = ["<div", ' class="', '">', "</div>"],
1007
1013
  $f48d0fbb00835aaa$var$_tmpl$2 = ["<style", ' type="text/css">', "</style>"];
1008
1014
  function $f48d0fbb00835aaa$export$d21e32dfedac04be(props) {
@@ -1303,10 +1309,18 @@ function $d92f338ba8f9da9b$export$791ef57e62e21c3f({
1303
1309
  set_top_row_shortened_by_(blocks_in_top_row_taken - 1); // minus one because the content block wrapper also is an element
1304
1310
  });
1305
1311
 
1306
- return $5vyXB$solidjs.createMemo(() => $d92f338ba8f9da9b$export$92aa5d691d588f3f({
1312
+ const remapped_ = $5vyXB$solidjs.createMemo(() => $d92f338ba8f9da9b$export$92aa5d691d588f3f({
1307
1313
  wrapped_blocks_: get_wrapped_blocks_(),
1308
1314
  n_cols_currently_showing_: n_cols_currently_showing_()
1309
- }).content_blocks_by_index_);
1315
+ }));
1316
+ const content_blocks_by_index_ = $5vyXB$solidjs.createMemo(() => remapped_().content_blocks_by_index_);
1317
+ return Object.assign(content_blocks_by_index_, {
1318
+ trailing_: product_count => $d92f338ba8f9da9b$export$b94605e5b3ce01c({
1319
+ ...remapped_(),
1320
+ n_cols_currently_showing_: n_cols_currently_showing_(),
1321
+ product_count: product_count
1322
+ })
1323
+ });
1310
1324
  }
1311
1325
  function $d92f338ba8f9da9b$export$92aa5d691d588f3f({
1312
1326
  wrapped_blocks_: wrapped_blocks_,
@@ -1314,13 +1328,16 @@ function $d92f338ba8f9da9b$export$92aa5d691d588f3f({
1314
1328
  }) {
1315
1329
  // This computation should be quite cheap since it just moves around things into an array
1316
1330
  const content_blocks_by_index_ = [];
1331
+ const rows_by_index_ = []; // the row of each block at each index of content_blocks_by_index_, in the same order
1317
1332
  const constructed_block_arrays = new WeakSet();
1318
1333
  // Need to keep track of products displaced by blocks above when mapping rows to indexes in the actual grid
1319
1334
  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
1320
1335
  if (!n_cols_currently_showing_)
1321
1336
  // Nope out of here if we don't know how many columns are showing
1322
1337
  return {
1323
- content_blocks_by_index_: content_blocks_by_index_
1338
+ content_blocks_by_index_: content_blocks_by_index_,
1339
+ rows_by_index_: rows_by_index_,
1340
+ displaced_products_: displaced_products_
1324
1341
  };
1325
1342
  for (let i = 0; i < wrapped_blocks_.length; i++) {
1326
1343
  // i = row to show at
@@ -1365,6 +1382,7 @@ function $d92f338ba8f9da9b$export$92aa5d691d588f3f({
1365
1382
  content_blocks_by_index_[final_target_index] = array;
1366
1383
  }
1367
1384
  } else content_blocks_by_index_[final_target_index] = block_content;
1385
+ (rows_by_index_[final_target_index] ||= []).push(i);
1368
1386
  // Update displacement
1369
1387
  for (let j = 0; j < span_rows; j++) {
1370
1388
  const row = displaced_products_[i + j] ||= [];
@@ -1373,9 +1391,44 @@ function $d92f338ba8f9da9b$export$92aa5d691d588f3f({
1373
1391
  }
1374
1392
  return {
1375
1393
  content_blocks_by_index_: content_blocks_by_index_,
1394
+ rows_by_index_: rows_by_index_,
1376
1395
  displaced_products_: displaced_products_
1377
1396
  };
1378
1397
  }
1398
+ function $d92f338ba8f9da9b$export$b94605e5b3ce01c({
1399
+ content_blocks_by_index_: content_blocks_by_index_,
1400
+ rows_by_index_: rows_by_index_,
1401
+ displaced_products_: displaced_products_,
1402
+ n_cols_currently_showing_: n_cols_currently_showing_,
1403
+ product_count: product_count
1404
+ }) {
1405
+ const trailing = [];
1406
+ if (!n_cols_currently_showing_ || product_count <= 0) return trailing;
1407
+ // Find the row the last product lands in: each row has room for the columns that blocks don't take up
1408
+ let last_product_row = 0;
1409
+ for (let seen_products = 0;; last_product_row++) {
1410
+ const row = displaced_products_[last_product_row];
1411
+ const taken_by_blocks = typeof row === "number" ? row : row ? row.filter(item => item).length : 0;
1412
+ seen_products += Math.max(0, n_cols_currently_showing_ - taken_by_blocks);
1413
+ if (seen_products >= product_count) break;
1414
+ // Rows past the ones blocks take up all have room for products, so we're done by then at the latest
1415
+ if (last_product_row >= displaced_products_.length + product_count) break;
1416
+ }
1417
+ for (let i = product_count; i < content_blocks_by_index_.length; i++) {
1418
+ const block = content_blocks_by_index_[i];
1419
+ if (block === undefined) continue;
1420
+ const rows = rows_by_index_[i] || [];
1421
+ if (Array.isArray(block) && rows.length > 1) {
1422
+ // Several blocks share this index (e.g. the end of one row and the start of the next): keep the ones in the last product's row
1423
+ const in_last_row = block.filter((_, j) => rows[j] <= last_product_row);
1424
+ if (in_last_row.length) trailing.push(in_last_row);
1425
+ continue;
1426
+ }
1427
+ if ((rows[0] ?? Infinity) > last_product_row) continue; // a row below the last product's row: keep it hidden
1428
+ trailing.push(block);
1429
+ }
1430
+ return trailing;
1431
+ }
1379
1432
  /**
1380
1433
  * 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.
1381
1434
  * Then renders the content and wraps it into a div with the correct styling.
@@ -1405,6 +1458,7 @@ function $d92f338ba8f9da9b$var$wrap_blocks_in_div(rendered_content_blocks, max_s
1405
1458
  content: () => {
1406
1459
  // Sneaky on-demand rendering, so we don't render more blocks than we can show: we have the rendered value here and don't return a function that renders because if our block would be moved around we'd be guaranteed to re-render
1407
1460
  // However, no need to count products to know if we should render: the <For> loops in Placeholders and render_displays will only call this function if there's actually a product here that wants to display this block
1461
+ // (or, once all products have loaded, ResultsProductCards renders the blocks placed after the last product)
1408
1462
  set_rendering_delayed_(false);
1409
1463
  return content;
1410
1464
  },
@@ -11,7 +11,7 @@ import { GetListingRequest } from "@depict-ai/types/api/GetListingRequest";
11
11
  import { BaseSearchRequestV3 } from "@depict-ai/types/api/BaseSearchRequestV3";
12
12
  import { FeaturedInDisplay } from "@depict-ai/types/api/FeaturedInResponseV3";
13
13
  import { SearchFilter as _SearchFilter3 } from "@depict-ai/types/api/SearchRequestV2";
14
- export const version = "4.10.21";
14
+ export const version = "4.10.22";
15
15
  /**
16
16
  * Use `javascript_media_query` but return a reactive accessor instead of taking a callback function
17
17
  */
@@ -425,10 +425,8 @@ export function remap_blocks_to_index<T = () => JSX.Element | Promise<JSX.Elemen
425
425
  })[];
426
426
  n_cols_currently_showing_: number | null;
427
427
  }): {
428
- content_blocks_by_index_: (Awaited<T> | T[])[];
429
- readonly displaced_products_?: undefined;
430
- } | {
431
428
  readonly content_blocks_by_index_: (Awaited<T> | T[])[];
429
+ readonly rows_by_index_: number[][];
432
430
  readonly displaced_products_: (number | (true | undefined)[])[];
433
431
  };
434
432
  /** @jsxImportSource solid-js */
@@ -7,7 +7,7 @@ import { createStore as $i7OB2$createStore, reconcile as $i7OB2$reconcile } from
7
7
  /*! Depict.ai search and product listing SDK */
8
8
  import { register_es_version } from "../../multi_import_deduplicator.mjs";
9
9
  register_es_version("ui", "latest");
10
- const $ec291e0010116877$export$83d89fbfd8236492 = "4.10.21";
10
+ const $ec291e0010116877$export$83d89fbfd8236492 = "4.10.22";
11
11
  function $dc9262ef6f786812$export$d9f36cf74e24d595(media_query) {
12
12
  const signal = $i7OB2$createSignal(false);
13
13
  $i7OB2$onCleanup($i7OB2$javascript_media_query(media_query, ({
@@ -899,8 +899,14 @@ function $0449e7d49398c077$export$a1fd619a4743ca08({
899
899
  setFirstResultInViewport(Math.min(...intersecting) + 1); // +1 because we want to start counting at 1
900
900
  setLastResultsInViewport(Math.max(...intersecting) + 1);
901
901
  });
902
- return renderedDisplays_;
902
+ // Content blocks placed after the last product (but still in its row) have no product card to render in front of, so render them after the cards once there are no more products to load
903
+ const trailingContentBlocks_ = $i7OB2$createMemo(() => {
904
+ if (!all_products_loaded_[0]()) return [];
905
+ return content_blocks_?.()?.trailing_?.(displays_by_key_().size) || [];
906
+ });
907
+ return [renderedDisplays_, trailingContentBlocks_]; // Regarding the as unknown: https://github.com/solidjs/solid/releases/tag/v1.7.0
903
908
  }
909
+
904
910
  var $c8d5ff4524619fcd$var$_tmpl$ = ["<div", ' class="', '">', "</div>"],
905
911
  $c8d5ff4524619fcd$var$_tmpl$2 = ["<style", ' type="text/css">', "</style>"];
906
912
  function $c8d5ff4524619fcd$export$d21e32dfedac04be(props) {
@@ -1201,10 +1207,18 @@ function $e7a7eb102ddc0c79$export$791ef57e62e21c3f({
1201
1207
  set_top_row_shortened_by_(blocks_in_top_row_taken - 1); // minus one because the content block wrapper also is an element
1202
1208
  });
1203
1209
 
1204
- return $i7OB2$createMemo(() => $e7a7eb102ddc0c79$export$92aa5d691d588f3f({
1210
+ const remapped_ = $i7OB2$createMemo(() => $e7a7eb102ddc0c79$export$92aa5d691d588f3f({
1205
1211
  wrapped_blocks_: get_wrapped_blocks_(),
1206
1212
  n_cols_currently_showing_: n_cols_currently_showing_()
1207
- }).content_blocks_by_index_);
1213
+ }));
1214
+ const content_blocks_by_index_ = $i7OB2$createMemo(() => remapped_().content_blocks_by_index_);
1215
+ return Object.assign(content_blocks_by_index_, {
1216
+ trailing_: product_count => $e7a7eb102ddc0c79$export$b94605e5b3ce01c({
1217
+ ...remapped_(),
1218
+ n_cols_currently_showing_: n_cols_currently_showing_(),
1219
+ product_count: product_count
1220
+ })
1221
+ });
1208
1222
  }
1209
1223
  function $e7a7eb102ddc0c79$export$92aa5d691d588f3f({
1210
1224
  wrapped_blocks_: wrapped_blocks_,
@@ -1212,13 +1226,16 @@ function $e7a7eb102ddc0c79$export$92aa5d691d588f3f({
1212
1226
  }) {
1213
1227
  // This computation should be quite cheap since it just moves around things into an array
1214
1228
  const content_blocks_by_index_ = [];
1229
+ const rows_by_index_ = []; // the row of each block at each index of content_blocks_by_index_, in the same order
1215
1230
  const constructed_block_arrays = new WeakSet();
1216
1231
  // Need to keep track of products displaced by blocks above when mapping rows to indexes in the actual grid
1217
1232
  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
1218
1233
  if (!n_cols_currently_showing_)
1219
1234
  // Nope out of here if we don't know how many columns are showing
1220
1235
  return {
1221
- content_blocks_by_index_: content_blocks_by_index_
1236
+ content_blocks_by_index_: content_blocks_by_index_,
1237
+ rows_by_index_: rows_by_index_,
1238
+ displaced_products_: displaced_products_
1222
1239
  };
1223
1240
  for (let i = 0; i < wrapped_blocks_.length; i++) {
1224
1241
  // i = row to show at
@@ -1263,6 +1280,7 @@ function $e7a7eb102ddc0c79$export$92aa5d691d588f3f({
1263
1280
  content_blocks_by_index_[final_target_index] = array;
1264
1281
  }
1265
1282
  } else content_blocks_by_index_[final_target_index] = block_content;
1283
+ (rows_by_index_[final_target_index] ||= []).push(i);
1266
1284
  // Update displacement
1267
1285
  for (let j = 0; j < span_rows; j++) {
1268
1286
  const row = displaced_products_[i + j] ||= [];
@@ -1271,9 +1289,44 @@ function $e7a7eb102ddc0c79$export$92aa5d691d588f3f({
1271
1289
  }
1272
1290
  return {
1273
1291
  content_blocks_by_index_: content_blocks_by_index_,
1292
+ rows_by_index_: rows_by_index_,
1274
1293
  displaced_products_: displaced_products_
1275
1294
  };
1276
1295
  }
1296
+ function $e7a7eb102ddc0c79$export$b94605e5b3ce01c({
1297
+ content_blocks_by_index_: content_blocks_by_index_,
1298
+ rows_by_index_: rows_by_index_,
1299
+ displaced_products_: displaced_products_,
1300
+ n_cols_currently_showing_: n_cols_currently_showing_,
1301
+ product_count: product_count
1302
+ }) {
1303
+ const trailing = [];
1304
+ if (!n_cols_currently_showing_ || product_count <= 0) return trailing;
1305
+ // Find the row the last product lands in: each row has room for the columns that blocks don't take up
1306
+ let last_product_row = 0;
1307
+ for (let seen_products = 0;; last_product_row++) {
1308
+ const row = displaced_products_[last_product_row];
1309
+ const taken_by_blocks = typeof row === "number" ? row : row ? row.filter(item => item).length : 0;
1310
+ seen_products += Math.max(0, n_cols_currently_showing_ - taken_by_blocks);
1311
+ if (seen_products >= product_count) break;
1312
+ // Rows past the ones blocks take up all have room for products, so we're done by then at the latest
1313
+ if (last_product_row >= displaced_products_.length + product_count) break;
1314
+ }
1315
+ for (let i = product_count; i < content_blocks_by_index_.length; i++) {
1316
+ const block = content_blocks_by_index_[i];
1317
+ if (block === undefined) continue;
1318
+ const rows = rows_by_index_[i] || [];
1319
+ if (Array.isArray(block) && rows.length > 1) {
1320
+ // Several blocks share this index (e.g. the end of one row and the start of the next): keep the ones in the last product's row
1321
+ const in_last_row = block.filter((_, j) => rows[j] <= last_product_row);
1322
+ if (in_last_row.length) trailing.push(in_last_row);
1323
+ continue;
1324
+ }
1325
+ if ((rows[0] ?? Infinity) > last_product_row) continue; // a row below the last product's row: keep it hidden
1326
+ trailing.push(block);
1327
+ }
1328
+ return trailing;
1329
+ }
1277
1330
  /**
1278
1331
  * 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.
1279
1332
  * Then renders the content and wraps it into a div with the correct styling.
@@ -1303,6 +1356,7 @@ function $e7a7eb102ddc0c79$var$wrap_blocks_in_div(rendered_content_blocks, max_s
1303
1356
  content: () => {
1304
1357
  // Sneaky on-demand rendering, so we don't render more blocks than we can show: we have the rendered value here and don't return a function that renders because if our block would be moved around we'd be guaranteed to re-render
1305
1358
  // However, no need to count products to know if we should render: the <For> loops in Placeholders and render_displays will only call this function if there's actually a product here that wants to display this block
1359
+ // (or, once all products have loaded, ResultsProductCards renders the blocks placed after the last product)
1306
1360
  set_rendering_delayed_(false);
1307
1361
  return content;
1308
1362
  },