@depict-ai/react-ui 1.5.19 → 2.0.0

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.
Files changed (49) hide show
  1. package/ES10/index.cjs +149 -69
  2. package/ES10/index.d.ts +64 -21
  3. package/ES10/index.js +152 -74
  4. package/README.md +2 -1
  5. package/dist/main.js +293 -0
  6. package/dist/module.js +285 -0
  7. package/dist/styles/components/PLP/Buttons.scss +124 -0
  8. package/dist/styles/components/PLP/MorphingSign.scss +31 -0
  9. package/dist/styles/components/PLP/PLPResults.scss +20 -0
  10. package/dist/styles/components/PLP/ProductListingPage.scss +142 -0
  11. package/dist/styles/components/PLP/ScrollStatus.scss +24 -0
  12. package/dist/styles/components/PLP/SelectedFilters.scss +74 -0
  13. package/dist/styles/components/PLP/SlidableItems.scss +99 -0
  14. package/dist/styles/components/PLP/SortAndFilter/FloatingButtons.scss +75 -0
  15. package/dist/styles/components/PLP/SortAndFilter/SortAndFilter.scss +728 -0
  16. package/dist/styles/components/PLP/SortAndFilter/SortAndFilterModal.scss +160 -0
  17. package/dist/styles/components/PLP/SortAndFilter/WhiteSortAndFilter.scss +148 -0
  18. package/dist/styles/components/PLP/Toast.scss +54 -0
  19. package/dist/styles/components/PLP/index.scss +45 -0
  20. package/dist/styles/components/category/BreadCrumbs.scss +23 -0
  21. package/dist/styles/components/category/CategoryTitle.scss +28 -0
  22. package/dist/styles/components/category/QuickLinks.scss +71 -0
  23. package/dist/styles/components/category/index.scss +23 -0
  24. package/dist/styles/components/search/Autocomplete.scss +117 -0
  25. package/dist/styles/components/search/CategorySuggestions.scss +74 -0
  26. package/dist/styles/components/search/InstantCard.scss +117 -0
  27. package/dist/styles/components/search/InstantResults.scss +10 -0
  28. package/dist/styles/components/search/PreviousSearches.scss +77 -0
  29. package/dist/styles/components/search/QueryInput.scss +167 -0
  30. package/dist/styles/components/search/SearchModal.scss +95 -0
  31. package/dist/styles/components/search/SearchRecommendations.scss +25 -0
  32. package/dist/styles/components/search/ShowingResultsFor.scss +10 -0
  33. package/dist/styles/components/search/index.scss +40 -0
  34. package/dist/styles/default.css +1 -0
  35. package/dist/styles/helpers/custom_input.scss +162 -0
  36. package/dist/styles/helpers/supports-hover.scss +5 -0
  37. package/dist/styles/helpers/utils.scss +82 -0
  38. package/dist/styles/plain-css-fallback-styling.css +1 -1
  39. package/dist/styles/variables.scss +47 -0
  40. package/latest/index.cjs +145 -68
  41. package/latest/index.d.ts +64 -21
  42. package/latest/index.js +148 -73
  43. package/package.json +9 -9
  44. package/server/ES10/index.cjs +125 -1
  45. package/server/ES10/index.d.ts +64 -21
  46. package/server/ES10/index.js +127 -5
  47. package/server/latest/index.cjs +122 -1
  48. package/server/latest/index.d.ts +64 -21
  49. package/server/latest/index.js +124 -5
@@ -1,26 +1,9 @@
1
- import { BaseProductListingConfig, BaseProviderConfig, BaseSearchProviderConfig, BaseCategoryProviderConfig, ModernDisplayWithPageUrl, BaseSearchPageConfig, BaseCategoryPageConfig, CategoryTitle, embedded_num_products, ImagePlaceholder as _ImagePlaceholder1, TextPlaceholder as _TextPlaceholder1, ExclusiveId, fetchDepictRecommendations } from "@depict-ai/ui/ES10";
2
- import { Display, ModernDisplay } from "@depict-ai/utilishared/ES10";
3
- import React, { ReactNode, PropsWithChildren, ReactElement } from "react";
4
1
  import { DPC } from "@depict-ai/dpc/ES10";
2
+ import React, { PropsWithChildren, ReactNode, ReactPortal, ReactElement } from "react";
3
+ import { BaseProviderConfig, BaseSearchProviderConfig, BaseCategoryProviderConfig, ModernDisplayWithPageUrl, BaseProductListingConfig, BaseSearchPageConfig, BaseCategoryPageConfig, CategoryTitle, embedded_num_products, ImagePlaceholder as _ImagePlaceholder1, TextPlaceholder as _TextPlaceholder1, ExclusiveId, fetchDepictRecommendations } from "@depict-ai/ui/ES10";
5
4
  import { Locale } from "@depict-ai/ui/locales/ES10";
