@depict-ai/ui 4.0.0 → 4.0.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.
@@ -92,7 +92,7 @@ $parcel$export(module.exports, "defaultCategoryTitlePlugin", () => $33eed84f447a
92
92
  $parcel$export(module.exports, "version", () => $aa1938dec50d6c12$export$83d89fbfd8236492);
93
93
  $parcel$export(module.exports, "SearchField", () => $98aef9965764903d$export$316f6f283ae64765);
94
94
  /*! Depict.ai search and product listing SDK */
95
- const $aa1938dec50d6c12$export$83d89fbfd8236492 = "4.0.0";
95
+ const $aa1938dec50d6c12$export$83d89fbfd8236492 = "4.0.2";
96
96
  function $a28000bc10de28ad$export$e417c49320921907(dependency, fetcher) {
97
97
  const [promiseOfCurrentFetcherRun, setPromiseOfCurrentFetcherRun] = $3hooq$solidjs.createSignal();
98
98
  const deparallelizedFetcher = $3hooq$depictaiutilishared.deparallelize_no_drop(async dependencyValue => {
@@ -1960,6 +1960,7 @@ function $858fdcf73148519f$export$e6fffe67d4cdd848(whatToWatch) {
1960
1960
  return size;
1961
1961
  }
1962
1962
  const $858fdcf73148519f$var$onIdleFunctionsSymbol = /*@__PURE__*/Symbol("onIdleFunctions");
1963
+ const $858fdcf73148519f$export$f8945274f08a3105 = /*@__PURE__*/Symbol("listingContextAspectRatios");
1963
1964
  function $858fdcf73148519f$export$6e5611bc7e57e477(props) {
1964
1965
  // Enable reactive props
1965
1966
  const otherOptions = $3hooq$solidjs.createMemo(() => {
@@ -2024,6 +2025,21 @@ function $858fdcf73148519f$export$6e5611bc7e57e477(props) {
2024
2025
  let timeoutSet = false;
2025
2026
  let gotCleanedUp = false;
2026
2027
  img.classList.add("s-responsive-image");
2028
+ if (listingContext) {
2029
+ let prevValue;
2030
+ const aspectRatios = listingContext[$858fdcf73148519f$export$f8945274f08a3105] || (listingContext[$858fdcf73148519f$export$f8945274f08a3105] = new (0, $3hooq$depictaiutilishared.ListenableSet)());
2031
+ img.addEventListener("load", $3hooq$depictaiutilishared.catchify(() => {
2032
+ // Save our aspect ratio whenever it changes, so that we can base the containers on the most dominant aspect ratio, used in SearchModalV2
2033
+ const aspectRatio_ = img.naturalWidth / img.naturalHeight;
2034
+ if (prevValue) aspectRatios.delete(prevValue);
2035
+ const newValue = !isNaN(aspectRatio_) ? {
2036
+ aspectRatio_: aspectRatio_
2037
+ } : undefined;
2038
+ if (newValue) aspectRatios.add(newValue);
2039
+ prevValue = newValue;
2040
+ }));
2041
+ $3hooq$solidjs.onCleanup(() => prevValue && aspectRatios.delete(prevValue));
2042
+ }
2027
2043
  $3hooq$solidjs.onCleanup(() => gotCleanedUp = true);
2028
2044
  $3hooq$solidjsweb.spread(img, $3hooq$solidjs.mergeProps(otherOptions), false, true);
2029
2045
  $3hooq$solidjs.createEffect(() => {
@@ -2091,9 +2107,29 @@ function $28535bb7671c63d1$export$e4b984597b71e989(props) {
2091
2107
  // create a signal that's the same for all items in this listing
2092
2108
  context[$28535bb7671c63d1$export$d7b7ab832c20e2f4] = $3hooq$solidjs.createSignal();
2093
2109
  const [currentImageSize, setCurrentImageSize] = (context === null || context === void 0 ? void 0 : context[$28535bb7671c63d1$export$d7b7ab832c20e2f4]) || $28535bb7671c63d1$var$backupSizeSignal; // use global fallback signal (might lead to blurry images) if no context is available
2110
+ const aspectRatiosSet = context ? context[(0, $858fdcf73148519f$export$f8945274f08a3105)] || (context[(0, $858fdcf73148519f$export$f8945274f08a3105)] = new (0, $3hooq$depictaiutilishared.ListenableSet)()) : undefined;
2111
+ const [aspectRatios, setAspectRatios] = $3hooq$solidjs.createSignal(aspectRatiosSet, {
2112
+ equals: false
2113
+ });
2114
+ const aspectRatioToUse = $3hooq$solidjs.createMemo(() => {
2115
+ const aspectRatiosSet = aspectRatios(); // This signal "changes" to the same set every time the set changes, so we can use it as a dependency here
2116
+ useMostPrevalentAspectRatio: {
2117
+ if (!aspectRatiosSet || !props.autoAdjustAspectRatio) break useMostPrevalentAspectRatio;
2118
+ // Get the aspect ratio that most of the loaded images inside the ListingProvider we are, load
2119
+ const asArray = [...aspectRatiosSet].map(_ref => {
2120
+ let {
2121
+ aspectRatio_: aspectRatio_
2122
+ } = _ref;
2123
+ return aspectRatio_;
2124
+ });
2125
+ const mostPrevalentAspectRatio = $3hooq$depictaiutilishared.findMostFrequentItem(asArray);
2126
+ if (mostPrevalentAspectRatio) return "var(".concat((0, $c0cf6af094336798$export$8a2234b5b1a5ebd4), ", ").concat(mostPrevalentAspectRatio, ")");
2127
+ }
2128
+ return props.aspectRatio;
2129
+ });
2094
2130
  const container = $3hooq$solidjsweb.createComponent((0, $ce467edb5343cfcd$export$94026ee33dbabc26), {
2095
2131
  get aspectRatio() {
2096
- return props.aspectRatio;
2132
+ return aspectRatioToUse();
2097
2133
  },
2098
2134
  get ["class"]() {
2099
2135
  return props.class;
@@ -2102,6 +2138,10 @@ function $28535bb7671c63d1$export$e4b984597b71e989(props) {
2102
2138
  const owner = $3hooq$solidjs.getOwner();
2103
2139
  let createdSizeAccessor = false;
2104
2140
  let wasCleanedUp = false;
2141
+ for (const event of ["add", "delete"]) {
2142
+ aspectRatiosSet === null || aspectRatiosSet === void 0 || aspectRatiosSet.addEventListener(event, () => setAspectRatios(aspectRatiosSet));
2143
+ $3hooq$solidjs.onCleanup(() => aspectRatiosSet === null || aspectRatiosSet === void 0 ? void 0 : aspectRatiosSet.removeEventListener(event, () => setAspectRatios(aspectRatiosSet)));
2144
+ }
2105
2145
  $3hooq$solidjs.createEffect(() => {
2106
2146
  if (currentImageSize() || wasCleanedUp) return; // We get into the effect when onCleanup is called if we don't have wasCleanedUp
2107
2147
  // ensure we always have a size accessor
@@ -2977,7 +3017,8 @@ function $43600b30502feeda$var$RawSearchModalV2(_ref) {
2977
3017
  get src() {
2978
3018
  return props.src_;
2979
3019
  },
2980
- aspectRatio: "var(".concat((0, $c0cf6af094336798$export$8a2234b5b1a5ebd4), ", 1)")
3020
+ autoAdjustAspectRatio: true,
3021
+ aspectRatio: 1
2981
3022
  }),
2982
3023
  ...instant_results_options_
2983
3024
  })));
@@ -3198,7 +3239,17 @@ async function $4cf7d9829d60d844$export$79b1565500412d9b(search_modal, modal_fn_
3198
3239
  const actually_close = () => {
3199
3240
  dispose();
3200
3241
  on_dispose === null || on_dispose === void 0 || on_dispose();
3201
- modal_els.forEach(el => el.remove());
3242
+ const {
3243
+ activeElement: activeElement
3244
+ } = document;
3245
+ modal_els.forEach(el => {
3246
+ if (el.contains(activeElement)) {
3247
+ var _blur, _ref;
3248
+ // Fix page jumping to the bottom when closing modal with scape after animation in safari
3249
+ activeElement === null || activeElement === void 0 || (_blur = (_ref = activeElement).blur) === null || _blur === void 0 || _blur.call(_ref);
3250
+ }
3251
+ el.remove();
3252
+ });
3202
3253
  };
3203
3254
  if (animation_started && +new Date() - animation_started > 1000)
3204
3255
  // Animation broke, close it this time
@@ -11053,30 +11104,37 @@ function $a60bc7692ce52705$export$44f738469d5570cf(_ref) {
11053
11104
  modalSearchFieldOuterWidth_: modalSearchFieldOuterWidth_
11054
11105
  } = _ref;
11055
11106
  return $3hooq$solidjs.createRoot(dispose => {
11107
+ const [innerWidthReactive, setInnerWidthReactive] = $3hooq$solidjs.createSignal(innerWidth);
11108
+ const resizeObserver = new ResizeObserver(records => setInnerWidthReactive(records.at(-1).contentRect.width));
11109
+ const {
11110
+ left: left,
11111
+ top: top,
11112
+ width: width
11113
+ } = actualField_.getBoundingClientRect();
11056
11114
  const fakeField = makeFakeField_();
11057
11115
  const owner = $3hooq$solidjs.getOwner();
11058
11116
  const inModalFieldWidth = $3hooq$solidjs.createMemo(
11059
11117
  // Can't have `min(${modalSearchFieldOuterWidth_()}px, var(--field-max-width, 600px))` because the WAAPI doesn't support that, so we need ot calculate it in JS
11060
- () => Math.min(modalSearchFieldOuterWidth_(), parseFloat(getComputedStyle(actualField_).getPropertyValue("--field-max-width") || "600")) + "px");
11118
+ () => Math.min(modalSearchFieldOuterWidth_(), parseFloat(getComputedStyle(actualField_).getPropertyValue("--field-max-width") || "600")));
11119
+ const inModalFieldWidthPx = $3hooq$solidjs.createMemo(() => inModalFieldWidth() + "px");
11120
+ let disableResizePollingTimeout;
11121
+ resizeObserver.observe(document.documentElement);
11122
+ $3hooq$solidjs.onCleanup(() => resizeObserver.disconnect());
11061
11123
  actualField_.replaceWith(fakeField);
11062
11124
  // Don't move the wrapped div since that would confuse run_in_root_or_auto_cleanup, but do actually move the field the user clicked around so that all selection stuff etc. is easier
11063
11125
  const addedToBody = wrap_ ? $3hooq$solidjsweb.ssr($a60bc7692ce52705$var$_tmpl$, $3hooq$solidjsweb.ssrHydrationKey(), $3hooq$solidjsweb.escape(actualField_)) : actualField_;
11064
11126
  document.body.append(addedToBody);
11065
- const {
11066
- left: left,
11067
- top: top,
11068
- width: width
11069
- } = fakeField.getBoundingClientRect();
11070
11127
  const zIndexOfFake = getComputedStyle(fakeField).zIndex;
11071
11128
  Object.assign(addedToBody.style, {
11072
11129
  position: "fixed",
11073
11130
  top: top + "px",
11131
+ left: left + "px",
11074
11132
  width: width + "px",
11075
11133
  ...(zIndexOfFake !== "auto" ? {
11076
11134
  zIndex: +zIndexOfFake + 1
11077
11135
  } : {})
11078
11136
  });
11079
- const pxOffCenter = innerWidth / 2 - (left + width / 2);
11137
+ const pxOffCenter = $3hooq$solidjs.untrack(innerWidthReactive) / 2 - (left + width / 2);
11080
11138
  const openDuration = pxOffCenter > 100 ? 250 : 125; // faster animations if little left-right movement
11081
11139
  const closeDuration = pxOffCenter > 100 ? 150 : 100;
11082
11140
  setPollAlignment_(true);
@@ -11095,24 +11153,30 @@ function $a60bc7692ce52705$export$44f738469d5570cf(_ref) {
11095
11153
  // Wait until the ResizeObserver has delivered a value in case that the modal is small or has much padding so we know that we can't animate our fake field to be wider than that
11096
11154
  addedToBody.animate([{
11097
11155
  left: left + "px",
11098
- transform: "translateX(0%)",
11099
11156
  width: width + "px"
11100
11157
  }, {
11101
- left: "50%",
11102
- transform: "translateX(-50%)",
11103
- width: $3hooq$solidjs.untrack(inModalFieldWidth)
11158
+ left: "".concat($3hooq$solidjs.untrack(innerWidthReactive) / 2 - $3hooq$solidjs.untrack(inModalFieldWidth) / 2, "px"),
11159
+ width: $3hooq$solidjs.untrack(inModalFieldWidthPx)
11104
11160
  }], {
11105
11161
  duration: openDuration,
11106
11162
  easing: "ease-in"
11107
11163
  }).finished.then(() => {
11108
11164
  setPollAlignment_(false);
11109
- $3hooq$solidjs.runWithOwner(owner, () => $3hooq$solidjs.createEffect(() =>
11110
- // When animation has finished, still dynamically set the size of the search field behind in case the user resizes the window
11111
- Object.assign(addedToBody.style, {
11112
- left: "50%",
11113
- transform: "translateX(-50%)",
11114
- width: inModalFieldWidth()
11115
- })));
11165
+ $3hooq$solidjs.runWithOwner(owner, () => $3hooq$solidjs.createEffect(() => {
11166
+ // When animation has finished, still dynamically set the size of the search field behind in case the user resizes the window
11167
+ Object.assign(addedToBody.style, {
11168
+ // This is left: 50%, transform: translateX(-50) with extra steps but when using it safari and firefox glitch out like crazy
11169
+ left: "".concat(innerWidthReactive() / 2 - inModalFieldWidth() / 2, "px"),
11170
+ width: inModalFieldWidthPx()
11171
+ });
11172
+ // We might only have changed the left position which align_field doesn't know about, make it poll the position for a while
11173
+ setPollAlignment_(true);
11174
+ if (disableResizePollingTimeout) clearTimeout(disableResizePollingTimeout);
11175
+ disableResizePollingTimeout = setTimeout($3hooq$depictaiutilishared.catchify(() => {
11176
+ setPollAlignment_(false);
11177
+ disableResizePollingTimeout = undefined;
11178
+ }), 1000);
11179
+ }));
11116
11180
  });
11117
11181
  return true;
11118
11182
  }, false);
@@ -11155,13 +11219,11 @@ function $a60bc7692ce52705$export$44f738469d5570cf(_ref) {
11155
11219
  transition: "opacity ".concat(closeDuration, "ms ease-out")
11156
11220
  }));
11157
11221
  await Promise.all([addedToBody.animate([{
11158
- width: $3hooq$solidjs.untrack(inModalFieldWidth),
11159
- left: "50%",
11160
- transform: "translateX(-50%)"
11222
+ width: $3hooq$solidjs.untrack(inModalFieldWidthPx),
11223
+ left: "".concat($3hooq$solidjs.untrack(innerWidthReactive) / 2 - $3hooq$solidjs.untrack(inModalFieldWidth) / 2, "px")
11161
11224
  }, {
11162
11225
  width: width + "px",
11163
- left: left + "px",
11164
- transform: "translateX(0%)"
11226
+ left: left + "px"
11165
11227
  }], {
11166
11228
  duration: closeDuration,
11167
11229
  fill: "forwards",
@@ -10,7 +10,7 @@ import { ProductListingRequestV3 } from "@depict-ai/types/api/ProductListingRequ
10
10
  import { GetListingRequest } from "@depict-ai/types/api/GetListingRequest";
11
11
  import { BaseSearchRequestV3 } from "@depict-ai/types/api/BaseSearchRequestV3";
12
12
  import { SearchFilter as _SearchFilter2 } from "@depict-ai/types/api/SearchRequestV2";
13
- export const version = "4.0.0";
13
+ export const version = "4.0.2";
14
14
  export type ModalAlignmentSignals = {
15
15
  body_: Signal<JSX.CSSProperties>;
16
16
  field_: Signal<JSX.CSSProperties>;
@@ -407,6 +407,28 @@ export function ShopifyResponsiveImg(props: {
407
407
  } & Omit<JSX.ImgHTMLAttributes<HTMLImageElement>, "srcset" | "src" | "sizes"> & {
408
408
  src: string;
409
409
  }): JSX.Element;
410
+ type ImagePlaceholderBaseOptions = {
411
+ style?: JSX.CSSProperties;
412
+ class?: string;
413
+ };
414
+ type ImagePlaceholderBlockOptions = {
415
+ width: string;
416
+ height: string;
417
+ };
418
+ type ImagePlaceholderImageOptions = {
419
+ aspectRatio: number | string;
420
+ };
421
+ /**
422
+ * A placeholder that can be used instead of an image or other block of content while it's loading.
423
+ * The placeholder has `display:block`, meaning it will create a new "row" in the layout for itself. Can be used either for images with a defined aspect ratio (ContainedImage) or blocks.
424
+ * @property aspectRatio if aspectRatio is defined the placeholder will be in "image mode" and fill out the available width and then adjust the height according to the aspectRatio
425
+ * @property width If width and height is set, the defined width and height will be used.
426
+ * @property height If width and height is set, the defined width and height will be used.
427
+ * @property class extra classes to add to the placeholder
428
+ * @property style extra styles to add to the placeholder
429
+ */
430
+ export function ImagePlaceholder(props: ImagePlaceholderBaseOptions & (ImagePlaceholderBlockOptions | ImagePlaceholderImageOptions)): JSX.Element;
431
+ export function DefaultInstantCardPlaceholder(): HTMLDivElement;
410
432
  export const shopifyContainedImageContextSymbol: unique symbol;
411
433
  /**
412
434
  * Abstraction built on top of ShopifyResponsiveImg. This is your one-stop-shop If you just need a responsive image.
@@ -417,11 +439,13 @@ export const shopifyContainedImageContextSymbol: unique symbol;
417
439
  * @property aspectRatio aspect ratio of the image
418
440
  * @property class extra class to add to the container
419
441
  * @property alt alt text for the image
442
+ * @property autoAdjustAspectRatio whether to automatically adjust the aspect ratio of the image to the majority of the aspect ratios of loaded images in the current listing provider. Defaults to false. Can be overriden with css variable --image-aspect-ratio
420
443
  * @property imgProps props to pass to ShopifyResponsiveImg to add to the <img> element
421
444
  */
422
445
  export function ShopifyContainedImage(props: {
423
446
  src: string;
424
447
  aspectRatio: number | string;
448
+ autoAdjustAspectRatio?: boolean;
425
449
  class?: string;
426
450
  imgProps?: Omit<Parameters<typeof ShopifyResponsiveImg>[0], "size" | "src">;
427
451
  }): HTMLDivElement;
@@ -489,28 +513,6 @@ interface Styles {
489
513
  [selector: string]: JSX.CSSProperties;
490
514
  }
491
515
  export const styles_to_valid_css_string: (styles: Styles) => string;
492
- type ImagePlaceholderBaseOptions = {
493
- style?: JSX.CSSProperties;
494
- class?: string;
495
- };
496
- type ImagePlaceholderBlockOptions = {
497
- width: string;
498
- height: string;
499
- };
500
- type ImagePlaceholderImageOptions = {
501
- aspectRatio: number | string;
502
- };
503
- /**
504
- * A placeholder that can be used instead of an image or other block of content while it's loading.
505
- * The placeholder has `display:block`, meaning it will create a new "row" in the layout for itself. Can be used either for images with a defined aspect ratio (ContainedImage) or blocks.
506
- * @property aspectRatio if aspectRatio is defined the placeholder will be in "image mode" and fill out the available width and then adjust the height according to the aspectRatio
507
- * @property width If width and height is set, the defined width and height will be used.
508
- * @property height If width and height is set, the defined width and height will be used.
509
- * @property class extra classes to add to the placeholder
510
- * @property style extra styles to add to the placeholder
511
- */
512
- export function ImagePlaceholder(props: ImagePlaceholderBaseOptions & (ImagePlaceholderBlockOptions | ImagePlaceholderImageOptions)): JSX.Element;
513
- export function DefaultInstantCardPlaceholder(): HTMLDivElement;
514
516
  /**
515
517
  * Second generation search modal - the solid component that gets added to <body> when the search modal is opened
516
518
  */
@@ -642,7 +644,7 @@ export type BaseSearchProviderConfig<InputDisplay extends Display, PossibleTrans
642
644
  */
643
645
  enableContentSearch?: boolean;
644
646
  /**
645
- * The search modal component to use. You can switch between the classic and the new search modal. Provide one of the components here that you can import from the same package as the one you're using to see this message.
647
+ * The search modal component to use. You can switch between the classic and the new search modal. Provide one of the components here that you can import from the same package as the one you're using to see this message (`SearchModalV2` or `ClassicSearchModal`).
646
648
  * You also need to reflect the choice in SCSS, example:
647
649
  * ```scss
648
650
  * @use "@depict-ai/js-ui" as plp-styling with (
@@ -1,7 +1,7 @@
1
- import { add_to_version_info as $b8hua$add_to_version_info, deparallelize_no_drop as $b8hua$deparallelize_no_drop, catchify as $b8hua$catchify, make_random_classname as $b8hua$make_random_classname, ContainedImage as $b8hua$ContainedImage, standard_price_format as $b8hua$standard_price_format, javascript_media_query as $b8hua$javascript_media_query, dlog as $b8hua$dlog, camelCasifyObject as $b8hua$camelCasifyObject, make_asyncIterable_exiter as $b8hua$make_asyncIterable_exiter, href_change_ipns as $b8hua$href_change_ipns, observer as $b8hua$observer, report as $b8hua$report, base64_encode_unicode as $b8hua$base64_encode_unicode, base64_decode_unicode as $b8hua$base64_decode_unicode, queueMacroTask as $b8hua$queueMacroTask, dwarn as $b8hua$dwarn, slider_fading_factory as $b8hua$slider_fading_factory, Amazing_Slider as $b8hua$Amazing_Slider, slider_snap_css as $b8hua$slider_snap_css, n_col_styling_with_dist as $b8hua$n_col_styling_with_dist, layout_get_visible_recs_without_partial_rows as $b8hua$layout_get_visible_recs_without_partial_rows, layout_get_total_rec_amount_for_row as $b8hua$layout_get_total_rec_amount_for_row, layout_media_query_header as $b8hua$layout_media_query_header, use_href_accessor as $b8hua$use_href_accessor, get_session_id as $b8hua$get_session_id, add_version_query_params as $b8hua$add_version_query_params, base_url as $b8hua$base_url, instant_exec_on_suspect_history_change as $b8hua$instant_exec_on_suspect_history_change, slider_fractional_factory as $b8hua$slider_fractional_factory, useExpandingContainer as $b8hua$useExpandingContainer, hex_to_rgb as $b8hua$hex_to_rgb, relative_luminance_from_rgb as $b8hua$relative_luminance_from_rgb, snakeCasifyObject as $b8hua$snakeCasifyObject, fetch_retry as $b8hua$fetch_retry, make_url_with_query_params as $b8hua$make_url_with_query_params, sort_obj as $b8hua$sort_obj, ListenableSet as $b8hua$ListenableSet1, insert_surfaces as $b8hua$insert_surfaces } from "@depict-ai/utilishared/ES10";
1
+ import { add_to_version_info as $b8hua$add_to_version_info, deparallelize_no_drop as $b8hua$deparallelize_no_drop, catchify as $b8hua$catchify, make_random_classname as $b8hua$make_random_classname, ContainedImage as $b8hua$ContainedImage, standard_price_format as $b8hua$standard_price_format, javascript_media_query as $b8hua$javascript_media_query, dlog as $b8hua$dlog, camelCasifyObject as $b8hua$camelCasifyObject, make_asyncIterable_exiter as $b8hua$make_asyncIterable_exiter, href_change_ipns as $b8hua$href_change_ipns, observer as $b8hua$observer, report as $b8hua$report, base64_encode_unicode as $b8hua$base64_encode_unicode, base64_decode_unicode as $b8hua$base64_decode_unicode, ListenableSet as $b8hua$ListenableSet, findMostFrequentItem as $b8hua$findMostFrequentItem, queueMacroTask as $b8hua$queueMacroTask, dwarn as $b8hua$dwarn, slider_fading_factory as $b8hua$slider_fading_factory, Amazing_Slider as $b8hua$Amazing_Slider, slider_snap_css as $b8hua$slider_snap_css, n_col_styling_with_dist as $b8hua$n_col_styling_with_dist, layout_get_visible_recs_without_partial_rows as $b8hua$layout_get_visible_recs_without_partial_rows, layout_get_total_rec_amount_for_row as $b8hua$layout_get_total_rec_amount_for_row, layout_media_query_header as $b8hua$layout_media_query_header, use_href_accessor as $b8hua$use_href_accessor, get_session_id as $b8hua$get_session_id, add_version_query_params as $b8hua$add_version_query_params, base_url as $b8hua$base_url, instant_exec_on_suspect_history_change as $b8hua$instant_exec_on_suspect_history_change, slider_fractional_factory as $b8hua$slider_fractional_factory, useExpandingContainer as $b8hua$useExpandingContainer, hex_to_rgb as $b8hua$hex_to_rgb, relative_luminance_from_rgb as $b8hua$relative_luminance_from_rgb, snakeCasifyObject as $b8hua$snakeCasifyObject, fetch_retry as $b8hua$fetch_retry, make_url_with_query_params as $b8hua$make_url_with_query_params, sort_obj as $b8hua$sort_obj, insert_surfaces as $b8hua$insert_surfaces } from "@depict-ai/utilishared/ES10";
2
2
  import { createSignal as $b8hua$createSignal, createResource as $b8hua$createResource, createEffect as $b8hua$createEffect, untrack as $b8hua$untrack, createMemo as $b8hua$createMemo, onCleanup as $b8hua$onCleanup, Show as $b8hua$Show, createComputed as $b8hua$createComputed, For as $b8hua$For, getOwner as $b8hua$getOwner, runWithOwner as $b8hua$runWithOwner, on as $b8hua$on, Index as $b8hua$Index, batch as $b8hua$batch, ErrorBoundary as $b8hua$ErrorBoundary, createContext as $b8hua$createContext, useContext as $b8hua$useContext, mergeProps as $b8hua$mergeProps1, createUniqueId as $b8hua$createUniqueId, createRenderEffect as $b8hua$createRenderEffect, createSelector as $b8hua$createSelector, children as $b8hua$children, splitProps as $b8hua$splitProps, createRoot as $b8hua$createRoot, Suspense as $b8hua$Suspense, createReaction as $b8hua$createReaction, mapArray as $b8hua$mapArray } from "solid-js";
3
3
  import { ssr as $b8hua$ssr, ssrHydrationKey as $b8hua$ssrHydrationKey, escape as $b8hua$escape, createComponent as $b8hua$createComponent, ssrAttribute as $b8hua$ssrAttribute, ssrClassList as $b8hua$ssrClassList, ssrStyle as $b8hua$ssrStyle, ssrElement as $b8hua$ssrElement, mergeProps as $b8hua$mergeProps, insert as $b8hua$insert, spread as $b8hua$spread, isServer as $b8hua$isServer, Dynamic as $b8hua$Dynamic } from "solid-js/web";
4
- import { ListenableSet as $b8hua$ListenableSet, catchify as $b8hua$catchify1, use_href_accessor as $b8hua$use_href_accessor1, report as $b8hua$report1 } from "@depict-ai/utilishared/ES10";
4
+ import { ListenableSet as $b8hua$ListenableSet1, catchify as $b8hua$catchify1, use_href_accessor as $b8hua$use_href_accessor1, report as $b8hua$report1 } from "@depict-ai/utilishared/ES10";
5
5
  import $b8hua$babelruntimehelpersdefineProperty from "@babel/runtime/helpers/defineProperty";
6
6
  import $b8hua$babelruntimehelpersclassPrivateFieldSet from "@babel/runtime/helpers/classPrivateFieldSet";
7
7
  import $b8hua$babelruntimehelpersclassPrivateFieldGet from "@babel/runtime/helpers/classPrivateFieldGet";
@@ -10,7 +10,7 @@ import { createStore as $b8hua$createStore, reconcile as $b8hua$reconcile } from
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.0.0";
13
+ const $8db9a15135765c11$export$83d89fbfd8236492 = "4.0.2";
14
14
  function $a604a8ffa4e4c03f$export$e417c49320921907(dependency, fetcher) {
15
15
  const [promiseOfCurrentFetcherRun, setPromiseOfCurrentFetcherRun] = $b8hua$createSignal();
16
16
  const deparallelizedFetcher = $b8hua$deparallelize_no_drop(async dependencyValue => {
@@ -1878,6 +1878,7 @@ function $56047603f9d212b6$export$e6fffe67d4cdd848(whatToWatch) {
1878
1878
  return size;
1879
1879
  }
1880
1880
  const $56047603f9d212b6$var$onIdleFunctionsSymbol = /*@__PURE__*/Symbol("onIdleFunctions");
1881
+ const $56047603f9d212b6$export$f8945274f08a3105 = /*@__PURE__*/Symbol("listingContextAspectRatios");
1881
1882
  function $56047603f9d212b6$export$6e5611bc7e57e477(props) {
1882
1883
  // Enable reactive props
1883
1884
  const otherOptions = $b8hua$createMemo(() => {
@@ -1942,6 +1943,21 @@ function $56047603f9d212b6$export$6e5611bc7e57e477(props) {
1942
1943
  let timeoutSet = false;
1943
1944
  let gotCleanedUp = false;
1944
1945
  img.classList.add("s-responsive-image");
1946
+ if (listingContext) {
1947
+ let prevValue;
1948
+ const aspectRatios = listingContext[$56047603f9d212b6$export$f8945274f08a3105] || (listingContext[$56047603f9d212b6$export$f8945274f08a3105] = new (0, $b8hua$ListenableSet)());
1949
+ img.addEventListener("load", $b8hua$catchify(() => {
1950
+ // Save our aspect ratio whenever it changes, so that we can base the containers on the most dominant aspect ratio, used in SearchModalV2
1951
+ const aspectRatio_ = img.naturalWidth / img.naturalHeight;
1952
+ if (prevValue) aspectRatios.delete(prevValue);
1953
+ const newValue = !isNaN(aspectRatio_) ? {
1954
+ aspectRatio_: aspectRatio_
1955
+ } : undefined;
1956
+ if (newValue) aspectRatios.add(newValue);
1957
+ prevValue = newValue;
1958
+ }));
1959
+ $b8hua$onCleanup(() => prevValue && aspectRatios.delete(prevValue));
1960
+ }
1945
1961
  $b8hua$onCleanup(() => gotCleanedUp = true);
1946
1962
  $b8hua$spread(img, $b8hua$mergeProps1(otherOptions), false, true);
1947
1963
  $b8hua$createEffect(() => {
@@ -2009,9 +2025,29 @@ function $4df489344a0f97c7$export$e4b984597b71e989(props) {
2009
2025
  // create a signal that's the same for all items in this listing
2010
2026
  context[$4df489344a0f97c7$export$d7b7ab832c20e2f4] = $b8hua$createSignal();
2011
2027
  const [currentImageSize, setCurrentImageSize] = (context === null || context === void 0 ? void 0 : context[$4df489344a0f97c7$export$d7b7ab832c20e2f4]) || $4df489344a0f97c7$var$backupSizeSignal; // use global fallback signal (might lead to blurry images) if no context is available
2028
+ const aspectRatiosSet = context ? context[(0, $56047603f9d212b6$export$f8945274f08a3105)] || (context[(0, $56047603f9d212b6$export$f8945274f08a3105)] = new (0, $b8hua$ListenableSet)()) : undefined;
2029
+ const [aspectRatios, setAspectRatios] = $b8hua$createSignal(aspectRatiosSet, {
2030
+ equals: false
2031
+ });
2032
+ const aspectRatioToUse = $b8hua$createMemo(() => {
2033
+ const aspectRatiosSet = aspectRatios(); // This signal "changes" to the same set every time the set changes, so we can use it as a dependency here
2034
+ useMostPrevalentAspectRatio: {
2035
+ if (!aspectRatiosSet || !props.autoAdjustAspectRatio) break useMostPrevalentAspectRatio;
2036
+ // Get the aspect ratio that most of the loaded images inside the ListingProvider we are, load
2037
+ const asArray = [...aspectRatiosSet].map(_ref => {
2038
+ let {
2039
+ aspectRatio_: aspectRatio_
2040
+ } = _ref;
2041
+ return aspectRatio_;
2042
+ });
2043
+ const mostPrevalentAspectRatio = $b8hua$findMostFrequentItem(asArray);
2044
+ if (mostPrevalentAspectRatio) return "var(".concat((0, $5eaa00b951637e96$export$8a2234b5b1a5ebd4), ", ").concat(mostPrevalentAspectRatio, ")");
2045
+ }
2046
+ return props.aspectRatio;
2047
+ });
2012
2048
  const container = $b8hua$createComponent((0, $801e8845d3fa3653$export$94026ee33dbabc26), {
2013
2049
  get aspectRatio() {
2014
- return props.aspectRatio;
2050
+ return aspectRatioToUse();
2015
2051
  },
2016
2052
  get ["class"]() {
2017
2053
  return props.class;
@@ -2020,6 +2056,10 @@ function $4df489344a0f97c7$export$e4b984597b71e989(props) {
2020
2056
  const owner = $b8hua$getOwner();
2021
2057
  let createdSizeAccessor = false;
2022
2058
  let wasCleanedUp = false;
2059
+ for (const event of ["add", "delete"]) {
2060
+ aspectRatiosSet === null || aspectRatiosSet === void 0 || aspectRatiosSet.addEventListener(event, () => setAspectRatios(aspectRatiosSet));
2061
+ $b8hua$onCleanup(() => aspectRatiosSet === null || aspectRatiosSet === void 0 ? void 0 : aspectRatiosSet.removeEventListener(event, () => setAspectRatios(aspectRatiosSet)));
2062
+ }
2023
2063
  $b8hua$createEffect(() => {
2024
2064
  if (currentImageSize() || wasCleanedUp) return; // We get into the effect when onCleanup is called if we don't have wasCleanedUp
2025
2065
  // ensure we always have a size accessor
@@ -2895,7 +2935,8 @@ function $06fcd2a345efd24d$var$RawSearchModalV2(_ref) {
2895
2935
  get src() {
2896
2936
  return props.src_;
2897
2937
  },
2898
- aspectRatio: "var(".concat((0, $5eaa00b951637e96$export$8a2234b5b1a5ebd4), ", 1)")
2938
+ autoAdjustAspectRatio: true,
2939
+ aspectRatio: 1
2899
2940
  }),
2900
2941
  ...instant_results_options_
2901
2942
  })));
@@ -2973,7 +3014,7 @@ const $6a439680ae7e9ba3$var$TabsContext = /*@__PURE__*/$b8hua$createContext();
2973
3014
  const $6a439680ae7e9ba3$var$useTabs = () => $b8hua$useContext($6a439680ae7e9ba3$var$TabsContext);
2974
3015
  function $6a439680ae7e9ba3$export$b2539bed5023c21c(props) {
2975
3016
  return $b8hua$createComponent($6a439680ae7e9ba3$var$TabsContext.Provider, {
2976
- value: new (0, $b8hua$ListenableSet)(),
3017
+ value: new (0, $b8hua$ListenableSet1)(),
2977
3018
  get children() {
2978
3019
  return $b8hua$createComponent($6a439680ae7e9ba3$var$ActualTabs, $b8hua$mergeProps(props, {
2979
3020
  get children() {
@@ -3116,7 +3157,17 @@ async function $d5f1e6a0f9117286$export$79b1565500412d9b(search_modal, modal_fn_
3116
3157
  const actually_close = () => {
3117
3158
  dispose();
3118
3159
  on_dispose === null || on_dispose === void 0 || on_dispose();
3119
- modal_els.forEach(el => el.remove());
3160
+ const {
3161
+ activeElement: activeElement
3162
+ } = document;
3163
+ modal_els.forEach(el => {
3164
+ if (el.contains(activeElement)) {
3165
+ var _blur, _ref;
3166
+ // Fix page jumping to the bottom when closing modal with scape after animation in safari
3167
+ activeElement === null || activeElement === void 0 || (_blur = (_ref = activeElement).blur) === null || _blur === void 0 || _blur.call(_ref);
3168
+ }
3169
+ el.remove();
3170
+ });
3120
3171
  };
3121
3172
  if (animation_started && +new Date() - animation_started > 1000)
3122
3173
  // Animation broke, close it this time
@@ -10890,7 +10941,7 @@ function $d53ebed6f63304e4$export$6d0c9c22f6652669(_ref) {
10890
10941
  number_: num_results,
10891
10942
  i18n_: i18n_
10892
10943
  });
10893
- const queries_without_content_results_ = new (0, $b8hua$ListenableSet1)();
10944
+ const queries_without_content_results_ = new (0, $b8hua$ListenableSet)();
10894
10945
  const [check_query, set_check_query] = $b8hua$createSignal(false);
10895
10946
  const placeholders_enabled = $b8hua$createMemo(() => {
10896
10947
  // don't show placeholders when the user toggles filters
@@ -10971,30 +11022,37 @@ function $937791b86d3d1509$export$44f738469d5570cf(_ref) {
10971
11022
  modalSearchFieldOuterWidth_: modalSearchFieldOuterWidth_
10972
11023
  } = _ref;
10973
11024
  return $b8hua$createRoot(dispose => {
11025
+ const [innerWidthReactive, setInnerWidthReactive] = $b8hua$createSignal(innerWidth);
11026
+ const resizeObserver = new ResizeObserver(records => setInnerWidthReactive(records.at(-1).contentRect.width));
11027
+ const {
11028
+ left: left,
11029
+ top: top,
11030
+ width: width
11031
+ } = actualField_.getBoundingClientRect();
10974
11032
  const fakeField = makeFakeField_();
10975
11033
  const owner = $b8hua$getOwner();
10976
11034
  const inModalFieldWidth = $b8hua$createMemo(
10977
11035
  // Can't have `min(${modalSearchFieldOuterWidth_()}px, var(--field-max-width, 600px))` because the WAAPI doesn't support that, so we need ot calculate it in JS
10978
- () => Math.min(modalSearchFieldOuterWidth_(), parseFloat(getComputedStyle(actualField_).getPropertyValue("--field-max-width") || "600")) + "px");
11036
+ () => Math.min(modalSearchFieldOuterWidth_(), parseFloat(getComputedStyle(actualField_).getPropertyValue("--field-max-width") || "600")));
11037
+ const inModalFieldWidthPx = $b8hua$createMemo(() => inModalFieldWidth() + "px");
11038
+ let disableResizePollingTimeout;
11039
+ resizeObserver.observe(document.documentElement);
11040
+ $b8hua$onCleanup(() => resizeObserver.disconnect());
10979
11041
  actualField_.replaceWith(fakeField);
10980
11042
  // Don't move the wrapped div since that would confuse run_in_root_or_auto_cleanup, but do actually move the field the user clicked around so that all selection stuff etc. is easier
10981
11043
  const addedToBody = wrap_ ? $b8hua$ssr($937791b86d3d1509$var$_tmpl$, $b8hua$ssrHydrationKey(), $b8hua$escape(actualField_)) : actualField_;
10982
11044
  document.body.append(addedToBody);
10983
- const {
10984
- left: left,
10985
- top: top,
10986
- width: width
10987
- } = fakeField.getBoundingClientRect();
10988
11045
  const zIndexOfFake = getComputedStyle(fakeField).zIndex;
10989
11046
  Object.assign(addedToBody.style, {
10990
11047
  position: "fixed",
10991
11048
  top: top + "px",
11049
+ left: left + "px",
10992
11050
  width: width + "px",
10993
11051
  ...(zIndexOfFake !== "auto" ? {
10994
11052
  zIndex: +zIndexOfFake + 1
10995
11053
  } : {})
10996
11054
  });
10997
- const pxOffCenter = innerWidth / 2 - (left + width / 2);
11055
+ const pxOffCenter = $b8hua$untrack(innerWidthReactive) / 2 - (left + width / 2);
10998
11056
  const openDuration = pxOffCenter > 100 ? 250 : 125; // faster animations if little left-right movement
10999
11057
  const closeDuration = pxOffCenter > 100 ? 150 : 100;
11000
11058
  setPollAlignment_(true);
@@ -11013,24 +11071,30 @@ function $937791b86d3d1509$export$44f738469d5570cf(_ref) {
11013
11071
  // Wait until the ResizeObserver has delivered a value in case that the modal is small or has much padding so we know that we can't animate our fake field to be wider than that
11014
11072
  addedToBody.animate([{
11015
11073
  left: left + "px",
11016
- transform: "translateX(0%)",
11017
11074
  width: width + "px"
11018
11075
  }, {
11019
- left: "50%",
11020
- transform: "translateX(-50%)",
11021
- width: $b8hua$untrack(inModalFieldWidth)
11076
+ left: "".concat($b8hua$untrack(innerWidthReactive) / 2 - $b8hua$untrack(inModalFieldWidth) / 2, "px"),
11077
+ width: $b8hua$untrack(inModalFieldWidthPx)
11022
11078
  }], {
11023
11079
  duration: openDuration,
11024
11080
  easing: "ease-in"
11025
11081
  }).finished.then(() => {
11026
11082
  setPollAlignment_(false);
11027
- $b8hua$runWithOwner(owner, () => $b8hua$createEffect(() =>
11028
- // When animation has finished, still dynamically set the size of the search field behind in case the user resizes the window
11029
- Object.assign(addedToBody.style, {
11030
- left: "50%",
11031
- transform: "translateX(-50%)",
11032
- width: inModalFieldWidth()
11033
- })));
11083
+ $b8hua$runWithOwner(owner, () => $b8hua$createEffect(() => {
11084
+ // When animation has finished, still dynamically set the size of the search field behind in case the user resizes the window
11085
+ Object.assign(addedToBody.style, {
11086
+ // This is left: 50%, transform: translateX(-50) with extra steps but when using it safari and firefox glitch out like crazy
11087
+ left: "".concat(innerWidthReactive() / 2 - inModalFieldWidth() / 2, "px"),
11088
+ width: inModalFieldWidthPx()
11089
+ });
11090
+ // We might only have changed the left position which align_field doesn't know about, make it poll the position for a while
11091
+ setPollAlignment_(true);
11092
+ if (disableResizePollingTimeout) clearTimeout(disableResizePollingTimeout);
11093
+ disableResizePollingTimeout = setTimeout($b8hua$catchify(() => {
11094
+ setPollAlignment_(false);
11095
+ disableResizePollingTimeout = undefined;
11096
+ }), 1000);
11097
+ }));
11034
11098
  });
11035
11099
  return true;
11036
11100
  }, false);
@@ -11073,13 +11137,11 @@ function $937791b86d3d1509$export$44f738469d5570cf(_ref) {
11073
11137
  transition: "opacity ".concat(closeDuration, "ms ease-out")
11074
11138
  }));
11075
11139
  await Promise.all([addedToBody.animate([{
11076
- width: $b8hua$untrack(inModalFieldWidth),
11077
- left: "50%",
11078
- transform: "translateX(-50%)"
11140
+ width: $b8hua$untrack(inModalFieldWidthPx),
11141
+ left: "".concat($b8hua$untrack(innerWidthReactive) / 2 - $b8hua$untrack(inModalFieldWidth) / 2, "px")
11079
11142
  }, {
11080
11143
  width: width + "px",
11081
- left: left + "px",
11082
- transform: "translateX(0%)"
11144
+ left: left + "px"
11083
11145
  }], {
11084
11146
  duration: closeDuration,
11085
11147
  fill: "forwards",