@askdialog/dialog-vue 3.4.0 → 3.5.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 ADDED
@@ -0,0 +1,324 @@
1
+ # @askdialog/dialog-vue
2
+
3
+ Vue 3 component library for Dialog AI-powered product assistance.
4
+
5
+ ## Table of contents
6
+
7
+ - [Installation](#installation)
8
+ - [Usage](#usage)
9
+ - [Available Components](#available-components)
10
+ - [DialogProductBlock](#dialogproductblock)
11
+ - [DialogInput](#dialoginput)
12
+ - [Storefront search](#storefront-search)
13
+ - [useDialogSearch](#usedialogsearch)
14
+ - [DialogSearchBar](#dialogsearchbar)
15
+ - [DialogSearchResults](#dialogsearchresults)
16
+ - [DialogSearchPagination](#dialogsearchpagination)
17
+ - [Theming](#theming)
18
+ - [Development](#development)
19
+ - [TypeScript](#typescript)
20
+ - [Vue Version](#vue-version)
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ npm install @askdialog/dialog-vue @askdialog/dialog-sdk
26
+ # or
27
+ pnpm add @askdialog/dialog-vue @askdialog/dialog-sdk
28
+ # or
29
+ yarn add @askdialog/dialog-vue @askdialog/dialog-sdk
30
+ ```
31
+
32
+ ## Usage
33
+
34
+ ```vue
35
+ <script setup lang="ts">
36
+ import { Dialog } from '@askdialog/dialog-sdk';
37
+ import { DialogProductBlock } from '@askdialog/dialog-vue';
38
+ import '@askdialog/dialog-vue/style.css';
39
+
40
+ const client = new Dialog({
41
+ apiKey: 'your-api-key',
42
+ locale: 'en',
43
+ callbacks: {
44
+ addToCart: () => Promise.resolve(),
45
+ getProduct: () => Promise.resolve({
46
+ // Product data
47
+ }),
48
+ },
49
+ });
50
+ </script>
51
+
52
+ <template>
53
+ <DialogProductBlock
54
+ :client="client"
55
+ product-id="product-123"
56
+ product-title="Product Name"
57
+ />
58
+ </template>
59
+ ```
60
+
61
+ ## Available Components
62
+
63
+ ### DialogProductBlock
64
+
65
+ Full-featured dialog component with suggestions and input.
66
+
67
+ **Props:**
68
+ - `client` (Dialog) - Dialog SDK client instance (required)
69
+ - `productId` (string) - Product ID (required)
70
+ - `productTitle` (string) - Product title (required)
71
+ - `selectedVariantId` (string, optional) - Selected variant ID
72
+ - `enableInput` (boolean, optional) - Enable input field (default: true)
73
+
74
+ **Example:**
75
+ ```vue
76
+ <DialogProductBlock
77
+ :client="client"
78
+ product-id="9403924119882"
79
+ product-title="Blizzard King All-Mountain Snowboard"
80
+ selected-variant-id="variant-123"
81
+ :enable-input="true"
82
+ />
83
+ ```
84
+
85
+ ### DialogInput
86
+
87
+ Standalone input component for asking questions.
88
+
89
+ **Props:**
90
+ - `client` (Dialog) - Dialog SDK client instance (required)
91
+ - `productId` (string) - Product ID (required)
92
+ - `productTitle` (string) - Product title (required)
93
+ - `placeholder` (string, optional) - Input placeholder text
94
+ - `selectedVariantId` (string, optional) - Selected variant ID
95
+
96
+ **Example:**
97
+ ```vue
98
+ <DialogInput
99
+ :client="client"
100
+ product-id="9403924119882"
101
+ product-title="Product Name"
102
+ placeholder="Ask something about this product..."
103
+ />
104
+ ```
105
+
106
+ ### Storefront search
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.
109
+
110
+ ```vue
111
+ <script setup lang="ts">
112
+ import { Dialog } from '@askdialog/dialog-sdk';
113
+ import {
114
+ DialogSearchBar,
115
+ DialogSearchResults,
116
+ useDialogSearch,
117
+ } from '@askdialog/dialog-vue';
118
+ import '@askdialog/dialog-vue/style.css';
119
+
120
+ const client = new Dialog({ apiKey: 'your-api-key', locale: 'en' });
121
+
122
+ const { controller, state } = useDialogSearch({ client });
123
+ </script>
124
+
125
+ <template>
126
+ <DialogSearchBar :controller="controller" placeholder="Search products..." />
127
+ <DialogSearchResults :controller="controller" :state="state" />
128
+ </template>
129
+ ```
130
+
131
+ #### useDialogSearch
132
+
133
+ Creates one search controller per composable instance and disposes it on unmount.
134
+
135
+ **Options:**
136
+ - `client` (Dialog) - Dialog SDK client instance (required)
137
+ - `surface` (SearchSurface, optional) - Where results are displayed, for analytics (default: `'search_page'`)
138
+ - `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
+ - `debounceMs` (number, optional) - Keystroke debounce (default: 250)
140
+ - `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
142
+
143
+ Options are read once during setup — later changes don't rebind the live controller.
144
+
145
+ **Returns:** `{ controller, state }` — pass both to the components below. `state` is a `ShallowRef`; `state.value.status` is `idle` / `loading` / `success` / `empty` / `error`.
146
+
147
+ #### DialogSearchBar
148
+
149
+ Search input: typing runs a debounced search, submitting (Enter) searches immediately.
150
+
151
+ **Props:**
152
+ - `controller` (SearchController) - From `useDialogSearch` (required)
153
+ - `placeholder` (string, optional) - Input placeholder text (default: `'Search products...'`)
154
+ - `autoFocus` (boolean, optional) - Focus the input on mount (default: false)
155
+ - `submitAriaLabel` (string, optional) - Accessible label of the submit button (default: `'Search'`)
156
+
157
+ #### DialogSearchResults
158
+
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.
160
+
161
+ **Props:**
162
+ - `controller` (SearchController) - From `useDialogSearch` (required)
163
+ - `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)
165
+
166
+ #### DialogSearchPagination
167
+
168
+ Previous/next controls with a page indicator; hidden while there is a single page. Rendered by `DialogSearchResults` — exported only for custom layouts.
169
+
170
+ **Props:**
171
+ - `controller` (SearchController) - From `useDialogSearch` (required)
172
+ - `state` (SearchControllerState) - From `useDialogSearch` (required)
173
+
174
+ ## Theming
175
+
176
+ The components use CSS variables for theming. You can customize the theme through the Dialog SDK client:
177
+
178
+ ```ts
179
+ const client = new Dialog({
180
+ apiKey: 'your-api-key',
181
+ theme: {
182
+ backgroundColor: 'pink',
183
+ primaryColor: 'pink',
184
+ ctaTextColor: 'white',
185
+ ctaBorderType: 'rounded',
186
+ capitalizeCtas: true,
187
+ fontFamily: 'Arial',
188
+ highlightProductName: true,
189
+ title: {
190
+ fontSize: '22px',
191
+ color: 'purple',
192
+ },
193
+ description: {
194
+ color: 'blue',
195
+ fontSize: '18px',
196
+ },
197
+ content: {
198
+ color: 'green',
199
+ fontSize: '10px',
200
+ },
201
+ },
202
+ });
203
+ ```
204
+
205
+ ## Development
206
+
207
+ This section is for contributors working on the library itself.
208
+
209
+ ### Prerequisites
210
+
211
+ - Node.js >= 22
212
+ - pnpm >= 10
213
+
214
+ ### Setup
215
+
216
+ ```bash
217
+ # From monorepo root
218
+ pnpm install
219
+ ```
220
+
221
+ ### Development Workflows
222
+
223
+ #### Daily Development
224
+
225
+ Work on components with instant feedback:
226
+
227
+ ```bash
228
+ # From monorepo root
229
+ pnpm dev:vue-example
230
+ # Opens vue-example app at http://localhost:5173
231
+ ```
232
+
233
+ **What happens:**
234
+ - The example app runs with Vite dev server
235
+ - Components are resolved from **source files** (`packages/vue/src/`) via alias
236
+ - Changes to components are immediately reflected (HMR enabled)
237
+ - No rebuild required
238
+
239
+ #### Testing Built Library
240
+
241
+ Test the library as consumers would receive it from npm:
242
+
243
+ ```bash
244
+ # Step 1: Build the library
245
+ pnpm build:vue
246
+
247
+ # Step 2: Run example app against built dist/
248
+ cd packages/vue-example
249
+ pnpm dev:test-dist
250
+ # Or from root: TEST_DIST=true pnpm dev:vue-example
251
+ ```
252
+
253
+ **When to use:**
254
+ - Before creating a pull request
255
+ - After modifying build configuration
256
+ - To verify the build works correctly
257
+ - Before publishing a new version
258
+
259
+ ### Build Commands
260
+
261
+ ```bash
262
+ # Build the library only
263
+ pnpm build:vue
264
+
265
+ # Build all packages in the monorepo
266
+ pnpm build
267
+
268
+ # Clean dist folder
269
+ pnpm --filter @askdialog/dialog-vue clean
270
+
271
+ # Lint code
272
+ pnpm --filter @askdialog/dialog-vue lint
273
+
274
+ # Fix linting issues
275
+ pnpm --filter @askdialog/dialog-vue lint:fix
276
+ ```
277
+
278
+ ### Project Structure
279
+
280
+ ```
281
+ packages/vue/
282
+ ├── src/
283
+ │ ├── main.ts # Library entry point
284
+ │ ├── components/ # Exported components
285
+ │ │ ├── index.ts # Component barrel export
286
+ │ │ ├── DialogProductBlock/
287
+ │ │ │ ├── DialogProductBlock.vue
288
+ │ │ │ ├── DialogInput.vue
289
+ │ │ │ ├── ThemeProvider.vue
290
+ │ │ │ └── ...
291
+ │ │ └── DialogSearch/
292
+ │ │ ├── DialogSearchBar.vue
293
+ │ │ ├── DialogSearchResults.vue
294
+ │ │ ├── useDialogSearch.ts
295
+ │ │ └── ...
296
+ │ └── icons/ # Icon components
297
+ ├── dist/ # Build output (gitignored)
298
+ ├── package.json
299
+ ├── vite.config.ts # Library build configuration
300
+ └── project.json # Nx configuration
301
+ ```
302
+
303
+ ### Publishing
304
+
305
+ ```bash
306
+ # From monorepo root
307
+ pnpm publish:vue
308
+ ```
309
+
310
+ **Pre-publish checklist:**
311
+ - [ ] All tests pass
312
+ - [ ] Version updated in `package.json`
313
+ - [ ] Tested with built library (`pnpm dev:test-dist`)
314
+ - [ ] Tarball inspected with `pnpm pack`
315
+ - [ ] CHANGELOG updated
316
+
317
+ ## TypeScript
318
+
319
+ This package includes TypeScript type definitions. The types are automatically available when you install the package.
320
+
321
+ ## Vue Version
322
+
323
+ This package requires Vue 3 or higher as a peer dependency.
324
+
@@ -1,4 +1,3 @@
1
- import { SearchPriceRange, SearchProduct } from '@askdialog/dialog-sdk';
1
+ import { SearchPriceRange } from '@askdialog/dialog-sdk';
2
2
  export declare const formatSearchPrice: (priceRange: SearchPriceRange | undefined, locale?: string) => string;
3
- export declare const formatSearchCompareAtPrice: (product: SearchProduct, locale?: string) => string;
4
3
  export declare const safeProductHref: (url: string) => string | undefined;
@@ -8,8 +8,8 @@ export interface UseDialogSearchOptions {
8
8
  navigate?: (url: string, hit: SearchHit) => void;
9
9
  debounceMs?: number;
10
10
  hitsPerPage?: number;
11
+ /** Storefront locale for the searched index (`products_fr`); defaults to the client's. */
11
12
  locale?: string;
12
- countryCode?: string;
13
13
  }
14
14
  export interface DialogSearch {
15
15
  controller: SearchController;
@@ -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-card-compare-at{color:#a3a3a3;text-decoration:line-through}.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;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}