6
- export const version = "1.5.19";
7
- interface PLPConfig<T extends Display> extends BaseProductListingConfig {
8
- /**
9
- * The product card to use for rendering products.
10
- */
11
- productCard: DepictProductCard<T>;
12
- }
13
- /**
14
- * The Depict product card props.
15
- */
16
- export interface DepictProductCardProps<T extends Display> {
17
- /** The display data to render. */
18
- display: T | null;
19
- }
20
- /**
21
- * Depict product card to use for rendering products.
22
- */
23
- export type DepictProductCard<T extends Display> = (props: DepictProductCardProps<T>) => ReactNode;
5
+ import { Display, ModernDisplay } from "@depict-ai/utilishared/ES10";
6
+ export const version = "2.0.0";
24
7
  interface UsePerformanceClientReturn {
25
8
  dpc: DPC;
26
9
  }
@@ -172,6 +155,23 @@ export function DepictProvider<InputDisplay extends Display, OutputDisplay exten
172
155
  * @returns {JSX.Element}
173
156
  */
174
157
  export const ComponentAligner: import("react").ForwardRefExoticComponent<import("react").RefAttributes<unknown>>;
158
+ interface PLPConfig<T extends Display> extends BaseProductListingConfig {
159
+ /**
160
+ * The product card to use for rendering products.
161
+ */
162
+ productCard: DepictProductCard<T>;
163
+ }
164
+ /**
165
+ * The Depict product card props.
166
+ */
167
+ export interface DepictProductCardProps<T extends Display> {
168
+ /** The display data to render. */
169
+ display: T | null;
170
+ }
171
+ /**
172
+ * Depict product card to use for rendering products.
173
+ */
174
+ export type DepictProductCard<T extends Display> = (props: DepictProductCardProps<T>) => ReactNode;
175
175
  interface SearchPageConfig<T extends Display> extends BaseSearchPageConfig, PLPConfig<T> {
176
176
  /**
177
177
  * When using multiple search instances on the same page, you need to set a unique stateKey for each one. We recommend using an incrementing number, such as "1", "2", "3", etc. To associate a modal with a SearchPage keyed component, set the same stateKey on both. If no stateKey is provided, the "default" instance will be used.
@@ -320,6 +320,49 @@ export const ImagePlaceholder: React.FC<Parameters<typeof _ImagePlaceholder1>[0]
320
320
  export const TextPlaceholder: React.FC<Parameters<typeof _TextPlaceholder1>[0] & {
321
321
  className?: string;
322
322
  }>;
323
+ interface RecommendationConfig<T extends Display> extends BaseProductListingConfig {
324
+ /**
325
+ * A promise containing the recommendations to render, see https://docs.depict.ai/api-guide/recommendations/api-client/fetching
326
+ */
327
+ recommendations: Promise<T[]>;
328
+ /**
329
+ * The product card function to use for rendering products.
330
+ */
331
+ productCard: DepictProductCard<T>;
332
+ }
333
+ interface RecommendationGridConfig<T extends Display> extends RecommendationConfig<T> {
334
+ viewMoreButton?: {
335
+ text: string;
336
+ startRows?: number;
337
+ rowsPerClick?: number;
338
+ };
339
+ }
340
+ declare function SolidRecommendationWrapper<T extends Display>(props: RecommendationGridConfig<T>, set_portals: (portals: ReactPortal[]) => void): HTMLDivElement;
341
+ interface RecommendationSliderConfig<T extends Display> extends RecommendationConfig<T> {
342
+ viewMoreButton?: {
343
+ text: string;
344
+ startRows?: number;
345
+ rowsPerClick?: number;
346
+ };
347
+ }
348
+ /**
349
+ * Renders a slider of the provided products
350
+ * @param recommendations a promise resolving to an array of displays to render
351
+ * @param productCard a function that renders a product card or a placeholder for one
352
+ * @param columnsAtSize the number of columns to show at each media breakpoint
353
+ * @param gridSpacing the spacing between the product cards
354
+ */
355
+ export function RecommendationSlider<T extends Display>(props: Parameters<typeof SolidRecommendationSliderWrapper<T>>[0]): import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
356
+ declare function SolidRecommendationSliderWrapper<T extends Display>(props: RecommendationSliderConfig<T>, set_portals: (portals: ReactPortal[]) => void): HTMLDivElement;
357
+ /**
358
+ * Renders a product grid of the provided products
359
+ * @param recommendations a promise resolving to an array of displays to render
360
+ * @param productCard a function that renders a product card or a placeholder for one
361
+ * @param columnsAtSize the number of columns to show at each media breakpoint
362
+ * @param gridSpacing the spacing between the product cards
363
+ * @param viewMoreButton optional configuration for the view more button. If unset, all products will be shown by default. Otherwise, a view more button with the given text will be shown. With the properties startRows and rowsPerClick, you can configure how many rows should be shown initially and how many rows should be added on each click.
364
+ */
365
+ export function RecommendationGrid<T extends Display>(props: Parameters<typeof SolidRecommendationWrapper<T>>[0]): import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
323
366
  /**
324
367
  * Parameters to configure the search modal.
325
368
  */
