@askdialog/dialog-vue 3.5.0 → 3.7.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 (25) hide show
  1. package/README.md +28 -9
  2. package/dist/components/DialogSearch/DialogSearchCollections.vue.d.ts +9 -0
  3. package/dist/components/DialogSearch/DialogSearchPagination.vue.d.ts +1 -0
  4. package/dist/components/DialogSearch/DialogSearchProductCard.vue.d.ts +6 -1
  5. package/dist/components/DialogSearch/DialogSearchProducts.vue.d.ts +10 -0
  6. package/dist/components/DialogSearch/DialogSearchResults.vue.d.ts +14 -2
  7. package/dist/components/DialogSearch/{DialogSearchProductCardContent.vue.d.ts → HighlightedTitle.vue.d.ts} +2 -3
  8. package/dist/components/DialogSearch/cssColor.d.ts +3 -0
  9. package/dist/components/DialogSearch/panelPlacement.d.ts +5 -0
  10. package/dist/components/DialogSearch/searchCollections.d.ts +6 -0
  11. package/dist/components/DialogSearch/searchDisplay.d.ts +5 -2
  12. package/dist/components/DialogSearch/searchLayout.d.ts +1 -0
  13. package/dist/components/DialogSearch/searchMessages.d.ts +14 -0
  14. package/dist/components/DialogSearch/searchPagination.d.ts +2 -0
  15. package/dist/components/DialogSearch/searchTheme.d.ts +3 -0
  16. package/dist/components/DialogSearch/titleHighlight.d.ts +6 -0
  17. package/dist/components/DialogSearch/useAnchorRect.d.ts +6 -1
  18. package/dist/components/DialogSearch/useDialogSearch.d.ts +15 -6
  19. package/dist/components/index.d.ts +1 -0
  20. package/dist/dialog-vue.css +1 -1
  21. package/dist/dialog-vue.js +902 -533
  22. package/dist/dialog-vue.umd.cjs +3 -3
  23. package/dist/icons/ArrowRightIcon.vue.d.ts +2 -0
  24. package/dist/icons/CaretRightIcon.vue.d.ts +2 -0
  25. package/package.json +2 -2
package/README.md CHANGED
@@ -39,7 +39,7 @@ import '@askdialog/dialog-vue/style.css';
39
39
 
