@wix/headless-stores 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/astro/actions/package.json +4 -0
- package/cjs/dist/astro/actions/custom-checkout.d.ts +50 -0
- package/cjs/dist/astro/actions/custom-checkout.js +53 -0
- package/cjs/dist/astro/actions/index.d.ts +1 -0
- package/cjs/dist/astro/actions/index.js +1 -0
- package/cjs/dist/data-component-tags.d.ts +8 -0
- package/cjs/dist/data-component-tags.js +9 -0
- package/cjs/dist/enums/index.d.ts +2 -0
- package/cjs/dist/enums/index.js +2 -0
- package/cjs/dist/enums/social-platform-enums.d.ts +25 -0
- package/cjs/dist/enums/social-platform-enums.js +27 -0
- package/cjs/dist/enums/sort-enums.d.ts +17 -0
- package/cjs/dist/enums/sort-enums.js +18 -0
- package/cjs/dist/react/Category.d.ts +242 -0
- package/cjs/dist/react/Category.js +235 -0
- package/cjs/dist/react/CategoryList.d.ts +107 -0
- package/cjs/dist/react/CategoryList.js +91 -0
- package/cjs/dist/react/Choice.d.ts +211 -0
- package/cjs/dist/react/Choice.js +213 -0
- package/cjs/dist/react/Option.d.ts +242 -0
- package/cjs/dist/react/Option.js +346 -0
- package/cjs/dist/react/Product.d.ts +1065 -0
- package/cjs/dist/react/Product.js +1157 -0
- package/cjs/dist/react/ProductList.d.ts +400 -0
- package/cjs/dist/react/ProductList.js +368 -0
- package/cjs/dist/react/core/CategoryList.d.ts +194 -0
- package/cjs/dist/react/core/CategoryList.js +180 -0
- package/cjs/dist/react/core/Product.d.ts +225 -0
- package/cjs/dist/react/core/Product.js +190 -0
- package/cjs/dist/react/core/ProductList.d.ts +235 -0
- package/cjs/dist/react/core/ProductList.js +217 -0
- package/cjs/dist/react/core/ProductListFilters.d.ts +138 -0
- package/cjs/dist/react/core/ProductListFilters.js +242 -0
- package/cjs/dist/react/core/ProductListPagination.d.ts +49 -0
- package/cjs/dist/react/core/ProductListPagination.js +41 -0
- package/cjs/dist/react/core/ProductListSort.d.ts +19 -0
- package/cjs/dist/react/core/ProductListSort.js +52 -0
- package/cjs/dist/react/core/ProductModifiers.d.ts +416 -0
- package/cjs/dist/react/core/ProductModifiers.js +413 -0
- package/cjs/dist/react/core/ProductVariantSelector.d.ts +313 -0
- package/cjs/dist/react/core/ProductVariantSelector.js +291 -0
- package/cjs/dist/react/core/SelectedVariant.d.ts +230 -0
- package/cjs/dist/react/core/SelectedVariant.js +269 -0
- package/cjs/dist/react/index.d.ts +6 -0
- package/cjs/dist/react/index.js +6 -0
- package/cjs/dist/react/types.d.ts +8 -0
- package/cjs/dist/react/types.js +9 -0
- package/cjs/dist/server-actions/custom-checkout-action.d.ts +49 -0
- package/cjs/dist/server-actions/custom-checkout-action.js +64 -0
- package/cjs/dist/server-actions/index.d.ts +1 -0
- package/cjs/dist/server-actions/index.js +1 -0
- package/cjs/dist/services/buy-now-service.d.ts +346 -0
- package/cjs/dist/services/buy-now-service.js +197 -0
- package/cjs/dist/services/categories-list-service.d.ts +164 -0
- package/cjs/dist/services/categories-list-service.js +148 -0
- package/cjs/dist/services/index.d.ts +5 -0
- package/cjs/dist/services/index.js +5 -0
- package/cjs/dist/services/pay-now-service.d.ts +214 -0
- package/cjs/dist/services/pay-now-service.js +156 -0
- package/cjs/dist/services/product-modifiers-service.d.ts +34 -0
- package/cjs/dist/services/product-modifiers-service.js +107 -0
- package/cjs/dist/services/product-service.d.ts +177 -0
- package/cjs/dist/services/product-service.js +190 -0
- package/cjs/dist/services/products-list-search-service.d.ts +1 -0
- package/cjs/dist/services/products-list-search-service.js +1 -0
- package/cjs/dist/services/products-list-service.d.ts +429 -0
- package/cjs/dist/services/products-list-service.js +893 -0
- package/cjs/dist/services/selected-variant-service.d.ts +66 -0
- package/cjs/dist/services/selected-variant-service.js +527 -0
- package/cjs/dist/utils/index.d.ts +1 -0
- package/cjs/dist/utils/index.js +30 -0
- package/cjs/dist/utils/url-params.d.ts +73 -0
- package/cjs/dist/utils/url-params.js +114 -0
- package/cjs/package.json +3 -0
- package/dist/astro/actions/custom-checkout.d.ts +50 -0
- package/dist/astro/actions/custom-checkout.js +53 -0
- package/dist/astro/actions/index.d.ts +1 -0
- package/dist/astro/actions/index.js +1 -0
- package/dist/data-component-tags.d.ts +8 -0
- package/dist/data-component-tags.js +9 -0
- package/dist/enums/index.d.ts +2 -0
- package/dist/enums/index.js +2 -0
- package/dist/enums/social-platform-enums.d.ts +25 -0
- package/dist/enums/social-platform-enums.js +27 -0
- package/dist/enums/sort-enums.d.ts +17 -0
- package/dist/enums/sort-enums.js +18 -0
- package/dist/react/Category.d.ts +242 -0
- package/dist/react/Category.js +235 -0
- package/dist/react/CategoryList.d.ts +107 -0
- package/dist/react/CategoryList.js +91 -0
- package/dist/react/Choice.d.ts +211 -0
- package/dist/react/Choice.js +213 -0
- package/dist/react/Option.d.ts +242 -0
- package/dist/react/Option.js +346 -0
- package/dist/react/Product.d.ts +1065 -0
- package/dist/react/Product.js +1157 -0
- package/dist/react/ProductList.d.ts +400 -0
- package/dist/react/ProductList.js +368 -0
- package/dist/react/core/CategoryList.d.ts +194 -0
- package/dist/react/core/CategoryList.js +180 -0
- package/dist/react/core/Product.d.ts +225 -0
- package/dist/react/core/Product.js +190 -0
- package/dist/react/core/ProductList.d.ts +235 -0
- package/dist/react/core/ProductList.js +217 -0
- package/dist/react/core/ProductListFilters.d.ts +138 -0
- package/dist/react/core/ProductListFilters.js +242 -0
- package/dist/react/core/ProductListPagination.d.ts +49 -0
- package/dist/react/core/ProductListPagination.js +41 -0
- package/dist/react/core/ProductListSort.d.ts +19 -0
- package/dist/react/core/ProductListSort.js +52 -0
- package/dist/react/core/ProductModifiers.d.ts +416 -0
- package/dist/react/core/ProductModifiers.js +413 -0
- package/dist/react/core/ProductVariantSelector.d.ts +313 -0
- package/dist/react/core/ProductVariantSelector.js +291 -0
- package/dist/react/core/SelectedVariant.d.ts +230 -0
- package/dist/react/core/SelectedVariant.js +269 -0
- package/dist/react/index.d.ts +6 -0
- package/dist/react/index.js +6 -0
- package/dist/react/types.d.ts +8 -0
- package/dist/react/types.js +9 -0
- package/dist/server-actions/custom-checkout-action.d.ts +49 -0
- package/dist/server-actions/custom-checkout-action.js +64 -0
- package/dist/server-actions/index.d.ts +1 -0
- package/dist/server-actions/index.js +1 -0
- package/dist/services/buy-now-service.d.ts +346 -0
- package/dist/services/buy-now-service.js +197 -0
- package/dist/services/categories-list-service.d.ts +164 -0
- package/dist/services/categories-list-service.js +148 -0
- package/dist/services/index.d.ts +5 -0
- package/dist/services/index.js +5 -0
- package/dist/services/pay-now-service.d.ts +214 -0
- package/dist/services/pay-now-service.js +156 -0
- package/dist/services/product-modifiers-service.d.ts +34 -0
- package/dist/services/product-modifiers-service.js +107 -0
- package/dist/services/product-service.d.ts +177 -0
- package/dist/services/product-service.js +190 -0
- package/dist/services/products-list-search-service.d.ts +0 -0
- package/dist/services/products-list-search-service.js +1 -0
- package/dist/services/products-list-service.d.ts +429 -0
- package/dist/services/products-list-service.js +893 -0
- package/dist/services/selected-variant-service.d.ts +66 -0
- package/dist/services/selected-variant-service.js +527 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +30 -0
- package/dist/utils/url-params.d.ts +73 -0
- package/dist/utils/url-params.js +114 -0
- package/package.json +89 -0
- package/react/package.json +4 -0
- package/server-actions/package.json +4 -0
- package/services/package.json +4 -0
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
import { SelectedVariantServiceConfig } from '../../services/selected-variant-service.js';
|
|
2
|
+
import { type ConnectedOption, type ConnectedOptionChoice, InventoryAvailabilityStatus } from '@wix/auto_sdk_stores_products-v-3';
|
|
3
|
+
export interface RootProps {
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
selectedVariantServiceConfig?: SelectedVariantServiceConfig;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Root component that provides the ProductVariantSelector service context to its children.
|
|
9
|
+
* This component sets up the necessary services for rendering and managing product variant selection.
|
|
10
|
+
*
|
|
11
|
+
* @order 1
|
|
12
|
+
* @component
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* import { ProductVariantSelector } from '@wix/stores/components';
|
|
16
|
+
*
|
|
17
|
+
* function VariantSelector() {
|
|
18
|
+
* return (
|
|
19
|
+
* <ProductVariantSelector.Root selectedVariantServiceConfig={{ fetchInventoryData: true }}>
|
|
20
|
+
* <div>
|
|
21
|
+
* <ProductVariantSelector.Options>
|
|
22
|
+
* {({ options, hasOptions, selectedChoices }) => (
|
|
23
|
+
* <div>
|
|
24
|
+
* {hasOptions && options.map(option => (
|
|
25
|
+
* <div key={option.id}>
|
|
26
|
+
* <label>{option.name}</label>
|
|
27
|
+
* <select value={selectedChoices[option.id] || ''}>
|
|
28
|
+
* {option.choices?.map(choice => (
|
|
29
|
+
* <option key={choice.id} value={choice.id}>
|
|
30
|
+
* {choice.description}
|
|
31
|
+
* </option>
|
|
32
|
+
* ))}
|
|
33
|
+
* </select>
|
|
34
|
+
* </div>
|
|
35
|
+
* ))}
|
|
36
|
+
* </div>
|
|
37
|
+
* )}
|
|
38
|
+
* </ProductVariantSelector.Options>
|
|
39
|
+
* </div>
|
|
40
|
+
* </ProductVariantSelector.Root>
|
|
41
|
+
* );
|
|
42
|
+
* }
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export declare function Root(props: RootProps): React.ReactNode;
|
|
46
|
+
/**
|
|
47
|
+
* Props for Options headless component
|
|
48
|
+
*/
|
|
49
|
+
export interface OptionsProps {
|
|
50
|
+
/** Render prop function that receives options data */
|
|
51
|
+
children: (props: OptionsRenderProps) => React.ReactNode;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Render props for Options component
|
|
55
|
+
*/
|
|
56
|
+
export interface OptionsRenderProps {
|
|
57
|
+
/** Array of product options */
|
|
58
|
+
options: ConnectedOption[];
|
|
59
|
+
/** Whether product has options */
|
|
60
|
+
hasOptions: boolean;
|
|
61
|
+
/** Currently selected choices */
|
|
62
|
+
selectedChoices: Record<string, string>;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Headless component for all product options
|
|
66
|
+
*
|
|
67
|
+
* @component
|
|
68
|
+
* @example
|
|
69
|
+
* ```tsx
|
|
70
|
+
* import { ProductVariantSelector } from '@wix/stores/components';
|
|
71
|
+
*
|
|
72
|
+
* function VariantPicker() {
|
|
73
|
+
* return (
|
|
74
|
+
* <ProductVariantSelector.Options>
|
|
75
|
+
* {({ options, hasOptions, selectedChoices }) => (
|
|
76
|
+
* <div>
|
|
77
|
+
* {hasOptions && options.map(option => (
|
|
78
|
+
* <div key={option.id}>
|
|
79
|
+
* <label>{option.name}</label>
|
|
80
|
+
* <select value={selectedChoices[option.id] || ''}>
|
|
81
|
+
* {option.choices?.map(choice => (
|
|
82
|
+
* <option key={choice.id} value={choice.id}>
|
|
83
|
+
* {choice.description}
|
|
84
|
+
* </option>
|
|
85
|
+
* ))}
|
|
86
|
+
* </select>
|
|
87
|
+
* </div>
|
|
88
|
+
* ))}
|
|
89
|
+
* </div>
|
|
90
|
+
* )}
|
|
91
|
+
* </ProductVariantSelector.Options>
|
|
92
|
+
* );
|
|
93
|
+
* }
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export declare function Options(props: OptionsProps): import("react").ReactNode;
|
|
97
|
+
/**
|
|
98
|
+
* Props for Option headless component
|
|
99
|
+
*/
|
|
100
|
+
export interface OptionProps {
|
|
101
|
+
/** Product option data */
|
|
102
|
+
option: ConnectedOption;
|
|
103
|
+
/** Render prop function that receives option data */
|
|
104
|
+
children: (props: OptionRenderProps) => React.ReactNode;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Render props for Option component
|
|
108
|
+
*/
|
|
109
|
+
export interface OptionRenderProps {
|
|
110
|
+
/** Option name */
|
|
111
|
+
name: string;
|
|
112
|
+
/** Array of choices for this option */
|
|
113
|
+
choices: ConnectedOptionChoice[];
|
|
114
|
+
/** Currently selected value for this option */
|
|
115
|
+
selectedValue: string | null;
|
|
116
|
+
/** Whether this option has choices */
|
|
117
|
+
hasChoices: boolean;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Headless component for choices within a specific product option
|
|
121
|
+
*
|
|
122
|
+
* @component
|
|
123
|
+
* @example
|
|
124
|
+
* ```tsx
|
|
125
|
+
* import { ProductVariantSelector } from '@wix/stores/components';
|
|
126
|
+
*
|
|
127
|
+
* function OptionSelector({ option }) {
|
|
128
|
+
* return (
|
|
129
|
+
* <ProductVariantSelector.Option option={option}>
|
|
130
|
+
* {({ name, choices, selectedValue, hasChoices }) => (
|
|
131
|
+
* <div>
|
|
132
|
+
* <label>{name}</label>
|
|
133
|
+
* {hasChoices && (
|
|
134
|
+
* <select value={selectedValue || ''}>
|
|
135
|
+
* <option value="">Select {name}</option>
|
|
136
|
+
* {choices.map(choice => (
|
|
137
|
+
* <option key={choice.id} value={choice.name}>
|
|
138
|
+
* {choice.description}
|
|
139
|
+
* </option>
|
|
140
|
+
* ))}
|
|
141
|
+
* </select>
|
|
142
|
+
* )}
|
|
143
|
+
* </div>
|
|
144
|
+
* )}
|
|
145
|
+
* </ProductVariantSelector.Option>
|
|
146
|
+
* );
|
|
147
|
+
* }
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
export declare function Option(props: OptionProps): import("react").ReactNode;
|
|
151
|
+
/**
|
|
152
|
+
* Props for Choice headless component
|
|
153
|
+
*/
|
|
154
|
+
export interface ChoiceProps {
|
|
155
|
+
/** Product option data */
|
|
156
|
+
option: ConnectedOption;
|
|
157
|
+
/** Choice data */
|
|
158
|
+
choice: ConnectedOptionChoice;
|
|
159
|
+
/** Render prop function that receives choice data */
|
|
160
|
+
children: (props: ChoiceRenderProps) => React.ReactNode;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Render props for Choice component
|
|
164
|
+
*/
|
|
165
|
+
export interface ChoiceRenderProps {
|
|
166
|
+
/** Choice value to display */
|
|
167
|
+
value: string;
|
|
168
|
+
/** Whether this choice is currently selected */
|
|
169
|
+
isSelected: boolean;
|
|
170
|
+
/** Whether this choice is visible */
|
|
171
|
+
isVisible: boolean;
|
|
172
|
+
/** Whether this choice is in stock */
|
|
173
|
+
isInStock: boolean;
|
|
174
|
+
/** Whether this choice is available for pre-order */
|
|
175
|
+
isPreOrderEnabled: boolean;
|
|
176
|
+
/** Function to select this choice */
|
|
177
|
+
select: () => void;
|
|
178
|
+
/** Option name */
|
|
179
|
+
optionName: string;
|
|
180
|
+
/** Choice value */
|
|
181
|
+
choiceValue: string;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Headless component for individual choice selection
|
|
185
|
+
*
|
|
186
|
+
* @component
|
|
187
|
+
* @example
|
|
188
|
+
* ```tsx
|
|
189
|
+
* import { ProductVariantSelector } from '@wix/stores/components';
|
|
190
|
+
*
|
|
191
|
+
* function ChoiceButton({ option, choice }) {
|
|
192
|
+
* return (
|
|
193
|
+
* <ProductVariantSelector.Choice option={option} choice={choice}>
|
|
194
|
+
* {({ value, isSelected, isVisible, isInStock, select }) => (
|
|
195
|
+
* <button
|
|
196
|
+
* onClick={select}
|
|
197
|
+
* disabled={!isVisible || !isInStock}
|
|
198
|
+
* className={`choice-btn ${isSelected ? 'selected' : ''} ${!isInStock ? 'out-of-stock' : ''}`}
|
|
199
|
+
* >
|
|
200
|
+
* {value}
|
|
201
|
+
* {!isInStock && ' (Out of Stock)'}
|
|
202
|
+
* </button>
|
|
203
|
+
* )}
|
|
204
|
+
* </ProductVariantSelector.Choice>
|
|
205
|
+
* );
|
|
206
|
+
* }
|
|
207
|
+
* ```
|
|
208
|
+
*/
|
|
209
|
+
export declare function Choice(props: ChoiceProps): import("react").ReactNode;
|
|
210
|
+
/**
|
|
211
|
+
* Props for Stock headless component
|
|
212
|
+
*/
|
|
213
|
+
export interface StockProps {
|
|
214
|
+
/** Render prop function that receives stock data */
|
|
215
|
+
children: (props: StockRenderProps) => React.ReactNode;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Render props for Stock component
|
|
219
|
+
*/
|
|
220
|
+
export interface StockRenderProps {
|
|
221
|
+
/** Whether product is in stock */
|
|
222
|
+
inStock: boolean;
|
|
223
|
+
/** Whether pre-order is enabled */
|
|
224
|
+
isPreOrderEnabled: boolean;
|
|
225
|
+
/** Raw inventory availability status */
|
|
226
|
+
availabilityStatus: InventoryAvailabilityStatus | string;
|
|
227
|
+
/** Whether stock tracking is enabled */
|
|
228
|
+
trackInventory: boolean;
|
|
229
|
+
/** Current variant id */
|
|
230
|
+
currentVariantId: string | null;
|
|
231
|
+
/** Available quantity */
|
|
232
|
+
availableQuantity: number | null;
|
|
233
|
+
/** Currently selected quantity */
|
|
234
|
+
selectedQuantity: number;
|
|
235
|
+
/** Function to increment quantity */
|
|
236
|
+
incrementQuantity: () => void;
|
|
237
|
+
/** Function to decrement quantity */
|
|
238
|
+
decrementQuantity: () => void;
|
|
239
|
+
/** Function to set selected quantity */
|
|
240
|
+
setSelectedQuantity: (quantity: number) => void;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Headless component for product stock status
|
|
244
|
+
*
|
|
245
|
+
* @component
|
|
246
|
+
* @example
|
|
247
|
+
* ```tsx
|
|
248
|
+
* import { ProductVariantSelector } from '@wix/stores/components';
|
|
249
|
+
*
|
|
250
|
+
* function StockIndicator() {
|
|
251
|
+
* return (
|
|
252
|
+
* <ProductVariantSelector.Stock>
|
|
253
|
+
* {({ inStock, isPreOrderEnabled, selectedQuantity, availableQuantity, incrementQuantity, decrementQuantity }) => (
|
|
254
|
+
* <div>
|
|
255
|
+
* <div className={`stock-status ${inStock ? 'in-stock' : 'out-of-stock'}`}>
|
|
256
|
+
* {inStock ? 'In Stock' : isPreOrderEnabled ? 'Pre-order Available' : 'Out of Stock'}
|
|
257
|
+
* </div>
|
|
258
|
+
* {availableQuantity && (
|
|
259
|
+
* <div>Only {availableQuantity} left!</div>
|
|
260
|
+
* )}
|
|
261
|
+
* <div className="quantity-selector">
|
|
262
|
+
* <button onClick={decrementQuantity}>-</button>
|
|
263
|
+
* <span>{selectedQuantity}</span>
|
|
264
|
+
* <button onClick={incrementQuantity}>+</button>
|
|
265
|
+
* </div>
|
|
266
|
+
* </div>
|
|
267
|
+
* )}
|
|
268
|
+
* </ProductVariantSelector.Stock>
|
|
269
|
+
* );
|
|
270
|
+
* }
|
|
271
|
+
* ```
|
|
272
|
+
*/
|
|
273
|
+
export declare function Stock(props: StockProps): import("react").ReactNode;
|
|
274
|
+
/**
|
|
275
|
+
* Props for Reset headless component
|
|
276
|
+
*/
|
|
277
|
+
export interface ResetProps {
|
|
278
|
+
/** Render prop function that receives reset data */
|
|
279
|
+
children: (props: ResetRenderProps) => React.ReactNode;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Render props for Reset component
|
|
283
|
+
*/
|
|
284
|
+
export interface ResetRenderProps {
|
|
285
|
+
/** Function to reset all selections */
|
|
286
|
+
reset: () => void;
|
|
287
|
+
/** Whether the reset button should be rendered */
|
|
288
|
+
hasSelections: boolean;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Headless component for resetting variant selections
|
|
292
|
+
*
|
|
293
|
+
* @component
|
|
294
|
+
* @example
|
|
295
|
+
* ```tsx
|
|
296
|
+
* import { ProductVariantSelector } from '@wix/stores/components';
|
|
297
|
+
*
|
|
298
|
+
* function ResetButton() {
|
|
299
|
+
* return (
|
|
300
|
+
* <ProductVariantSelector.Reset>
|
|
301
|
+
* {({ reset, hasSelections }) => (
|
|
302
|
+
* hasSelections && (
|
|
303
|
+
* <button onClick={reset} className="reset-button">
|
|
304
|
+
* Clear All Selections
|
|
305
|
+
* </button>
|
|
306
|
+
* )
|
|
307
|
+
* )}
|
|
308
|
+
* </ProductVariantSelector.Reset>
|
|
309
|
+
* );
|
|
310
|
+
* }
|
|
311
|
+
* ```
|
|
312
|
+
*/
|
|
313
|
+
export declare function Reset(props: ResetProps): import("react").ReactNode;
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useService, WixServices } from '@wix/services-manager-react';
|
|
3
|
+
import { SelectedVariantServiceDefinition, SelectedVariantService, } from '../../services/selected-variant-service.js';
|
|
4
|
+
import { createServicesMap } from '@wix/services-manager';
|
|
5
|
+
import { InventoryAvailabilityStatus, } from '@wix/auto_sdk_stores_products-v-3';
|
|
6
|
+
/**
|
|
7
|
+
* Root component that provides the ProductVariantSelector service context to its children.
|
|
8
|
+
* This component sets up the necessary services for rendering and managing product variant selection.
|
|
9
|
+
*
|
|
10
|
+
* @order 1
|
|
11
|
+
* @component
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* import { ProductVariantSelector } from '@wix/stores/components';
|
|
15
|
+
*
|
|
16
|
+
* function VariantSelector() {
|
|
17
|
+
* return (
|
|
18
|
+
* <ProductVariantSelector.Root selectedVariantServiceConfig={{ fetchInventoryData: true }}>
|
|
19
|
+
* <div>
|
|
20
|
+
* <ProductVariantSelector.Options>
|
|
21
|
+
* {({ options, hasOptions, selectedChoices }) => (
|
|
22
|
+
* <div>
|
|
23
|
+
* {hasOptions && options.map(option => (
|
|
24
|
+
* <div key={option.id}>
|
|
25
|
+
* <label>{option.name}</label>
|
|
26
|
+
* <select value={selectedChoices[option.id] || ''}>
|
|
27
|
+
* {option.choices?.map(choice => (
|
|
28
|
+
* <option key={choice.id} value={choice.id}>
|
|
29
|
+
* {choice.description}
|
|
30
|
+
* </option>
|
|
31
|
+
* ))}
|
|
32
|
+
* </select>
|
|
33
|
+
* </div>
|
|
34
|
+
* ))}
|
|
35
|
+
* </div>
|
|
36
|
+
* )}
|
|
37
|
+
* </ProductVariantSelector.Options>
|
|
38
|
+
* </div>
|
|
39
|
+
* </ProductVariantSelector.Root>
|
|
40
|
+
* );
|
|
41
|
+
* }
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export function Root(props) {
|
|
45
|
+
return (_jsx(WixServices, { servicesMap: createServicesMap().addService(SelectedVariantServiceDefinition, SelectedVariantService, props.selectedVariantServiceConfig), children: props.children }));
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Headless component for all product options
|
|
49
|
+
*
|
|
50
|
+
* @component
|
|
51
|
+
* @example
|
|
52
|
+
* ```tsx
|
|
53
|
+
* import { ProductVariantSelector } from '@wix/stores/components';
|
|
54
|
+
*
|
|
55
|
+
* function VariantPicker() {
|
|
56
|
+
* return (
|
|
57
|
+
* <ProductVariantSelector.Options>
|
|
58
|
+
* {({ options, hasOptions, selectedChoices }) => (
|
|
59
|
+
* <div>
|
|
60
|
+
* {hasOptions && options.map(option => (
|
|
61
|
+
* <div key={option.id}>
|
|
62
|
+
* <label>{option.name}</label>
|
|
63
|
+
* <select value={selectedChoices[option.id] || ''}>
|
|
64
|
+
* {option.choices?.map(choice => (
|
|
65
|
+
* <option key={choice.id} value={choice.id}>
|
|
66
|
+
* {choice.description}
|
|
67
|
+
* </option>
|
|
68
|
+
* ))}
|
|
69
|
+
* </select>
|
|
70
|
+
* </div>
|
|
71
|
+
* ))}
|
|
72
|
+
* </div>
|
|
73
|
+
* )}
|
|
74
|
+
* </ProductVariantSelector.Options>
|
|
75
|
+
* );
|
|
76
|
+
* }
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export function Options(props) {
|
|
80
|
+
const variantService = useService(SelectedVariantServiceDefinition);
|
|
81
|
+
const selectedChoices = variantService.selectedChoices.get();
|
|
82
|
+
const options = variantService.productOptions.get();
|
|
83
|
+
return props.children({
|
|
84
|
+
options,
|
|
85
|
+
hasOptions: options.length > 0,
|
|
86
|
+
selectedChoices,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Headless component for choices within a specific product option
|
|
91
|
+
*
|
|
92
|
+
* @component
|
|
93
|
+
* @example
|
|
94
|
+
* ```tsx
|
|
95
|
+
* import { ProductVariantSelector } from '@wix/stores/components';
|
|
96
|
+
*
|
|
97
|
+
* function OptionSelector({ option }) {
|
|
98
|
+
* return (
|
|
99
|
+
* <ProductVariantSelector.Option option={option}>
|
|
100
|
+
* {({ name, choices, selectedValue, hasChoices }) => (
|
|
101
|
+
* <div>
|
|
102
|
+
* <label>{name}</label>
|
|
103
|
+
* {hasChoices && (
|
|
104
|
+
* <select value={selectedValue || ''}>
|
|
105
|
+
* <option value="">Select {name}</option>
|
|
106
|
+
* {choices.map(choice => (
|
|
107
|
+
* <option key={choice.id} value={choice.name}>
|
|
108
|
+
* {choice.description}
|
|
109
|
+
* </option>
|
|
110
|
+
* ))}
|
|
111
|
+
* </select>
|
|
112
|
+
* )}
|
|
113
|
+
* </div>
|
|
114
|
+
* )}
|
|
115
|
+
* </ProductVariantSelector.Option>
|
|
116
|
+
* );
|
|
117
|
+
* }
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
export function Option(props) {
|
|
121
|
+
const variantService = useService(SelectedVariantServiceDefinition);
|
|
122
|
+
const selectedChoices = variantService.selectedChoices.get();
|
|
123
|
+
const { option } = props;
|
|
124
|
+
const name = option.name || '';
|
|
125
|
+
const choices = option.choicesSettings?.choices || [];
|
|
126
|
+
const selectedValue = selectedChoices[name] || null;
|
|
127
|
+
return props.children({
|
|
128
|
+
name,
|
|
129
|
+
choices,
|
|
130
|
+
selectedValue,
|
|
131
|
+
hasChoices: choices.length > 0,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Headless component for individual choice selection
|
|
136
|
+
*
|
|
137
|
+
* @component
|
|
138
|
+
* @example
|
|
139
|
+
* ```tsx
|
|
140
|
+
* import { ProductVariantSelector } from '@wix/stores/components';
|
|
141
|
+
*
|
|
142
|
+
* function ChoiceButton({ option, choice }) {
|
|
143
|
+
* return (
|
|
144
|
+
* <ProductVariantSelector.Choice option={option} choice={choice}>
|
|
145
|
+
* {({ value, isSelected, isVisible, isInStock, select }) => (
|
|
146
|
+
* <button
|
|
147
|
+
* onClick={select}
|
|
148
|
+
* disabled={!isVisible || !isInStock}
|
|
149
|
+
* className={`choice-btn ${isSelected ? 'selected' : ''} ${!isInStock ? 'out-of-stock' : ''}`}
|
|
150
|
+
* >
|
|
151
|
+
* {value}
|
|
152
|
+
* {!isInStock && ' (Out of Stock)'}
|
|
153
|
+
* </button>
|
|
154
|
+
* )}
|
|
155
|
+
* </ProductVariantSelector.Choice>
|
|
156
|
+
* );
|
|
157
|
+
* }
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
export function Choice(props) {
|
|
161
|
+
const variantService = useService(SelectedVariantServiceDefinition);
|
|
162
|
+
const selectedChoices = variantService.selectedChoices.get();
|
|
163
|
+
const { option, choice } = props;
|
|
164
|
+
const optionName = option.name || '';
|
|
165
|
+
const choiceValue = choice.name || '';
|
|
166
|
+
const isSelected = selectedChoices[optionName] === choiceValue;
|
|
167
|
+
// Check if this choice is available based on current selections
|
|
168
|
+
const isVisible = variantService.isChoiceAvailable(optionName, choiceValue);
|
|
169
|
+
// Check if this choice results in an in-stock variant
|
|
170
|
+
const isInStock = variantService.isChoiceInStock(optionName, choiceValue);
|
|
171
|
+
// Check if this choice is available for pre-order
|
|
172
|
+
const isPreOrderEnabled = variantService.isChoicePreOrderEnabled(optionName, choiceValue);
|
|
173
|
+
const value = choiceValue;
|
|
174
|
+
const select = () => {
|
|
175
|
+
const newChoices = {
|
|
176
|
+
...selectedChoices,
|
|
177
|
+
[optionName]: choiceValue,
|
|
178
|
+
};
|
|
179
|
+
variantService.setSelectedChoices(newChoices);
|
|
180
|
+
};
|
|
181
|
+
return props.children({
|
|
182
|
+
value,
|
|
183
|
+
isSelected,
|
|
184
|
+
isVisible,
|
|
185
|
+
isInStock,
|
|
186
|
+
isPreOrderEnabled,
|
|
187
|
+
select,
|
|
188
|
+
optionName,
|
|
189
|
+
choiceValue,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Headless component for product stock status
|
|
194
|
+
*
|
|
195
|
+
* @component
|
|
196
|
+
* @example
|
|
197
|
+
* ```tsx
|
|
198
|
+
* import { ProductVariantSelector } from '@wix/stores/components';
|
|
199
|
+
*
|
|
200
|
+
* function StockIndicator() {
|
|
201
|
+
* return (
|
|
202
|
+
* <ProductVariantSelector.Stock>
|
|
203
|
+
* {({ inStock, isPreOrderEnabled, selectedQuantity, availableQuantity, incrementQuantity, decrementQuantity }) => (
|
|
204
|
+
* <div>
|
|
205
|
+
* <div className={`stock-status ${inStock ? 'in-stock' : 'out-of-stock'}`}>
|
|
206
|
+
* {inStock ? 'In Stock' : isPreOrderEnabled ? 'Pre-order Available' : 'Out of Stock'}
|
|
207
|
+
* </div>
|
|
208
|
+
* {availableQuantity && (
|
|
209
|
+
* <div>Only {availableQuantity} left!</div>
|
|
210
|
+
* )}
|
|
211
|
+
* <div className="quantity-selector">
|
|
212
|
+
* <button onClick={decrementQuantity}>-</button>
|
|
213
|
+
* <span>{selectedQuantity}</span>
|
|
214
|
+
* <button onClick={incrementQuantity}>+</button>
|
|
215
|
+
* </div>
|
|
216
|
+
* </div>
|
|
217
|
+
* )}
|
|
218
|
+
* </ProductVariantSelector.Stock>
|
|
219
|
+
* );
|
|
220
|
+
* }
|
|
221
|
+
* ```
|
|
222
|
+
*/
|
|
223
|
+
export function Stock(props) {
|
|
224
|
+
const variantService = useService(SelectedVariantServiceDefinition);
|
|
225
|
+
const inStock = variantService.isInStock.get();
|
|
226
|
+
const isPreOrderEnabled = variantService.isPreOrderEnabled.get();
|
|
227
|
+
const trackInventory = variantService.trackQuantity.get();
|
|
228
|
+
const currentVariantId = variantService.selectedVariantId.get();
|
|
229
|
+
const availableQuantity = variantService.quantityAvailable.get();
|
|
230
|
+
const selectedQuantity = variantService.selectedQuantity.get();
|
|
231
|
+
// Return raw availability status - UI components will handle display conversion
|
|
232
|
+
const availabilityStatus = inStock
|
|
233
|
+
? InventoryAvailabilityStatus.IN_STOCK
|
|
234
|
+
: InventoryAvailabilityStatus.OUT_OF_STOCK;
|
|
235
|
+
const incrementQuantity = () => {
|
|
236
|
+
variantService.incrementQuantity();
|
|
237
|
+
};
|
|
238
|
+
const decrementQuantity = () => {
|
|
239
|
+
variantService.decrementQuantity();
|
|
240
|
+
};
|
|
241
|
+
const setSelectedQuantity = (quantity) => {
|
|
242
|
+
variantService.setSelectedQuantity(quantity);
|
|
243
|
+
};
|
|
244
|
+
return props.children({
|
|
245
|
+
inStock,
|
|
246
|
+
availableQuantity,
|
|
247
|
+
isPreOrderEnabled,
|
|
248
|
+
currentVariantId,
|
|
249
|
+
availabilityStatus,
|
|
250
|
+
trackInventory,
|
|
251
|
+
selectedQuantity,
|
|
252
|
+
incrementQuantity,
|
|
253
|
+
setSelectedQuantity,
|
|
254
|
+
decrementQuantity,
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Headless component for resetting variant selections
|
|
259
|
+
*
|
|
260
|
+
* @component
|
|
261
|
+
* @example
|
|
262
|
+
* ```tsx
|
|
263
|
+
* import { ProductVariantSelector } from '@wix/stores/components';
|
|
264
|
+
*
|
|
265
|
+
* function ResetButton() {
|
|
266
|
+
* return (
|
|
267
|
+
* <ProductVariantSelector.Reset>
|
|
268
|
+
* {({ reset, hasSelections }) => (
|
|
269
|
+
* hasSelections && (
|
|
270
|
+
* <button onClick={reset} className="reset-button">
|
|
271
|
+
* Clear All Selections
|
|
272
|
+
* </button>
|
|
273
|
+
* )
|
|
274
|
+
* )}
|
|
275
|
+
* </ProductVariantSelector.Reset>
|
|
276
|
+
* );
|
|
277
|
+
* }
|
|
278
|
+
* ```
|
|
279
|
+
*/
|
|
280
|
+
export function Reset(props) {
|
|
281
|
+
const variantService = useService(SelectedVariantServiceDefinition);
|
|
282
|
+
const selectedChoices = variantService.selectedChoices.get();
|
|
283
|
+
const hasSelections = Object.keys(selectedChoices).length > 0;
|
|
284
|
+
const reset = () => {
|
|
285
|
+
variantService.resetSelections();
|
|
286
|
+
};
|
|
287
|
+
return props.children({
|
|
288
|
+
reset,
|
|
289
|
+
hasSelections,
|
|
290
|
+
});
|
|
291
|
+
}
|