@@ -1,6 +1,10 @@
1
- import { createElement as $7h5e1$createElement, useRef as $7h5e1$useRef, Fragment as $7h5e1$Fragment } from "react";
2
- import { ImagePlaceholder as $7h5e1$ImagePlaceholder, TextPlaceholder as $7h5e1$TextPlaceholder } from "@depict-ai/ui/ES10";
3
- import { renderToString as $7h5e1$renderToString, generateHydrationScript as $7h5e1$generateHydrationScript } from "solid-js/web";
1
+ import { createElement as $7h5e1$createElement, useRef as $7h5e1$useRef, Fragment as $7h5e1$Fragment, useEffect as $7h5e1$useEffect, Component as $7h5e1$Component } from "react";
2
+ import { ImagePlaceholder as $7h5e1$ImagePlaceholder, TextPlaceholder as $7h5e1$TextPlaceholder, RecommendationGrid as $7h5e1$RecommendationGrid, defaultColsAtSize as $7h5e1$defaultColsAtSize, defaultGridSpacing as $7h5e1$defaultGridSpacing, ProductCardError as $7h5e1$ProductCardError } from "@depict-ai/ui/ES10";
3
+ import { renderToString as $7h5e1$renderToString, generateHydrationScript as $7h5e1$generateHydrationScript, isServer as $7h5e1$isServer } from "solid-js/web";
4
+ import { untrack as $7h5e1$untrack, getOwner as $7h5e1$getOwner, runWithOwner as $7h5e1$runWithOwner, onCleanup as $7h5e1$onCleanup } from "solid-js";
5
+ import { renderToString as $7h5e1$renderToString1 } from "react-dom/server";
6
+ import { jsx as $7h5e1$jsx } from "react/jsx-runtime";
7
+ import { createPortal as $7h5e1$createPortal } from "react-dom";
4
8
  import { register_es_version } from "../../multi_import_deduplicator.mjs";
5
9
  register_es_version("react-ui", "ES10");
6
10
  function $e8e755ef02e716bf$export$4b564d7f5a1b1d43(_ref) {
@@ -21,7 +25,113 @@ function $e8e755ef02e716bf$export$4b564d7f5a1b1d43(_ref) {
21
25
  }
22
26
  }));
23
27
  }
