@depict-ai/ui 4.3.1 → 4.3.2

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
@@ -94,7 +94,7 @@ $parcel$export(module.exports, "BreadCrumbs", () => $1f4925833f07df29$export$5b7
94
94
  $parcel$export(module.exports, "QuickLinks", () => $1f4925833f07df29$export$de035477d6fef996);
95
95
  $parcel$export(module.exports, "CategoryPage", () => $14f289047713d67a$export$e2bf8ce7779e827e);
96
96
  /*! Depict.ai search and product listing SDK */
97
- const $b757f75811f3261f$export$83d89fbfd8236492 = "4.3.1";
97
+ const $b757f75811f3261f$export$83d89fbfd8236492 = "4.3.2";
98
98
  const $4e04be41243c3d80$var$transform_elements = sorted_cols_at_size => {
99
99
  const cols_at_size = [];
100
100
  for (let i = 0; i < sorted_cols_at_size.length; i++) {
@@ -1061,7 +1061,7 @@ function $19950faaac026e09$export$6e5611bc7e57e477(props) {
1061
1061
  });
1062
1062
  // Work around https://github.com/solidjs/solid/issues/1828
1063
1063
  const img = new Image(); // Need to use new Image or browser might not start loading image before it's in the DOM
1064
- const [, otherAttributes] = $gVhhF$solidjs.splitProps(props, ["resolutions", "size", "src", "srcSet", "loading", "customUrls" // Can't have properties ending on underscore because the property name mangling will get confused by this <-
1064
+ const [, otherAttributes] = $gVhhF$solidjs.splitProps(props, ["resolutions", "size", "src", "srcSet", "loading", "keyRatioUpdating", "customUrls" // Can't have properties ending on underscore because the property name mangling will get confused by this <-
1065
1065
  ]);
1066
1066
 
1067
1067
  const [hasSetSize, setHasSetSize] = $gVhhF$solidjs.createSignal(false);
@@ -1117,13 +1117,18 @@ function $19950faaac026e09$export$6e5611bc7e57e477(props) {
1117
1117
  let hasDecodedFastPath = false;
1118
1118
  let timeoutSet = false;
1119
1119
  let gotCleanedUp = false;
1120
+ let srcJustChanged = true;
1120
1121
  img.classList.add("s-responsive-image");
1121
1122
  if (listingContext) {
1122
1123
  let prevValue;
1123
1124
  const aspectRatios = listingContext[$19950faaac026e09$export$f8945274f08a3105] ||= new Set();
1124
1125
  const [, setMostPrevalentAspectRatio] = listingContext[$19950faaac026e09$export$6066eb417ed2e9f7] ||= $gVhhF$solidjs.createSignal();
1125
1126
  img.addEventListener("load", $gVhhF$depictaiutilishared.catchify(() => {
1126
- // Save our aspect ratio whenever it changes, so that we can base the containers on the most dominant aspect ratio, used in SearchModalV2
1127
+ if (props.keyRatioUpdating) {
1128
+ if (!srcJustChanged) return;
1129
+ srcJustChanged = false;
1130
+ }
1131
+ // Save our aspect ratio whenever it changes, so that we can base the containers on the most dominant aspect ratio, used in SearchModalV2 and LookItem
1127
1132
  const aspectRatio_ = img.naturalWidth / img.naturalHeight;
1128
1133
  if (prevValue) aspectRatios.delete(prevValue);
1129
1134
  const newValue = !isNaN(aspectRatio_) ? {
@@ -1142,6 +1147,10 @@ function $19950faaac026e09$export$6e5611bc7e57e477(props) {
1142
1147
  }
1143
1148
  $gVhhF$solidjs.onCleanup(() => gotCleanedUp = true);
1144
1149
  $gVhhF$solidjsweb.spread(img, $gVhhF$solidjs.mergeProps(modifiedOtherAttributes), false, true);
1150
+ $gVhhF$solidjs.createRenderEffect(() => {
1151
+ props.src;
1152
+ srcJustChanged = true;
1153
+ });
1145
1154
  $gVhhF$solidjs.createEffect(() => {
1146
1155
  if (!props.size()) return; // wait until we have a size, run every time the size changes
1147
1156
  if (timeoutSet) return;
@@ -1211,48 +1220,22 @@ function $a33065cfed827fc0$export$e4b984597b71e989(props) {
1211
1220
  const [mostPrevalentAspectRatio] = context ?
1212
1221
  // If the context exists we have to create the signal here as getting it here would be too late when it's created by ShopifyResponsiveImg below
1213
1222
  context[(0, $19950faaac026e09$export$6066eb417ed2e9f7)] ||= $gVhhF$solidjs.createSignal() : [];
1214
- const [aspectRatio, setAspectRatio] = $gVhhF$solidjs.createSignal($gVhhF$solidjs.untrack(() => props.aspectRatio));
1215
1223
  const container = $93304d59a9747aa6$export$94026ee33dbabc26({
1216
1224
  // Write getters manually instead of using JSX, so we can do more complex logic in the aspectRatio getter without increasing bundle size
1217
1225
  get class() {
1218
1226
  return props.class;
1219
1227
  },
1220
1228
  get aspectRatio() {
1221
- return aspectRatio();
1229
+ if (props.autoAdjustAspectRatio) {
1230
+ const targetRatio = mostPrevalentAspectRatio?.();
1231
+ if (targetRatio != undefined) return `var(${(0, $6f604560873e4f69$export$8a2234b5b1a5ebd4)}, ${targetRatio})`;
1232
+ }
1233
+ return props.aspectRatio;
1222
1234
  }
1223
1235
  });
1224
1236
  const owner = $gVhhF$solidjs.getOwner();
1225
1237
  let createdSizeAccessor = false;
1226
1238
  let wasCleanedUp = false;
1227
- let timeout;
1228
- $gVhhF$solidjs.createEffect(() => {
1229
- const {
1230
- autoAdjustAspectRatio: autoAdjustAspectRatio
1231
- } = props;
1232
- if (autoAdjustAspectRatio) {
1233
- const targetRatio = mostPrevalentAspectRatio?.();
1234
- if (targetRatio != undefined) {
1235
- const targetValue = `var(${(0, $6f604560873e4f69$export$8a2234b5b1a5ebd4)}, ${targetRatio})`;
1236
- const updateAspectRatio = $gVhhF$depictaiutilishared.catchify(() => setAspectRatio(targetValue));
1237
- if (autoAdjustAspectRatio === "smoothed") {
1238
- if (!timeout)
1239
- // If we don't have a timeout yet, also update instantly. This is so that the aspect ratio does get set at the start of a transition, if it changes (when using smoothing).
1240
- updateAspectRatio();
1241
- clearTimeout(timeout);
1242
- timeout = setTimeout(() => {
1243
- timeout = undefined;
1244
- updateAspectRatio();
1245
- }, 500);
1246
- return;
1247
- }
1248
- return updateAspectRatio();
1249
- }
1250
- } else {
1251
- clearTimeout(timeout);
1252
- timeout = undefined;
1253
- }
1254
- setAspectRatio(props.aspectRatio);
1255
- });
1256
1239
  $gVhhF$solidjs.createEffect(() => {
1257
1240
  if (currentImageSize() || wasCleanedUp) return; // We get into the effect when onCleanup is called if we don't have wasCleanedUp
1258
1241
  // ensure we always have a size accessor
@@ -1298,6 +1281,12 @@ function $d212a67662c5cf38$export$9d4a4b669b1929ab(props) {
1298
1281
  }
1299
1282
  }));
1300
1283
  }
1284
+ function $d659702496cb72ea$export$a71e92cfbb498adc(props) {
1285
+ return $gVhhF$solidjs.createMemo(() => {
1286
+ const price_formatting = props.price_formatting_;
1287
+ return $gVhhF$depictaiutilishared.standard_price_format(props.price_, price_formatting.places_after_comma_, price_formatting.decimal_places_delimiter_, price_formatting.thousands_delimiter_);
1288
+ });
1289
+ }
1301
1290
  var $1ae437d7d388a66e$var$_tmpl$ = /*#__PURE__*/$gVhhF$solidjsweb.template(`<div class=img-wrapper>`),
1302
1291
  $1ae437d7d388a66e$var$_tmpl$2 = /*#__PURE__*/$gVhhF$solidjsweb.template(`<span class="d-price original">`),
1303
1292
  $1ae437d7d388a66e$var$_tmpl$3 = /*#__PURE__*/$gVhhF$solidjsweb.template(`<div class=right-part><div class=text-container><span class="d-title line-clamp"></span><span class=d-price></span><!$><!/></div><!$><!/>`),
@@ -1308,7 +1297,9 @@ function $1ae437d7d388a66e$export$b73ed90f0ee50dc3({
1308
1297
  isExpanded_: isExpanded_,
1309
1298
  textFadeInAnimationRunning_: textFadeInAnimationRunning_,
1310
1299
  outerRef_: outerRef_,
1311
- animationDuration_: animationDuration_
1300
+ animationDuration_: animationDuration_,
1301
+ priceFormatting_: priceFormatting_,
1302
+ pseudoRouter_: pseudoRouter_
1312
1303
  }) {
1313
1304
  const variantToUse = $gVhhF$solidjs.createMemo(() => {
1314
1305
  const display = display_();
@@ -1320,7 +1311,9 @@ function $1ae437d7d388a66e$export$b73ed90f0ee50dc3({
1320
1311
  const [animationEffectExists, setAnimationEffectExists] = $gVhhF$solidjs.createSignal(false);
1321
1312
  const [salePrice] = $gVhhF$solidjs.createResource(() => variantToUse()?.sale_price);
1322
1313
  const [originalPrice] = $gVhhF$solidjs.createResource(() => variantToUse()?.original_price);
1323
- const isOnSale = $gVhhF$solidjs.createMemo(() => salePrice.latest !== originalPrice.latest); // .latest doesn't trigger suspense
1314
+ const isOnSale = $gVhhF$solidjs.createMemo(() => !salePrice.loading && !originalPrice.loading && salePrice.latest !== originalPrice.latest); // .latest doesn't trigger suspense after the initial load
1315
+ const enableLink = $gVhhF$solidjs.createMemo(() => isExpanded_() && !animationIsRunning());
1316
+ const href = $gVhhF$solidjs.createMemo(() => variantToUse()?.page_url);
1324
1317
  const FavoriteButton = FavoriteButton_; // Just to get rid of the type error - TS doesn't understand <Show>
1325
1318
  return (() => {
1326
1319
  var _el$ = $gVhhF$solidjsweb.getNextElement($1ae437d7d388a66e$var$_tmpl$4),
@@ -1330,9 +1323,17 @@ function $1ae437d7d388a66e$export$b73ed90f0ee50dc3({
1330
1323
  [_el$15, _co$4] = $gVhhF$solidjsweb.getNextMarker(_el$14.nextSibling);
1331
1324
  var _ref$ = outerRef_;
1332
1325
  typeof _ref$ === "function" ? $gVhhF$solidjsweb.use(_ref$, _el$) : outerRef_ = _el$;
1333
- $gVhhF$solidjsweb.spread(_el$, $gVhhF$solidjsweb.mergeProps(() => isExpanded_() && !animationIsRunning() ? {
1334
- href: variantToUse()?.page_url
1335
- } : {}), false, true);
1326
+ $gVhhF$solidjsweb.spread(_el$, $gVhhF$solidjsweb.mergeProps(() => enableLink() ? {
1327
+ href: href()
1328
+ } : {}, {
1329
+ get onClick() {
1330
+ return $gVhhF$depictaiutilishared.catchify(event_ => enableLink() && pseudoRouter_.navigate_.go_to_({
1331
+ new_url_: href(),
1332
+ is_replace_: false,
1333
+ event_: event_
1334
+ }));
1335
+ }
1336
+ }), false, true);
1336
1337
  $gVhhF$solidjsweb.insert(_el$, $gVhhF$solidjsweb.createComponent((0, $gVhhF$solidjs.Show), {
1337
1338
  when: imageUrl,
1338
1339
  get fallback() {
@@ -1360,7 +1361,10 @@ function $1ae437d7d388a66e$export$b73ed90f0ee50dc3({
1360
1361
  return isExpanded_() ? 0.75 : 1;
1361
1362
  },
1362
1363
  get autoAdjustAspectRatio() {
1363
- return isExpanded_() ? "smoothed" : false;
1364
+ return isExpanded_();
1365
+ },
1366
+ imgProps: {
1367
+ keyRatioUpdating: true
1364
1368
  }
1365
1369
  });
1366
1370
  }
@@ -1417,26 +1421,68 @@ function $1ae437d7d388a66e$export$b73ed90f0ee50dc3({
1417
1421
  height: "1em",
1418
1422
  width: "20ch"
1419
1423
  }));
1420
- $gVhhF$solidjsweb.insert(_el$6, (() => {
1421
- var _c$ = $gVhhF$solidjsweb.memo(() => !!(!variantToUse() || salePrice.loading));
1422
- return () => _c$() ? $gVhhF$solidjsweb.createComponent((0, $061ff5b4c3d36171$export$89c6019e4baa40b1), {
1423
- height: "1em",
1424
- width: "20ch"
1425
- }) : salePrice();
1426
- })());
1424
+ $gVhhF$solidjsweb.insert(_el$6, $gVhhF$solidjsweb.createComponent((0, $gVhhF$solidjs.Show), {
1425
+ get when() {
1426
+ return variantToUse() && !salePrice.loading;
1427
+ },
1428
+ get fallback() {
1429
+ return $gVhhF$solidjsweb.createComponent((0, $061ff5b4c3d36171$export$89c6019e4baa40b1), {
1430
+ height: "1em",
1431
+ width: "20ch"
1432
+ });
1433
+ },
1434
+ get children() {
1435
+ return $gVhhF$solidjsweb.createComponent((0, $gVhhF$solidjs.Show), {
1436
+ get when() {
1437
+ return salePrice.latest;
1438
+ },
1439
+ get children() {
1440
+ return [$gVhhF$solidjsweb.memo(() => priceFormatting_().pre_), $gVhhF$solidjsweb.createComponent((0, $d659702496cb72ea$export$a71e92cfbb498adc), {
1441
+ get price_() {
1442
+ return salePrice();
1443
+ },
1444
+ get price_formatting_() {
1445
+ return priceFormatting_();
1446
+ }
1447
+ }), $gVhhF$solidjsweb.memo(() => priceFormatting_().post_)];
1448
+ }
1449
+ });
1450
+ }
1451
+ }));
1427
1452
  $gVhhF$solidjsweb.insert(_el$4, $gVhhF$solidjsweb.createComponent((0, $gVhhF$solidjs.Show), {
1428
1453
  get when() {
1429
1454
  return isOnSale();
1430
1455
  },
1431
1456
  get children() {
1432
1457
  var _el$7 = $gVhhF$solidjsweb.getNextElement($1ae437d7d388a66e$var$_tmpl$2);
1433
- $gVhhF$solidjsweb.insert(_el$7, (() => {
1434
- var _c$2 = $gVhhF$solidjsweb.memo(() => !!(!variantToUse() || originalPrice.loading));
1435
- return () => _c$2() ? $gVhhF$solidjsweb.createComponent((0, $061ff5b4c3d36171$export$89c6019e4baa40b1), {
1436
- height: "1em",
1437
- width: "20ch"
1438
- }) : originalPrice();
1439
- })());
1458
+ $gVhhF$solidjsweb.insert(_el$7, $gVhhF$solidjsweb.createComponent((0, $gVhhF$solidjs.Show), {
1459
+ get when() {
1460
+ return variantToUse() && !originalPrice.loading;
1461
+ },
1462
+ get fallback() {
1463
+ return $gVhhF$solidjsweb.createComponent((0, $061ff5b4c3d36171$export$89c6019e4baa40b1), {
1464
+ height: "1em",
1465
+ width: "20ch"
1466
+ });
1467
+ },
1468
+ get children() {
1469
+ return $gVhhF$solidjsweb.createComponent((0, $gVhhF$solidjs.Show), {
1470
+ get when() {
1471
+ return salePrice.latest;
1472
+ },
1473
+ get children() {
1474
+ return [$gVhhF$solidjsweb.memo(() => priceFormatting_().pre_), $gVhhF$solidjsweb.createComponent((0, $d659702496cb72ea$export$a71e92cfbb498adc), {
1475
+ get price_() {
1476
+ return originalPrice();
1477
+ },
1478
+ get price_formatting_() {
1479
+ return priceFormatting_();
1480
+ }
1481
+ }), $gVhhF$solidjsweb.memo(() => priceFormatting_().post_)];
1482
+ }
1483
+ });
1484
+ }
1485
+ }));
1440
1486
  return _el$7;
1441
1487
  }
1442
1488
  }), _el$9, _co$);
@@ -1513,7 +1559,9 @@ function $905010a06f9aeae5$export$ebf0b1d4f90c09ae({
1513
1559
  userWantsExpandedSignal_: [userWantsExpanded, setUserWantsExpanded],
1514
1560
  containerWidth_: containerWidth_,
1515
1561
  animationDuration_: animationDuration_,
1516
- supportsHover_: supportsHover_
1562
+ supportsHover_: supportsHover_,
1563
+ priceFormatting_: priceFormatting_,
1564
+ pseudoRouter_: pseudoRouter_
1517
1565
  }) {
1518
1566
  let isAffectedByChromeBug = false;
1519
1567
  // If the user requests the drawer to be expanded or not
@@ -1567,11 +1615,13 @@ function $905010a06f9aeae5$export$ebf0b1d4f90c09ae({
1567
1615
  },
1568
1616
  children: (display, index) => {
1569
1617
  return $gVhhF$solidjsweb.createComponent((0, $1ae437d7d388a66e$export$b73ed90f0ee50dc3), {
1618
+ pseudoRouter_: pseudoRouter_,
1570
1619
  animationDuration_: animationDuration_,
1571
1620
  display_: display,
1572
1621
  FavoriteButton_: FavoriteButton_,
1573
1622
  isExpanded_: userWantsExpanded,
1574
1623
  textFadeInAnimationRunning_: textFadeInAnimationRunning,
1624
+ priceFormatting_: priceFormatting_,
1575
1625
  outerRef_: el => $gVhhF$solidjs.createEffect(() => {
1576
1626
  if (index !== 0) return;
1577
1627
  const resizeObserver = new ResizeObserver($gVhhF$depictaiutilishared.catchify(records => setLookItemHeight(records.at(-1).contentRect.height)));
@@ -1614,10 +1664,10 @@ function $ad882bbe664dbd53$export$44809a8a3e867e30({
1614
1664
  expandedLooksSignal_: [expandedLooks_, setExpandedLooks],
1615
1665
  FavoriteButton_: FavoriteButton_,
1616
1666
  placeholderImageAspectRatio_: placeholderImageAspectRatio_,
1617
- animationDuration_: animationDuration_
1667
+ animationDuration_: animationDuration_,
1668
+ priceFormatting_: priceFormatting_,
1669
+ pseudoRouter_: pseudoRouter_
1618
1670
  }) {
1619
- // TODO: shopify, run displayTransformers to get dynamic prices
1620
- // TODO: format prices
1621
1671
  const [coverImage] = display_?.image_urls || [];
1622
1672
  const useWantsExpandedSignal_ = $gVhhF$solidjs.createSignal(false);
1623
1673
  const [userWantsExpanded, setUserWantsExpanded] = useWantsExpandedSignal_;
@@ -1661,7 +1711,7 @@ function $ad882bbe664dbd53$export$44809a8a3e867e30({
1661
1711
  when: display_,
1662
1712
  get fallback() {
1663
1713
  return $gVhhF$solidjsweb.createComponent((0, $3bc4a89b971a3af5$export$3f37af283f8fb843), {
1664
- aspectRatio: placeholderImageAspectRatio_
1714
+ aspectRatio: `var(${(0, $6f604560873e4f69$export$8a2234b5b1a5ebd4)}, ${placeholderImageAspectRatio_})`
1665
1715
  });
1666
1716
  },
1667
1717
  get children() {
@@ -1679,11 +1729,125 @@ function $ad882bbe664dbd53$export$44809a8a3e867e30({
1679
1729
  containerWidth_: containerWidth_,
1680
1730
  animationDuration_: animationDuration_,
1681
1731
  supportsHover_: supportsHover_,
1682
- FavoriteButton_: FavoriteButton_
1732
+ FavoriteButton_: FavoriteButton_,
1733
+ priceFormatting_: priceFormatting_,
1734
+ pseudoRouter_: pseudoRouter_
1683
1735
  })]);
1684
1736
  return container;
1685
1737
  }
1686
1738
  $gVhhF$solidjsweb.delegateEvents(["click"]);
1739
+
1740
+ /**
1741
+ * This function is used to determine if the user is trying to open a link in a new tab or window, and we therefore should not single page navigate
1742
+ * @param clickEvent The click event that triggered the navigation
1743
+ */
1744
+ function $747421cd28dec5b5$export$29d28dadc2d6b631(clickEvent) {
1745
+ return clickEvent?.button ||
1746
+ // if not zero it's a wheel click which opens in new tab
1747
+ clickEvent?.metaKey ||
1748
+ // if true, cmd button on macOS which opens in new tab
1749
+ clickEvent?.ctrlKey ||
1750
+ // if true, ctrl button on windows or linux which opens in new tab
1751
+ clickEvent?.shiftKey // if true, shift button on windows, linux or macOS which opens in a new window
1752
+ ;
1753
+ }
1754
+
1755
+ class $e96dd13889871fc0$export$7e1297a3a19f10d8 {
1756
+ /**
1757
+ * Function that will be called when we want to navigate, or a string saying it's not an SPA. You can change this OTG
1758
+ */ /**
1759
+ * We store listing_id in history.state and do operate on this both here and in js-ui, this is the key to be used which js-ui provides
1760
+ */
1761
+ #throwing_on_navigation(...args) {
1762
+ const {
1763
+ on_navigation_: on_navigation_
1764
+ } = this;
1765
+ if (typeof on_navigation_ !== "function") throw new Error("on_navigation_ is not a function");
1766
+ // make sure that we don't accidentally catchify if the SDK consumer has fucked up
1767
+ try {
1768
+ return on_navigation_(...args);
1769
+ } catch (e) {
1770
+ queueMicrotask(() => {
1771
+ throw e;
1772
+ });
1773
+ }
1774
+ }
1775
+ /**
1776
+ * Vue has async router that needs to be awaited (it navigates after a microtask)
1777
+ * This standardises waiting for all kinds of routers
1778
+ */
1779
+ #get_navigation_happened_promise(is_replace) {
1780
+ return new Promise(resolve => {
1781
+ const handler = what_happened => {
1782
+ if (what_happened === (is_replace ? "replaceState" : "pushState")) {
1783
+ resolve();
1784
+ (0, $gVhhF$depictaiutilishared.instant_exec_on_suspect_history_change).delete(handler);
1785
+ }
1786
+ };
1787
+ (0, $gVhhF$depictaiutilishared.instant_exec_on_suspect_history_change).add(handler);
1788
+ });
1789
+ }
1790
+ navigate_ = {
1791
+ /**
1792
+ * Call this if you *just* want to replace the state object in history.state
1793
+ */
1794
+ replace_state_: new_state => {
1795
+ // This doesn't break any router, so we just do this directly for now, since many don't expose an interface for changing the state
1796
+ globalThis?.history?.replaceState(new_state, "");
1797
+ },
1798
+ /**
1799
+ * Call this to change the URL
1800
+ * @param new_url_ new URL to go to
1801
+ * @param event_ event if you have this in a click handler, will not do anything on cmd/ctrl or non-left click then
1802
+ * @param force_spa_navigation_ if you want to force SPA navigation even if on_navigation_ is set to "hard_navigation". You should only set this to true for inter-SDK-page navigations
1803
+ * @param is_replace_ if you want to replace the current URL in history instead of pushing a new one
1804
+ * @param listing_id_ If you are navigating to a category and know the listing_id of, please provide it. This is for making a better devEx in js-ui
1805
+ */
1806
+ go_to_: $gVhhF$depictaiutilishared.catchify(async ({
1807
+ new_url_: raw_new_url,
1808
+ event_: event_,
1809
+ force_spa_navigation_: force_spa_navigation_,
1810
+ is_replace_: is_replace_,
1811
+ listing_query_: listing_query_,
1812
+ scroll = true
1813
+ }) => {
1814
+ const new_url_ = raw_new_url instanceof URL ? raw_new_url : new URL(raw_new_url, location.origin);
1815
+ const wants_hard_navigation = this.on_navigation_ === "hard_navigation";
1816
+ if ($747421cd28dec5b5$export$29d28dadc2d6b631(event_)) return;
1817
+ const different_origin = new_url_.origin !== location.origin;
1818
+ if (wants_hard_navigation && (!force_spa_navigation_ || different_origin)) {
1819
+ if (force_spa_navigation_ && different_origin)
1820
+ // If we call history.pushState on a different origin, it will throw an error, so fallback to hard navigations
1821
+ $gVhhF$depictaiutilishared.dwarn("Can't single page navigate to", new_url_.href, "due to different origin, this MIGHT mean you should fix the URLs");
1822
+ if (!event_)
1823
+ // If we haven't gotten an event, nothing will happen by not calling prevent default, so we need to change the URL
1824
+ location.assign(new_url_);
1825
+ return;
1826
+ }
1827
+ event_?.preventDefault();
1828
+ const promise = this.#get_navigation_happened_promise(true);
1829
+ if (force_spa_navigation_ && wants_hard_navigation) {
1830
+ // Don't allow hard navigation if we're forcing SPA navigation, which we do for things where PageReplacer can be used for performance
1831
+ const new_state = history.state;
1832
+ if (listing_query_) {
1833
+ // In JS-UI we need to know the listing_id of the current category, therefore push it into state
1834
+ if (!this.listing_query_state_key) $gVhhF$depictaiutilishared.report(new Error("listing_query_state_key is not set"), "error");
1835
+ new_state[this.listing_query_state_key] = listing_query_;
1836
+ }
1837
+ history[is_replace_ ? "replaceState" : "pushState"](new_state, "", new_url_);
1838
+ } else this.#throwing_on_navigation.call(this, {
1839
+ is_replace: is_replace_,
1840
+ new_url: new_url_ instanceof URL ? new_url_ : new URL(new_url_, location.origin),
1841
+ scroll: scroll
1842
+ });
1843
+ await promise;
1844
+ })
1845
+ };
1846
+ constructor(on_navigation, listing_query_state_key) {
1847
+ this.listing_query_state_key = listing_query_state_key;
1848
+ this.on_navigation_ = on_navigation;
1849
+ }
1850
+ }
1687
1851
  var $072863633018e322$var$_tmpl$ = /*#__PURE__*/$gVhhF$solidjsweb.template(`<div class="depict recommendations looks"style=--animation-duration:240ms>`);
1688
1852
  let $072863633018e322$var$expandedLooksSignal_;
1689
1853
  function $072863633018e322$export$1935e6bdfc5ed8ce(props) {
@@ -1692,6 +1856,7 @@ function $072863633018e322$export$1935e6bdfc5ed8ce(props) {
1692
1856
  equals: false
1693
1857
  });
1694
1858
  const expandingAnimationDuration = 240;
1859
+ const pseudoRouter = new (0, $e96dd13889871fc0$export$7e1297a3a19f10d8)("hard_navigation");
1695
1860
  const grid_spacing_override = $gVhhF$solidjs.createMemo(() => {
1696
1861
  const {
1697
1862
  gridSpacing_: gridSpacing_
@@ -1717,21 +1882,37 @@ function $072863633018e322$export$1935e6bdfc5ed8ce(props) {
1717
1882
  });
1718
1883
  const decoded = await response?.json?.().catch(() => false);
1719
1884
  if (!decoded)
1720
- // If network fails, make sure to return empty array adn SolidRecommendationSlider will remove its elements
1885
+ // If network fails, make sure to return empty array and SolidRecommendationSlider will remove its elements
1721
1886
  return [];
1722
- return decoded.listings;
1887
+ const {
1888
+ listings: listings
1889
+ } = decoded;
1890
+ const baseData = {
1891
+ merchant: merchant,
1892
+ market: market,
1893
+ locale: locale
1894
+ };
1895
+ return $072863633018e322$var$runDisplayTransformersForLooks(baseData, listings, props.displayTransformers_);
1896
+ });
1897
+ $gVhhF$solidjs.createEffect(() => {
1898
+ const {
1899
+ onNavigation_: onNavigation_
1900
+ } = props;
1901
+ if (onNavigation_) pseudoRouter.on_navigation_ = onNavigation_;
1723
1902
  });
1724
1903
  return (() => {
1725
1904
  var _el$ = $gVhhF$solidjsweb.getNextElement($072863633018e322$var$_tmpl$);
1726
1905
  $gVhhF$solidjsweb.insert(_el$, $gVhhF$solidjsweb.createComponent((0, $84798aaa863a4909$export$e68cff63f76bd15b), {
1727
1906
  get children() {
1728
1907
  return $363ce4d1d71041aa$export$d41d19e89346fa2({
1729
- product_card_template_: (display, info) => $ad882bbe664dbd53$export$44809a8a3e867e30({
1908
+ product_card_template_: display => $ad882bbe664dbd53$export$44809a8a3e867e30({
1730
1909
  display_: display,
1731
1910
  FavoriteButton_: props.FavoriteButton_,
1732
1911
  placeholderImageAspectRatio_: props.imagePlaceholderAspectRatio_,
1733
1912
  animationDuration_: expandingAnimationDuration,
1734
- expandedLooksSignal_: $072863633018e322$var$expandedLooksSignal_
1913
+ expandedLooksSignal_: $072863633018e322$var$expandedLooksSignal_,
1914
+ priceFormatting_: () => props.priceFormatting_,
1915
+ pseudoRouter_: pseudoRouter
1735
1916
  }),
1736
1917
  recommendations_resource_: looksResource,
1737
1918
  title_: () => props.title_,
@@ -1746,6 +1927,53 @@ function $072863633018e322$export$1935e6bdfc5ed8ce(props) {
1746
1927
  })();
1747
1928
  }, "LookSlider failed");
1748
1929
  }
1930
+ async function $072863633018e322$var$runDisplayTransformersForLooks(baseData, listings, displayTransformers) {
1931
+ try {
1932
+ const {
1933
+ products: productTransformer,
1934
+ categories: providedListingTransformer
1935
+ } = displayTransformers || {};
1936
+ if (!productTransformer && !providedListingTransformer) return listings;
1937
+ const listingTransformer = providedListingTransformer || (({
1938
+ data: data
1939
+ }) => data);
1940
+ const displaysToTransform = [];
1941
+ const displayIdsPerListingId = {};
1942
+ const transformedListingsPromise = listingTransformer({
1943
+ ...baseData,
1944
+ data: listings.map(({
1945
+ displays: displays,
1946
+ ...listing
1947
+ }) => {
1948
+ // Populate our displays by id and displayIdToListings object in the .map where we add ancestors to the listings, for peak efficiency
1949
+ for (let i = 0; i < displays.length; i++) {
1950
+ const display = displays[i];
1951
+ const uniqueIdOfDisplay = $a5871dacf261adf8$export$548d053aba053d79(display);
1952
+ displaysToTransform.push(display);
1953
+ (displayIdsPerListingId[listing.listing_id] ||= []).push(uniqueIdOfDisplay);
1954
+ }
1955
+ return {
1956
+ ...listing,
1957
+ ancestors: []
1958
+ };
1959
+ })
1960
+ });
1961
+ // This allows the person providing the displayTransformer to re-order and remove displays
1962
+ const transformedProducts = productTransformer ? await productTransformer({
1963
+ ...baseData,
1964
+ displays: displaysToTransform
1965
+ }) : displaysToTransform;
1966
+ const transformedListings = await transformedListingsPromise;
1967
+ const transformedDisplayById = Object.fromEntries(transformedProducts.map(display => [$a5871dacf261adf8$export$548d053aba053d79(display), display]));
1968
+ return transformedListings.map(listing => $gVhhF$solidjs.mergeProps(listing, {
1969
+ // use mergeProps because in preview browser we add getters in this object, that would be called too early otherwise
1970
+ displays: (displayIdsPerListingId[listing.listing_id] || []).map(displayId => transformedDisplayById[displayId]).filter(v => v)
1971
+ }));
1972
+ } catch (e) {
1973
+ $gVhhF$depictaiutilishared.dwarn("Displaytransformers threw", e);
1974
+ return [];
1975
+ }
1976
+ }
1749
1977
  const $d84fe647b84b5dc5$export$3064e1e8c6513da3 = new Set();
1750
1978
  let $d84fe647b84b5dc5$var$has_ran = false;
1751
1979
  function $d84fe647b84b5dc5$export$5162a71f252e6122() {
@@ -1786,21 +2014,6 @@ function $d84fe647b84b5dc5$var$starts_with_any_prefix(key) {
1786
2014
  }
1787
2015
  }
1788
2016
 
1789
- /**
1790
- * This function is used to determine if the user is trying to open a link in a new tab or window, and we therefore should not single page navigate
1791
- * @param clickEvent The click event that triggered the navigation
1792
- */
1793
- function $747421cd28dec5b5$export$29d28dadc2d6b631(clickEvent) {
1794
- return clickEvent?.button ||
1795
- // if not zero it's a wheel click which opens in new tab
1796
- clickEvent?.metaKey ||
1797
- // if true, cmd button on macOS which opens in new tab
1798
- clickEvent?.ctrlKey ||
1799
- // if true, ctrl button on windows or linux which opens in new tab
1800
- clickEvent?.shiftKey // if true, shift button on windows, linux or macOS which opens in a new window
1801
- ;
1802
- }
1803
-
1804
2017
  /**
1805
2018
  * Symbol used to identify the version of a SearchModal function. Values right now: 1 = 1st gen classic modal, 2 = second gen modal
1806
2019
  */
@@ -1840,12 +2053,6 @@ function $deaaf04362a1bc71$export$f50b88e2a00918b5(fn) {
1840
2053
  }
1841
2054
  };
1842
2055
  }
1843
- function $d659702496cb72ea$export$a71e92cfbb498adc(props) {
1844
- return $gVhhF$solidjs.createMemo(() => {
1845
- const price_formatting = props.price_formatting_;
1846
- return $gVhhF$depictaiutilishared.standard_price_format(props.price_, price_formatting.places_after_comma_, price_formatting.decimal_places_delimiter_, price_formatting.thousands_delimiter_);
1847
- });
1848
- }
1849
2056
  function $f144ea315d9e4caa$export$fb40a80c530e5f2b(selectedIndex, groupIndex, indexInGroup) {
1850
2057
  const isSelected = $gVhhF$solidjs.createMemo(() => {
1851
2058
  const selectedValue = selectedIndex();
@@ -5043,102 +5250,6 @@ function $6e22b5314fb52f4c$var$history_state_change(signals, entries, state) {
5043
5250
  }
5044
5251
  });
5045
5252
  }
5046
- class $e96dd13889871fc0$export$7e1297a3a19f10d8 {
5047
- /**
5048
- * Function that will be called when we want to navigate, or a string saying it's not an SPA. You can change this OTG
5049
- */ /**
5050
- * We store listing_id in history.state and do operate on this both here and in js-ui, this is the key to be used which js-ui provides
5051
- */
5052
- #throwing_on_navigation(...args) {
5053
- const {
5054
- on_navigation_: on_navigation_
5055
- } = this;
5056
- if (typeof on_navigation_ !== "function") throw new Error("on_navigation_ is not a function");
5057
- // make sure that we don't accidentally catchify if the SDK consumer has fucked up
5058
- try {
5059
- return on_navigation_(...args);
5060
- } catch (e) {
5061
- queueMicrotask(() => {
5062
- throw e;
5063
- });
5064
- }
5065
- }
5066
- /**
5067
- * Vue has async router that needs to be awaited (it navigates after a microtask)
5068
- * This standardises waiting for all kinds of routers
5069
- */
5070
- #get_navigation_happened_promise(is_replace) {
5071
- return new Promise(resolve => {
5072
- const handler = what_happened => {
5073
- if (what_happened === (is_replace ? "replaceState" : "pushState")) {
5074
- resolve();
5075
- (0, $gVhhF$depictaiutilishared.instant_exec_on_suspect_history_change).delete(handler);
5076
- }
5077
- };
5078
- (0, $gVhhF$depictaiutilishared.instant_exec_on_suspect_history_change).add(handler);
5079
- });
5080
- }
5081
- navigate_ = {
5082
- /**
5083
- * Call this if you *just* want to replace the state object in history.state
5084
- */
5085
- replace_state_: new_state => {
5086
- // This doesn't break any router, so we just do this directly for now, since many don't expose an interface for changing the state
5087
- globalThis?.history?.replaceState(new_state, "");
5088
- },
5089
- /**
5090
- * Call this to change the URL
5091
- * @param new_url_ new URL to go to
5092
- * @param event_ event if you have this in a click handler, will not do anything on cmd/ctrl or non-left click then
5093
- * @param force_spa_navigation_ if you want to force SPA navigation even if on_navigation_ is set to "hard_navigation". You should only set this to true for inter-SDK-page navigations
5094
- * @param is_replace_ if you want to replace the current URL in history instead of pushing a new one
5095
- * @param listing_id_ If you are navigating to a category and know the listing_id of, please provide it. This is for making a better devEx in js-ui
5096
- */
5097
- go_to_: $gVhhF$depictaiutilishared.catchify(async ({
5098
- new_url_: raw_new_url,
5099
- event_: event_,
5100
- force_spa_navigation_: force_spa_navigation_,
5101
- is_replace_: is_replace_,
5102
- listing_query_: listing_query_,
5103
- scroll = true
5104
- }) => {
5105
- const new_url_ = raw_new_url instanceof URL ? raw_new_url : new URL(raw_new_url, location.origin);
5106
- const wants_hard_navigation = this.on_navigation_ === "hard_navigation";
5107
- if ($747421cd28dec5b5$export$29d28dadc2d6b631(event_)) return;
5108
- const different_origin = new_url_.origin !== location.origin;
5109
- if (wants_hard_navigation && (!force_spa_navigation_ || different_origin)) {
5110
- if (force_spa_navigation_ && different_origin)
5111
- // If we call history.pushState on a different origin, it will throw an error, so fallback to hard navigations
5112
- $gVhhF$depictaiutilishared.dwarn("Can't single page navigate to", new_url_.href, "due to different origin, this MIGHT mean you should fix the URLs");
5113
- if (!event_)
5114
- // If we haven't gotten an event, nothing will happen by not calling prevent default, so we need to change the URL
5115
- location.assign(new_url_);
5116
- return;
5117
- }
5118
- event_?.preventDefault();
5119
- const promise = this.#get_navigation_happened_promise(true);
5120
- if (force_spa_navigation_ && wants_hard_navigation) {
5121
- // Don't allow hard navigation if we're forcing SPA navigation, which we do for things where PageReplacer can be used for performance
5122
- const new_state = history.state;
5123
- if (listing_query_) {
5124
- // In JS-UI we need to know the listing_id of the current category, therefore push it into state
5125
- if (!this.listing_query_state_key) $gVhhF$depictaiutilishared.report(new Error("listing_query_state_key is not set"), "error");
5126
- new_state[this.listing_query_state_key] = listing_query_;
5127
- }
5128
- history[is_replace_ ? "replaceState" : "pushState"](new_state, "", new_url_);
5129
- } else this.#throwing_on_navigation.call(this, {
5130
- is_replace: is_replace_,
5131
- new_url: new_url_ instanceof URL ? new_url_ : new URL(new_url_, location.origin),
5132
- scroll: scroll
5133
- });
5134
- await promise;
5135
- })
5136
- };
5137
- constructor(on_navigation, listing_query_state_key) {
5138
- this.listing_query_state_key = listing_query_state_key;
5139
- this.on_navigation_ = on_navigation;
5140
- }
5141
- }
5142
5253
  var $bbe694fe824b9c78$var$_tmpl$ = /*#__PURE__*/$gVhhF$solidjsweb.template(`<div class=image-container>`);
5143
5254
  function $bbe694fe824b9c78$export$41e1a079d40a0d58(props) {
5144
5255
  const [display] = $gVhhF$solidjs.createResource(() => ({