@depict-ai/ui 4.0.1 → 4.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ES10/index.cjs CHANGED
@@ -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.1";
95
+ const $aa1938dec50d6c12$export$83d89fbfd8236492 = "4.0.3";
96
96
  function $a28000bc10de28ad$export$e417c49320921907(dependency, fetcher) {
97
97
  const [promiseOfCurrentFetcherRun, setPromiseOfCurrentFetcherRun] = $52FdA$solidjs.createSignal();
98
98
  const deparallelizedFetcher = $52FdA$depictaiutilishared.deparallelize_no_drop(async dependencyValue => {
@@ -2533,6 +2533,7 @@ function $858fdcf73148519f$export$e6fffe67d4cdd848(whatToWatch) {
2533
2533
  return size;
2534
2534
  }
2535
2535
  const $858fdcf73148519f$var$onIdleFunctionsSymbol = /*@__PURE__*/Symbol("onIdleFunctions");
2536
+ const $858fdcf73148519f$export$f8945274f08a3105 = /*@__PURE__*/Symbol("listingContextAspectRatios");
2536
2537
  function $858fdcf73148519f$export$6e5611bc7e57e477(props) {
2537
2538
  // Enable reactive props
2538
2539
  const otherOptions = $52FdA$solidjs.createMemo(() => {
@@ -2597,6 +2598,21 @@ function $858fdcf73148519f$export$6e5611bc7e57e477(props) {
2597
2598
  let timeoutSet = false;
2598
2599
  let gotCleanedUp = false;
2599
2600
  img.classList.add("s-responsive-image");
2601
+ if (listingContext) {
2602
+ let prevValue;
2603
+ const aspectRatios = listingContext[$858fdcf73148519f$export$f8945274f08a3105] || (listingContext[$858fdcf73148519f$export$f8945274f08a3105] = new (0, $52FdA$depictaiutilishared.ListenableSet)());
2604
+ img.addEventListener("load", $52FdA$depictaiutilishared.catchify(() => {
2605
+ // Save our aspect ratio whenever it changes, so that we can base the containers on the most dominant aspect ratio, used in SearchModalV2
2606
+ const aspectRatio_ = img.naturalWidth / img.naturalHeight;
2607
+ if (prevValue) aspectRatios.delete(prevValue);
2608
+ const newValue = !isNaN(aspectRatio_) ? {
2609
+ aspectRatio_: aspectRatio_
2610
+ } : undefined;
2611
+ if (newValue) aspectRatios.add(newValue);
2612
+ prevValue = newValue;
2613
+ }));
2614
+ $52FdA$solidjs.onCleanup(() => prevValue && aspectRatios.delete(prevValue));
2615
+ }
2600
2616
  $52FdA$solidjs.onCleanup(() => gotCleanedUp = true);
2601
2617
  $52FdA$solidjsweb.spread(img, $52FdA$solidjs.mergeProps(otherOptions), false, true);
2602
2618
  $52FdA$solidjs.createEffect(() => {
@@ -2664,9 +2680,29 @@ function $28535bb7671c63d1$export$e4b984597b71e989(props) {
2664
2680
  // create a signal that's the same for all items in this listing
2665
2681
  context[$28535bb7671c63d1$export$d7b7ab832c20e2f4] = $52FdA$solidjs.createSignal();
2666
2682
  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
2683
+ const aspectRatiosSet = context ? context[(0, $858fdcf73148519f$export$f8945274f08a3105)] || (context[(0, $858fdcf73148519f$export$f8945274f08a3105)] = new (0, $52FdA$depictaiutilishared.ListenableSet)()) : undefined;
2684
+ const [aspectRatios, setAspectRatios] = $52FdA$solidjs.createSignal(aspectRatiosSet, {
2685
+ equals: false
2686
+ });
2687
+ const aspectRatioToUse = $52FdA$solidjs.createMemo(() => {
2688
+ const aspectRatiosSet = aspectRatios(); // This signal "changes" to the same set every time the set changes, so we can use it as a dependency here
2689
+ useMostPrevalentAspectRatio: {
2690
+ if (!aspectRatiosSet || !props.autoAdjustAspectRatio) break useMostPrevalentAspectRatio;
2691
+ // Get the aspect ratio that most of the loaded images inside the ListingProvider we are, load
2692
+ const asArray = [...aspectRatiosSet].map(_ref => {
2693
+ let {
2694
+ aspectRatio_: aspectRatio_
2695
+ } = _ref;
2696
+ return aspectRatio_;
2697
+ });
2698
+ const mostPrevalentAspectRatio = $52FdA$depictaiutilishared.findMostFrequentItem(asArray);
2699
+ if (mostPrevalentAspectRatio) return "var(".concat((0, $c0cf6af094336798$export$8a2234b5b1a5ebd4), ", ").concat(mostPrevalentAspectRatio, ")");
2700
+ }
2701
+ return props.aspectRatio;
2702
+ });
2667
2703
  const container = $52FdA$solidjsweb.createComponent((0, $ce467edb5343cfcd$export$94026ee33dbabc26), {
2668
2704
  get aspectRatio() {
2669
- return props.aspectRatio;
2705
+ return aspectRatioToUse();
2670
2706
  },
2671
2707
  get ["class"]() {
2672
2708
  return props.class;
@@ -2675,6 +2711,10 @@ function $28535bb7671c63d1$export$e4b984597b71e989(props) {
2675
2711
  const owner = $52FdA$solidjs.getOwner();
2676
2712
  let createdSizeAccessor = false;
2677
2713
  let wasCleanedUp = false;
2714
+ for (const event of ["add", "delete"]) {
2715
+ aspectRatiosSet === null || aspectRatiosSet === void 0 || aspectRatiosSet.addEventListener(event, () => setAspectRatios(aspectRatiosSet));
2716
+ $52FdA$solidjs.onCleanup(() => aspectRatiosSet === null || aspectRatiosSet === void 0 ? void 0 : aspectRatiosSet.removeEventListener(event, () => setAspectRatios(aspectRatiosSet)));
2717
+ }
2678
2718
  $52FdA$solidjs.createEffect(() => {
2679
2719
  if (currentImageSize() || wasCleanedUp) return; // We get into the effect when onCleanup is called if we don't have wasCleanedUp
2680
2720
  // ensure we always have a size accessor
@@ -3742,7 +3782,8 @@ function $43600b30502feeda$var$RawSearchModalV2(_ref) {
3742
3782
  get src() {
3743
3783
  return props.src_;
3744
3784
  },
3745
- aspectRatio: "var(".concat((0, $c0cf6af094336798$export$8a2234b5b1a5ebd4), ", 1)")
3785
+ autoAdjustAspectRatio: true,
3786
+ aspectRatio: 1
3746
3787
  }),
3747
3788
  ...instant_results_options_
3748
3789
  }), _el$4, _co$);
@@ -4094,7 +4135,17 @@ async function $4cf7d9829d60d844$export$79b1565500412d9b(search_modal, modal_fn_
4094
4135
  const actually_close = () => {
4095
4136
  dispose();
4096
4137
  on_dispose === null || on_dispose === void 0 || on_dispose();
4097
- modal_els.forEach(el => el.remove());
4138
+ const {
4139
+ activeElement: activeElement
4140
+ } = document;
4141
+ modal_els.forEach(el => {
4142
+ if (el.contains(activeElement)) {
4143
+ var _blur, _ref;
4144
+ // Fix page jumping to the bottom when closing modal with scape after animation in safari
4145
+ activeElement === null || activeElement === void 0 || (_blur = (_ref = activeElement).blur) === null || _blur === void 0 || _blur.call(_ref);
4146
+ }
4147
+ el.remove();
4148
+ });
4098
4149
  };
4099
4150
  if (animation_started && +new Date() - animation_started > 1000)
4100
4151
  // Animation broke, close it this time
package/ES10/index.d.ts CHANGED
@@ -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.1";
13
+ export const version = "4.0.3";
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
  */
package/ES10/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { add_to_version_info as $8tj43$add_to_version_info, deparallelize_no_drop as $8tj43$deparallelize_no_drop, catchify as $8tj43$catchify, make_random_classname as $8tj43$make_random_classname, ContainedImage as $8tj43$ContainedImage, standard_price_format as $8tj43$standard_price_format, javascript_media_query as $8tj43$javascript_media_query, dlog as $8tj43$dlog, camelCasifyObject as $8tj43$camelCasifyObject, buildThresholdList as $8tj43$buildThresholdList, make_asyncIterable_exiter as $8tj43$make_asyncIterable_exiter, href_change_ipns as $8tj43$href_change_ipns, observer as $8tj43$observer, report as $8tj43$report, base64_encode_unicode as $8tj43$base64_encode_unicode, base64_decode_unicode as $8tj43$base64_decode_unicode, queueMacroTask as $8tj43$queueMacroTask, dwarn as $8tj43$dwarn, slider_fading_factory as $8tj43$slider_fading_factory, Amazing_Slider as $8tj43$Amazing_Slider, slider_snap_css as $8tj43$slider_snap_css, n_col_styling_with_dist as $8tj43$n_col_styling_with_dist, layout_get_visible_recs_without_partial_rows as $8tj43$layout_get_visible_recs_without_partial_rows, layout_get_total_rec_amount_for_row as $8tj43$layout_get_total_rec_amount_for_row, layout_media_query_header as $8tj43$layout_media_query_header, use_href_accessor as $8tj43$use_href_accessor, get_session_id as $8tj43$get_session_id, add_version_query_params as $8tj43$add_version_query_params, base_url as $8tj43$base_url, instant_exec_on_suspect_history_change as $8tj43$instant_exec_on_suspect_history_change, slider_fractional_factory as $8tj43$slider_fractional_factory, useExpandingContainer as $8tj43$useExpandingContainer, hex_to_rgb as $8tj43$hex_to_rgb, relative_luminance_from_rgb as $8tj43$relative_luminance_from_rgb, snakeCasifyObject as $8tj43$snakeCasifyObject, fetch_retry as $8tj43$fetch_retry, make_url_with_query_params as $8tj43$make_url_with_query_params, sort_obj as $8tj43$sort_obj, is_debug as $8tj43$is_debug, ListenableSet as $8tj43$ListenableSet1, insert_surfaces as $8tj43$insert_surfaces } from "@depict-ai/utilishared/ES10";
1
+ import { add_to_version_info as $8tj43$add_to_version_info, deparallelize_no_drop as $8tj43$deparallelize_no_drop, catchify as $8tj43$catchify, make_random_classname as $8tj43$make_random_classname, ContainedImage as $8tj43$ContainedImage, standard_price_format as $8tj43$standard_price_format, javascript_media_query as $8tj43$javascript_media_query, dlog as $8tj43$dlog, camelCasifyObject as $8tj43$camelCasifyObject, buildThresholdList as $8tj43$buildThresholdList, make_asyncIterable_exiter as $8tj43$make_asyncIterable_exiter, href_change_ipns as $8tj43$href_change_ipns, observer as $8tj43$observer, report as $8tj43$report, base64_encode_unicode as $8tj43$base64_encode_unicode, base64_decode_unicode as $8tj43$base64_decode_unicode, ListenableSet as $8tj43$ListenableSet, findMostFrequentItem as $8tj43$findMostFrequentItem, queueMacroTask as $8tj43$queueMacroTask, dwarn as $8tj43$dwarn, slider_fading_factory as $8tj43$slider_fading_factory, Amazing_Slider as $8tj43$Amazing_Slider, slider_snap_css as $8tj43$slider_snap_css, n_col_styling_with_dist as $8tj43$n_col_styling_with_dist, layout_get_visible_recs_without_partial_rows as $8tj43$layout_get_visible_recs_without_partial_rows, layout_get_total_rec_amount_for_row as $8tj43$layout_get_total_rec_amount_for_row, layout_media_query_header as $8tj43$layout_media_query_header, use_href_accessor as $8tj43$use_href_accessor, get_session_id as $8tj43$get_session_id, add_version_query_params as $8tj43$add_version_query_params, base_url as $8tj43$base_url, instant_exec_on_suspect_history_change as $8tj43$instant_exec_on_suspect_history_change, slider_fractional_factory as $8tj43$slider_fractional_factory, useExpandingContainer as $8tj43$useExpandingContainer, hex_to_rgb as $8tj43$hex_to_rgb, relative_luminance_from_rgb as $8tj43$relative_luminance_from_rgb, snakeCasifyObject as $8tj43$snakeCasifyObject, fetch_retry as $8tj43$fetch_retry, make_url_with_query_params as $8tj43$make_url_with_query_params, sort_obj as $8tj43$sort_obj, is_debug as $8tj43$is_debug, insert_surfaces as $8tj43$insert_surfaces } from "@depict-ai/utilishared/ES10";
2
2
  import { createSignal as $8tj43$createSignal, createResource as $8tj43$createResource, createEffect as $8tj43$createEffect, untrack as $8tj43$untrack, createMemo as $8tj43$createMemo, onCleanup as $8tj43$onCleanup, Show as $8tj43$Show, createComputed as $8tj43$createComputed, For as $8tj43$For, getOwner as $8tj43$getOwner, runWithOwner as $8tj43$runWithOwner, on as $8tj43$on, Index as $8tj43$Index, batch as $8tj43$batch, ErrorBoundary as $8tj43$ErrorBoundary, createContext as $8tj43$createContext, useContext as $8tj43$useContext, mergeProps as $8tj43$mergeProps1, createUniqueId as $8tj43$createUniqueId, createRenderEffect as $8tj43$createRenderEffect, createSelector as $8tj43$createSelector, children as $8tj43$children, splitProps as $8tj43$splitProps, createRoot as $8tj43$createRoot, Suspense as $8tj43$Suspense, createReaction as $8tj43$createReaction, mapArray as $8tj43$mapArray } from "solid-js";
3
3
  import { template as $8tj43$template, getNextElement as $8tj43$getNextElement, addEventListener as $8tj43$addEventListener, insert as $8tj43$insert, memo as $8tj43$memo, runHydrationEvents as $8tj43$runHydrationEvents, createComponent as $8tj43$createComponent, getNextMarker as $8tj43$getNextMarker, use as $8tj43$use, effect as $8tj43$effect, classList as $8tj43$classList, setAttribute as $8tj43$setAttribute, delegateEvents as $8tj43$delegateEvents, style as $8tj43$style, className as $8tj43$className, spread as $8tj43$spread, mergeProps as $8tj43$mergeProps, setProperty as $8tj43$setProperty, isServer as $8tj43$isServer, Dynamic as $8tj43$Dynamic } from "solid-js/web";
4
- import { ListenableSet as $8tj43$ListenableSet, catchify as $8tj43$catchify1, use_href_accessor as $8tj43$use_href_accessor1, report as $8tj43$report1 } from "@depict-ai/utilishared/ES10";
4
+ import { ListenableSet as $8tj43$ListenableSet1, catchify as $8tj43$catchify1, use_href_accessor as $8tj43$use_href_accessor1, report as $8tj43$report1 } from "@depict-ai/utilishared/ES10";
5
5
  import $8tj43$babelruntimehelpersdefineProperty from "@babel/runtime/helpers/defineProperty";
6
6
  import $8tj43$babelruntimehelpersclassPrivateFieldSet from "@babel/runtime/helpers/classPrivateFieldSet";
7
7
  import $8tj43$babelruntimehelpersclassPrivateFieldGet from "@babel/runtime/helpers/classPrivateFieldGet";
@@ -10,7 +10,7 @@ import { createStore as $8tj43$createStore, reconcile as $8tj43$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.1";
13
+ const $8db9a15135765c11$export$83d89fbfd8236492 = "4.0.3";
14
14
  function $a604a8ffa4e4c03f$export$e417c49320921907(dependency, fetcher) {
15
15
  const [promiseOfCurrentFetcherRun, setPromiseOfCurrentFetcherRun] = $8tj43$createSignal();
16
16
  const deparallelizedFetcher = $8tj43$deparallelize_no_drop(async dependencyValue => {
@@ -2451,6 +2451,7 @@ function $56047603f9d212b6$export$e6fffe67d4cdd848(whatToWatch) {
2451
2451
  return size;
2452
2452
  }
2453
2453
  const $56047603f9d212b6$var$onIdleFunctionsSymbol = /*@__PURE__*/Symbol("onIdleFunctions");
2454
+ const $56047603f9d212b6$export$f8945274f08a3105 = /*@__PURE__*/Symbol("listingContextAspectRatios");
2454
2455
  function $56047603f9d212b6$export$6e5611bc7e57e477(props) {
2455
2456
  // Enable reactive props
2456
2457
  const otherOptions = $8tj43$createMemo(() => {
@@ -2515,6 +2516,21 @@ function $56047603f9d212b6$export$6e5611bc7e57e477(props) {
2515
2516
  let timeoutSet = false;
2516
2517
  let gotCleanedUp = false;
2517
2518
  img.classList.add("s-responsive-image");
2519
+ if (listingContext) {
2520
+ let prevValue;
2521
+ const aspectRatios = listingContext[$56047603f9d212b6$export$f8945274f08a3105] || (listingContext[$56047603f9d212b6$export$f8945274f08a3105] = new (0, $8tj43$ListenableSet)());
2522
+ img.addEventListener("load", $8tj43$catchify(() => {
2523
+ // Save our aspect ratio whenever it changes, so that we can base the containers on the most dominant aspect ratio, used in SearchModalV2
2524
+ const aspectRatio_ = img.naturalWidth / img.naturalHeight;
2525
+ if (prevValue) aspectRatios.delete(prevValue);
2526
+ const newValue = !isNaN(aspectRatio_) ? {
2527
+ aspectRatio_: aspectRatio_
2528
+ } : undefined;
2529
+ if (newValue) aspectRatios.add(newValue);
2530
+ prevValue = newValue;
2531
+ }));
2532
+ $8tj43$onCleanup(() => prevValue && aspectRatios.delete(prevValue));
2533
+ }
2518
2534
  $8tj43$onCleanup(() => gotCleanedUp = true);
2519
2535
  $8tj43$spread(img, $8tj43$mergeProps1(otherOptions), false, true);
2520
2536
  $8tj43$createEffect(() => {
@@ -2582,9 +2598,29 @@ function $4df489344a0f97c7$export$e4b984597b71e989(props) {
2582
2598
  // create a signal that's the same for all items in this listing
2583
2599
  context[$4df489344a0f97c7$export$d7b7ab832c20e2f4] = $8tj43$createSignal();
2584
2600
  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
2601
+ const aspectRatiosSet = context ? context[(0, $56047603f9d212b6$export$f8945274f08a3105)] || (context[(0, $56047603f9d212b6$export$f8945274f08a3105)] = new (0, $8tj43$ListenableSet)()) : undefined;
2602
+ const [aspectRatios, setAspectRatios] = $8tj43$createSignal(aspectRatiosSet, {
2603
+ equals: false
2604
+ });
2605
+ const aspectRatioToUse = $8tj43$createMemo(() => {
2606
+ const aspectRatiosSet = aspectRatios(); // This signal "changes" to the same set every time the set changes, so we can use it as a dependency here
2607
+ useMostPrevalentAspectRatio: {
2608
+ if (!aspectRatiosSet || !props.autoAdjustAspectRatio) break useMostPrevalentAspectRatio;
2609
+ // Get the aspect ratio that most of the loaded images inside the ListingProvider we are, load
2610
+ const asArray = [...aspectRatiosSet].map(_ref => {
2611
+ let {
2612
+ aspectRatio_: aspectRatio_
2613
+ } = _ref;
2614
+ return aspectRatio_;
2615
+ });
2616
+ const mostPrevalentAspectRatio = $8tj43$findMostFrequentItem(asArray);
2617
+ if (mostPrevalentAspectRatio) return "var(".concat((0, $5eaa00b951637e96$export$8a2234b5b1a5ebd4), ", ").concat(mostPrevalentAspectRatio, ")");
2618
+ }
2619
+ return props.aspectRatio;
2620
+ });
2585
2621
  const container = $8tj43$createComponent((0, $801e8845d3fa3653$export$94026ee33dbabc26), {
2586
2622
  get aspectRatio() {
2587
- return props.aspectRatio;
2623
+ return aspectRatioToUse();
2588
2624
  },
2589
2625
  get ["class"]() {
2590
2626
  return props.class;
@@ -2593,6 +2629,10 @@ function $4df489344a0f97c7$export$e4b984597b71e989(props) {
2593
2629
  const owner = $8tj43$getOwner();
2594
2630
  let createdSizeAccessor = false;
2595
2631
  let wasCleanedUp = false;
2632
+ for (const event of ["add", "delete"]) {
2633
+ aspectRatiosSet === null || aspectRatiosSet === void 0 || aspectRatiosSet.addEventListener(event, () => setAspectRatios(aspectRatiosSet));
2634
+ $8tj43$onCleanup(() => aspectRatiosSet === null || aspectRatiosSet === void 0 ? void 0 : aspectRatiosSet.removeEventListener(event, () => setAspectRatios(aspectRatiosSet)));
2635
+ }
2596
2636
  $8tj43$createEffect(() => {
2597
2637
  if (currentImageSize() || wasCleanedUp) return; // We get into the effect when onCleanup is called if we don't have wasCleanedUp
2598
2638
  // ensure we always have a size accessor
@@ -3660,7 +3700,8 @@ function $06fcd2a345efd24d$var$RawSearchModalV2(_ref) {
3660
3700
  get src() {
3661
3701
  return props.src_;
3662
3702
  },
3663
- aspectRatio: "var(".concat((0, $5eaa00b951637e96$export$8a2234b5b1a5ebd4), ", 1)")
3703
+ autoAdjustAspectRatio: true,
3704
+ aspectRatio: 1
3664
3705
  }),
3665
3706
  ...instant_results_options_
3666
3707
  }), _el$4, _co$);
@@ -3841,7 +3882,7 @@ const $6a439680ae7e9ba3$var$TabsContext = /*@__PURE__*/$8tj43$createContext();
3841
3882
  const $6a439680ae7e9ba3$var$useTabs = () => $8tj43$useContext($6a439680ae7e9ba3$var$TabsContext);
3842
3883
  function $6a439680ae7e9ba3$export$b2539bed5023c21c(props) {
3843
3884
  return $8tj43$createComponent($6a439680ae7e9ba3$var$TabsContext.Provider, {
3844
- value: new (0, $8tj43$ListenableSet)(),
3885
+ value: new (0, $8tj43$ListenableSet1)(),
3845
3886
  get children() {
3846
3887
  return $8tj43$createComponent($6a439680ae7e9ba3$var$ActualTabs, $8tj43$mergeProps(props, {
3847
3888
  get children() {
@@ -4012,7 +4053,17 @@ async function $d5f1e6a0f9117286$export$79b1565500412d9b(search_modal, modal_fn_
4012
4053
  const actually_close = () => {
4013
4054
  dispose();
4014
4055
  on_dispose === null || on_dispose === void 0 || on_dispose();
4015
- modal_els.forEach(el => el.remove());
4056
+ const {
4057
+ activeElement: activeElement
4058
+ } = document;
4059
+ modal_els.forEach(el => {
4060
+ if (el.contains(activeElement)) {
4061
+ var _blur, _ref;
4062
+ // Fix page jumping to the bottom when closing modal with scape after animation in safari
4063
+ activeElement === null || activeElement === void 0 || (_blur = (_ref = activeElement).blur) === null || _blur === void 0 || _blur.call(_ref);
4064
+ }
4065
+ el.remove();
4066
+ });
4016
4067
  };
4017
4068
  if (animation_started && +new Date() - animation_started > 1000)
4018
4069
  // Animation broke, close it this time
@@ -13295,7 +13346,7 @@ function $d53ebed6f63304e4$export$6d0c9c22f6652669(_ref) {
13295
13346
  number_: num_results,
13296
13347
  i18n_: i18n_
13297
13348
  });
13298
- const queries_without_content_results_ = new (0, $8tj43$ListenableSet1)();
13349
+ const queries_without_content_results_ = new (0, $8tj43$ListenableSet)();
13299
13350
  const [check_query, set_check_query] = $8tj43$createSignal(false);
13300
13351
  const placeholders_enabled = $8tj43$createMemo(() => {
13301
13352
  // don't show placeholders when the user toggles filters
package/latest/index.cjs CHANGED
@@ -86,7 +86,7 @@ $parcel$export(module.exports, "defaultCategoryTitlePlugin", () => $a3280f0aad99
86
86
  $parcel$export(module.exports, "version", () => $b757f75811f3261f$export$83d89fbfd8236492);
87
87
  $parcel$export(module.exports, "SearchField", () => $c0a0659cf97e8eb2$export$316f6f283ae64765);
88
88
  /*! Depict.ai search and product listing SDK */
89
- const $b757f75811f3261f$export$83d89fbfd8236492 = "4.0.1";
89
+ const $b757f75811f3261f$export$83d89fbfd8236492 = "4.0.3";
90
90
  function $53df95e470b2f8d2$export$e417c49320921907(dependency, fetcher) {
91
91
  const [promiseOfCurrentFetcherRun, setPromiseOfCurrentFetcherRun] = $gVhhF$solidjs.createSignal();
92
92
  const deparallelizedFetcher = $gVhhF$depictaiutilishared.deparallelize_no_drop(async dependencyValue => {
@@ -2423,6 +2423,7 @@ function $19950faaac026e09$export$e6fffe67d4cdd848(whatToWatch) {
2423
2423
  return size;
2424
2424
  }
2425
2425
  const $19950faaac026e09$var$onIdleFunctionsSymbol = /*@__PURE__*/Symbol("onIdleFunctions");
2426
+ const $19950faaac026e09$export$f8945274f08a3105 = /*@__PURE__*/Symbol("listingContextAspectRatios");
2426
2427
  function $19950faaac026e09$export$6e5611bc7e57e477(props) {
2427
2428
  // Enable reactive props
2428
2429
  const otherOptions = $gVhhF$solidjs.createMemo(() => {
@@ -2487,6 +2488,21 @@ function $19950faaac026e09$export$6e5611bc7e57e477(props) {
2487
2488
  let timeoutSet = false;
2488
2489
  let gotCleanedUp = false;
2489
2490
  img.classList.add("s-responsive-image");
2491
+ if (listingContext) {
2492
+ let prevValue;
2493
+ const aspectRatios = listingContext[$19950faaac026e09$export$f8945274f08a3105] ||= new (0, $gVhhF$depictaiutilishared.ListenableSet)();
2494
+ img.addEventListener("load", $gVhhF$depictaiutilishared.catchify(() => {
2495
+ // Save our aspect ratio whenever it changes, so that we can base the containers on the most dominant aspect ratio, used in SearchModalV2
2496
+ const aspectRatio_ = img.naturalWidth / img.naturalHeight;
2497
+ if (prevValue) aspectRatios.delete(prevValue);
2498
+ const newValue = !isNaN(aspectRatio_) ? {
2499
+ aspectRatio_: aspectRatio_
2500
+ } : undefined;
2501
+ if (newValue) aspectRatios.add(newValue);
2502
+ prevValue = newValue;
2503
+ }));
2504
+ $gVhhF$solidjs.onCleanup(() => prevValue && aspectRatios.delete(prevValue));
2505
+ }
2490
2506
  $gVhhF$solidjs.onCleanup(() => gotCleanedUp = true);
2491
2507
  $gVhhF$solidjsweb.spread(img, $gVhhF$solidjs.mergeProps(otherOptions), false, true);
2492
2508
  $gVhhF$solidjs.createEffect(() => {
@@ -2554,9 +2570,28 @@ function $a33065cfed827fc0$export$e4b984597b71e989(props) {
2554
2570
  // create a signal that's the same for all items in this listing
2555
2571
  context[$a33065cfed827fc0$export$d7b7ab832c20e2f4] = $gVhhF$solidjs.createSignal();
2556
2572
  const [currentImageSize, setCurrentImageSize] = context?.[$a33065cfed827fc0$export$d7b7ab832c20e2f4] || $a33065cfed827fc0$var$backupSizeSignal; // use global fallback signal (might lead to blurry images) if no context is available
2573
+ const aspectRatiosSet = context ?
2574
+ // If the context exists we have to create the set here as getting it here would be too late when it's created by ShopifyResponsiveImg below
2575
+ context[(0, $19950faaac026e09$export$f8945274f08a3105)] ||= new (0, $gVhhF$depictaiutilishared.ListenableSet)() : undefined;
2576
+ const [aspectRatios, setAspectRatios] = $gVhhF$solidjs.createSignal(aspectRatiosSet, {
2577
+ equals: false
2578
+ });
2579
+ const aspectRatioToUse = $gVhhF$solidjs.createMemo(() => {
2580
+ const aspectRatiosSet = aspectRatios(); // This signal "changes" to the same set every time the set changes, so we can use it as a dependency here
2581
+ useMostPrevalentAspectRatio: {
2582
+ if (!aspectRatiosSet || !props.autoAdjustAspectRatio) break useMostPrevalentAspectRatio;
2583
+ // Get the aspect ratio that most of the loaded images inside the ListingProvider we are, load
2584
+ const asArray = [...aspectRatiosSet].map(({
2585
+ aspectRatio_: aspectRatio_
2586
+ }) => aspectRatio_);
2587
+ const mostPrevalentAspectRatio = $gVhhF$depictaiutilishared.findMostFrequentItem(asArray);
2588
+ if (mostPrevalentAspectRatio) return `var(${(0, $6f604560873e4f69$export$8a2234b5b1a5ebd4)}, ${mostPrevalentAspectRatio})`;
2589
+ }
2590
+ return props.aspectRatio;
2591
+ });
2557
2592
  const container = $gVhhF$solidjsweb.createComponent((0, $93304d59a9747aa6$export$94026ee33dbabc26), {
2558
2593
  get aspectRatio() {
2559
- return props.aspectRatio;
2594
+ return aspectRatioToUse();
2560
2595
  },
2561
2596
  get ["class"]() {
2562
2597
  return props.class;
@@ -2565,6 +2600,10 @@ function $a33065cfed827fc0$export$e4b984597b71e989(props) {
2565
2600
  const owner = $gVhhF$solidjs.getOwner();
2566
2601
  let createdSizeAccessor = false;
2567
2602
  let wasCleanedUp = false;
2603
+ for (const event of ["add", "delete"]) {
2604
+ aspectRatiosSet?.addEventListener(event, () => setAspectRatios(aspectRatiosSet));
2605
+ $gVhhF$solidjs.onCleanup(() => aspectRatiosSet?.removeEventListener(event, () => setAspectRatios(aspectRatiosSet)));
2606
+ }
2568
2607
  $gVhhF$solidjs.createEffect(() => {
2569
2608
  if (currentImageSize() || wasCleanedUp) return; // We get into the effect when onCleanup is called if we don't have wasCleanedUp
2570
2609
  // ensure we always have a size accessor
@@ -3579,7 +3618,8 @@ function $11597ae03e703a47$var$RawSearchModalV2({
3579
3618
  get src() {
3580
3619
  return props.src_;
3581
3620
  },
3582
- aspectRatio: `var(${(0, $6f604560873e4f69$export$8a2234b5b1a5ebd4)}, 1)`
3621
+ autoAdjustAspectRatio: true,
3622
+ aspectRatio: 1
3583
3623
  }),
3584
3624
  ...instant_results_options_
3585
3625
  }), _el$4, _co$);
@@ -3920,7 +3960,15 @@ async function $9abb0a35d4b60ed3$export$79b1565500412d9b(search_modal, modal_fn_
3920
3960
  const actually_close = () => {
3921
3961
  dispose();
3922
3962
  on_dispose?.();
3923
- modal_els.forEach(el => el.remove());
3963
+ const {
3964
+ activeElement: activeElement
3965
+ } = document;
3966
+ modal_els.forEach(el => {
3967
+ if (el.contains(activeElement))
3968
+ // Fix page jumping to the bottom when closing modal with scape after animation in safari
3969
+ activeElement?.blur?.();
3970
+ el.remove();
3971
+ });
3924
3972
  };
3925
3973
  if (animation_started && +new Date() - animation_started > 1000)
3926
3974
  // Animation broke, close it this time
package/latest/index.d.ts CHANGED
@@ -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.1";
13
+ export const version = "4.0.3";
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
  */