24
- const $9bd9bb8700ab2ada$export$83d89fbfd8236492 = "1.5.19";
28
+ class $88d93ed7309e90d1$export$d0f82e3ef89b1f22 extends (0, $7h5e1$Component) {
29
+ constructor(props) {
30
+ super(props);
31
+ this.state = {
32
+ hasError: false
33
+ };
34
+ }
35
+ static getDerivedStateFromError() {
36
+ // Update state so the next render will show the fallback UI.
37
+ return {
38
+ hasError: true
39
+ };
40
+ }
41
+ componentDidCatch(error) {
42
+ this.props.on_error(error);
43
+ }
44
+ render() {
45
+ if (this.state.hasError)
46
+ // You can render any custom fallback UI
47
+ return $7h5e1$createElement("div", {
48
+ children: "Component failed"
49
+ });
50
+ return this.props.children;
51
+ }
52
+ }
53
+ async function $6593e4e126cb318f$export$79c79419c1ef0081(_ref) {
54
+ let {
55
+ display: display,
56
+ component_portals: component_portals,
57
+ set_portals: set_portals,
58
+ react_template: react_template
59
+ } = _ref;
60
+ let set_react_has_ran_hooks;
61
+ let was_cleaned_up = false;
62
+ const react_has_ran_hooks = new Promise(r => set_react_has_ran_hooks = r);
63
+ const solid_container = document.createElement("div");
64
+ const owner = $7h5e1$getOwner();
65
+ const reactProductCard = $7h5e1$jsx(props => {
66
+ // Sneak in a hook into their product card component to know once react has finished rendering and running hooks
67
+ $7h5e1$useEffect(set_react_has_ran_hooks, []);
68
+ return react_template(props);
69
+ }, {
70
+ display: display
71
+ });
72
+ const reactProductCardInErrorBoundary = $7h5e1$jsx((0, $88d93ed7309e90d1$export$d0f82e3ef89b1f22), {
73
+ children: reactProductCard,
74
+ on_error: error => $7h5e1$runWithOwner(owner, () => {
75
+ if (was_cleaned_up) return; // Would infinite loop if we'd throw after we've already been cleaned up. That is because the `ErrorBoundary` won't be "registered" with the cleaned-up owner anymore so react would hear about the throw and attempt to re-render the error boundary or something which would throw again, etc.
76
+ throw new (0, $7h5e1$ProductCardError)(error);
77
+ })
78
+ });
79
+ const portal = $7h5e1$createPortal(reactProductCardInErrorBoundary, solid_container);
80
+ component_portals.add(portal);
81
+ set_portals([...component_portals]);
82
+ $7h5e1$onCleanup(() => {
83
+ was_cleaned_up = true;
84
+ // this will stop working after any await so be careful to not await before this, or you'll have to carry the owner over with getOwner and runWithOwner
85
+ component_portals.delete(portal);
86
+ // Updating i.e. the merchant will cause a setState call while rendering the DepictProvider component which is illegal because it usually infinite loops react apps. In our case it doesn't though, so we just evade detection by doing it a microtask later. See also https://github.com/facebook/react/issues/18178#issuecomment-595846312
87
+ queueMicrotask(() => set_portals([...component_portals]));
88
+ });
89
+ await react_has_ran_hooks; // After React has created elements it still takes some time to actually connect the refs and run the hooks. We don't want to replace placeholders before then.
90
+ return [solid_container];
91
+ }
92
+ function $48b0916cc674770c$export$bd8acc07a8bae229(props, set_portals) {
93
+ const component_portals = new Set();
94
+ return $7h5e1$RecommendationGrid({
95
+ get recommendations() {
96
+ return props.recommendations;
97
+ },
98
+ product_card_template: display => {
99
+ if (0, $7h5e1$isServer)
100
+ // This function can't be async on the server
101
+ // @ts-ignore
102
+ return {
103
+ t: $7h5e1$renderToString1($7h5e1$createElement(() => props.productCard({
104
+ display: display
105
+ })))
106
+ };
107
+ return $6593e4e126cb318f$export$79c79419c1ef0081({
108
+ display: display,
109
+ react_template: $7h5e1$untrack(() => props.productCard),
110
+ component_portals: component_portals,
111
+ set_portals: set_portals
112
+ });
113
+ },
114
+ get cols_at_size() {
115
+ return props.columnsAtSize || (0, $7h5e1$defaultColsAtSize);
116
+ },
117
+ get grid_spacing() {
118
+ var _props$gridSpacing;
119
+ return (_props$gridSpacing = props.gridSpacing) !== null && _props$gridSpacing !== void 0 ? _props$gridSpacing : (0, $7h5e1$defaultGridSpacing);
120
+ },
121
+ get view_more_button() {
122
+ var _viewMoreButton$start;
123
+ const {
124
+ viewMoreButton: viewMoreButton
125
+ } = props;
126
+ return viewMoreButton ? {
127
+ text: viewMoreButton.text,
128
+ start_rows: (_viewMoreButton$start = viewMoreButton.startRows) !== null && _viewMoreButton$start !== void 0 ? _viewMoreButton$start : 2,
129
+ rows_per_click: viewMoreButton.rowsPerClick
130
+ } : undefined;
131
+ }
132
+ });
133
+ }
134
+ const $9bd9bb8700ab2ada$export$83d89fbfd8236492 = "2.0.0";
25
135
  function $5c4add0a8fe94894$export$9fac37a9c21c2f3b(props) {
26
136
  return props.children;
27
137
  }
@@ -45,6 +155,11 @@ function $5c4add0a8fe94894$export$466cdc317043f6cb() {
45
155
  children: []
46
156
  });
47
157
  }