40
40
  const client = new Dialog({
41
41
  apiKey: 'your-api-key',
42
- locale: 'en',
42
+ locale: 'en', currency: 'EUR',
43
43
  callbacks: {
44
44
  addToCart: () => Promise.resolve(),
45
45
  getProduct: () => Promise.resolve({
@@ -105,7 +105,7 @@ Standalone input component for asking questions.
105
105
 
106
106
  ### Storefront search
107
107
 
108
- Vue 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.
108
+ `useDialogSearch` binds the SDK controller to component state. The controller manages requests and analytics; components handle rendering and navigation.
109
109
 
110
110
  ```vue
111
111
  <script setup lang="ts">
@@ -117,14 +117,14 @@ import {
117
117
  } from '@askdialog/dialog-vue';
118
118
  import '@askdialog/dialog-vue/style.css';
119
119
 
120
- const client = new Dialog({ apiKey: 'your-api-key', locale: 'en' });
120
+ const client = new Dialog({ apiKey: 'your-api-key', locale: 'en-US', currency: 'USD' });
121
121
 
122
- const { controller, state } = useDialogSearch({ client });
122
+ const { controller, state, theme } = useDialogSearch({ client, language: 'en', currency: client.currency });
123
123
  </script>
124
124
 
125
125
  <template>
126
126
  <DialogSearchBar :controller="controller" placeholder="Search products..." />
127
- <DialogSearchResults :controller="controller" :state="state" />
127
+ <DialogSearchResults :controller="controller" :state="state" :theme="theme" />
128
128
  </template>
129
129
  ```
130
130
 
@@ -134,15 +134,30 @@ Creates one search controller per composable instance and disposes it on unmount
134
134
 
135
135
  **Options:**
136
136
  - `client` (Dialog) - Dialog SDK client instance (required)
137
+ - `language` (string, required) - Lowercase ISO 639-1 language code, e.g. `fr`
138
+ - `currency` (string, required) - ISO 4217 currency, e.g. `EUR`
137
139
  - `surface` (SearchSurface, optional) - Where results are displayed, for analytics (default: `'search_page'`)
138
140
  - `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.
139
141
  - `debounceMs` (number, optional) - Keystroke debounce (default: 250)
140
142
  - `hitsPerPage` (number, optional) - Results per page (default: 12)
141
- - `locale` (string, optional) - Storefront locale naming the searched index (`products_fr`); defaults to the client's
143
+ - `sections` (SearchSection[], optional) - Extra indices searched alongside the products; `collections` fills the collections column of `DialogSearchResults`. Only request an index the catalog exposes: a missing one fails the whole search.
144
+
145
+ Search language and currency are explicit and independent of `client.locale`, which can be a regional locale such as `fr-FR`.
142
146
 
143
147
  Options are read once during setup — later changes don't rebind the live controller.
144
148
 
145
- **Returns:** `{ controller, state }` — pass both to the components below. `state` is a `ShallowRef`; `state.value.status` is `idle` / `loading` / `success` / `empty` / `error`.
149
+ **Returns:** `{ controller, state, theme }` — pass them to the components below; `theme` is the client's theme, for `DialogSearchResults`. `state` is a `ShallowRef`; `state.value.status` is `idle` / `loading` / `success` / `empty` / `error`.
150
+
151
+ With the collections column, for a catalog that exposes a collections index:
152
+
153
+ ```ts
154
+ const { controller, state, theme } = useDialogSearch({
155
+ client,
156
+ language: 'en',
157
+ currency: client.currency,
158
+ sections: [{ index: 'collections', hitsPerPage: 5 }],
159
+ });
160
+ ```
146
161
 
147
162
  #### DialogSearchBar
148
163
 
@@ -156,12 +171,15 @@ Search input: typing runs a debounced search, submitting (Enter) searches immedi
156
171
 
157
172
  #### DialogSearchResults
158
173
 
159
- 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. Clicking outside the panel (and outside the bar) closes it; typing again or re-focusing the bar reopens it with the results kept.
174
+ Floating results panel overlaying the page content: portaled to `document.body` in `position: fixed`, centered on the bar (up to 1440px wide, filling the viewport) and 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. It shows the same layout as the Shopify search overlay: a collections column on the left when `sections` requests them, the products on the right as a list or a 3-column grid, the query match emphasized in every title, and either a "See all results" button or the pagination controls. Below 768px the panel stacks, collections in a horizontal rail above the products. Colors, radii and font follow the SDK theme (dark palette when `backgroundColor` is dark, straight or rounded corners from `ctaBorderType`). Each card links to the product page and records search attribution (viewport impressions, select on click and middle-click) automatically. Clicking outside the panel (and outside the bar) closes it; typing again or re-focusing the bar reopens it with the results kept.
160
175
 
161
176
  **Props:**
162
177
  - `controller` (SearchController) - From `useDialogSearch` (required)
163
178
  - `state` (SearchControllerState) - From `useDialogSearch` (required)
164
- - `locale` (string, optional) - BCP 47 locale used to format the card prices via `Intl.NumberFormat` (browser default when omitted)
179
+ - `locale` (string, optional) - BCP 47 locale for prices, counts and labels (English labels and browser number format when omitted)
180
+ - `theme` (Theme, optional) - The client's theme, as returned by `useDialogSearch`; styles the panel (palette, radii, font)
181
+ - `layout` (`'list' | 'grid'`, optional) - Products layout (default: `'list'`)
182
+ - `seeAllHref` ((query) => string, optional) - Link of the "See all results" footer button; omitted, the panel paginates instead
165
183
 
166
184
  #### DialogSearchPagination
167
185
 
@@ -170,6 +188,7 @@ Previous/next controls with a page indicator; hidden while there is a single pag
170
188
  **Props:**
171
189
  - `controller` (SearchController) - From `useDialogSearch` (required)
172
190
  - `state` (SearchControllerState) - From `useDialogSearch` (required)
191
+ - `locale` (string, optional) - Locale of the button labels
173
192
 
174
193
  ## Theming
175
194
 
@@ -0,0 +1,9 @@
1
+ import { SearchHit } from '@askdialog/dialog-sdk';
2
+ import { SearchMessages } from './searchMessages';
3
+ type __VLS_Props = {
4
+ collections: SearchHit[];
5
+ query: string;
6
+ messages: SearchMessages;
7
+ };
8
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
9
+ export default _default;
@@ -2,6 +2,7 @@ import { SearchController, SearchControllerState } from '@askdialog/dialog-sdk';
2
2
  interface Props {
3
3
  controller: SearchController;
4
4
  state: SearchControllerState;
5
+ locale?: string;
5
6
  }
6
7
  declare const _default: import('vue').DefineComponent<Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
7
8
  export default _default;
@@ -4,8 +4,13 @@ interface Props {
4
4
  hit: SearchHit;
5
5
  index: number;
6
6
  locale?: string;
7
+ /** Committed query, emphasized inside the title. */
8
+ query?: string;
7
9
  }
8
- declare const _default: import('vue').DefineComponent<Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
10
+ declare const _default: import('vue').DefineComponent<Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<Props> & Readonly<{}>, {
11
+ locale: string;
12
+ query: string;
13
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
9
14
  cardRef: HTMLLIElement;
10
15
  }, HTMLLIElement>;
11
16
  export default _default;
@@ -0,0 +1,10 @@
1
+ import { SearchController, SearchResult } from '@askdialog/dialog-sdk';
2
+ import { SearchMessages } from './searchMessages';
3
+ type __VLS_Props = {
4
+ controller: SearchController;
5
+ response: SearchResult;
6
+ locale: string | undefined;
7
+ messages: SearchMessages;
8
+ };
9
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLElement>;
10
+ export default _default;
@@ -1,10 +1,22 @@
1
- import { SearchController, SearchControllerState } from '@askdialog/dialog-sdk';
1
+ import { SearchController, SearchControllerState, Theme } from '@askdialog/dialog-sdk';
2
+ import { SearchProductsLayout } from './searchLayout';
2
3
  interface Props {
3
4
  controller: SearchController;
4
5
  state: SearchControllerState;
6
+ /** BCP 47 locale for prices, counts and labels. */
5
7
  locale?: string;
8
+ /** Usually `client.theme`, as returned by `useDialogSearch`. */
9
+ theme?: Theme;
10
+ layout?: SearchProductsLayout;
11
+ /** Link of the "See all results" footer; omitted, the panel paginates instead. */
12
+ seeAllHref?: (query: string) => string;
6
13
  }
7
- declare const _default: import('vue').DefineComponent<Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
14
+ declare const _default: import('vue').DefineComponent<Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<Props> & Readonly<{}>, {
15
+ theme: Theme;
16
+ locale: string;
17
+ layout: SearchProductsLayout;
18
+ seeAllHref: (query: string) => string;
19
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
8
20
  anchorRef: HTMLDivElement;
9
21
  panelRef: HTMLDivElement;
10
22
  }, any>;
@@ -1,7 +1,6 @@
1
- import { SearchHit } from '@askdialog/dialog-sdk';
2
1
  type __VLS_Props = {
3
- hit: SearchHit;
4
- locale?: string;
2
+ title: string;
3
+ query: string;
5
4
  };
6
5
  declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
7
6
  export default _default;
@@ -0,0 +1,3 @@
1
+ export type Rgb = [number, number, number];
2
+ export declare const parseCssColor: (color: string) => Rgb | undefined;
3
+ export declare const relativeLuminance: (color: string) => number | undefined;
@@ -0,0 +1,5 @@
1
+ import { CSSProperties } from 'vue';
2
+ import { AnchorRect } from './useAnchorRect';
3
+ export declare const isAnchorOnScreen: (rect: AnchorRect, viewportHeight: number) => boolean;
4
+ /** Centered on the bar, clamped to the viewport; flips above when short of room below. */
5
+ export declare const panelStyle: (rect: AnchorRect, viewportWidth: number, viewportHeight: number) => CSSProperties;
@@ -0,0 +1,6 @@
1
+ import { SearchHit } from '@askdialog/dialog-sdk';
2
+ /** Collections without a link cannot navigate on selection and are not rendered. */
3
+ export declare const navigableCollections: (collections: SearchHit[] | undefined) => {
4
+ collection: SearchHit;
5
+ href: string;
6
+ }[];
@@ -1,3 +1,6 @@
1
- import { SearchPriceRange } from '@askdialog/dialog-sdk';
1
+ import { SearchHit, SearchPriceRange } from '@askdialog/dialog-sdk';
2
+ /** The lowest price only, as on the Shopify storefront search. */
2
3
  export declare const formatSearchPrice: (priceRange: SearchPriceRange | undefined, locale?: string) => string;
3
- export declare const safeProductHref: (url: string) => string | undefined;
4
+ export declare const safeHref: (url: string) => string | undefined;
5
+ export declare const hitHref: (hit: SearchHit) => string | undefined;
6
+ export declare const hitTitle: (hit: SearchHit) => string;
@@ -0,0 +1 @@
1
+ export type SearchProductsLayout = "list" | "grid";
@@ -0,0 +1,14 @@
1
+ export interface SearchMessages {
2
+ searching: (query: string) => string;
3
+ noResults: string;
4
+ retry: string;
5
+ collectionsLabel: string;
6
+ productsLabel: string;
7
+ collectionsCount: (count: number) => string;
8
+ resultsCount: (count: number) => string;
9
+ seeAllLabel: (count: number) => string;
10
+ previous: string;
11
+ next: string;
12
+ pageOf: (page: number, pages: number) => string;
13
+ }
14
+ export declare const getSearchMessages: (locale: string | undefined) => SearchMessages;
@@ -0,0 +1,2 @@
1
+ import { SearchControllerState } from '@askdialog/dialog-sdk';
2
+ export declare const hasPagination: (state: SearchControllerState) => boolean;
@@ -0,0 +1,3 @@
1
+ import { Theme } from '@askdialog/dialog-sdk';
2
+ export type SearchPanelVariables = Record<`--dso-${string}`, string>;
3
+ export declare const resolveSearchPanelVariables: (theme: Theme | undefined) => SearchPanelVariables;
@@ -0,0 +1,6 @@
1
+ export interface TitleParts {
2
+ before: string;
3
+ match: string;
4
+ after: string;
5
+ }
6
+ export declare const splitTitleMatch: (title: string, query: string) => TitleParts;
@@ -5,8 +5,13 @@ export interface AnchorRect {
5
5
  left: number;
6
6
  width: number;
7
7
  }
8
+ interface Viewport {
9
+ width: number;
10
+ height: number;
11
+ }
8
12
  export declare const useAnchorRect: (active: Ref<boolean>) => {
9
13
  anchorRef: Ref<HTMLDivElement | undefined>;
10
14
  rect: Ref<AnchorRect | undefined>;
11
- viewportHeight: Ref<number>;
15
+ viewport: Ref<Viewport>;
12
16
  };
17
+ export {};
@@ -1,19 +1,28 @@
1
- import { Dialog, SearchController, SearchControllerState, SearchHit, SearchSurface } from '@askdialog/dialog-sdk';
1
+ import { Dialog, SearchController, SearchControllerState, SearchHit, SearchSection, SearchSurface, Theme } from '@askdialog/dialog-sdk';
2
2
  import { ShallowRef } from 'vue';
3
3
  export interface UseDialogSearchOptions {
4
4
  client: Dialog;
5
- /** Where the results are displayed, for search analytics. */
5
+ /** Lowercase ISO 639-1 language code, e.g. `fr`. */
6
+ language: string;
7
+ /** ISO 4217 currency, independent of language. */
8
+ currency: string;
9
+ /** UI surface used in search analytics. */
6
10
  surface?: SearchSurface;
7
- /** Router adapter called after selection attribution; omit to let the cards' `<a href>` navigate natively. */
11
+ /** Navigate after recording selection; omit to use native links. */
8
12
  navigate?: (url: string, hit: SearchHit) => void;
9
13
  debounceMs?: number;
10
14
  hitsPerPage?: number;
11
- /** Storefront locale for the searched index (`products_fr`); defaults to the client's. */
12
- locale?: string;
15
+ /**
16
+ * Extra indices searched alongside the products, e.g. `[{ index: 'collections', hitsPerPage: 5 }]`.
17
+ * Only request an index the catalog exposes: a missing one fails the whole search.
18
+ */
19
+ sections?: readonly SearchSection[];
13
20
  }
14
21
  export interface DialogSearch {
15
22
  controller: SearchController;
16
23
  state: Readonly<ShallowRef<SearchControllerState>>;
24
+ /** The client's theme, for `DialogSearchResults`. */
25
+ theme: Theme;
17
26
  }
18
- /** Options are read once during setup — later changes don't rebind the live controller. */
27
+ /** Options are fixed when the controller is created. */
19
28
  export declare const useDialogSearch: (options: UseDialogSearchOptions) => DialogSearch;
@@ -5,4 +5,5 @@ import { default as DialogSearchPagination } from './DialogSearch/DialogSearchPa
5
5
  import { default as DialogSearchProductCard } from './DialogSearch/DialogSearchProductCard.vue';
6
6
  import { default as DialogSearchResults } from './DialogSearch/DialogSearchResults.vue';
7
7
  export { DialogProductBlock, DialogInput, DialogSearchBar, DialogSearchPagination, DialogSearchProductCard, DialogSearchResults, };
8
+ export type { SearchProductsLayout } from './DialogSearch/searchLayout';
8
9
  export { useDialogSearch, type DialogSearch, type UseDialogSearchOptions, } from './DialogSearch/useDialogSearch';
@@ -1 +1 @@
1
- .dialog-block-header-container[data-v-28e6dda7]{display:flex;flex-direction:column;align-items:flex-start;justify-content:flex-start}.dialog-block-title[data-v-28e6dda7]{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[data-v-28e6dda7]{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[data-v-db34d4b4]{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[data-v-db34d4b4]:hover{transform:scale(1.01)}.dialog-block-suggestions-item-label[data-v-db34d4b4]{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[data-v-db34d4b4]{stroke:var(--dialog-theme-primary-color)}.dialog-block-suggestions-skeleton-item[data-v-26a64b58],.dialog-block-suggestions-skeleton-item[data-v-26a64b58]:empty{display:block;width:100%;width:90%;height:18px;border-radius:18px;padding:12px 16px;background-color:#f1f1f1;animation:pulse-26a64b58 1.5s ease-in-out infinite}@keyframes pulse-26a64b58{0%{background-color:#f1f1f1}50%{background-color:#fff}to{background-color:#f1f1f1}}.dialog-block-suggestions-container[data-v-18c9e78b]{display:flex;flex-direction:column;gap:12px;width:100%}.dialog-input-wrapper[data-v-4f5901c9]{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[data-v-4f5901c9]{display:flex;justify-items:center;align-items:center;gap:12px;width:100%;height:100%}.dialog-ask-anything-input-ai-input[data-v-4f5901c9]{outline:unset;box-shadow:unset;border:unset;width:100%;font-size:16px;background:transparent;padding-inline-end:35px}.dialog-input-submit[data-v-4f5901c9]{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[data-v-4f5901c9]:disabled{opacity:.5}.dialog-block-container[data-v-c57aa677]{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[data-v-c57aa677]>*{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:focus-within{border-color:#00000026;box-shadow:0 6px 20px -6px #0000001a,0 0 0 2px #1717171f}.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
+ .dialog-block-header-container[data-v-28e6dda7]{display:flex;flex-direction:column;align-items:flex-start;justify-content:flex-start}.dialog-block-title[data-v-28e6dda7]{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[data-v-28e6dda7]{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[data-v-db34d4b4]{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[data-v-db34d4b4]:hover{transform:scale(1.01)}.dialog-block-suggestions-item-label[data-v-db34d4b4]{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[data-v-db34d4b4]{stroke:var(--dialog-theme-primary-color)}.dialog-block-suggestions-skeleton-item[data-v-26a64b58],.dialog-block-suggestions-skeleton-item[data-v-26a64b58]:empty{display:block;width:100%;width:90%;height:18px;border-radius:18px;padding:12px 16px;background-color:#f1f1f1;animation:pulse-26a64b58 1.5s ease-in-out infinite}@keyframes pulse-26a64b58{0%{background-color:#f1f1f1}50%{background-color:#fff}to{background-color:#f1f1f1}}.dialog-block-suggestions-container[data-v-18c9e78b]{display:flex;flex-direction:column;gap:12px;width:100%}.dialog-input-wrapper[data-v-4f5901c9]{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[data-v-4f5901c9]{display:flex;justify-items:center;align-items:center;gap:12px;width:100%;height:100%}.dialog-ask-anything-input-ai-input[data-v-4f5901c9]{outline:unset;box-shadow:unset;border:unset;width:100%;font-size:16px;background:transparent;padding-inline-end:35px}.dialog-input-submit[data-v-4f5901c9]{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[data-v-4f5901c9]:disabled{opacity:.5}.dialog-block-container[data-v-c57aa677]{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[data-v-c57aa677]>*{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:focus-within{border-color:#00000026;box-shadow:0 6px 20px -6px #0000001a,0 0 0 2px #1717171f}.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;padding:4px 0;font-size:12px;color:var(--dso-text-sec, #737373)}.dialog-search-pagination button{margin:0;padding:6px 14px;border:1px solid var(--dso-border, rgba(0, 0, 0, .1));border-radius:var(--dso-r-btn, 10px);background:transparent;font:inherit;color:var(--dso-text, #171717);cursor:pointer;transition:background-color .12s ease}.dialog-search-pagination button:hover:not(:disabled){background-color:var(--dso-hover, rgba(0, 0, 0, .04))}.dialog-search-pagination button:disabled{opacity:.4;cursor:default}.dialog-search-match{font-weight:600}.dialog-search-muted{opacity:.55}.dialog-search-card{width:100%}.dialog-search-product{display:grid;grid-template-columns:56px minmax(0,1fr) auto;gap:16px;align-items:center;padding:8px;border-radius:var(--dso-r-item);color:inherit;text-decoration:none}a.dialog-search-product:hover{background:var(--dso-hover)}.dialog-search-product-thumb{flex:none;width:56px;height:56px;overflow:hidden;border:1px solid var(--dso-border);border-radius:var(--dso-r-thumb);background:var(--dso-thumb)}.dialog-search-product-thumb img{display:block;width:100%;height:100%;object-fit:cover}.dialog-search-product-title{flex:1;min-width:0;font-size:14px;line-height:1.3;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;word-break:break-word}.dialog-search-product-price{font-size:15px;font-weight:600;font-variant-numeric:tabular-nums;white-space:nowrap}@media(min-width:768px){.dialog-search-panel--grid .dialog-search-product{display:flex;flex-direction:column;align-items:stretch;gap:10px;padding:12px;border:1px solid var(--dso-border)}.dialog-search-panel--grid .dialog-search-product-thumb{width:100%;height:auto;aspect-ratio:4 / 3;border:0}}@media(max-width:767px){.dialog-search-product{grid-template-columns:52px minmax(0,1fr) auto;gap:12px}.dialog-search-product-thumb{width:52px;height:52px}.dialog-search-product-price{font-size:14px}}.dialog-search-collections{display:flex;flex-direction:column;gap:4px;min-height:0;padding:20px 12px 20px 24px;border-right:1px solid var(--dso-border);background:var(--dso-side);overflow-y:auto}.dialog-search-collection-list{display:flex;flex-direction:column;gap:4px;margin:0;padding:0;list-style:none}.dialog-search-collection{display:flex;align-items:center;gap:12px;padding:8px 12px;border-radius:var(--dso-r-item);color:inherit;text-decoration:none}.dialog-search-collection:hover{background:var(--dso-hover)}.dialog-search-collection-thumb{flex:none;width:40px;height:40px;overflow:hidden;border-radius:var(--dso-r-thumb);background:var(--dso-thumb)}.dialog-search-collection-thumb img{display:block;width:100%;height:100%;object-fit:cover}.dialog-search-collection-title{flex:1;min-width:0;font-size:14px;line-height:1.3;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;word-break:break-word}.dialog-search-caret{display:inline-flex;flex:none;color:var(--dso-text-sec)}@media(max-width:767px){.dialog-search-collections{flex:none;gap:10px;padding:0;border-right:0;background:transparent;overflow:visible}.dialog-search-collections .dialog-search-section-head{padding:0 16px}.dialog-search-collection-list{flex-direction:row;gap:10px;padding:0 16px;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}.dialog-search-collection-list::-webkit-scrollbar{display:none}.dialog-search-collection{flex:none;flex-direction:column;align-items:stretch;gap:8px;width:80px;padding:0}.dialog-search-collection-thumb{width:80px;height:50px;border-radius:var(--dso-r-item)}.dialog-search-collection-title{font-size:13px}.dialog-search-caret{display:none}}.dialog-search-products{display:flex;flex-direction:column;gap:14px;min-height:0;padding:20px 24px 12px;overflow-y:auto}.dialog-search-products .dialog-search-section-head{padding:0 8px}.dialog-search-results{display:flex;flex-direction:column;margin:0;padding:0;list-style:none}.dialog-search-empty{padding:8px;color:var(--dso-text-sec)}@media(min-width:768px){.dialog-search-panel--grid .dialog-search-results{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}}@media(max-width:767px){.dialog-search-products{gap:6px;padding:0 8px 8px;overflow:visible}}.dialog-search-panel{position:fixed;z-index:9999;box-sizing:border-box;display:flex;flex-direction:column;margin:0;padding:0;background:var(--dso-panel);border-radius:var(--dso-r-panel);box-shadow:0 24px 64px #00000047;overflow:hidden;font-family:var(--dso-font, inherit);font-size:14px;line-height:1.35;color:var(--dso-text);-webkit-font-smoothing:antialiased}.dialog-search-panel *,.dialog-search-panel *:before,.dialog-search-panel *:after{box-sizing:border-box}.dialog-search-status{margin:0;padding:16px 24px;color:var(--dso-text-sec)}.dialog-search-status-error{color:#b3261e}.dialog-search-error{display:flex;flex-direction:column;align-items:flex-start;gap:8px;padding-bottom:16px}.dialog-search-retry{margin:0 24px;padding:6px 14px;border:1px solid var(--dso-border);border-radius:var(--dso-r-btn);background:transparent;font:inherit;font-size:13px;color:var(--dso-text);cursor:pointer;transition:background-color .12s ease}.dialog-search-retry:hover{background-color:var(--dso-hover)}.dialog-search-body{display:grid;grid-template-columns:340px minmax(0,1fr);flex:1;min-height:0}.dialog-search-body--no-collections{grid-template-columns:minmax(0,1fr)}.dialog-search-section-head{display:flex;justify-content:space-between;align-items:baseline;padding:0 12px 8px}.dialog-search-label{margin:0;font-size:11px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--dso-text-sec)}.dialog-search-label-count{font-size:12px;font-weight:500;letter-spacing:0;text-transform:none}.dialog-search-count{font-size:12px;color:var(--dso-text-sec)}.dialog-search-footer{display:flex;justify-content:flex-end;align-items:center;flex:none;padding:14px 24px;border-top:1px solid var(--dso-border)}.dialog-search-cta{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:40px;padding:0 20px;border:1px solid var(--dso-primary);border-radius:var(--dso-r-btn);background:var(--dso-primary);color:var(--dso-cta-text);font-size:14px;font-weight:500;text-decoration:none}.dialog-search-cta:hover{filter:brightness(.95)}.dialog-search-footer .dialog-search-pagination{flex:1}@media(max-width:767px){.dialog-search-body{display:flex;flex-direction:column;gap:18px;padding-top:16px;overflow-y:auto}.dialog-search-footer{padding:12px 16px}.dialog-search-cta{width:100%;height:44px}.dialog-search-cta svg{display:none}}