@askdialog/dialog-react 2.0.2 → 2.2.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.
package/README.md CHANGED
@@ -86,6 +86,71 @@ Standalone input component for asking questions.
86
86
  />
87
87
  ```
88
88
 
89
+ ### Storefront search
90
+
91
+ React binding of the SDK search controller (`createSearchController`): debounce, cancellation, stale-response protection, pagination and search attribution analytics all come from the SDK — these components only render and route.
92
+
93
+ ```tsx
94
+ import { Dialog } from '@askdialog/dialog-sdk';
95
+ import {
96
+ DialogSearchBar,
97
+ DialogSearchResults,
98
+ useDialogSearch,
99
+ } from '@askdialog/dialog-react';
100
+ import '@askdialog/dialog-react/style.css';
101
+
102
+ const client = new Dialog({ apiKey: 'your-api-key', locale: 'en' });
103
+
104
+ function SearchPage() {
105
+ const { controller, state } = useDialogSearch({ client });
106
+
107
+ return (
108
+ <>
109
+ <DialogSearchBar controller={controller} placeholder="Search products..." />
110
+ <DialogSearchResults controller={controller} state={state} />
111
+ </>
112
+ );
113
+ }
114
+ ```
115
+
116
+ #### useDialogSearch
117
+
118
+ Creates one search controller per hook instance and disposes it on unmount.
119
+
120
+ **Options:**
121
+ - `client` (Dialog) - Dialog SDK client instance (required)
122
+ - `surface` (SearchSurface, optional) - Where results are displayed, for analytics (default: `'search_page'`)
123
+ - `navigate` ((url, hit) => void, optional) - Router adapter called after selection attribution (e.g. `(url) => router.push(url)`). Omit it to let the cards' plain `<a href>` links navigate natively.
124
+ - `debounceMs` (number, optional) - Keystroke debounce (default: 250)
125
+ - `hitsPerPage` (number, optional) - Results per page (default: 12)
126
+
127
+ **Returns:** `{ controller, state }` — pass both to the components below. `state.status` is `idle` / `loading` / `success` / `empty` / `error`.
128
+
129
+ #### DialogSearchBar
130
+
131
+ Search input: typing runs a debounced search, submitting (Enter) searches immediately.
132
+
133
+ **Props:**
134
+ - `controller` (SearchController) - From `useDialogSearch` (required)
135
+ - `placeholder` (string, optional) - Input placeholder text
136
+ - `autoFocus` (boolean, optional) - Focus the input on mount
137
+
138
+ #### DialogSearchResults
139
+
140
+ Floating results panel overlaying the page content: portaled to `document.body` in `position: fixed`, anchored under the spot where the component is rendered (place it right after the bar), so no ancestor stacking context or `overflow: hidden` can hide it. Renders the controller states; successful searches render a scrollable list of `DialogSearchProductCard` rows plus the pagination controls. Each card links to the product page and records search attribution (viewport impressions, select on click and middle-click) automatically.
141
+
142
+ **Props:**
143
+ - `controller` (SearchController) - From `useDialogSearch` (required)
144
+ - `state` (SearchControllerState) - From `useDialogSearch` (required)
145
+
146
+ #### DialogSearchPagination
147
+
148
+ Previous/next controls with a page indicator; hidden while there is a single page. Rendered by `DialogSearchResults` — exported only for custom layouts.
149
+
150
+ **Props:**
151
+ - `controller` (SearchController) - From `useDialogSearch` (required)
152
+ - `state` (SearchControllerState) - From `useDialogSearch` (required)
153
+
89
154
  ## Theming
90
155
 
91
156
  The components use CSS variables for theming. You can customize the theme through the Dialog SDK client:
@@ -0,0 +1,10 @@
1
+ import { FC } from 'react';
2
+ import { SearchController } from '@askdialog/dialog-sdk';
3
+ interface DialogSearchBarProps {
4
+ controller: SearchController;
5
+ placeholder?: string;
6
+ autoFocus?: boolean;
7
+ submitAriaLabel?: string;
8
+ }
9
+ export declare const DialogSearchBar: FC<DialogSearchBarProps>;
10
+ export {};
@@ -0,0 +1,8 @@
1
+ import { FC } from 'react';
2
+ import { SearchController, SearchControllerState } from '@askdialog/dialog-sdk';
3
+ interface DialogSearchPaginationProps {
4
+ controller: SearchController;
5
+ state: SearchControllerState;
6
+ }
7
+ export declare const DialogSearchPagination: FC<DialogSearchPaginationProps>;
8
+ export {};
@@ -0,0 +1,9 @@
1
+ import { FC } from 'react';
2
+ import { SearchController, SearchHit } from '@askdialog/dialog-sdk';
3
+ interface DialogSearchProductCardProps {
4
+ controller: SearchController;
5
+ hit: SearchHit;
6
+ index: number;
7
+ }
8
+ export declare const DialogSearchProductCard: FC<DialogSearchProductCardProps>;
9
+ export {};
@@ -0,0 +1,8 @@
1
+ import { FC } from 'react';
2
+ import { SearchController, SearchControllerState } from '@askdialog/dialog-sdk';
3
+ interface DialogSearchResultsProps {
4
+ controller: SearchController;
5
+ state: SearchControllerState;
6
+ }
7
+ export declare const DialogSearchResults: FC<DialogSearchResultsProps>;
8
+ export {};
@@ -0,0 +1,3 @@
1
+ import { SearchPriceRange } from '@askdialog/dialog-sdk';
2
+ export declare const formatSearchPrice: (priceRange: SearchPriceRange | undefined) => string;
3
+ export declare const safeProductHref: (url: string) => string | undefined;
@@ -0,0 +1,10 @@
1
+ import { RefObject } from 'react';
2
+ export interface AnchorRect {
3
+ top: number;
4
+ left: number;
5
+ width: number;
6
+ }
7
+ export declare const useAnchorRect: (active: boolean) => {
8
+ anchorRef: RefObject<HTMLDivElement | null>;
9
+ rect: AnchorRect | undefined;
10
+ };
@@ -0,0 +1,16 @@
1
+ import { Dialog, SearchController, SearchControllerState, SearchHit, SearchSurface } from '@askdialog/dialog-sdk';
2
+ export interface UseDialogSearchOptions {
3
+ client: Dialog;
4
+ /** Where the results are displayed, for search analytics. */
5
+ surface?: SearchSurface;
6
+ /** Router adapter called after selection attribution; omit to let the cards' `<a href>` navigate natively. */
7
+ navigate?: (url: string, hit: SearchHit) => void;
8
+ debounceMs?: number;
9
+ hitsPerPage?: number;
10
+ }
11
+ export interface DialogSearch {
12
+ controller: SearchController;
13
+ state: SearchControllerState;
14
+ }
15
+ /** Options are read when the controller is created — later changes don't rebind a live controller. */
16
+ export declare const useDialogSearch: (options: UseDialogSearchOptions) => DialogSearch;
@@ -1,2 +1,7 @@
1
1
  export { DialogProductBlock } from './DialogProductBlock/DialogProductBlock';
2
2
  export { DialogInput } from './DialogProductBlock/DialogInput';
3
+ export { DialogSearchBar } from './DialogSearch/DialogSearchBar';
4
+ export { DialogSearchPagination } from './DialogSearch/DialogSearchPagination';
5
+ export { DialogSearchProductCard } from './DialogSearch/DialogSearchProductCard';
6
+ export { DialogSearchResults } from './DialogSearch/DialogSearchResults';
7
+ export { useDialogSearch, type DialogSearch, type UseDialogSearchOptions, } from './DialogSearch/useDialogSearch';
@@ -1 +1 @@
1
- .dialog-block-header-container{display:flex;flex-direction:column;align-items:flex-start;justify-content:flex-start}.dialog-block-title{color:var(--dialog-theme-title-color, #272727);font-family:var(--dialog-theme-font-family);font-size:var(--dialog-theme-title-font-size);font-style:normal;font-weight:500;line-height:20px;letter-spacing:1.3px;text-transform:uppercase}.dialog-block-description{color:var(--dialog-theme-description-color, #6c6c6c);font-family:var(--dialog-theme-font-family);font-size:var(--dialog-theme-description-font-size);font-style:normal;font-weight:500;line-height:20px}.dialog-block-suggestions-item{background-color:#f1f1f1;border:none;outline:none;padding:12px 16px;width:fit-content;cursor:pointer;display:flex;justify-content:flex-start;background-color:#fff;align-items:center;gap:8px;border:1px solid #dddce2;border-radius:24px}.dialog-block-suggestions-item:hover{transform:scale(1.01)}.dialog-block-suggestions-item-label{color:var(--dialog-theme-content-color, #575665);font-size:var(--dialog-theme-content-font-size, 14px);font-weight:500;text-align:left;flex:1}.dialog-block-suggestions-item-icon path{stroke:var(--dialog-theme-primary-color)}.dialog-block-suggestions-skeleton-item,.dialog-block-suggestions-skeleton-item:empty{display:block;width:100%;width:90%;height:18px;border-radius:18px;padding:12px 16px;background-color:#f1f1f1;animation:pulse 1.5s ease-in-out infinite}@keyframes pulse{0%{background-color:#f1f1f1}50%{background-color:#fff}to{background-color:#f1f1f1}}.dialog-block-suggestions-container{display:flex;flex-direction:column;gap:12px;width:100%}.dialog-input-wrapper{position:relative;width:100%;height:50px;max-height:50px;padding:16px 20px;border:1px solid #d9d9d9;border-radius:var(--dialog-theme-cta-border-type, 24px);background:#fff;display:flex;align-items:center;box-sizing:border-box}.dialog-input-container{display:flex;justify-items:center;align-items:center;gap:12px;width:100%;height:100%}.dialog-ask-anything-input-ai-input{outline:unset;box-shadow:unset;border:unset;width:100%;font-size:16px;background:transparent;padding-right:35px}.dialog-input-submit{width:40px;height:40px;border-radius:100%;display:flex;align-items:center;justify-content:center;background-color:var(--dialog-theme-primary-color);position:absolute;cursor:pointer;top:calc(50% - 20px);right:4px;border:unset}.dialog-input-submit:disabled{opacity:.5}.dialog-block-container{position:relative;display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start;padding:24px 0;width:fit-content;gap:24px}.dialog-block-container>*{box-sizing:border-box}
1
+ .dialog-block-header-container{display:flex;flex-direction:column;align-items:flex-start;justify-content:flex-start}.dialog-block-title{color:var(--dialog-theme-title-color, #272727);font-family:var(--dialog-theme-font-family);font-size:var(--dialog-theme-title-font-size);font-style:normal;font-weight:500;line-height:20px;letter-spacing:1.3px;text-transform:uppercase}.dialog-block-description{color:var(--dialog-theme-description-color, #6c6c6c);font-family:var(--dialog-theme-font-family);font-size:var(--dialog-theme-description-font-size);font-style:normal;font-weight:500;line-height:20px}.dialog-block-suggestions-item{background-color:#f1f1f1;border:none;outline:none;padding:12px 16px;width:fit-content;cursor:pointer;display:flex;justify-content:flex-start;background-color:#fff;align-items:center;gap:8px;border:1px solid #dddce2;border-radius:24px}.dialog-block-suggestions-item:hover{transform:scale(1.01)}.dialog-block-suggestions-item-label{color:var(--dialog-theme-content-color, #575665);font-size:var(--dialog-theme-content-font-size, 14px);font-weight:500;text-align:start;flex:1}.dialog-block-suggestions-item-icon path{stroke:var(--dialog-theme-primary-color)}.dialog-block-suggestions-skeleton-item,.dialog-block-suggestions-skeleton-item:empty{display:block;width:100%;width:90%;height:18px;border-radius:18px;padding:12px 16px;background-color:#f1f1f1;animation:pulse 1.5s ease-in-out infinite}@keyframes pulse{0%{background-color:#f1f1f1}50%{background-color:#fff}to{background-color:#f1f1f1}}.dialog-block-suggestions-container{display:flex;flex-direction:column;gap:12px;width:100%}.dialog-input-wrapper{position:relative;width:100%;height:50px;max-height:50px;padding:16px 20px;border:1px solid #d9d9d9;border-radius:var(--dialog-theme-cta-border-type, 24px);background:#fff;display:flex;align-items:center;box-sizing:border-box}.dialog-input-container{display:flex;justify-items:center;align-items:center;gap:12px;width:100%;height:100%}.dialog-ask-anything-input-ai-input{outline:unset;box-shadow:unset;border:unset;width:100%;font-size:16px;background:transparent;padding-inline-end:35px}.dialog-input-submit{width:40px;height:40px;border-radius:100%;display:flex;align-items:center;justify-content:center;background-color:var(--dialog-theme-primary-color);position:absolute;cursor:pointer;top:calc(50% - 20px);inset-inline-end:4px;border:unset}.dialog-input-submit:disabled{opacity:.5}.dialog-block-container{position:relative;display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start;padding:24px 0;width:fit-content;gap:24px}.dialog-block-container>*{box-sizing:border-box}.dialog-search-bar{box-sizing:border-box;display:flex;align-items:center;gap:8px;width:100%;margin:0;padding:10px 10px 10px 14px;background:#fffc;backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);border:1px solid rgba(0,0,0,.05);border-radius:24px;box-shadow:0 6px 20px -6px #0000001a}.dialog-search-bar-field{display:flex;flex:1 0 0;min-width:0;align-items:center;gap:6px;padding:2px 0}.dialog-search-bar-icon{display:inline-flex;flex-shrink:0;color:#737373}.dialog-search-bar-input{flex:1 0 0;min-width:0;margin:0;padding:0;border:none;outline:none;background:transparent;font-family:Inter,sans-serif;font-weight:500;font-size:16px;line-height:24px;color:#171717;text-overflow:ellipsis;box-shadow:none;-moz-appearance:none;appearance:none;-webkit-appearance:none}.dialog-search-bar-input::placeholder{color:#a3a3a3;opacity:1}.dialog-search-bar-input:focus,.dialog-search-bar-input:focus-visible{outline:none;box-shadow:none;border:none}.dialog-search-bar-submit{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:28px;height:28px;padding:6px;border:none;border-radius:9999px;background:#171717;color:#fff;box-shadow:0 1px 1px #1717170d;cursor:pointer}.dialog-search-bar-submit:focus-visible{outline:2px solid #171717;outline-offset:2px}.dialog-search-pagination{display:flex;align-items:center;justify-content:center;gap:12px;margin-top:4px;font-family:Inter,sans-serif;font-weight:500;font-size:12px;line-height:16px;color:#737373}.dialog-search-pagination button{margin:0;padding:6px 14px;border:1px solid rgba(0,0,0,.05);border-radius:9999px;background:#fff;font:inherit;color:inherit;cursor:pointer;transition:background-color .12s ease}.dialog-search-pagination button:hover:not(:disabled){background-color:#fafafa}.dialog-search-pagination button:disabled{opacity:.4;cursor:default}.dialog-search-card{width:100%}.dialog-search-card-body{display:flex;align-items:center;gap:8px;border-radius:12px;color:inherit;text-decoration:none}a.dialog-search-card-body:hover{background:#00000008}.dialog-search-card-image{position:relative;flex-shrink:0;width:64px;height:64px;border-radius:12px;overflow:hidden;background:#f2f2f2}.dialog-search-card-image:after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;border-radius:12px;background:#00000008;pointer-events:none}.dialog-search-card-image img{display:block;width:100%;height:100%;object-fit:cover}.dialog-search-card-info{display:flex;flex:1 1 0;min-width:0;flex-direction:column;gap:4px}.dialog-search-card-title{margin:0;font-family:Inter,sans-serif;font-weight:500;font-size:13px;line-height:20px;color:#171717;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dialog-search-card-price{margin:0;font-family:Inter,sans-serif;font-weight:500;font-size:12px;line-height:16px;color:#737373}.dialog-search-panel{position:fixed;z-index:9999;box-sizing:border-box;display:flex;flex-direction:column;gap:8px;margin:0;padding:10px 14px;background:#ffffffe6;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid rgba(0,0,0,.05);border-radius:24px;box-shadow:0 6px 20px -6px #0000001a}.dialog-search-status{margin:0;font-family:Inter,sans-serif;font-weight:500;font-size:14px;line-height:20px;color:#a3a3a3}.dialog-search-status-error{color:#b3261e}.dialog-search-error{display:flex;flex-direction:column;align-items:flex-start;gap:8px}.dialog-search-retry{margin:0;padding:6px 14px;border:1px solid rgba(0,0,0,.05);border-radius:9999px;background:#fff;font-family:Inter,sans-serif;font-weight:500;font-size:13px;line-height:20px;color:#737373;cursor:pointer;transition:background-color .12s ease}.dialog-search-retry:hover{background-color:#fafafa}.dialog-search-results{display:flex;flex-direction:column;gap:12px;margin:0;padding:0;list-style:none;max-height:480px;min-height:0;overflow-y:auto}
@@ -1,12 +1,14 @@
1
- import { jsxs as d, jsx as t, Fragment as C } from "react/jsx-runtime";
2
- import { useRef as L, useState as m, useEffect as y, useMemo as k } from "react";
3
- const v = ({
1
+ import { jsxs as h, jsx as t, Fragment as b } from "react/jsx-runtime";
2
+ import { useRef as f, useState as v, useEffect as y, useMemo as k, useLayoutEffect as R, useCallback as w, useSyncExternalStore as E } from "react";
3
+ import { registerDialogInstallation as P, addAuditCapability as x, resolveTextDirection as A, SearchStatus as p, DialogSearchError as D, createSearchController as M } from "@askdialog/dialog-sdk";
4
+ import { createPortal as I } from "react-dom";
5
+ const B = ({
4
6
  title: e = "Your expert",
5
- description: n = "A question about this product?"
6
- }) => /* @__PURE__ */ d("div", { className: "dialog-block-header-container", children: [
7
+ description: s = "A question about this product?"
8
+ }) => /* @__PURE__ */ h("div", { className: "dialog-block-header-container", children: [
7
9
  /* @__PURE__ */ t("div", { className: "dialog-block-title", children: e }),
8
- /* @__PURE__ */ t("div", { className: "dialog-block-description", children: n })
9
- ] }), w = ({ color: e = "#181825" }) => /* @__PURE__ */ d(
10
+ /* @__PURE__ */ t("div", { className: "dialog-block-description", children: s })
11
+ ] }), K = ({ color: e = "#181825" }) => /* @__PURE__ */ h(
10
12
  "svg",
11
13
  {
12
14
  width: "20",
@@ -15,7 +17,7 @@ const v = ({
15
17
  fill: "none",
16
18
  xmlns: "http://www.w3.org/2000/svg",
17
19
  children: [
18
- /* @__PURE__ */ d("g", { clipPath: "url(#clip0_466_934)", children: [
20
+ /* @__PURE__ */ h("g", { clipPath: "url(#clip0_466_934)", children: [
19
21
  /* @__PURE__ */ t(
20
22
  "path",
21
23
  {
@@ -40,55 +42,55 @@ const v = ({
40
42
  /* @__PURE__ */ t("defs", { children: /* @__PURE__ */ t("clipPath", { id: "clip0_466_934", children: /* @__PURE__ */ t("rect", { width: "20", height: "20", fill: "white" }) }) })
41
43
  ]
42
44
  }
43
- ), S = ({
45
+ ), $ = ({
44
46
  client: e,
45
- questions: n,
46
- productId: l,
47
- productTitle: s,
48
- selectedVariantId: a
47
+ questions: s,
48
+ productId: r,
49
+ productTitle: n,
50
+ selectedVariantId: o
49
51
  }) => {
50
- const i = (r) => {
52
+ const c = (l) => {
51
53
  e.sendProductMessage({
52
- productId: l,
53
- productTitle: s,
54
- selectedVariantId: a,
55
- question: r,
54
+ productId: r,
55
+ productTitle: n,
56
+ selectedVariantId: o,
57
+ question: l,
56
58
  fromQuestionSuggestion: !0
57
59
  });
58
60
  };
59
- return /* @__PURE__ */ t(C, { children: n.map((r) => /* @__PURE__ */ d(
61
+ return /* @__PURE__ */ t(b, { children: s.map((l) => /* @__PURE__ */ h(
60
62
  "button",
61
63
  {
62
64
  className: "dialog-block-suggestions-item",
63
- onClick: () => i(r.question),
65
+ onClick: () => c(l.question),
64
66
  children: [
65
- /* @__PURE__ */ t(w, { color: e.theme.primaryColor }),
66
- /* @__PURE__ */ t("span", { className: "dialog-block-suggestions-item-label", children: r.question })
67
+ /* @__PURE__ */ t(K, { color: e.theme.primaryColor }),
68
+ /* @__PURE__ */ t("span", { className: "dialog-block-suggestions-item-label", children: l.question })
67
69
  ]
68
70
  },
69
- r.question
71
+ l.question
70
72
  )) });
71
- }, N = () => /* @__PURE__ */ d(C, { children: [
73
+ }, _ = () => /* @__PURE__ */ h(b, { children: [
72
74
  /* @__PURE__ */ t("div", { className: "dialog-block-suggestions-skeleton-item" }),
73
75
  /* @__PURE__ */ t("div", { className: "dialog-block-suggestions-skeleton-item" }),
74
76
  /* @__PURE__ */ t("div", { className: "dialog-block-suggestions-skeleton-item" })
75
- ] }), P = ({
77
+ ] }), T = ({
76
78
  client: e,
77
- questions: n,
78
- isLoading: l,
79
- productId: s,
80
- productTitle: a,
81
- selectedVariantId: i
82
- }) => /* @__PURE__ */ t("div", { className: "dialog-block-suggestions-container", children: l || !n ? /* @__PURE__ */ t(N, {}) : /* @__PURE__ */ t(
83
- S,
79
+ questions: s,
80
+ isLoading: r,
81
+ productId: n,
82
+ productTitle: o,
83
+ selectedVariantId: c
84
+ }) => /* @__PURE__ */ t("div", { className: "dialog-block-suggestions-container", children: r || !s ? /* @__PURE__ */ t(_, {}) : /* @__PURE__ */ t(
85
+ $,
84
86
  {
85
87
  client: e,
86
- questions: n,
87
- productId: s,
88
- productTitle: a,
89
- selectedVariantId: i
88
+ questions: s,
89
+ productId: n,
90
+ productTitle: o,
91
+ selectedVariantId: c
90
92
  }
91
- ) }), x = ({ color: e = "#ffffff" }) => /* @__PURE__ */ t(
93
+ ) }), j = ({ color: e = "#ffffff" }) => /* @__PURE__ */ t(
92
94
  "svg",
93
95
  {
94
96
  width: "20",
@@ -107,38 +109,38 @@ const v = ({
107
109
  }
108
110
  )
109
111
  }
110
- ), j = ({
112
+ ), V = ({
111
113
  client: e,
112
- placeholder: n = "Ask anything...",
113
- productId: l,
114
- productTitle: s,
115
- selectedVariantId: a
114
+ placeholder: s = "Ask anything...",
115
+ productId: r,
116
+ productTitle: n,
117
+ selectedVariantId: o
116
118
  }) => {
117
- const i = L(null), [r, o] = m(""), u = () => {
118
- var c;
119
- (c = i.current) == null || c.focus();
120
- }, g = () => {
121
- const c = r;
122
- c.trim() && (e.sendProductMessage({
123
- productId: l,
124
- productTitle: s,
125
- selectedVariantId: a,
126
- question: c,
119
+ const c = f(null), [l, a] = v(""), i = () => {
120
+ var d;
121
+ (d = c.current) == null || d.focus();
122
+ }, u = () => {
123
+ const d = l;
124
+ d.trim() && (e.sendProductMessage({
125
+ productId: r,
126
+ productTitle: n,
127
+ selectedVariantId: o,
128
+ question: d,
127
129
  fromQuestionSuggestion: !0
128
- }), o(""));
130
+ }), a(""));
129
131
  };
130
- return /* @__PURE__ */ d("div", { className: "dialog-input-wrapper", onClick: u, children: [
132
+ return /* @__PURE__ */ h("div", { className: "dialog-input-wrapper", onClick: i, children: [
131
133
  /* @__PURE__ */ t(
132
134
  "input",
133
135
  {
134
136
  id: "dialog-ask-anything-input-ai-input",
135
- ref: i,
136
- value: r,
137
- onChange: (c) => o(c.target.value),
137
+ ref: c,
138
+ value: l,
139
+ onChange: (d) => a(d.target.value),
138
140
  className: "dialog-ask-anything-input-ai-input",
139
- placeholder: n,
140
- onKeyDown: (c) => {
141
- c.key === "Enter" && g();
141
+ placeholder: s,
142
+ onKeyDown: (d) => {
143
+ d.key === "Enter" && u();
142
144
  }
143
145
  }
144
146
  ),
@@ -147,107 +149,436 @@ const v = ({
147
149
  {
148
150
  id: "send-message-button-ai-input",
149
151
  className: "dialog-input-submit",
150
- disabled: !r.trim(),
151
- onClick: g,
152
- children: /* @__PURE__ */ t(x, { color: e.theme.ctaTextColor })
152
+ disabled: !l.trim(),
153
+ onClick: u,
154
+ children: /* @__PURE__ */ t(j, { color: e.theme.ctaTextColor })
153
155
  }
154
156
  )
155
157
  ] });
156
- }, b = (e) => e.replace(/([A-Z])/g, "-$1").toLowerCase(), B = (e) => {
158
+ }, N = (e) => e.replace(/([A-Z])/g, "-$1").toLowerCase(), F = (e) => {
157
159
  if (!e) return;
158
- const n = document.body;
159
- Object.keys(e).forEach((l) => {
160
- const s = l, a = b(l);
161
- if (e[s] !== void 0) {
162
- if (typeof e[s] == "object") {
163
- Object.keys(e[s]).forEach(
164
- (i) => {
165
- var o;
166
- const r = i;
167
- if (r !== void 0) {
168
- const u = b(i), g = e[s];
169
- n.style.setProperty(
170
- `--dialog-theme-${a}-${u}`,
171
- (o = g[r]) == null ? void 0 : o.toString()
160
+ const s = document.body;
161
+ Object.keys(e).forEach((r) => {
162
+ const n = r, o = N(r);
163
+ if (e[n] !== void 0) {
164
+ if (typeof e[n] == "object") {
165
+ Object.keys(e[n]).forEach(
166
+ (c) => {
167
+ var a;
168
+ const l = c;
169
+ if (l !== void 0) {
170
+ const i = N(c), u = e[n];
171
+ s.style.setProperty(
172
+ `--dialog-theme-${o}-${i}`,
173
+ (a = u[l]) == null ? void 0 : a.toString()
172
174
  );
173
175
  }
174
176
  }
175
177
  );
176
178
  return;
177
179
  }
178
- if (s === "ctaBorderType") {
179
- const i = e[s] === "rounded" ? "24px" : "0";
180
- n.style.setProperty(`--dialog-theme-${a}`, i);
180
+ if (n === "ctaBorderType") {
181
+ const c = e[n] === "rounded" ? "24px" : "0";
182
+ s.style.setProperty(`--dialog-theme-${o}`, c);
181
183
  return;
182
184
  }
183
- n.style.setProperty(
184
- `--dialog-theme-${a}`,
185
- e[s].toString()
185
+ s.style.setProperty(
186
+ `--dialog-theme-${o}`,
187
+ e[n].toString()
186
188
  );
187
189
  }
188
190
  });
189
- }, M = ({ theme: e, children: n }) => (y(() => {
190
- e && B(e);
191
- }, [e]), /* @__PURE__ */ t(C, { children: n })), $ = ({
191
+ }, H = ({ theme: e, children: s }) => (y(() => {
192
+ e && F(e);
193
+ }, [e]), /* @__PURE__ */ t(b, { children: s })), ae = ({
192
194
  client: e,
193
- productId: n,
194
- productTitle: l,
195
- selectedVariantId: s,
196
- enableInput: a = !0
195
+ productId: s,
196
+ productTitle: r,
197
+ selectedVariantId: n,
198
+ enableInput: o = !0
197
199
  }) => {
198
- const [i, r] = m(!0), [o, u] = m(
200
+ const [c, l] = v(!0), [a, i] = v(
199
201
  void 0
202
+ );
203
+ y(() => {
204
+ P({
205
+ method: "react",
206
+ version: "2.2.0"
207
+ }), x("pdp-block");
208
+ }, []);
209
+ const u = k(
210
+ () => c ? "" : a == null ? void 0 : a.assistantName,
211
+ [a, c]
200
212
  ), g = k(
201
- () => i ? "" : o == null ? void 0 : o.assistantName,
202
- [o, i]
203
- ), f = k(
204
- () => i ? "" : o == null ? void 0 : o.description,
205
- [o, i]
206
- ), c = k(
207
- () => i ? "" : o == null ? void 0 : o.inputPlaceholder,
208
- [o, i]
213
+ () => c ? "" : a == null ? void 0 : a.description,
214
+ [a, c]
215
+ ), d = k(
216
+ () => c ? "" : a == null ? void 0 : a.inputPlaceholder,
217
+ [a, c]
218
+ ), C = k(
219
+ () => {
220
+ var m;
221
+ return A((m = e.getLocalizationInformations()) == null ? void 0 : m.languageCode);
222
+ },
223
+ [e]
209
224
  );
210
225
  return y(() => {
211
- let h = !0;
226
+ let m = !0;
212
227
  return (async () => {
213
- r(!0), u(void 0);
228
+ l(!0), i(void 0);
214
229
  try {
215
- const p = await e.getSuggestions(n);
216
- h && u(p);
217
- } catch (p) {
218
- console.error("error", p);
230
+ const S = await e.getSuggestions(s);
231
+ m && i(S);
232
+ } catch (S) {
233
+ console.error("error", S);
219
234
  } finally {
220
- h && r(!1);
235
+ m && l(!1);
221
236
  }
222
237
  })(), () => {
223
- h = !1;
238
+ m = !1;
224
239
  };
225
- }, [e, n]), /* @__PURE__ */ t(M, { theme: e.theme, children: /* @__PURE__ */ d("div", { id: "dialog-instant", className: "dialog-block-container", children: [
226
- /* @__PURE__ */ t(v, { title: g, description: f }),
240
+ }, [e, s]), /* @__PURE__ */ t(H, { theme: e.theme, children: /* @__PURE__ */ h(
241
+ "div",
242
+ {
243
+ id: "dialog-instant",
244
+ className: "dialog-block-container",
245
+ dir: C,
246
+ children: [
247
+ /* @__PURE__ */ t(B, { title: u, description: g }),
248
+ /* @__PURE__ */ t(
249
+ T,
250
+ {
251
+ client: e,
252
+ questions: a == null ? void 0 : a.questions,
253
+ isLoading: c,
254
+ productId: s,
255
+ productTitle: r,
256
+ selectedVariantId: n
257
+ }
258
+ ),
259
+ o && /* @__PURE__ */ t(
260
+ V,
261
+ {
262
+ client: e,
263
+ placeholder: d,
264
+ productId: s,
265
+ productTitle: r,
266
+ selectedVariantId: n
267
+ }
268
+ )
269
+ ]
270
+ }
271
+ ) });
272
+ }, O = () => /* @__PURE__ */ t(
273
+ "svg",
274
+ {
275
+ width: 16,
276
+ height: 16,
277
+ viewBox: "0 0 16 16",
278
+ fill: "none",
279
+ xmlns: "http://www.w3.org/2000/svg",
280
+ "aria-hidden": "true",
281
+ children: /* @__PURE__ */ t(
282
+ "path",
283
+ {
284
+ d: "M8 13V3M8 3L3 8M8 3L13 8",
285
+ stroke: "currentColor",
286
+ strokeWidth: "1.5",
287
+ strokeLinecap: "round",
288
+ strokeLinejoin: "round"
289
+ }
290
+ )
291
+ }
292
+ ), q = "M5.3217 0.588255C5.63241 -0.196084 6.36759 -0.196085 6.6783 0.588254C6.98901 1.37259 7.68193 2.82807 8.42693 3.57307C9.17193 4.31807 10.6274 5.01099 11.4117 5.3217C12.1961 5.63241 12.1961 6.36759 11.4117 6.6783C10.6274 6.98901 9.17193 7.68193 8.42693 8.42693C7.68193 9.17193 6.98901 10.6274 6.6783 11.4117C6.36759 12.1961 5.63241 12.1961 5.3217 11.4117C5.01099 10.6274 4.31807 9.17193 3.57307 8.42693C2.82808 7.68193 1.37259 6.98901 0.588255 6.6783C-0.196084 6.36759 -0.196085 5.63241 0.588254 5.3217C1.37259 5.01099 2.82807 4.31807 3.57307 3.57307C4.31807 2.82808 5.01099 1.37259 5.3217 0.588255Z", Q = ({
293
+ color: e = "currentColor"
294
+ }) => /* @__PURE__ */ t(
295
+ "svg",
296
+ {
297
+ width: 16,
298
+ height: 16,
299
+ viewBox: "0 0 12 12",
300
+ fill: "none",
301
+ xmlns: "http://www.w3.org/2000/svg",
302
+ "aria-hidden": "true",
303
+ children: /* @__PURE__ */ t("path", { d: q, fill: e })
304
+ }
305
+ ), ie = ({
306
+ controller: e,
307
+ placeholder: s = "Search products...",
308
+ autoFocus: r = !1,
309
+ submitAriaLabel: n = "Search"
310
+ }) => {
311
+ const [o, c] = v("");
312
+ return /* @__PURE__ */ h("form", { className: "dialog-search-bar", role: "search", onSubmit: (a) => {
313
+ a.preventDefault(), e.submit(o);
314
+ }, children: [
315
+ /* @__PURE__ */ h("div", { className: "dialog-search-bar-field", children: [
316
+ /* @__PURE__ */ t("span", { className: "dialog-search-bar-icon", children: /* @__PURE__ */ t(Q, {}) }),
317
+ /* @__PURE__ */ t(
318
+ "input",
319
+ {
320
+ type: "text",
321
+ className: "dialog-search-bar-input",
322
+ value: o,
323
+ "aria-label": s,
324
+ placeholder: s,
325
+ autoFocus: r,
326
+ onChange: (a) => {
327
+ c(a.target.value), e.setQuery(a.target.value);
328
+ }
329
+ }
330
+ )
331
+ ] }),
227
332
  /* @__PURE__ */ t(
228
- P,
333
+ "button",
229
334
  {
230
- client: e,
231
- questions: o == null ? void 0 : o.questions,
232
- isLoading: i,
233
- productId: n,
234
- productTitle: l,
235
- selectedVariantId: s
335
+ type: "submit",
336
+ className: "dialog-search-bar-submit",
337
+ "aria-label": n,
338
+ children: /* @__PURE__ */ t(O, {})
339
+ }
340
+ )
341
+ ] });
342
+ }, U = ({
343
+ controller: e,
344
+ state: s
345
+ }) => {
346
+ const r = s.response;
347
+ return r === void 0 || r.nbPages <= 1 ? null : /* @__PURE__ */ h("nav", { "aria-label": "Search results pages", className: "dialog-search-pagination", children: [
348
+ /* @__PURE__ */ t(
349
+ "button",
350
+ {
351
+ type: "button",
352
+ disabled: r.page === 0,
353
+ onClick: () => e.setPage(r.page - 1),
354
+ children: "Previous"
236
355
  }
237
356
  ),
238
- a && /* @__PURE__ */ t(
239
- j,
357
+ /* @__PURE__ */ h("span", { children: [
358
+ "Page ",
359
+ r.page + 1,
360
+ " / ",
361
+ r.nbPages
362
+ ] }),
363
+ /* @__PURE__ */ t(
364
+ "button",
240
365
  {
241
- client: e,
242
- placeholder: c,
243
- productId: n,
244
- productTitle: l,
245
- selectedVariantId: s
366
+ type: "button",
367
+ disabled: r.page >= r.nbPages - 1,
368
+ onClick: () => e.setPage(r.page + 1),
369
+ children: "Next"
246
370
  }
247
371
  )
248
- ] }) });
372
+ ] });
373
+ }, W = (e) => {
374
+ if (e === void 0)
375
+ return "";
376
+ const { min: s, max: r } = e, n = ({ amount: o, currencyCode: c }) => new Intl.NumberFormat(void 0, {
377
+ style: "currency",
378
+ currency: c
379
+ }).format(Number(o));
380
+ try {
381
+ return s.amount === r.amount ? n(s) : `${n(s)} – ${n(r)}`;
382
+ } catch {
383
+ return "";
384
+ }
385
+ }, z = (e) => {
386
+ try {
387
+ const { protocol: s } = new URL(e, window.location.href);
388
+ return s === "http:" || s === "https:" ? e : void 0;
389
+ } catch {
390
+ return;
391
+ }
392
+ }, Z = ({
393
+ controller: e,
394
+ hit: s,
395
+ index: r
396
+ }) => {
397
+ const n = f(null);
398
+ y(() => {
399
+ n.current !== null && e.observeResult(n.current, r);
400
+ }, [e, s, r]);
401
+ const o = (d) => {
402
+ const C = d.metaKey || d.ctrlKey || d.shiftKey || d.altKey;
403
+ e.selectResult(r, { navigate: !C }) && d.preventDefault();
404
+ }, c = (d) => {
405
+ d.button === 1 && e.selectResult(r, { navigate: !1 });
406
+ }, { product: l } = s, a = l.title ?? l.id, i = W(l.priceRange), u = l.url === void 0 ? void 0 : z(l.url), g = /* @__PURE__ */ h(b, { children: [
407
+ /* @__PURE__ */ t("div", { className: "dialog-search-card-image", children: l.imageUrl !== void 0 && /* @__PURE__ */ t("img", { src: l.imageUrl, alt: a, loading: "lazy" }) }),
408
+ /* @__PURE__ */ h("div", { className: "dialog-search-card-info", children: [
409
+ /* @__PURE__ */ t("p", { className: "dialog-search-card-title", children: a }),
410
+ i !== "" && /* @__PURE__ */ t("p", { className: "dialog-search-card-price", children: i })
411
+ ] })
412
+ ] });
413
+ return /* @__PURE__ */ t("li", { ref: n, className: "dialog-search-card", children: u === void 0 ? /* @__PURE__ */ t("div", { className: "dialog-search-card-body", children: g }) : /* @__PURE__ */ t(
414
+ "a",
415
+ {
416
+ className: "dialog-search-card-body",
417
+ href: u,
418
+ onClick: o,
419
+ onAuxClick: c,
420
+ children: g
421
+ }
422
+ ) });
423
+ }, G = (e) => {
424
+ const s = f(null), [r, n] = v(void 0);
425
+ return R(() => {
426
+ if (!e)
427
+ return;
428
+ const o = () => {
429
+ const c = s.current;
430
+ if (c === null)
431
+ return;
432
+ const { top: l, left: a, width: i } = c.getBoundingClientRect();
433
+ n(
434
+ (u) => u !== void 0 && u.top === l && u.left === a && u.width === i ? u : { top: l, left: a, width: i }
435
+ );
436
+ };
437
+ return o(), window.addEventListener("scroll", o, !0), window.addEventListener("resize", o), () => {
438
+ window.removeEventListener("scroll", o, !0), window.removeEventListener("resize", o);
439
+ };
440
+ }, [e]), { anchorRef: s, rect: r };
441
+ }, L = 8, X = 16, Y = (e) => e instanceof D ? `Search failed (${e.status}${e.code ? ` ${e.code}` : ""}): ${e.message}` : "Search failed: network error. Check your connection and try again.", J = (e, s) => {
442
+ const r = s.response;
443
+ switch (s.status) {
444
+ case p.LOADING:
445
+ return /* @__PURE__ */ h("p", { role: "status", className: "dialog-search-status", children: [
446
+ "Searching “",
447
+ s.query,
448
+ "”…"
449
+ ] });
450
+ case p.ERROR:
451
+ return /* @__PURE__ */ h("div", { className: "dialog-search-error", children: [
452
+ /* @__PURE__ */ t(
453
+ "p",
454
+ {
455
+ role: "alert",
456
+ className: "dialog-search-status dialog-search-status-error",
457
+ children: Y(s.error)
458
+ }
459
+ ),
460
+ /* @__PURE__ */ t(
461
+ "button",
462
+ {
463
+ type: "button",
464
+ className: "dialog-search-retry",
465
+ onClick: () => e.retry(),
466
+ children: "Retry"
467
+ }
468
+ )
469
+ ] });
470
+ case p.EMPTY:
471
+ return /* @__PURE__ */ h("p", { role: "status", className: "dialog-search-status", children: [
472
+ "No products match “",
473
+ r == null ? void 0 : r.query,
474
+ "”."
475
+ ] });
476
+ case p.SUCCESS:
477
+ return r === void 0 ? null : /* @__PURE__ */ h(b, { children: [
478
+ /* @__PURE__ */ h("p", { role: "status", className: "dialog-search-status", children: [
479
+ r.nbHits,
480
+ " result",
481
+ r.nbHits > 1 ? "s" : ""
482
+ ] }),
483
+ /* @__PURE__ */ t("ul", { className: "dialog-search-results", children: r.hits.map((n, o) => /* @__PURE__ */ t(
484
+ Z,
485
+ {
486
+ controller: e,
487
+ hit: n,
488
+ index: o
489
+ },
490
+ n.id
491
+ )) }),
492
+ /* @__PURE__ */ t(U, { controller: e, state: s })
493
+ ] });
494
+ default:
495
+ return null;
496
+ }
497
+ }, ce = ({
498
+ controller: e,
499
+ state: s
500
+ }) => {
501
+ const r = s.status !== p.IDLE, { anchorRef: n, rect: o } = G(r);
502
+ return /* @__PURE__ */ h(b, { children: [
503
+ /* @__PURE__ */ t("div", { ref: n }),
504
+ r && o !== void 0 && I(
505
+ /* @__PURE__ */ t(
506
+ "div",
507
+ {
508
+ className: "dialog-search-panel",
509
+ style: {
510
+ top: o.top + L,
511
+ left: o.left,
512
+ width: o.width,
513
+ maxHeight: `calc(100vh - ${o.top + L + X}px)`
514
+ },
515
+ children: J(e, s)
516
+ }
517
+ ),
518
+ document.body
519
+ )
520
+ ] });
521
+ }, ee = {
522
+ status: p.IDLE,
523
+ query: "",
524
+ page: 0
525
+ }, le = (e) => {
526
+ const s = f(e);
527
+ s.current = e;
528
+ const r = f(void 0), n = w(() => {
529
+ if (r.current === void 0) {
530
+ const { client: i, surface: u = "search_page", ...g } = s.current;
531
+ r.current = M({
532
+ search: (d, C) => i.search(d, C),
533
+ analytics: {
534
+ surface: u,
535
+ trackViewSearchResults: (d) => i.trackViewSearchResults(d),
536
+ trackSelectSearchResult: (d) => i.trackSelectSearchResult(d)
537
+ },
538
+ ...g
539
+ });
540
+ }
541
+ return r.current;
542
+ }, []), o = f(void 0);
543
+ o.current ?? (o.current = {
544
+ setQuery: (i) => n().setQuery(i),
545
+ submit: (i) => n().submit(i),
546
+ setPage: (i) => n().setPage(i),
547
+ retry: () => n().retry(),
548
+ observeResult: (i, u) => n().observeResult(i, u),
549
+ selectResult: (i, u) => n().selectResult(i, u),
550
+ subscribe: (i) => n().subscribe(i),
551
+ getState: () => n().getState(),
552
+ dispose: () => n().dispose()
553
+ }), y(() => {
554
+ P({
555
+ method: "react",
556
+ version: "2.2.0"
557
+ });
558
+ const i = n();
559
+ return () => {
560
+ i.dispose(), r.current === i && (r.current = void 0);
561
+ };
562
+ }, [n]);
563
+ const c = w(
564
+ (i) => n().subscribe(i),
565
+ [n]
566
+ ), l = w(
567
+ () => n().getState(),
568
+ [n]
569
+ ), a = E(
570
+ c,
571
+ l,
572
+ () => ee
573
+ );
574
+ return { controller: o.current, state: a };
249
575
  };
250
576
  export {
251
- j as DialogInput,
252
- $ as DialogProductBlock
577
+ V as DialogInput,
578
+ ae as DialogProductBlock,
579
+ ie as DialogSearchBar,
580
+ U as DialogSearchPagination,
581
+ Z as DialogSearchProductCard,
582
+ ce as DialogSearchResults,
583
+ le as useDialogSearch
253
584
  };
@@ -1 +1 @@
1
- (function(d,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],e):(d=typeof globalThis<"u"?globalThis:d||self,e(d["dialog-react"]={},d["react/jsx-runtime"],d.React))})(this,(function(d,e,g){"use strict";const y=({title:o="Your expert",description:t="A question about this product?"})=>e.jsxs("div",{className:"dialog-block-header-container",children:[e.jsx("div",{className:"dialog-block-title",children:o}),e.jsx("div",{className:"dialog-block-description",children:t})]}),L=({color:o="#181825"})=>e.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[e.jsxs("g",{clipPath:"url(#clip0_466_934)",children:[e.jsx("path",{d:"M5.41675 10.8333L6.07046 12.1408C6.2917 12.5832 6.40232 12.8045 6.55011 12.9962C6.68124 13.1663 6.83375 13.3188 7.00388 13.45C7.19559 13.5977 7.41684 13.7084 7.85932 13.9296L9.16675 14.5833L7.85932 15.237C7.41684 15.4583 7.19559 15.5689 7.00388 15.7167C6.83375 15.8478 6.68124 16.0003 6.55011 16.1704C6.40232 16.3622 6.2917 16.5834 6.07046 17.0259L5.41675 18.3333L4.76303 17.0259C4.54179 16.5834 4.43117 16.3622 4.28339 16.1704C4.15225 16.0003 3.99974 15.8478 3.82962 15.7167C3.6379 15.5689 3.41666 15.4583 2.97418 15.237L1.66675 14.5833L2.97418 13.9296C3.41666 13.7084 3.6379 13.5977 3.82962 13.45C3.99974 13.3188 4.15225 13.1663 4.28339 12.9962C4.43117 12.8045 4.54179 12.5832 4.76303 12.1408L5.41675 10.8333Z",stroke:o,strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"}),e.jsx("path",{d:"M12.5001 1.66666L13.4823 4.22034C13.7173 4.83136 13.8348 5.13688 14.0175 5.39386C14.1795 5.62162 14.3785 5.82061 14.6062 5.98256C14.8632 6.16529 15.1687 6.2828 15.7797 6.5178L18.3334 7.49999L15.7797 8.48217C15.1687 8.71718 14.8632 8.83469 14.6062 9.01742C14.3785 9.17937 14.1795 9.37836 14.0175 9.60612C13.8348 9.8631 13.7173 10.1686 13.4823 10.7796L12.5001 13.3333L11.5179 10.7796C11.2829 10.1686 11.1654 9.8631 10.9827 9.60612C10.8207 9.37836 10.6217 9.17937 10.3939 9.01742C10.137 8.83469 9.83145 8.71718 9.22043 8.48217L6.66675 7.49999L9.22043 6.5178C9.83145 6.28279 10.137 6.16529 10.3939 5.98256C10.6217 5.82061 10.8207 5.62162 10.9827 5.39386C11.1654 5.13688 11.2829 4.83136 11.5179 4.22034L12.5001 1.66666Z",stroke:o,strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})]}),e.jsx("defs",{children:e.jsx("clipPath",{id:"clip0_466_934",children:e.jsx("rect",{width:"20",height:"20",fill:"white"})})})]}),v=({client:o,questions:t,productId:l,productTitle:i,selectedVariantId:a})=>{const n=r=>{o.sendProductMessage({productId:l,productTitle:i,selectedVariantId:a,question:r,fromQuestionSuggestion:!0})};return e.jsx(e.Fragment,{children:t.map(r=>e.jsxs("button",{className:"dialog-block-suggestions-item",onClick:()=>n(r.question),children:[e.jsx(L,{color:o.theme.primaryColor}),e.jsx("span",{className:"dialog-block-suggestions-item-label",children:r.question})]},r.question))})},S=()=>e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"dialog-block-suggestions-skeleton-item"}),e.jsx("div",{className:"dialog-block-suggestions-skeleton-item"}),e.jsx("div",{className:"dialog-block-suggestions-skeleton-item"})]}),w=({client:o,questions:t,isLoading:l,productId:i,productTitle:a,selectedVariantId:n})=>e.jsx("div",{className:"dialog-block-suggestions-container",children:l||!t?e.jsx(S,{}):e.jsx(v,{client:o,questions:t,productId:i,productTitle:a,selectedVariantId:n})}),N=({color:o="#ffffff"})=>e.jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:e.jsx("path",{d:"M10 16.6667V3.33334M10 3.33334L5 8.33334M10 3.33334L15 8.33334",stroke:o,strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})}),C=({client:o,placeholder:t="Ask anything...",productId:l,productTitle:i,selectedVariantId:a})=>{const n=g.useRef(null),[r,s]=g.useState(""),u=()=>{var c;(c=n.current)==null||c.focus()},h=()=>{const c=r;c.trim()&&(o.sendProductMessage({productId:l,productTitle:i,selectedVariantId:a,question:c,fromQuestionSuggestion:!0}),s(""))},p=c=>{c.key==="Enter"&&h()};return e.jsxs("div",{className:"dialog-input-wrapper",onClick:u,children:[e.jsx("input",{id:"dialog-ask-anything-input-ai-input",ref:n,value:r,onChange:c=>s(c.target.value),className:"dialog-ask-anything-input-ai-input",placeholder:t,onKeyDown:p}),e.jsx("button",{id:"send-message-button-ai-input",className:"dialog-input-submit",disabled:!r.trim(),onClick:h,children:e.jsx(N,{color:o.theme.ctaTextColor})})]})},b=o=>o.replace(/([A-Z])/g,"-$1").toLowerCase(),m=o=>{if(!o)return;const t=document.body;Object.keys(o).forEach(l=>{const i=l,a=b(l);if(o[i]!==void 0){if(typeof o[i]=="object"){Object.keys(o[i]).forEach(n=>{var s;const r=n;if(r!==void 0){const u=b(n),h=o[i];t.style.setProperty(`--dialog-theme-${a}-${u}`,(s=h[r])==null?void 0:s.toString())}});return}if(i==="ctaBorderType"){const n=o[i]==="rounded"?"24px":"0";t.style.setProperty(`--dialog-theme-${a}`,n);return}t.style.setProperty(`--dialog-theme-${a}`,o[i].toString())}})},P=({theme:o,children:t})=>(g.useEffect(()=>{o&&m(o)},[o]),e.jsx(e.Fragment,{children:t})),M=({client:o,productId:t,productTitle:l,selectedVariantId:i,enableInput:a=!0})=>{const[n,r]=g.useState(!0),[s,u]=g.useState(void 0),h=g.useMemo(()=>n?"":s==null?void 0:s.assistantName,[s,n]),p=g.useMemo(()=>n?"":s==null?void 0:s.description,[s,n]),c=g.useMemo(()=>n?"":s==null?void 0:s.inputPlaceholder,[s,n]);return g.useEffect(()=>{let f=!0;return(async()=>{r(!0),u(void 0);try{const k=await o.getSuggestions(t);f&&u(k)}catch(k){console.error("error",k)}finally{f&&r(!1)}})(),()=>{f=!1}},[o,t]),e.jsx(P,{theme:o.theme,children:e.jsxs("div",{id:"dialog-instant",className:"dialog-block-container",children:[e.jsx(y,{title:h,description:p}),e.jsx(w,{client:o,questions:s==null?void 0:s.questions,isLoading:n,productId:t,productTitle:l,selectedVariantId:i}),a&&e.jsx(C,{client:o,placeholder:c,productId:t,productTitle:l,selectedVariantId:i})]})})};d.DialogInput=C,d.DialogProductBlock=M,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})}));
1
+ (function(g,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("react/jsx-runtime"),require("react"),require("@askdialog/dialog-sdk"),require("react-dom")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react","@askdialog/dialog-sdk","react-dom"],e):(g=typeof globalThis<"u"?globalThis:g||self,e(g["dialog-react"]={},g["react/jsx-runtime"],g.React,g.dialogSdk,g.ReactDOM))})(this,(function(g,e,d,f,N){"use strict";const L=({title:s="Your expert",description:r="A question about this product?"})=>e.jsxs("div",{className:"dialog-block-header-container",children:[e.jsx("div",{className:"dialog-block-title",children:s}),e.jsx("div",{className:"dialog-block-description",children:r})]}),P=({color:s="#181825"})=>e.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[e.jsxs("g",{clipPath:"url(#clip0_466_934)",children:[e.jsx("path",{d:"M5.41675 10.8333L6.07046 12.1408C6.2917 12.5832 6.40232 12.8045 6.55011 12.9962C6.68124 13.1663 6.83375 13.3188 7.00388 13.45C7.19559 13.5977 7.41684 13.7084 7.85932 13.9296L9.16675 14.5833L7.85932 15.237C7.41684 15.4583 7.19559 15.5689 7.00388 15.7167C6.83375 15.8478 6.68124 16.0003 6.55011 16.1704C6.40232 16.3622 6.2917 16.5834 6.07046 17.0259L5.41675 18.3333L4.76303 17.0259C4.54179 16.5834 4.43117 16.3622 4.28339 16.1704C4.15225 16.0003 3.99974 15.8478 3.82962 15.7167C3.6379 15.5689 3.41666 15.4583 2.97418 15.237L1.66675 14.5833L2.97418 13.9296C3.41666 13.7084 3.6379 13.5977 3.82962 13.45C3.99974 13.3188 4.15225 13.1663 4.28339 12.9962C4.43117 12.8045 4.54179 12.5832 4.76303 12.1408L5.41675 10.8333Z",stroke:s,strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"}),e.jsx("path",{d:"M12.5001 1.66666L13.4823 4.22034C13.7173 4.83136 13.8348 5.13688 14.0175 5.39386C14.1795 5.62162 14.3785 5.82061 14.6062 5.98256C14.8632 6.16529 15.1687 6.2828 15.7797 6.5178L18.3334 7.49999L15.7797 8.48217C15.1687 8.71718 14.8632 8.83469 14.6062 9.01742C14.3785 9.17937 14.1795 9.37836 14.0175 9.60612C13.8348 9.8631 13.7173 10.1686 13.4823 10.7796L12.5001 13.3333L11.5179 10.7796C11.2829 10.1686 11.1654 9.8631 10.9827 9.60612C10.8207 9.37836 10.6217 9.17937 10.3939 9.01742C10.137 8.83469 9.83145 8.71718 9.22043 8.48217L6.66675 7.49999L9.22043 6.5178C9.83145 6.28279 10.137 6.16529 10.3939 5.98256C10.6217 5.82061 10.8207 5.62162 10.9827 5.39386C11.1654 5.13688 11.2829 4.83136 11.5179 4.22034L12.5001 1.66666Z",stroke:s,strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})]}),e.jsx("defs",{children:e.jsx("clipPath",{id:"clip0_466_934",children:e.jsx("rect",{width:"20",height:"20",fill:"white"})})})]}),m=({client:s,questions:r,productId:t,productTitle:o,selectedVariantId:a})=>{const i=l=>{s.sendProductMessage({productId:t,productTitle:o,selectedVariantId:a,question:l,fromQuestionSuggestion:!0})};return e.jsx(e.Fragment,{children:r.map(l=>e.jsxs("button",{className:"dialog-block-suggestions-item",onClick:()=>i(l.question),children:[e.jsx(P,{color:s.theme.primaryColor}),e.jsx("span",{className:"dialog-block-suggestions-item-label",children:l.question})]},l.question))})},E=()=>e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"dialog-block-suggestions-skeleton-item"}),e.jsx("div",{className:"dialog-block-suggestions-skeleton-item"}),e.jsx("div",{className:"dialog-block-suggestions-skeleton-item"})]}),D=({client:s,questions:r,isLoading:t,productId:o,productTitle:a,selectedVariantId:i})=>e.jsx("div",{className:"dialog-block-suggestions-container",children:t||!r?e.jsx(E,{}):e.jsx(m,{client:s,questions:r,productId:o,productTitle:a,selectedVariantId:i})}),M=({color:s="#ffffff"})=>e.jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:e.jsx("path",{d:"M10 16.6667V3.33334M10 3.33334L5 8.33334M10 3.33334L15 8.33334",stroke:s,strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})}),v=({client:s,placeholder:r="Ask anything...",productId:t,productTitle:o,selectedVariantId:a})=>{const i=d.useRef(null),[l,c]=d.useState(""),n=()=>{var u;(u=i.current)==null||u.focus()},h=()=>{const u=l;u.trim()&&(s.sendProductMessage({productId:t,productTitle:o,selectedVariantId:a,question:u,fromQuestionSuggestion:!0}),c(""))},p=u=>{u.key==="Enter"&&h()};return e.jsxs("div",{className:"dialog-input-wrapper",onClick:n,children:[e.jsx("input",{id:"dialog-ask-anything-input-ai-input",ref:i,value:l,onChange:u=>c(u.target.value),className:"dialog-ask-anything-input-ai-input",placeholder:r,onKeyDown:p}),e.jsx("button",{id:"send-message-button-ai-input",className:"dialog-input-submit",disabled:!l.trim(),onClick:h,children:e.jsx(M,{color:s.theme.ctaTextColor})})]})},y=s=>s.replace(/([A-Z])/g,"-$1").toLowerCase(),A=s=>{if(!s)return;const r=document.body;Object.keys(s).forEach(t=>{const o=t,a=y(t);if(s[o]!==void 0){if(typeof s[o]=="object"){Object.keys(s[o]).forEach(i=>{var c;const l=i;if(l!==void 0){const n=y(i),h=s[o];r.style.setProperty(`--dialog-theme-${a}-${n}`,(c=h[l])==null?void 0:c.toString())}});return}if(o==="ctaBorderType"){const i=s[o]==="rounded"?"24px":"0";r.style.setProperty(`--dialog-theme-${a}`,i);return}r.style.setProperty(`--dialog-theme-${a}`,s[o].toString())}})},F=({theme:s,children:r})=>(d.useEffect(()=>{s&&A(s)},[s]),e.jsx(e.Fragment,{children:r})),I=({client:s,productId:r,productTitle:t,selectedVariantId:o,enableInput:a=!0})=>{const[i,l]=d.useState(!0),[c,n]=d.useState(void 0);d.useEffect(()=>{f.registerDialogInstallation({method:"react",version:"2.2.0"}),f.addAuditCapability("pdp-block")},[]);const h=d.useMemo(()=>i?"":c==null?void 0:c.assistantName,[c,i]),p=d.useMemo(()=>i?"":c==null?void 0:c.description,[c,i]),u=d.useMemo(()=>i?"":c==null?void 0:c.inputPlaceholder,[c,i]),C=d.useMemo(()=>{var b;return f.resolveTextDirection((b=s.getLocalizationInformations())==null?void 0:b.languageCode)},[s]);return d.useEffect(()=>{let b=!0;return(async()=>{l(!0),n(void 0);try{const S=await s.getSuggestions(r);b&&n(S)}catch(S){console.error("error",S)}finally{b&&l(!1)}})(),()=>{b=!1}},[s,r]),e.jsx(F,{theme:s.theme,children:e.jsxs("div",{id:"dialog-instant",className:"dialog-block-container",dir:C,children:[e.jsx(L,{title:h,description:p}),e.jsx(D,{client:s,questions:c==null?void 0:c.questions,isLoading:i,productId:r,productTitle:t,selectedVariantId:o}),a&&e.jsx(v,{client:s,placeholder:u,productId:r,productTitle:t,selectedVariantId:o})]})})},_=()=>e.jsx("svg",{width:16,height:16,viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:e.jsx("path",{d:"M8 13V3M8 3L3 8M8 3L13 8",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})}),T="M5.3217 0.588255C5.63241 -0.196084 6.36759 -0.196085 6.6783 0.588254C6.98901 1.37259 7.68193 2.82807 8.42693 3.57307C9.17193 4.31807 10.6274 5.01099 11.4117 5.3217C12.1961 5.63241 12.1961 6.36759 11.4117 6.6783C10.6274 6.98901 9.17193 7.68193 8.42693 8.42693C7.68193 9.17193 6.98901 10.6274 6.6783 11.4117C6.36759 12.1961 5.63241 12.1961 5.3217 11.4117C5.01099 10.6274 4.31807 9.17193 3.57307 8.42693C2.82808 7.68193 1.37259 6.98901 0.588255 6.6783C-0.196084 6.36759 -0.196085 5.63241 0.588254 5.3217C1.37259 5.01099 2.82807 4.31807 3.57307 3.57307C4.31807 2.82808 5.01099 1.37259 5.3217 0.588255Z",B=({color:s="currentColor"})=>e.jsx("svg",{width:16,height:16,viewBox:"0 0 12 12",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:e.jsx("path",{d:T,fill:s})}),O=({controller:s,placeholder:r="Search products...",autoFocus:t=!1,submitAriaLabel:o="Search"})=>{const[a,i]=d.useState(""),l=c=>{c.preventDefault(),s.submit(a)};return e.jsxs("form",{className:"dialog-search-bar",role:"search",onSubmit:l,children:[e.jsxs("div",{className:"dialog-search-bar-field",children:[e.jsx("span",{className:"dialog-search-bar-icon",children:e.jsx(B,{})}),e.jsx("input",{type:"text",className:"dialog-search-bar-input",value:a,"aria-label":r,placeholder:r,autoFocus:t,onChange:c=>{i(c.target.value),s.setQuery(c.target.value)}})]}),e.jsx("button",{type:"submit",className:"dialog-search-bar-submit","aria-label":o,children:e.jsx(_,{})})]})},k=({controller:s,state:r})=>{const t=r.response;return t===void 0||t.nbPages<=1?null:e.jsxs("nav",{"aria-label":"Search results pages",className:"dialog-search-pagination",children:[e.jsx("button",{type:"button",disabled:t.page===0,onClick:()=>s.setPage(t.page-1),children:"Previous"}),e.jsxs("span",{children:["Page ",t.page+1," / ",t.nbPages]}),e.jsx("button",{type:"button",disabled:t.page>=t.nbPages-1,onClick:()=>s.setPage(t.page+1),children:"Next"})]})},$=s=>{if(s===void 0)return"";const{min:r,max:t}=s,o=({amount:a,currencyCode:i})=>new Intl.NumberFormat(void 0,{style:"currency",currency:i}).format(Number(a));try{return r.amount===t.amount?o(r):`${o(r)} – ${o(t)}`}catch{return""}},q=s=>{try{const{protocol:r}=new URL(s,window.location.href);return r==="http:"||r==="https:"?s:void 0}catch{return}},w=({controller:s,hit:r,index:t})=>{const o=d.useRef(null);d.useEffect(()=>{o.current!==null&&s.observeResult(o.current,t)},[s,r,t]);const a=u=>{const C=u.metaKey||u.ctrlKey||u.shiftKey||u.altKey;s.selectResult(t,{navigate:!C})&&u.preventDefault()},i=u=>{u.button===1&&s.selectResult(t,{navigate:!1})},{product:l}=r,c=l.title??l.id,n=$(l.priceRange),h=l.url===void 0?void 0:q(l.url),p=e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"dialog-search-card-image",children:l.imageUrl!==void 0&&e.jsx("img",{src:l.imageUrl,alt:c,loading:"lazy"})}),e.jsxs("div",{className:"dialog-search-card-info",children:[e.jsx("p",{className:"dialog-search-card-title",children:c}),n!==""&&e.jsx("p",{className:"dialog-search-card-price",children:n})]})]});return e.jsx("li",{ref:o,className:"dialog-search-card",children:h===void 0?e.jsx("div",{className:"dialog-search-card-body",children:p}):e.jsx("a",{className:"dialog-search-card-body",href:h,onClick:a,onAuxClick:i,children:p})})},x=s=>{const r=d.useRef(null),[t,o]=d.useState(void 0);return d.useLayoutEffect(()=>{if(!s)return;const a=()=>{const i=r.current;if(i===null)return;const{top:l,left:c,width:n}=i.getBoundingClientRect();o(h=>h!==void 0&&h.top===l&&h.left===c&&h.width===n?h:{top:l,left:c,width:n})};return a(),window.addEventListener("scroll",a,!0),window.addEventListener("resize",a),()=>{window.removeEventListener("scroll",a,!0),window.removeEventListener("resize",a)}},[s]),{anchorRef:r,rect:t}},K=s=>s instanceof f.DialogSearchError?`Search failed (${s.status}${s.code?` ${s.code}`:""}): ${s.message}`:"Search failed: network error. Check your connection and try again.",V=(s,r)=>{const t=r.response;switch(r.status){case f.SearchStatus.LOADING:return e.jsxs("p",{role:"status",className:"dialog-search-status",children:["Searching “",r.query,"”…"]});case f.SearchStatus.ERROR:return e.jsxs("div",{className:"dialog-search-error",children:[e.jsx("p",{role:"alert",className:"dialog-search-status dialog-search-status-error",children:K(r.error)}),e.jsx("button",{type:"button",className:"dialog-search-retry",onClick:()=>s.retry(),children:"Retry"})]});case f.SearchStatus.EMPTY:return e.jsxs("p",{role:"status",className:"dialog-search-status",children:["No products match “",t==null?void 0:t.query,"”."]});case f.SearchStatus.SUCCESS:return t===void 0?null:e.jsxs(e.Fragment,{children:[e.jsxs("p",{role:"status",className:"dialog-search-status",children:[t.nbHits," result",t.nbHits>1?"s":""]}),e.jsx("ul",{className:"dialog-search-results",children:t.hits.map((o,a)=>e.jsx(w,{controller:s,hit:o,index:a},o.id))}),e.jsx(k,{controller:s,state:r})]});default:return null}},H=({controller:s,state:r})=>{const t=r.status!==f.SearchStatus.IDLE,{anchorRef:o,rect:a}=x(t);return e.jsxs(e.Fragment,{children:[e.jsx("div",{ref:o}),t&&a!==void 0&&N.createPortal(e.jsx("div",{className:"dialog-search-panel",style:{top:a.top+8,left:a.left,width:a.width,maxHeight:`calc(100vh - ${a.top+8+16}px)`},children:V(s,r)}),document.body)]})},j={status:f.SearchStatus.IDLE,query:"",page:0},Q=s=>{const r=d.useRef(s);r.current=s;const t=d.useRef(void 0),o=d.useCallback(()=>{if(t.current===void 0){const{client:n,surface:h="search_page",...p}=r.current;t.current=f.createSearchController({search:(u,C)=>n.search(u,C),analytics:{surface:h,trackViewSearchResults:u=>n.trackViewSearchResults(u),trackSelectSearchResult:u=>n.trackSelectSearchResult(u)},...p})}return t.current},[]),a=d.useRef(void 0);a.current??(a.current={setQuery:n=>o().setQuery(n),submit:n=>o().submit(n),setPage:n=>o().setPage(n),retry:()=>o().retry(),observeResult:(n,h)=>o().observeResult(n,h),selectResult:(n,h)=>o().selectResult(n,h),subscribe:n=>o().subscribe(n),getState:()=>o().getState(),dispose:()=>o().dispose()}),d.useEffect(()=>{f.registerDialogInstallation({method:"react",version:"2.2.0"});const n=o();return()=>{n.dispose(),t.current===n&&(t.current=void 0)}},[o]);const i=d.useCallback(n=>o().subscribe(n),[o]),l=d.useCallback(()=>o().getState(),[o]),c=d.useSyncExternalStore(i,l,()=>j);return{controller:a.current,state:c}};g.DialogInput=v,g.DialogProductBlock=I,g.DialogSearchBar=O,g.DialogSearchPagination=k,g.DialogSearchProductCard=w,g.DialogSearchResults=H,g.useDialogSearch=Q,Object.defineProperty(g,Symbol.toStringTag,{value:"Module"})}));
@@ -0,0 +1,2 @@
1
+ import { FC } from 'react';
2
+ export declare const ArrowUpIcon: FC;
@@ -0,0 +1,6 @@
1
+ import { FC } from 'react';
2
+ interface ShurikenIconProps {
3
+ color?: string;
4
+ }
5
+ export declare const ShurikenIcon: FC<ShurikenIconProps>;
6
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askdialog/dialog-react",
3
- "version": "2.0.2",
3
+ "version": "2.2.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/dialog-react.umd.js",
@@ -19,14 +19,14 @@
19
19
  "dist"
20
20
  ],
21
21
  "peerDependencies": {
22
- "@askdialog/dialog-sdk": "^2.0.1",
22
+ "@askdialog/dialog-sdk": "^2.1.0",
23
23
  "react": "^19.0.0",
24
24
  "react-dom": "^19.0.0"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@types/react": "^19.2.7",
28
28
  "@types/react-dom": "^19.2.3",
29
- "@askdialog/dialog-sdk": "2.0.1"
29
+ "@askdialog/dialog-sdk": "2.8.0"
30
30
  },
31
31
  "author": "Dialog",
32
32
  "publishConfig": {