158
+ function $5c4add0a8fe94894$export$82cfdc85a4d15688() {
159
+ return $7h5e1$createElement("div", {
160
+ children: []
161
+ });
162
+ }
48
163
  function $5c4add0a8fe94894$export$80e99ee6b29cadd2() {
49
164
  return $7h5e1$createElement("div", {
50
165
  className: "depict aligner",
@@ -64,6 +179,13 @@ function $5c4add0a8fe94894$export$3f37af283f8fb843(raw_react_props) {
64
179
  wrapper_type: "span"
65
180
  });
66
181
  }
182
+ function $5c4add0a8fe94894$export$b0a773486c1c2312(props) {
183
+ return $e8e755ef02e716bf$export$4b564d7f5a1b1d43({
184
+ solid_component: (0, $48b0916cc674770c$export$bd8acc07a8bae229),
185
+ props: props,
186
+ wrapper_type: "section"
187
+ });
188
+ }
67
189
  function $5c4add0a8fe94894$export$89c6019e4baa40b1(raw_react_props) {
68
190
  const react_props = {
69
191
  ...raw_react_props,
@@ -111,4 +233,4 @@ function $5c4add0a8fe94894$export$6501da23a2770fc() {
111
233
  }
112
234
  };
113
235
  }
114
- export { $5c4add0a8fe94894$export$9fac37a9c21c2f3b as DepictProvider, $5c4add0a8fe94894$export$a54ec244c8863715 as SearchPage, $5c4add0a8fe94894$export$f7d2f673fc2f091d as CategoryPage, $5c4add0a8fe94894$export$5646050d516e06bc as BreadCrumbs, $5c4add0a8fe94894$export$466cdc317043f6cb as QuickLinks, $5c4add0a8fe94894$export$80e99ee6b29cadd2 as ComponentAligner, $5c4add0a8fe94894$export$3f37af283f8fb843 as ImagePlaceholder, $5c4add0a8fe94894$export$89c6019e4baa40b1 as TextPlaceholder, $5c4add0a8fe94894$export$9bb30bbe003b82e0 as useSearchField, $5c4add0a8fe94894$export$a7f6cffb6b8ba11c as openModal, $5c4add0a8fe94894$export$912994940e660d32 as useSearchModal, $5c4add0a8fe94894$export$38b98fae14bd1f64 as usePerformanceClient, $5c4add0a8fe94894$export$6501da23a2770fc as useFetchRecommendations, $9bd9bb8700ab2ada$export$83d89fbfd8236492 as version };
236
+ export { $5c4add0a8fe94894$export$9fac37a9c21c2f3b as DepictProvider, $5c4add0a8fe94894$export$a54ec244c8863715 as SearchPage, $5c4add0a8fe94894$export$f7d2f673fc2f091d as CategoryPage, $5c4add0a8fe94894$export$5646050d516e06bc as BreadCrumbs, $5c4add0a8fe94894$export$466cdc317043f6cb as QuickLinks, $5c4add0a8fe94894$export$82cfdc85a4d15688 as RecommendationSlider, $5c4add0a8fe94894$export$80e99ee6b29cadd2 as ComponentAligner, $5c4add0a8fe94894$export$3f37af283f8fb843 as ImagePlaceholder, $5c4add0a8fe94894$export$b0a773486c1c2312 as RecommendationGrid, $5c4add0a8fe94894$export$89c6019e4baa40b1 as TextPlaceholder, $5c4add0a8fe94894$export$9bb30bbe003b82e0 as useSearchField, $5c4add0a8fe94894$export$a7f6cffb6b8ba11c as openModal, $5c4add0a8fe94894$export$912994940e660d32 as useSearchModal, $5c4add0a8fe94894$export$38b98fae14bd1f64 as usePerformanceClient, $5c4add0a8fe94894$export$6501da23a2770fc as useFetchRecommendations, $9bd9bb8700ab2ada$export$83d89fbfd8236492 as version };
@@ -1,6 +1,10 @@
1
1
  var $7QqFM$react = require("react");
2
2
  var $7QqFM$depictaiui = require("@depict-ai/ui/latest");
3
3
  var $7QqFM$solidjsweb = require("solid-js/web");
4
+ var $7QqFM$solidjs = require("solid-js");
5
+ var $7QqFM$reactdomserver = require("react-dom/server");
6
+ var $7QqFM$reactjsxruntime = require("react/jsx-runtime");
7
+ var $7QqFM$reactdom = require("react-dom");
4
8
  require("../../multi_import_deduplicator.cjs").register_es_version("react-ui", "latest");
5
9
  function $parcel$export(e, n, v, s) {
6
10
  Object.defineProperty(e, n, {
@@ -15,8 +19,10 @@ $parcel$export(module.exports, "SearchPage", () => $41e7e5d85b5e0d49$export$a54e
15
19
  $parcel$export(module.exports, "CategoryPage", () => $41e7e5d85b5e0d49$export$f7d2f673fc2f091d);
16
20
  $parcel$export(module.exports, "BreadCrumbs", () => $41e7e5d85b5e0d49$export$5646050d516e06bc);
17
21
  $parcel$export(module.exports, "QuickLinks", () => $41e7e5d85b5e0d49$export$466cdc317043f6cb);
22
+ $parcel$export(module.exports, "RecommendationSlider", () => $41e7e5d85b5e0d49$export$82cfdc85a4d15688);
18
23
  $parcel$export(module.exports, "ComponentAligner", () => $41e7e5d85b5e0d49$export$80e99ee6b29cadd2);
19
24
  $parcel$export(module.exports, "ImagePlaceholder", () => $41e7e5d85b5e0d49$export$3f37af283f8fb843);
25
+ $parcel$export(module.exports, "RecommendationGrid", () => $41e7e5d85b5e0d49$export$b0a773486c1c2312);
20
26
  $parcel$export(module.exports, "TextPlaceholder", () => $41e7e5d85b5e0d49$export$89c6019e4baa40b1);
21
27
  $parcel$export(module.exports, "useSearchField", () => $41e7e5d85b5e0d49$export$9bb30bbe003b82e0);
22
28
  $parcel$export(module.exports, "openModal", () => $41e7e5d85b5e0d49$export$a7f6cffb6b8ba11c);
@@ -41,7 +47,110 @@ function $35dfe83eec81954c$export$4b564d7f5a1b1d43({
41
47
  }
42
48
  }));
43
49
  }
44
- const $db7b67857900028b$export$83d89fbfd8236492 = "1.5.19";
50
+ class $d7a14567b529586f$export$d0f82e3ef89b1f22 extends (0, $7QqFM$react.Component) {
51
+ constructor(props) {
52
+ super(props);
53
+ this.state = {
54
+ hasError: false
55
+ };
56
+ }
57
+ static getDerivedStateFromError() {
58
+ // Update state so the next render will show the fallback UI.
59
+ return {
60
+ hasError: true
61
+ };
62
+ }
63
+ componentDidCatch(error) {
64
+ this.props.on_error(error);
65
+ }
66
+ render() {
67
+ if (this.state.hasError)
68
+ // You can render any custom fallback UI
69
+ return $7QqFM$react.createElement("div", {
70
+ children: "Component failed"
71
+ });
72
+ return this.props.children;
73
+ }
74
+ }
75
+ async function $ecaac5ceddb08f39$export$79c79419c1ef0081({
76
+ display: display,
77
+ component_portals: component_portals,
78
+ set_portals: set_portals,
79
+ react_template: react_template
80
+ }) {
81
+ let set_react_has_ran_hooks;
82
+ let was_cleaned_up = false;
83
+ const react_has_ran_hooks = new Promise(r => set_react_has_ran_hooks = r);
84
+ const solid_container = document.createElement("div");
85
+ const owner = $7QqFM$solidjs.getOwner();
86
+ const reactProductCard = $7QqFM$reactjsxruntime.jsx(props => {
87
+ // Sneak in a hook into their product card component to know once react has finished rendering and running hooks
88
+ $7QqFM$react.useEffect(set_react_has_ran_hooks, []);
89
+ return react_template(props);
90
+ }, {
91
+ display: display
92
+ });
93
+ const reactProductCardInErrorBoundary = $7QqFM$reactjsxruntime.jsx((0, $d7a14567b529586f$export$d0f82e3ef89b1f22), {
94
+ children: reactProductCard,
95
+ on_error: error => $7QqFM$solidjs.runWithOwner(owner, () => {
96
+ if (was_cleaned_up) return; // Would infinite loop if we'd throw after we've already been cleaned up. That is because the `ErrorBoundary` won't be "registered" with the cleaned-up owner anymore so react would hear about the throw and attempt to re-render the error boundary or something which would throw again, etc.
97
+ throw new (0, $7QqFM$depictaiui.ProductCardError)(error);
98
+ })
99
+ });
100
+ const portal = $7QqFM$reactdom.createPortal(reactProductCardInErrorBoundary, solid_container);
101
+ component_portals.add(portal);
102
+ set_portals([...component_portals]);
103
+ $7QqFM$solidjs.onCleanup(() => {
104
+ was_cleaned_up = true;
105
+ // this will stop working after any await so be careful to not await before this, or you'll have to carry the owner over with getOwner and runWithOwner
106
+ component_portals.delete(portal);
107
+ // Updating i.e. the merchant will cause a setState call while rendering the DepictProvider component which is illegal because it usually infinite loops react apps. In our case it doesn't though, so we just evade detection by doing it a microtask later. See also https://github.com/facebook/react/issues/18178#issuecomment-595846312
108
+ queueMicrotask(() => set_portals([...component_portals]));
109
+ });
110
+ await react_has_ran_hooks; // After React has created elements it still takes some time to actually connect the refs and run the hooks. We don't want to replace placeholders before then.
111
+ return [solid_container];
112
+ }
113
+ function $0aaa03f81d756b85$export$bd8acc07a8bae229(props, set_portals) {
114
+ const component_portals = new Set();
115
+ return $7QqFM$depictaiui.RecommendationGrid({
116
+ get recommendations() {
117
+ return props.recommendations;
118
+ },
119
+ product_card_template: display => {
120
+ if (0, $7QqFM$solidjsweb.isServer)
121
+ // This function can't be async on the server
122
+ // @ts-ignore
123
+ return {
124
+ t: $7QqFM$reactdomserver.renderToString($7QqFM$react.createElement(() => props.productCard({
125
+ display: display
126
+ })))
127
+ };
128
+ return $ecaac5ceddb08f39$export$79c79419c1ef0081({
129
+ display: display,
130
+ react_template: $7QqFM$solidjs.untrack(() => props.productCard),
131
+ component_portals: component_portals,
132
+ set_portals: set_portals
133
+ });
134
+ },
135
+ get cols_at_size() {
136
+ return props.columnsAtSize || (0, $7QqFM$depictaiui.defaultColsAtSize);
137
+ },
138
+ get grid_spacing() {
139
+ return props.gridSpacing ?? (0, $7QqFM$depictaiui.defaultGridSpacing);
140
+ },
141
+ get view_more_button() {
142
+ const {
143
+ viewMoreButton: viewMoreButton
144
+ } = props;
145
+ return viewMoreButton ? {
146
+ text: viewMoreButton.text,
147
+ start_rows: viewMoreButton.startRows ?? 2,
148
+ rows_per_click: viewMoreButton.rowsPerClick
149
+ } : undefined;
150
+ }
151
+ });
152
+ }
153
+ const $db7b67857900028b$export$83d89fbfd8236492 = "2.0.0";
45
154
  function $41e7e5d85b5e0d49$export$9fac37a9c21c2f3b(props) {
46
155
  return props.children;
47
156
  }
@@ -65,6 +174,11 @@ function $41e7e5d85b5e0d49$export$466cdc317043f6cb() {
65
174
  children: []
66
175
  });
67
176
  }
