@depict-ai/ui 4.3.0 → 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.
@@ -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.0";
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++) {
@@ -960,7 +960,7 @@ function $19950faaac026e09$export$6e5611bc7e57e477(props) {
960
960
  });
961
961
  // Work around https://github.com/solidjs/solid/issues/1828
962
962
  const img = new Image(); // Need to use new Image or browser might not start loading image before it's in the DOM
963
- const [, otherAttributes] = $5vyXB$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 <-
963
+ const [, otherAttributes] = $5vyXB$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 <-
964
964
  ]);
965
965
 
966
966
  const [hasSetSize, setHasSetSize] = $5vyXB$solidjs.createSignal(false);
@@ -1016,13 +1016,18 @@ function $19950faaac026e09$export$6e5611bc7e57e477(props) {
1016
1016
  let hasDecodedFastPath = false;
1017
1017
  let timeoutSet = false;
1018
1018
  let gotCleanedUp = false;
1019
+ let srcJustChanged = true;
1019
1020
  img.classList.add("s-responsive-image");
1020
1021
  if (listingContext) {
1021
1022
  let prevValue;
1022
1023
  const aspectRatios = listingContext[$19950faaac026e09$export$f8945274f08a3105] ||= new Set();
1023
1024
  const [, setMostPrevalentAspectRatio] = listingContext[$19950faaac026e09$export$6066eb417ed2e9f7] ||= $5vyXB$solidjs.createSignal();
1024
1025
  img.addEventListener("load", $5vyXB$depictaiutilishared.catchify(() => {
1025
- // Save our aspect ratio whenever it changes, so that we can base the containers on the most dominant aspect ratio, used in SearchModalV2
1026
+ if (props.keyRatioUpdating) {
1027
+ if (!srcJustChanged) return;
1028
+ srcJustChanged = false;
1029
+ }
1030
+ // 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
1026
1031
  const aspectRatio_ = img.naturalWidth / img.naturalHeight;
1027
1032
  if (prevValue) aspectRatios.delete(prevValue);
1028
1033
  const newValue = !isNaN(aspectRatio_) ? {
@@ -1041,6 +1046,10 @@ function $19950faaac026e09$export$6e5611bc7e57e477(props) {
1041
1046
  }
1042
1047
  $5vyXB$solidjs.onCleanup(() => gotCleanedUp = true);
1043
1048
  $5vyXB$solidjsweb.spread(img, $5vyXB$solidjs.mergeProps(modifiedOtherAttributes), false, true);
1049
+ $5vyXB$solidjs.createRenderEffect(() => {
1050
+ props.src;
1051
+ srcJustChanged = true;
1052
+ });
1044
1053
  $5vyXB$solidjs.createEffect(() => {
1045
1054
  if (!props.size()) return; // wait until we have a size, run every time the size changes
1046
1055
  if (timeoutSet) return;
@@ -1110,48 +1119,22 @@ function $a33065cfed827fc0$export$e4b984597b71e989(props) {
1110
1119
  const [mostPrevalentAspectRatio] = context ?
1111
1120
  // 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
1112
1121
  context[(0, $19950faaac026e09$export$6066eb417ed2e9f7)] ||= $5vyXB$solidjs.createSignal() : [];
1113
- const [aspectRatio, setAspectRatio] = $5vyXB$solidjs.createSignal($5vyXB$solidjs.untrack(() => props.aspectRatio));
1114
1122
  const container = $93304d59a9747aa6$export$94026ee33dbabc26({
1115
1123
  // Write getters manually instead of using JSX, so we can do more complex logic in the aspectRatio getter without increasing bundle size
1116
1124
  get class() {
1117
1125
  return props.class;
1118
1126
  },
1119
1127
  get aspectRatio() {
1120
- return aspectRatio();
1128
+ if (props.autoAdjustAspectRatio) {
1129
+ const targetRatio = mostPrevalentAspectRatio?.();
1130
+ if (targetRatio != undefined) return `var(${(0, $6f604560873e4f69$export$8a2234b5b1a5ebd4)}, ${targetRatio})`;
1131
+ }
1132
+ return props.aspectRatio;
1121
1133
  }
1122
1134
  });
1123
1135
  const owner = $5vyXB$solidjs.getOwner();
1124
1136
  let createdSizeAccessor = false;
1125
1137
  let wasCleanedUp = false;
1126
- let timeout;
1127
- $5vyXB$solidjs.createEffect(() => {
1128
- const {
1129
- autoAdjustAspectRatio: autoAdjustAspectRatio
1130
- } = props;
1131
- if (autoAdjustAspectRatio) {
1132
- const targetRatio = mostPrevalentAspectRatio?.();
1133
- if (targetRatio != undefined) {
1134
- const targetValue = `var(${(0, $6f604560873e4f69$export$8a2234b5b1a5ebd4)}, ${targetRatio})`;
1135
- const updateAspectRatio = $5vyXB$depictaiutilishared.catchify(() => setAspectRatio(targetValue));
1136
- if (autoAdjustAspectRatio === "smoothed") {
1137
- if (!timeout)
1138
- // 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).
1139
- updateAspectRatio();
1140
- clearTimeout(timeout);
1141
- timeout = setTimeout(() => {
1142
- timeout = undefined;
1143
- updateAspectRatio();
1144
- }, 500);
1145
- return;
1146
- }
1147
- return updateAspectRatio();
1148
- }
1149
- } else {
1150
- clearTimeout(timeout);
1151
- timeout = undefined;
1152
- }
1153
- setAspectRatio(props.aspectRatio);
1154
- });
1155
1138
  $5vyXB$solidjs.createEffect(() => {
1156
1139
  if (currentImageSize() || wasCleanedUp) return; // We get into the effect when onCleanup is called if we don't have wasCleanedUp
1157
1140
  // ensure we always have a size accessor
@@ -1197,7 +1180,13 @@ function $d212a67662c5cf38$export$9d4a4b669b1929ab(props) {
1197
1180
  }
1198
1181
  }));
1199
1182
  }
1200
- var $1ae437d7d388a66e$var$_tmpl$ = ["<div", ' class="img-wrapper"><!--$-->', "<!--/--><!--$-->", "<!--/--></div>"],
1183
+ function $d659702496cb72ea$export$a71e92cfbb498adc(props) {
1184
+ return $5vyXB$solidjs.createMemo(() => {
1185
+ const price_formatting = props.price_formatting_;
1186
+ return $5vyXB$depictaiutilishared.standard_price_format(props.price_, price_formatting.places_after_comma_, price_formatting.decimal_places_delimiter_, price_formatting.thousands_delimiter_);
1187
+ });
1188
+ }
1189
+ var $1ae437d7d388a66e$var$_tmpl$ = ["<div", ' class="img-wrapper">', "</div>"],
1201
1190
  $1ae437d7d388a66e$var$_tmpl$2 = ["<span", ' class="d-price original">', "</span>"],
1202
1191
  $1ae437d7d388a66e$var$_tmpl$3 = ["<div", ' class="right-part"><div class="text-container"><span class="d-title line-clamp">', '</span><span class="', '">', "</span><!--$-->", "<!--/--></div><!--$-->", "<!--/--></div>"];
1203
1192
  function $1ae437d7d388a66e$export$b73ed90f0ee50dc3({
@@ -1206,26 +1195,28 @@ function $1ae437d7d388a66e$export$b73ed90f0ee50dc3({
1206
1195
  isExpanded_: isExpanded_,
1207
1196
  textFadeInAnimationRunning_: textFadeInAnimationRunning_,
1208
1197
  outerRef_: outerRef_,
1209
- animationDuration_: animationDuration_
1198
+ animationDuration_: animationDuration_,
1199
+ priceFormatting_: priceFormatting_,
1200
+ pseudoRouter_: pseudoRouter_
1210
1201
  }) {
1211
1202
  const variantToUse = $5vyXB$solidjs.createMemo(() => {
1212
1203
  const display = display_();
1213
1204
  return display?.variant_displays[display?.variant_index];
1214
1205
  });
1215
- const imageUrls = () => variantToUse()?.image_urls;
1216
- const imageUrl = $5vyXB$solidjs.createMemo(() => imageUrls()?.[0]);
1217
- const secondaryImageUrl = $5vyXB$solidjs.createMemo(() => imageUrls()?.[1]);
1206
+ const imageUrl = $5vyXB$solidjs.createMemo(() => variantToUse()?.image_urls?.[0]);
1218
1207
  const [animationIsRunning, setAnimationIsRunning] = textFadeInAnimationRunning_;
1219
1208
  const [isExpandedThrottledByOurEffectRun, setIsExpandedThrottledByOurEffectRun] = $5vyXB$solidjs.createSignal($5vyXB$solidjs.untrack(isExpanded_));
1220
1209
  const [animationEffectExists, setAnimationEffectExists] = $5vyXB$solidjs.createSignal(false);
1221
1210
  const [salePrice] = $5vyXB$solidjs.createResource(() => variantToUse()?.sale_price);
1222
1211
  const [originalPrice] = $5vyXB$solidjs.createResource(() => variantToUse()?.original_price);
1223
- const isOnSale = $5vyXB$solidjs.createMemo(() => salePrice.latest !== originalPrice.latest); // .latest doesn't trigger suspense
1212
+ const isOnSale = $5vyXB$solidjs.createMemo(() => !salePrice.loading && !originalPrice.loading && salePrice.latest !== originalPrice.latest); // .latest doesn't trigger suspense after the initial load
1213
+ const enableLink = $5vyXB$solidjs.createMemo(() => isExpanded_() && !animationIsRunning());
1214
+ const href = $5vyXB$solidjs.createMemo(() => variantToUse()?.page_url);
1224
1215
  const FavoriteButton = FavoriteButton_; // Just to get rid of the type error - TS doesn't understand <Show>
1225
1216
  return $5vyXB$solidjsweb.ssrElement("a", $5vyXB$solidjsweb.mergeProps({
1226
1217
  "class": "look-item"
1227
- }, () => isExpanded_() && !animationIsRunning() ? {
1228
- href: variantToUse()?.page_url
1218
+ }, () => enableLink() ? {
1219
+ href: href()
1229
1220
  } : {}), () => ["<!--$-->", $5vyXB$solidjsweb.escape($5vyXB$solidjsweb.createComponent((0, $5vyXB$solidjs.Show), {
1230
1221
  when: imageUrl,
1231
1222
  get fallback() {
@@ -1252,25 +1243,10 @@ function $1ae437d7d388a66e$export$b73ed90f0ee50dc3({
1252
1243
  return isExpanded_() ? 0.75 : 1;
1253
1244
  },
1254
1245
  get autoAdjustAspectRatio() {
1255
- return isExpanded_() ? "smoothed" : false;
1256
- }
1257
- });
1258
- }
1259
- })), $5vyXB$solidjsweb.escape($5vyXB$solidjsweb.createComponent((0, $5vyXB$solidjs.Show), {
1260
- get when() {
1261
- return secondaryImageUrl();
1262
- },
1263
- get children() {
1264
- return $5vyXB$solidjsweb.createComponent((0, $d212a67662c5cf38$export$9d4a4b669b1929ab), {
1265
- get src() {
1266
- return secondaryImageUrl();
1246
+ return isExpanded_();
1267
1247
  },
1268
- get aspectRatio() {
1269
- return isExpanded_() ? 0.75 : 1;
1270
- },
1271
- "class": "secondary",
1272
- get autoAdjustAspectRatio() {
1273
- return isExpanded_() ? "smoothed" : false;
1248
+ imgProps: {
1249
+ keyRatioUpdating: true
1274
1250
  }
1275
1251
  });
1276
1252
  }
@@ -1284,18 +1260,66 @@ function $1ae437d7d388a66e$export$b73ed90f0ee50dc3({
1284
1260
  return $5vyXB$solidjsweb.ssr($1ae437d7d388a66e$var$_tmpl$3, $5vyXB$solidjsweb.ssrHydrationKey(), $5vyXB$solidjsweb.escape(variantToUse()?.title) ?? $5vyXB$solidjsweb.escape($5vyXB$solidjsweb.createComponent((0, $061ff5b4c3d36171$export$89c6019e4baa40b1), {
1285
1261
  height: "1em",
1286
1262
  width: "20ch"
1287
- })), `d-price ${isOnSale() ? "sale" : ""}`, !variantToUse() || salePrice.loading ? $5vyXB$solidjsweb.escape($5vyXB$solidjsweb.createComponent((0, $061ff5b4c3d36171$export$89c6019e4baa40b1), {
1288
- height: "1em",
1289
- width: "20ch"
1290
- })) : $5vyXB$solidjsweb.escape(salePrice()), $5vyXB$solidjsweb.escape($5vyXB$solidjsweb.createComponent((0, $5vyXB$solidjs.Show), {
1263
+ })), `d-price ${isOnSale() ? "sale" : ""}`, $5vyXB$solidjsweb.escape($5vyXB$solidjsweb.createComponent((0, $5vyXB$solidjs.Show), {
1291
1264
  get when() {
1292
- return isOnSale();
1265
+ return variantToUse() && !salePrice.loading;
1293
1266
  },
1294
- get children() {
1295
- return $5vyXB$solidjsweb.ssr($1ae437d7d388a66e$var$_tmpl$2, $5vyXB$solidjsweb.ssrHydrationKey(), !variantToUse() || originalPrice.loading ? $5vyXB$solidjsweb.escape($5vyXB$solidjsweb.createComponent((0, $061ff5b4c3d36171$export$89c6019e4baa40b1), {
1267
+ get fallback() {
1268
+ return $5vyXB$solidjsweb.createComponent((0, $061ff5b4c3d36171$export$89c6019e4baa40b1), {
1296
1269
  height: "1em",
1297
1270
  width: "20ch"
1298
- })) : $5vyXB$solidjsweb.escape(originalPrice()));
1271
+ });
1272
+ },
1273
+ get children() {
1274
+ return $5vyXB$solidjsweb.createComponent((0, $5vyXB$solidjs.Show), {
1275
+ get when() {
1276
+ return salePrice.latest;
1277
+ },
1278
+ get children() {
1279
+ return [priceFormatting_().pre_, $5vyXB$solidjsweb.createComponent((0, $d659702496cb72ea$export$a71e92cfbb498adc), {
1280
+ get price_() {
1281
+ return salePrice();
1282
+ },
1283
+ get price_formatting_() {
1284
+ return priceFormatting_();
1285
+ }
1286
+ }), priceFormatting_().post_];
1287
+ }
1288
+ });
1289
+ }
1290
+ })), $5vyXB$solidjsweb.escape($5vyXB$solidjsweb.createComponent((0, $5vyXB$solidjs.Show), {
1291
+ get when() {
1292
+ return isOnSale();
1293
+ },
1294
+ get children() {
1295
+ return $5vyXB$solidjsweb.ssr($1ae437d7d388a66e$var$_tmpl$2, $5vyXB$solidjsweb.ssrHydrationKey(), $5vyXB$solidjsweb.escape($5vyXB$solidjsweb.createComponent((0, $5vyXB$solidjs.Show), {
1296
+ get when() {
1297
+ return variantToUse() && !originalPrice.loading;
1298
+ },
1299
+ get fallback() {
1300
+ return $5vyXB$solidjsweb.createComponent((0, $061ff5b4c3d36171$export$89c6019e4baa40b1), {
1301
+ height: "1em",
1302
+ width: "20ch"
1303
+ });
1304
+ },
1305
+ get children() {
1306
+ return $5vyXB$solidjsweb.createComponent((0, $5vyXB$solidjs.Show), {
1307
+ get when() {
1308
+ return salePrice.latest;
1309
+ },
1310
+ get children() {
1311
+ return [priceFormatting_().pre_, $5vyXB$solidjsweb.createComponent((0, $d659702496cb72ea$export$a71e92cfbb498adc), {
1312
+ get price_() {
1313
+ return originalPrice();
1314
+ },
1315
+ get price_formatting_() {
1316
+ return priceFormatting_();
1317
+ }
1318
+ }), priceFormatting_().post_];
1319
+ }
1320
+ });
1321
+ }
1322
+ })));
1299
1323
  }
1300
1324
  })), $5vyXB$solidjsweb.escape($5vyXB$solidjsweb.createComponent((0, $5vyXB$solidjs.Show), {
1301
1325
  when: FavoriteButton_,
@@ -1365,7 +1389,9 @@ function $905010a06f9aeae5$export$ebf0b1d4f90c09ae({
1365
1389
  userWantsExpandedSignal_: [userWantsExpanded, setUserWantsExpanded],
1366
1390
  containerWidth_: containerWidth_,
1367
1391
  animationDuration_: animationDuration_,
1368
- supportsHover_: supportsHover_
1392
+ supportsHover_: supportsHover_,
1393
+ priceFormatting_: priceFormatting_,
1394
+ pseudoRouter_: pseudoRouter_
1369
1395
  }) {
1370
1396
  let isAffectedByChromeBug = false;
1371
1397
  // If the user requests the drawer to be expanded or not
@@ -1396,11 +1422,13 @@ function $905010a06f9aeae5$export$ebf0b1d4f90c09ae({
1396
1422
  },
1397
1423
  children: (display, index) => {
1398
1424
  return $5vyXB$solidjsweb.createComponent((0, $1ae437d7d388a66e$export$b73ed90f0ee50dc3), {
1425
+ pseudoRouter_: pseudoRouter_,
1399
1426
  animationDuration_: animationDuration_,
1400
1427
  display_: display,
1401
1428
  FavoriteButton_: FavoriteButton_,
1402
1429
  isExpanded_: userWantsExpanded,
1403
1430
  textFadeInAnimationRunning_: textFadeInAnimationRunning,
1431
+ priceFormatting_: priceFormatting_,
1404
1432
  outerRef_: el => $5vyXB$solidjs.createEffect(() => {
1405
1433
  if (index !== 0) return;
1406
1434
  const resizeObserver = new ResizeObserver($5vyXB$depictaiutilishared.catchify(records => setLookItemHeight(records.at(-1).contentRect.height)));
@@ -1441,10 +1469,10 @@ function $ad882bbe664dbd53$export$44809a8a3e867e30({
1441
1469
  expandedLooksSignal_: [expandedLooks_, setExpandedLooks],
1442
1470
  FavoriteButton_: FavoriteButton_,
1443
1471
  placeholderImageAspectRatio_: placeholderImageAspectRatio_,
1444
- animationDuration_: animationDuration_
1472
+ animationDuration_: animationDuration_,
1473
+ priceFormatting_: priceFormatting_,
1474
+ pseudoRouter_: pseudoRouter_
1445
1475
  }) {
1446
- // TODO: shopify, run displayTransformers to get dynamic prices
1447
- // TODO: format prices
1448
1476
  const [coverImage] = display_?.image_urls || [];
1449
1477
  const useWantsExpandedSignal_ = $5vyXB$solidjs.createSignal(false);
1450
1478
  const [userWantsExpanded, setUserWantsExpanded] = useWantsExpandedSignal_;
@@ -1476,7 +1504,7 @@ function $ad882bbe664dbd53$export$44809a8a3e867e30({
1476
1504
  when: display_,
1477
1505
  get fallback() {
1478
1506
  return $5vyXB$solidjsweb.createComponent((0, $3bc4a89b971a3af5$export$3f37af283f8fb843), {
1479
- aspectRatio: placeholderImageAspectRatio_
1507
+ aspectRatio: `var(${(0, $6f604560873e4f69$export$8a2234b5b1a5ebd4)}, ${placeholderImageAspectRatio_})`
1480
1508
  });
1481
1509
  },
1482
1510
  get children() {
@@ -1494,10 +1522,124 @@ function $ad882bbe664dbd53$export$44809a8a3e867e30({
1494
1522
  containerWidth_: containerWidth_,
1495
1523
  animationDuration_: animationDuration_,
1496
1524
  supportsHover_: supportsHover_,
1497
- FavoriteButton_: FavoriteButton_
1525
+ FavoriteButton_: FavoriteButton_,
1526
+ priceFormatting_: priceFormatting_,
1527
+ pseudoRouter_: pseudoRouter_
1498
1528
  })]);
1499
1529
  return container;
1500
1530
  }
1531
+
1532
+ /**
1533
+ * 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
1534
+ * @param clickEvent The click event that triggered the navigation
1535
+ */
1536
+ function $747421cd28dec5b5$export$29d28dadc2d6b631(clickEvent) {
1537
+ return clickEvent?.button ||
1538
+ // if not zero it's a wheel click which opens in new tab
1539
+ clickEvent?.metaKey ||
1540
+ // if true, cmd button on macOS which opens in new tab
1541
+ clickEvent?.ctrlKey ||
1542
+ // if true, ctrl button on windows or linux which opens in new tab
1543
+ clickEvent?.shiftKey // if true, shift button on windows, linux or macOS which opens in a new window
1544
+ ;
1545
+ }
1546
+
1547
+ class $e96dd13889871fc0$export$7e1297a3a19f10d8 {
1548
+ /**
1549
+ * Function that will be called when we want to navigate, or a string saying it's not an SPA. You can change this OTG
1550
+ */ /**
1551
+ * 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
1552
+ */
1553
+ #throwing_on_navigation(...args) {
1554
+ const {
1555
+ on_navigation_: on_navigation_
1556
+ } = this;
1557
+ if (typeof on_navigation_ !== "function") throw new Error("on_navigation_ is not a function");
1558
+ // make sure that we don't accidentally catchify if the SDK consumer has fucked up
1559
+ try {
1560
+ return on_navigation_(...args);
1561
+ } catch (e) {
1562
+ queueMicrotask(() => {
1563
+ throw e;
1564
+ });
1565
+ }
1566
+ }
1567
+ /**
1568
+ * Vue has async router that needs to be awaited (it navigates after a microtask)
1569
+ * This standardises waiting for all kinds of routers
1570
+ */
1571
+ #get_navigation_happened_promise(is_replace) {
1572
+ return new Promise(resolve => {
1573
+ const handler = what_happened => {
1574
+ if (what_happened === (is_replace ? "replaceState" : "pushState")) {
1575
+ resolve();
1576
+ (0, $5vyXB$depictaiutilishared.instant_exec_on_suspect_history_change).delete(handler);
1577
+ }
1578
+ };
1579
+ (0, $5vyXB$depictaiutilishared.instant_exec_on_suspect_history_change).add(handler);
1580
+ });
1581
+ }
1582
+ navigate_ = {
1583
+ /**
1584
+ * Call this if you *just* want to replace the state object in history.state
1585
+ */
1586
+ replace_state_: new_state => {
1587
+ // 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
1588
+ globalThis?.history?.replaceState(new_state, "");
1589
+ },
1590
+ /**
1591
+ * Call this to change the URL
1592
+ * @param new_url_ new URL to go to
1593
+ * @param event_ event if you have this in a click handler, will not do anything on cmd/ctrl or non-left click then
1594
+ * @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
1595
+ * @param is_replace_ if you want to replace the current URL in history instead of pushing a new one
1596
+ * @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
1597
+ */
1598
+ go_to_: $5vyXB$depictaiutilishared.catchify(async ({
1599
+ new_url_: raw_new_url,
1600
+ event_: event_,
1601
+ force_spa_navigation_: force_spa_navigation_,
1602
+ is_replace_: is_replace_,
1603
+ listing_query_: listing_query_,
1604
+ scroll = true
1605
+ }) => {
1606
+ const new_url_ = raw_new_url instanceof URL ? raw_new_url : new URL(raw_new_url, location.origin);
1607
+ const wants_hard_navigation = this.on_navigation_ === "hard_navigation";
1608
+ if ($747421cd28dec5b5$export$29d28dadc2d6b631(event_)) return;
1609
+ const different_origin = new_url_.origin !== location.origin;
1610
+ if (wants_hard_navigation && (!force_spa_navigation_ || different_origin)) {
1611
+ if (force_spa_navigation_ && different_origin)
1612
+ // If we call history.pushState on a different origin, it will throw an error, so fallback to hard navigations
1613
+ $5vyXB$depictaiutilishared.dwarn("Can't single page navigate to", new_url_.href, "due to different origin, this MIGHT mean you should fix the URLs");
1614
+ if (!event_)
1615
+ // If we haven't gotten an event, nothing will happen by not calling prevent default, so we need to change the URL
1616
+ location.assign(new_url_);
1617
+ return;
1618
+ }
1619
+ event_?.preventDefault();
1620
+ const promise = this.#get_navigation_happened_promise(true);
1621
+ if (force_spa_navigation_ && wants_hard_navigation) {
1622
+ // Don't allow hard navigation if we're forcing SPA navigation, which we do for things where PageReplacer can be used for performance
1623
+ const new_state = history.state;
1624
+ if (listing_query_) {
1625
+ // In JS-UI we need to know the listing_id of the current category, therefore push it into state
1626
+ if (!this.listing_query_state_key) $5vyXB$depictaiutilishared.report(new Error("listing_query_state_key is not set"), "error");
1627
+ new_state[this.listing_query_state_key] = listing_query_;
1628
+ }
1629
+ history[is_replace_ ? "replaceState" : "pushState"](new_state, "", new_url_);
1630
+ } else this.#throwing_on_navigation.call(this, {
1631
+ is_replace: is_replace_,
1632
+ new_url: new_url_ instanceof URL ? new_url_ : new URL(new_url_, location.origin),
1633
+ scroll: scroll
1634
+ });
1635
+ await promise;
1636
+ })
1637
+ };
1638
+ constructor(on_navigation, listing_query_state_key) {
1639
+ this.listing_query_state_key = listing_query_state_key;
1640
+ this.on_navigation_ = on_navigation;
1641
+ }
1642
+ }
1501
1643
  var $072863633018e322$var$_tmpl$ = ["<div", ' class="depict recommendations looks" style="', '">', "</div>"];
1502
1644
  let $072863633018e322$var$expandedLooksSignal_;
1503
1645
  function $072863633018e322$export$1935e6bdfc5ed8ce(props) {
@@ -1506,6 +1648,7 @@ function $072863633018e322$export$1935e6bdfc5ed8ce(props) {
1506
1648
  equals: false
1507
1649
  });
1508
1650
  const expandingAnimationDuration = 240;
1651
+ const pseudoRouter = new (0, $e96dd13889871fc0$export$7e1297a3a19f10d8)("hard_navigation");
1509
1652
  const grid_spacing_override = $5vyXB$solidjs.createMemo(() => {
1510
1653
  const {
1511
1654
  gridSpacing_: gridSpacing_
@@ -1531,19 +1674,35 @@ function $072863633018e322$export$1935e6bdfc5ed8ce(props) {
1531
1674
  });
1532
1675
  const decoded = await response?.json?.().catch(() => false);
1533
1676
  if (!decoded)
1534
- // If network fails, make sure to return empty array adn SolidRecommendationSlider will remove its elements
1677
+ // If network fails, make sure to return empty array and SolidRecommendationSlider will remove its elements
1535
1678
  return [];
1536
- return decoded.listings;
1679
+ const {
1680
+ listings: listings
1681
+ } = decoded;
1682
+ const baseData = {
1683
+ merchant: merchant,
1684
+ market: market,
1685
+ locale: locale
1686
+ };
1687
+ return $072863633018e322$var$runDisplayTransformersForLooks(baseData, listings, props.displayTransformers_);
1688
+ });
1689
+ $5vyXB$solidjs.createEffect(() => {
1690
+ const {
1691
+ onNavigation_: onNavigation_
1692
+ } = props;
1693
+ if (onNavigation_) pseudoRouter.on_navigation_ = onNavigation_;
1537
1694
  });
1538
1695
  return $5vyXB$solidjsweb.ssr($072863633018e322$var$_tmpl$, $5vyXB$solidjsweb.ssrHydrationKey(), $5vyXB$solidjsweb.ssrStyle(`--animation-duration: ${expandingAnimationDuration}ms`), $5vyXB$solidjsweb.escape($5vyXB$solidjsweb.createComponent((0, $84798aaa863a4909$export$e68cff63f76bd15b), {
1539
1696
  get children() {
1540
1697
  return $363ce4d1d71041aa$export$d41d19e89346fa2({
1541
- product_card_template_: (display, info) => $ad882bbe664dbd53$export$44809a8a3e867e30({
1698
+ product_card_template_: display => $ad882bbe664dbd53$export$44809a8a3e867e30({
1542
1699
  display_: display,
1543
1700
  FavoriteButton_: props.FavoriteButton_,
1544
1701
  placeholderImageAspectRatio_: props.imagePlaceholderAspectRatio_,
1545
1702
  animationDuration_: expandingAnimationDuration,
1546
- expandedLooksSignal_: $072863633018e322$var$expandedLooksSignal_
1703
+ expandedLooksSignal_: $072863633018e322$var$expandedLooksSignal_,
1704
+ priceFormatting_: () => props.priceFormatting_,
1705
+ pseudoRouter_: pseudoRouter
1547
1706
  }),
1548
1707
  recommendations_resource_: looksResource,
1549
1708
  title_: () => props.title_,
@@ -1556,6 +1715,53 @@ function $072863633018e322$export$1935e6bdfc5ed8ce(props) {
1556
1715
  })));
1557
1716
  }, "LookSlider failed");
1558
1717
  }
1718
+ async function $072863633018e322$var$runDisplayTransformersForLooks(baseData, listings, displayTransformers) {
1719
+ try {
1720
+ const {
1721
+ products: productTransformer,
1722
+ categories: providedListingTransformer
1723
+ } = displayTransformers || {};
1724
+ if (!productTransformer && !providedListingTransformer) return listings;
1725
+ const listingTransformer = providedListingTransformer || (({
1726
+ data: data
1727
+ }) => data);
1728
+ const displaysToTransform = [];
1729
+ const displayIdsPerListingId = {};
1730
+ const transformedListingsPromise = listingTransformer({
1731
+ ...baseData,
1732
+ data: listings.map(({
1733
+ displays: displays,
1734
+ ...listing
1735
+ }) => {
1736
+ // Populate our displays by id and displayIdToListings object in the .map where we add ancestors to the listings, for peak efficiency
1737
+ for (let i = 0; i < displays.length; i++) {
1738
+ const display = displays[i];
1739
+ const uniqueIdOfDisplay = $a5871dacf261adf8$export$548d053aba053d79(display);
1740
+ displaysToTransform.push(display);
1741
+ (displayIdsPerListingId[listing.listing_id] ||= []).push(uniqueIdOfDisplay);
1742
+ }
1743
+ return {
1744
+ ...listing,
1745
+ ancestors: []
1746
+ };
1747
+ })
1748
+ });
1749
+ // This allows the person providing the displayTransformer to re-order and remove displays
1750
+ const transformedProducts = productTransformer ? await productTransformer({
1751
+ ...baseData,
1752
+ displays: displaysToTransform
1753
+ }) : displaysToTransform;
1754
+ const transformedListings = await transformedListingsPromise;
1755
+ const transformedDisplayById = Object.fromEntries(transformedProducts.map(display => [$a5871dacf261adf8$export$548d053aba053d79(display), display]));
1756
+ return transformedListings.map(listing => $5vyXB$solidjs.mergeProps(listing, {
1757
+ // use mergeProps because in preview browser we add getters in this object, that would be called too early otherwise
1758
+ displays: (displayIdsPerListingId[listing.listing_id] || []).map(displayId => transformedDisplayById[displayId]).filter(v => v)
1759
+ }));
1760
+ } catch (e) {
1761
+ $5vyXB$depictaiutilishared.dwarn("Displaytransformers threw", e);
1762
+ return [];
1763
+ }
1764
+ }
1559
1765
  const $d84fe647b84b5dc5$export$3064e1e8c6513da3 = new Set();
1560
1766
  let $d84fe647b84b5dc5$var$has_ran = false;
1561
1767
  function $d84fe647b84b5dc5$export$5162a71f252e6122() {
@@ -1596,21 +1802,6 @@ function $d84fe647b84b5dc5$var$starts_with_any_prefix(key) {
1596
1802
  }
1597
1803
  }
1598
1804
 
1599
- /**
1600
- * 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
1601
- * @param clickEvent The click event that triggered the navigation
1602
- */
1603
- function $747421cd28dec5b5$export$29d28dadc2d6b631(clickEvent) {
1604
- return clickEvent?.button ||
1605
- // if not zero it's a wheel click which opens in new tab
1606
- clickEvent?.metaKey ||
1607
- // if true, cmd button on macOS which opens in new tab
1608
- clickEvent?.ctrlKey ||
1609
- // if true, ctrl button on windows or linux which opens in new tab
1610
- clickEvent?.shiftKey // if true, shift button on windows, linux or macOS which opens in a new window
1611
- ;
1612
- }
1613
-
1614
1805
  /**
1615
1806
  * Symbol used to identify the version of a SearchModal function. Values right now: 1 = 1st gen classic modal, 2 = second gen modal
1616
1807
  */
@@ -1650,12 +1841,6 @@ function $deaaf04362a1bc71$export$f50b88e2a00918b5(fn) {
1650
1841
  }
1651
1842
  };
1652
1843
  }
1653
- function $d659702496cb72ea$export$a71e92cfbb498adc(props) {
1654
- return $5vyXB$solidjs.createMemo(() => {
1655
- const price_formatting = props.price_formatting_;
1656
- return $5vyXB$depictaiutilishared.standard_price_format(props.price_, price_formatting.places_after_comma_, price_formatting.decimal_places_delimiter_, price_formatting.thousands_delimiter_);
1657
- });
1658
- }
1659
1844
  function $f144ea315d9e4caa$export$fb40a80c530e5f2b(selectedIndex, groupIndex, indexInGroup) {
1660
1845
  const isSelected = $5vyXB$solidjs.createMemo(() => {
1661
1846
  const selectedValue = selectedIndex();
@@ -4080,102 +4265,6 @@ function $6e22b5314fb52f4c$var$history_state_change(signals, entries, state) {
4080
4265
  }
4081
4266
  });
4082
4267
  }
4083
- class $e96dd13889871fc0$export$7e1297a3a19f10d8 {
4084
- /**
4085
- * Function that will be called when we want to navigate, or a string saying it's not an SPA. You can change this OTG
4086
- */ /**
4087
- * 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
4088
- */
4089
- #throwing_on_navigation(...args) {
4090
- const {
4091
- on_navigation_: on_navigation_
4092
- } = this;
4093
- if (typeof on_navigation_ !== "function") throw new Error("on_navigation_ is not a function");
4094
- // make sure that we don't accidentally catchify if the SDK consumer has fucked up
4095
- try {
4096
- return on_navigation_(...args);
4097
- } catch (e) {
4098
- queueMicrotask(() => {
4099
- throw e;
4100
- });
4101
- }
4102
- }
4103
- /**
4104
- * Vue has async router that needs to be awaited (it navigates after a microtask)
4105
- * This standardises waiting for all kinds of routers
4106
- */
4107
- #get_navigation_happened_promise(is_replace) {
4108
- return new Promise(resolve => {
4109
- const handler = what_happened => {
4110
- if (what_happened === (is_replace ? "replaceState" : "pushState")) {
4111
- resolve();
4112
- (0, $5vyXB$depictaiutilishared.instant_exec_on_suspect_history_change).delete(handler);
4113
- }
4114
- };
4115
- (0, $5vyXB$depictaiutilishared.instant_exec_on_suspect_history_change).add(handler);
4116
- });
4117
- }
4118
- navigate_ = {
4119
- /**
4120
- * Call this if you *just* want to replace the state object in history.state
4121
- */
4122
- replace_state_: new_state => {
4123
- // 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
4124
- globalThis?.history?.replaceState(new_state, "");
4125
- },
4126
- /**
4127
- * Call this to change the URL
4128
- * @param new_url_ new URL to go to
4129
- * @param event_ event if you have this in a click handler, will not do anything on cmd/ctrl or non-left click then
4130
- * @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
4131
- * @param is_replace_ if you want to replace the current URL in history instead of pushing a new one
4132
- * @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
4133
- */
4134
- go_to_: $5vyXB$depictaiutilishared.catchify(async ({
4135
- new_url_: raw_new_url,
4136
- event_: event_,
4137
- force_spa_navigation_: force_spa_navigation_,
4138
- is_replace_: is_replace_,
4139
- listing_query_: listing_query_,
4140
- scroll = true
4141
- }) => {
4142
- const new_url_ = raw_new_url instanceof URL ? raw_new_url : new URL(raw_new_url, location.origin);
4143
- const wants_hard_navigation = this.on_navigation_ === "hard_navigation";
4144
- if ($747421cd28dec5b5$export$29d28dadc2d6b631(event_)) return;
4145
- const different_origin = new_url_.origin !== location.origin;
4146
- if (wants_hard_navigation && (!force_spa_navigation_ || different_origin)) {
4147
- if (force_spa_navigation_ && different_origin)
4148
- // If we call history.pushState on a different origin, it will throw an error, so fallback to hard navigations
4149
- $5vyXB$depictaiutilishared.dwarn("Can't single page navigate to", new_url_.href, "due to different origin, this MIGHT mean you should fix the URLs");
4150
- if (!event_)
4151
- // If we haven't gotten an event, nothing will happen by not calling prevent default, so we need to change the URL
4152
- location.assign(new_url_);
4153
- return;
4154
- }
4155
- event_?.preventDefault();
4156
- const promise = this.#get_navigation_happened_promise(true);
4157
- if (force_spa_navigation_ && wants_hard_navigation) {
4158
- // Don't allow hard navigation if we're forcing SPA navigation, which we do for things where PageReplacer can be used for performance
4159
- const new_state = history.state;
4160
- if (listing_query_) {
4161
- // In JS-UI we need to know the listing_id of the current category, therefore push it into state
4162
- if (!this.listing_query_state_key) $5vyXB$depictaiutilishared.report(new Error("listing_query_state_key is not set"), "error");
4163
- new_state[this.listing_query_state_key] = listing_query_;
4164
- }
4165
- history[is_replace_ ? "replaceState" : "pushState"](new_state, "", new_url_);
4166
- } else this.#throwing_on_navigation.call(this, {
4167
- is_replace: is_replace_,
4168
- new_url: new_url_ instanceof URL ? new_url_ : new URL(new_url_, location.origin),
4169
- scroll: scroll
4170
- });
4171
- await promise;
4172
- })
4173
- };
4174
- constructor(on_navigation, listing_query_state_key) {
4175
- this.listing_query_state_key = listing_query_state_key;
4176
- this.on_navigation_ = on_navigation;
4177
- }
4178
- }
4179
4268
  var $bbe694fe824b9c78$var$_tmpl$ = ["<div", ' class="image-container">', "</div>"];
4180
4269
  function $bbe694fe824b9c78$export$41e1a079d40a0d58(props) {
4181
4270
  const [display] = $5vyXB$solidjs.createResource(() => ({