177
+ function $41e7e5d85b5e0d49$export$82cfdc85a4d15688() {
178
+ return $7QqFM$react.createElement("div", {
179
+ children: []
180
+ });
181
+ }
68
182
  function $41e7e5d85b5e0d49$export$80e99ee6b29cadd2() {
69
183
  return $7QqFM$react.createElement("div", {
70
184
  className: "depict aligner",
@@ -84,6 +198,13 @@ function $41e7e5d85b5e0d49$export$3f37af283f8fb843(raw_react_props) {
84
198
  wrapper_type: "span"
85
199
  });
86
200
  }
201
+ function $41e7e5d85b5e0d49$export$b0a773486c1c2312(props) {
202
+ return $35dfe83eec81954c$export$4b564d7f5a1b1d43({
203
+ solid_component: (0, $0aaa03f81d756b85$export$bd8acc07a8bae229),
204
+ props: props,
205
+ wrapper_type: "section"
206
+ });
207
+ }
87
208
  function $41e7e5d85b5e0d49$export$89c6019e4baa40b1(raw_react_props) {
88
209
  const react_props = {
89
210
  ...raw_react_props,
@@ -1,26 +1,9 @@
1
- import { BaseProductListingConfig, BaseProviderConfig, BaseSearchProviderConfig, BaseCategoryProviderConfig, ModernDisplayWithPageUrl, BaseSearchPageConfig, BaseCategoryPageConfig, CategoryTitle, embedded_num_products, ImagePlaceholder as _ImagePlaceholder1, TextPlaceholder as _TextPlaceholder1, ExclusiveId, fetchDepictRecommendations } from "@depict-ai/ui/latest";
2
- import { Display, ModernDisplay } from "@depict-ai/utilishared/latest";
3
- import React, { ReactNode, PropsWithChildren, ReactElement } from "react";
4
1
  import { DPC } from "@depict-ai/dpc/latest";
2
+ import React, { PropsWithChildren, ReactNode, ReactPortal, ReactElement } from "react";
3
+ import { BaseProviderConfig, BaseSearchProviderConfig, BaseCategoryProviderConfig, ModernDisplayWithPageUrl, BaseProductListingConfig, BaseSearchPageConfig, BaseCategoryPageConfig, CategoryTitle, embedded_num_products, ImagePlaceholder as _ImagePlaceholder1, TextPlaceholder as _TextPlaceholder1, ExclusiveId, fetchDepictRecommendations } from "@depict-ai/ui/latest";
5
4
  import { Locale } from "@depict-ai/ui/locales/latest";
6
- export const version = "1.5.19";
7
- interface PLPConfig<T extends Display> extends BaseProductListingConfig {
8
- /**
9
- * The product card to use for rendering products.
10
- */
11
- productCard: DepictProductCard<T>;
12
- }
13
- /**
14
- * The Depict product card props.
15
- */
16
- export interface DepictProductCardProps<T extends Display> {
17
- /** The display data to render. */
18
- display: T | null;
19
- }
20
- /**
21
- * Depict product card to use for rendering products.
22
- */
23
- export type DepictProductCard<T extends Display> = (props: DepictProductCardProps<T>) => ReactNode;
5
+ import { Display, ModernDisplay } from "@depict-ai/utilishared/latest";
6
+ export const version = "2.0.0";
24
7
  interface UsePerformanceClientReturn {
25
8
  dpc: DPC;
26
9
  }
@@ -172,6 +155,23 @@ export function DepictProvider<InputDisplay extends Display, OutputDisplay exten
172
155
  * @returns {JSX.Element}
173
156
  */
174
157
  export const ComponentAligner: import("react").ForwardRefExoticComponent<import("react").RefAttributes<unknown>>;
158
+ interface PLPConfig<T extends Display> extends BaseProductListingConfig {
159
+ /**
160
+ * The product card to use for rendering products.
161
+ */
162
+ productCard: DepictProductCard<T>;
163
+ }
164
+ /**
165
+ * The Depict product card props.
166
+ */
167
+ export interface DepictProductCardProps<T extends Display> {
168
+ /** The display data to render. */
169
+ display: T | null;
170
+ }
171
+ /**
172
+ * Depict product card to use for rendering products.
173
+ */
174
+ export type DepictProductCard<T extends Display> = (props: DepictProductCardProps<T>) => ReactNode;
175
175
  interface SearchPageConfig<T extends Display> extends BaseSearchPageConfig, PLPConfig<T> {
176
176
  /**
177
177
  * When using multiple search instances on the same page, you need to set a unique stateKey for each one. We recommend using an incrementing number, such as "1", "2", "3", etc. To associate a modal with a SearchPage keyed component, set the same stateKey on both. If no stateKey is provided, the "default" instance will be used.
@@ -320,6 +320,49 @@ export const ImagePlaceholder: React.FC<Parameters<typeof _ImagePlaceholder1>[0]
320
320
  export const TextPlaceholder: React.FC<Parameters<typeof _TextPlaceholder1>[0] & {
321
321
  className?: string;
322
322
  }>;
323
+ interface RecommendationConfig<T extends Display> extends BaseProductListingConfig {
324
+ /**
325
+ * A promise containing the recommendations to render, see https://docs.depict.ai/api-guide/recommendations/api-client/fetching
326
+ */
327
+ recommendations: Promise<T[]>;
328
+ /**
329
+ * The product card function to use for rendering products.
330
+ */
331
+ productCard: DepictProductCard<T>;
332
+ }
333
+ interface RecommendationGridConfig<T extends Display> extends RecommendationConfig<T> {
334
+ viewMoreButton?: {
335
+ text: string;
336
+ startRows?: number;
337
+ rowsPerClick?: number;
338
+ };
339
+ }
340
+ declare function SolidRecommendationWrapper<T extends Display>(props: RecommendationGridConfig<T>, set_portals: (portals: ReactPortal[]) => void): HTMLDivElement;
341
+ interface RecommendationSliderConfig<T extends Display> extends RecommendationConfig<T> {
342
+ viewMoreButton?: {
343
+ text: string;
344
+ startRows?: number;
345
+ rowsPerClick?: number;
346
+ };
347
+ }
348
+ /**
349
+ * Renders a slider of the provided products
350
+ * @param recommendations a promise resolving to an array of displays to render
351
+ * @param productCard a function that renders a product card or a placeholder for one
352
+ * @param columnsAtSize the number of columns to show at each media breakpoint
353
+ * @param gridSpacing the spacing between the product cards
354
+ */
355
+ export function RecommendationSlider<T extends Display>(props: Parameters<typeof SolidRecommendationSliderWrapper<T>>[0]): import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
356
+ declare function SolidRecommendationSliderWrapper<T extends Display>(props: RecommendationSliderConfig<T>, set_portals: (portals: ReactPortal[]) => void): HTMLDivElement;
357
+ /**
358
+ * Renders a product grid of the provided products
359
+ * @param recommendations a promise resolving to an array of displays to render
360
+ * @param productCard a function that renders a product card or a placeholder for one
361
+ * @param columnsAtSize the number of columns to show at each media breakpoint
362
+ * @param gridSpacing the spacing between the product cards
363
+ * @param viewMoreButton optional configuration for the view more button. If unset, all products will be shown by default. Otherwise, a view more button with the given text will be shown. With the properties startRows and rowsPerClick, you can configure how many rows should be shown initially and how many rows should be added on each click.
364
+ */
365
+ export function RecommendationGrid<T extends Display>(props: Parameters<typeof SolidRecommendationWrapper<T>>[0]): import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
323
366
  /**
324
367
  * Parameters to configure the search modal.
325
368
  */