@wix/headless-stores 0.0.52 → 0.0.54

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 (149) hide show
  1. package/cjs/dist/astro/actions/custom-checkout.d.ts +1 -1
  2. package/cjs/dist/astro/actions/custom-checkout.js +2 -2
  3. package/cjs/dist/astro/actions/index.d.ts +1 -1
  4. package/cjs/dist/astro/actions/index.js +1 -1
  5. package/cjs/dist/enums/index.d.ts +2 -2
  6. package/cjs/dist/enums/index.js +2 -2
  7. package/cjs/dist/react/Category.d.ts +168 -67
  8. package/cjs/dist/react/Category.js +166 -50
  9. package/cjs/dist/react/CategoryList.d.ts +56 -138
  10. package/cjs/dist/react/CategoryList.js +44 -129
  11. package/cjs/dist/react/Choice.d.ts +193 -0
  12. package/cjs/dist/react/Choice.js +259 -0
  13. package/cjs/dist/react/Option.d.ts +224 -0
  14. package/cjs/dist/react/Option.js +388 -0
  15. package/cjs/dist/react/Product.d.ts +339 -96
  16. package/cjs/dist/react/Product.js +507 -94
  17. package/cjs/dist/react/{BuyNow.js → core/BuyNow.js} +2 -2
  18. package/cjs/dist/react/core/Category.d.ts +98 -0
  19. package/cjs/dist/react/core/Category.js +81 -0
  20. package/cjs/dist/react/core/CategoryList.d.ts +185 -0
  21. package/cjs/dist/react/core/CategoryList.js +174 -0
  22. package/{dist/react → cjs/dist/react/core}/PayNow.js +2 -2
  23. package/cjs/dist/react/core/Product.d.ts +148 -0
  24. package/cjs/dist/react/core/Product.js +126 -0
  25. package/cjs/dist/react/{ProductList.d.ts → core/ProductList.d.ts} +3 -3
  26. package/cjs/dist/react/{ProductList.js → core/ProductList.js} +10 -10
  27. package/{dist/react → cjs/dist/react/core}/ProductListFilters.d.ts +3 -3
  28. package/{dist/react → cjs/dist/react/core}/ProductListFilters.js +7 -7
  29. package/cjs/dist/react/{ProductListPagination.js → core/ProductListPagination.js} +8 -8
  30. package/{dist/react → cjs/dist/react/core}/ProductListSort.d.ts +1 -1
  31. package/cjs/dist/react/{ProductListSort.js → core/ProductListSort.js} +3 -3
  32. package/{dist/react → cjs/dist/react/core}/ProductModifiers.d.ts +1 -1
  33. package/{dist/react → cjs/dist/react/core}/ProductModifiers.js +13 -13
  34. package/{dist/react → cjs/dist/react/core}/ProductVariantSelector.d.ts +2 -2
  35. package/{dist/react → cjs/dist/react/core}/ProductVariantSelector.js +7 -10
  36. package/{dist/react → cjs/dist/react/core}/SelectedVariant.d.ts +2 -2
  37. package/{dist/react → cjs/dist/react/core}/SelectedVariant.js +43 -15
  38. package/cjs/dist/react/index.d.ts +15 -10
  39. package/cjs/dist/react/index.js +15 -10
  40. package/cjs/dist/react/types.d.ts +8 -0
  41. package/cjs/dist/react/types.js +9 -0
  42. package/cjs/dist/server-actions/custom-checkout-action.js +14 -10
  43. package/cjs/dist/server-actions/index.d.ts +1 -1
  44. package/cjs/dist/server-actions/index.js +1 -1
  45. package/cjs/dist/services/buy-now-service.d.ts +1 -1
  46. package/cjs/dist/services/buy-now-service.js +6 -6
  47. package/cjs/dist/services/categories-list-service.d.ts +4 -4
  48. package/cjs/dist/services/categories-list-service.js +10 -10
  49. package/cjs/dist/services/category-service.d.ts +18 -22
  50. package/cjs/dist/services/category-service.js +12 -10
  51. package/cjs/dist/services/index.d.ts +7 -7
  52. package/cjs/dist/services/index.js +7 -7
  53. package/cjs/dist/services/pay-now-service.d.ts +1 -1
  54. package/cjs/dist/services/pay-now-service.js +4 -4
  55. package/cjs/dist/services/product-modifiers-service.d.ts +3 -3
  56. package/cjs/dist/services/product-modifiers-service.js +7 -7
  57. package/cjs/dist/services/product-service.d.ts +4 -4
  58. package/cjs/dist/services/product-service.js +18 -18
  59. package/cjs/dist/services/products-list-search-service.d.ts +5 -5
  60. package/cjs/dist/services/products-list-search-service.js +117 -117
  61. package/cjs/dist/services/products-list-service.d.ts +4 -4
  62. package/cjs/dist/services/products-list-service.js +12 -12
  63. package/cjs/dist/services/selected-variant-service.d.ts +6 -2
  64. package/cjs/dist/services/selected-variant-service.js +86 -83
  65. package/cjs/dist/utils/index.d.ts +1 -0
  66. package/cjs/dist/utils/index.js +5 -4
  67. package/cjs/dist/utils/renderAsChild.d.ts +96 -0
  68. package/cjs/dist/utils/renderAsChild.js +66 -0
  69. package/cjs/dist/utils/renderChildren.d.ts +41 -0
  70. package/cjs/dist/utils/renderChildren.js +44 -0
  71. package/cjs/dist/utils/url-params.js +3 -3
  72. package/dist/astro/actions/custom-checkout.d.ts +1 -1
  73. package/dist/astro/actions/custom-checkout.js +2 -2
  74. package/dist/astro/actions/index.d.ts +1 -1
  75. package/dist/astro/actions/index.js +1 -1
  76. package/dist/enums/index.d.ts +2 -2
  77. package/dist/enums/index.js +2 -2
  78. package/dist/react/Category.d.ts +168 -67
  79. package/dist/react/Category.js +166 -50
  80. package/dist/react/CategoryList.d.ts +56 -138
  81. package/dist/react/CategoryList.js +44 -129
  82. package/dist/react/Choice.d.ts +193 -0
  83. package/dist/react/Choice.js +259 -0
  84. package/dist/react/Option.d.ts +224 -0
  85. package/dist/react/Option.js +388 -0
  86. package/dist/react/Product.d.ts +339 -96
  87. package/dist/react/Product.js +507 -94
  88. package/dist/react/{BuyNow.js → core/BuyNow.js} +2 -2
  89. package/dist/react/core/Category.d.ts +98 -0
  90. package/dist/react/core/Category.js +81 -0
  91. package/dist/react/core/CategoryList.d.ts +185 -0
  92. package/dist/react/core/CategoryList.js +174 -0
  93. package/{cjs/dist/react → dist/react/core}/PayNow.js +2 -2
  94. package/dist/react/core/Product.d.ts +148 -0
  95. package/dist/react/core/Product.js +126 -0
  96. package/dist/react/{ProductList.d.ts → core/ProductList.d.ts} +3 -3
  97. package/dist/react/{ProductList.js → core/ProductList.js} +10 -10
  98. package/{cjs/dist/react → dist/react/core}/ProductListFilters.d.ts +3 -3
  99. package/{cjs/dist/react → dist/react/core}/ProductListFilters.js +7 -7
  100. package/dist/react/{ProductListPagination.js → core/ProductListPagination.js} +8 -8
  101. package/{cjs/dist/react → dist/react/core}/ProductListSort.d.ts +1 -1
  102. package/dist/react/{ProductListSort.js → core/ProductListSort.js} +3 -3
  103. package/{cjs/dist/react → dist/react/core}/ProductModifiers.d.ts +1 -1
  104. package/{cjs/dist/react → dist/react/core}/ProductModifiers.js +13 -13
  105. package/{cjs/dist/react → dist/react/core}/ProductVariantSelector.d.ts +2 -2
  106. package/{cjs/dist/react → dist/react/core}/ProductVariantSelector.js +7 -10
  107. package/{cjs/dist/react → dist/react/core}/SelectedVariant.d.ts +2 -2
  108. package/{cjs/dist/react → dist/react/core}/SelectedVariant.js +43 -15
  109. package/dist/react/index.d.ts +15 -10
  110. package/dist/react/index.js +15 -10
  111. package/dist/react/types.d.ts +8 -0
  112. package/dist/react/types.js +9 -0
  113. package/dist/server-actions/custom-checkout-action.js +14 -10
  114. package/dist/server-actions/index.d.ts +1 -1
  115. package/dist/server-actions/index.js +1 -1
  116. package/dist/services/buy-now-service.d.ts +1 -1
  117. package/dist/services/buy-now-service.js +6 -6
  118. package/dist/services/categories-list-service.d.ts +4 -4
  119. package/dist/services/categories-list-service.js +10 -10
  120. package/dist/services/category-service.d.ts +18 -22
  121. package/dist/services/category-service.js +12 -10
  122. package/dist/services/index.d.ts +7 -7
  123. package/dist/services/index.js +7 -7
  124. package/dist/services/pay-now-service.d.ts +1 -1
  125. package/dist/services/pay-now-service.js +4 -4
  126. package/dist/services/product-modifiers-service.d.ts +3 -3
  127. package/dist/services/product-modifiers-service.js +7 -7
  128. package/dist/services/product-service.d.ts +4 -4
  129. package/dist/services/product-service.js +18 -18
  130. package/dist/services/products-list-search-service.d.ts +5 -5
  131. package/dist/services/products-list-search-service.js +117 -117
  132. package/dist/services/products-list-service.d.ts +4 -4
  133. package/dist/services/products-list-service.js +12 -12
  134. package/dist/services/selected-variant-service.d.ts +6 -2
  135. package/dist/services/selected-variant-service.js +86 -83
  136. package/dist/utils/index.d.ts +1 -0
  137. package/dist/utils/index.js +5 -4
  138. package/dist/utils/renderAsChild.d.ts +96 -0
  139. package/dist/utils/renderAsChild.js +66 -0
  140. package/dist/utils/renderChildren.d.ts +41 -0
  141. package/dist/utils/renderChildren.js +44 -0
  142. package/dist/utils/url-params.js +3 -3
  143. package/package.json +7 -3
  144. /package/cjs/dist/react/{BuyNow.d.ts → core/BuyNow.d.ts} +0 -0
  145. /package/cjs/dist/react/{PayNow.d.ts → core/PayNow.d.ts} +0 -0
  146. /package/cjs/dist/react/{ProductListPagination.d.ts → core/ProductListPagination.d.ts} +0 -0
  147. /package/dist/react/{BuyNow.d.ts → core/BuyNow.d.ts} +0 -0
  148. /package/dist/react/{PayNow.d.ts → core/PayNow.d.ts} +0 -0
  149. /package/dist/react/{ProductListPagination.d.ts → core/ProductListPagination.d.ts} +0 -0
@@ -1,10 +1,52 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useService, WixServices } from "@wix/services-manager-react";
3
- import { ProductServiceDefinition, ProductService, } from "../services/product-service.js";
4
- import { createServicesMap } from "@wix/services-manager";
1
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import React from 'react';
3
+ import { renderAsChild } from '../utils/index.js';
4
+ import * as CoreProduct from './core/Product.js';
5
+ import * as ProductVariantSelector from './core/ProductVariantSelector.js';
6
+ import * as ProductModifiers from './core/ProductModifiers.js';
7
+ import * as SelectedVariant from './core/SelectedVariant.js';
8
+ import * as Option from './Option.js';
9
+ import { AsContent } from './types.js';
10
+ const VariantsContext = React.createContext(null);
5
11
  /**
6
- * Root component that provides the Product service context to its children.
7
- * This component sets up the necessary services for rendering and managing a single product's data.
12
+ * Hook to access variants context
13
+ */
14
+ export function useVariantsContext() {
15
+ const context = React.useContext(VariantsContext);
16
+ if (!context) {
17
+ throw new Error('useVariantsContext must be used within a Product.Variants component');
18
+ }
19
+ return context;
20
+ }
21
+ const ModifiersContext = React.createContext(null);
22
+ /**
23
+ * Hook to access modifiers context
24
+ */
25
+ export function useModifiersContext() {
26
+ const context = React.useContext(ModifiersContext);
27
+ if (!context) {
28
+ throw new Error('useModifiersContext must be used within a Product.Modifiers component');
29
+ }
30
+ return context;
31
+ }
32
+ var TestIds;
33
+ (function (TestIds) {
34
+ TestIds["productRoot"] = "product-root";
35
+ TestIds["productName"] = "product-name";
36
+ TestIds["productDescription"] = "product-description";
37
+ TestIds["productPrice"] = "product-price";
38
+ TestIds["productCompareAtPrice"] = "product-compare-at-price";
39
+ TestIds["productVariants"] = "product-variants";
40
+ TestIds["productVariantOptions"] = "product-variant-options";
41
+ TestIds["productVariantOption"] = "product-variant-option";
42
+ TestIds["productModifiers"] = "product-modifiers";
43
+ TestIds["productModifierOptions"] = "product-modifier-options";
44
+ TestIds["productModifierOption"] = "product-modifier-option";
45
+ })(TestIds || (TestIds = {}));
46
+ /**
47
+ * Root component that provides all necessary service contexts for a complete product experience.
48
+ * This composite component combines Product, ProductVariantSelector, ProductModifiers, and SelectedVariant
49
+ * functionality following the documented API patterns with proper data attributes.
8
50
  *
9
51
  * @order 1
10
52
  * @component
@@ -12,115 +54,486 @@ import { createServicesMap } from "@wix/services-manager";
12
54
  * ```tsx
13
55
  * import { Product } from '@wix/stores/components';
14
56
  *
15
- * function ProductPage() {
57
+ * function ProductPage({ product }) {
16
58
  * return (
17
- * <Product.Root productServiceConfig={{ product: myProduct }}>
18
- * <div>
19
- * <Product.Name>
20
- * {({ name }) => (
21
- * <h1
22
- * className="text-4xl font-bold text-content-primary mb-4"
23
- * data-testid="product-name"
24
- * >
25
- * {name}
26
- * </h1>
27
- * )}
28
- * </Product.Name>
29
- * </div>
59
+ * <Product.Root product={product}>
60
+ * <Product.Name className="text-4xl font-bold" />
30
61
  * </Product.Root>
31
62
  * );
32
63
  * }
33
64
  * ```
34
65
  */
35
66
  export function Root(props) {
36
- return (_jsx(WixServices, { servicesMap: createServicesMap().addService(ProductServiceDefinition, ProductService, props.productServiceConfig), children: props.children }));
67
+ return (_jsx(CoreProduct.Root, { productServiceConfig: { product: props.product }, "data-testid": TestIds.productRoot, children: _jsx(ProductVariantSelector.Root, { children: _jsx(ProductModifiers.Root, { children: _jsx(SelectedVariant.Root, { children: props.children }) }) }) }));
37
68
  }
38
69
  /**
39
- * Headless component for product name display
70
+ * Displays the product name with customizable rendering following the documented API.
40
71
  *
41
72
  * @component
42
73
  * @example
43
74
  * ```tsx
44
- * import { Product } from '@wix/stores/components';
75
+ * // Default usage
76
+ * <Product.Name className="text-4xl font-bold" />
45
77
  *
46
- * function ProductHeader() {
47
- * return (
48
- * <Product.Name>
49
- * {({ name }) => (
50
- * <h1>{name}</h1>
51
- * )}
52
- * </Product.Name>
53
- * );
54
- * }
78
+ * // asChild with primitive
79
+ * <Product.Name asChild>
80
+ * <h1 className="text-4xl font-bold" />
81
+ * </Product.Name>
82
+ *
83
+ * // asChild with react component
84
+ * <Product.Name asChild>
85
+ * {React.forwardRef(({name, ...props}, ref) => (
86
+ * <h1 ref={ref} {...props} className="text-4xl font-bold">
87
+ * {name}
88
+ * </h1>
89
+ * ))}
90
+ * </Product.Name>
55
91
  * ```
56
92
  */
57
- export function Name(props) {
58
- const service = useService(ProductServiceDefinition);
59
- const product = service.product.get();
60
- const name = product.name;
61
- return props.children({
62
- name,
63
- });
64
- }
93
+ export const Name = React.forwardRef((props, ref) => {
94
+ const { asChild, children, className } = props;
95
+ return (_jsx(CoreProduct.Name, { children: ({ name }) => {
96
+ const attributes = {
97
+ 'data-testid': TestIds.productName,
98
+ };
99
+ if (asChild) {
100
+ const rendered = renderAsChild({
101
+ children,
102
+ props: { name },
103
+ ref,
104
+ content: name,
105
+ attributes,
106
+ });
107
+ if (rendered)
108
+ return rendered;
109
+ }
110
+ return (_jsx("div", { className: className, ...attributes, children: name }));
111
+ } }));
112
+ });
65
113
  /**
66
- * Headless component for product description display
114
+ * Displays the product description with customizable rendering and format options following the documented API.
67
115
  *
68
116
  * @component
69
117
  * @example
70
118
  * ```tsx
71
- * import { Product } from '@wix/stores/components';
119
+ * // Default usage (plain text)
120
+ * <Product.Description className="text-content-secondary" />
72
121
  *
73
- * function ProductDescription() {
74
- * return (
75
- * <Product.Description>
76
- * {({ plainDescription, description }) => (
77
- * <div>
78
- * {plainDescription && (
79
- * <div
80
- * dangerouslySetInnerHTML={{
81
- * __html: plainDescription,
82
- * }}
83
- * />
84
- * )}
85
- * {description && (
86
- * <div>Rich content description available</div>
87
- * )}
88
- * </div>
89
- * )}
90
- * </Product.Description>
91
- * );
92
- * }
122
+ * // HTML content
123
+ * <Product.Description as="html" className="prose" />
124
+ *
125
+ * // asChild with custom rendering
126
+ * <Product.Description as="html" asChild>
127
+ * {({ description }) => (
128
+ * <div
129
+ * className="text-content-secondary"
130
+ * dangerouslySetInnerHTML={{ __html: description }}
131
+ * />
132
+ * )}
133
+ * </Product.Description>
93
134
  * ```
94
135
  */
95
- export function Description(props) {
96
- const service = useService(ProductServiceDefinition);
97
- const product = service.product.get();
98
- const descriptionRichContent = product.description;
99
- const plainDescription = product.plainDescription;
100
- return props.children({
101
- description: descriptionRichContent,
102
- plainDescription: plainDescription,
103
- });
104
- }
105
- export function Media(props) {
106
- const service = useService(ProductServiceDefinition);
107
- const product = service.product.get();
108
- const media = product.media?.itemsInfo?.items ?? [];
109
- return props.children({
110
- media,
111
- });
112
- }
113
- export function Content(props) {
114
- const service = useService(ProductServiceDefinition);
115
- const product = service.product.get();
116
- return props.children({
117
- product,
118
- });
119
- }
120
- export function Loading(props) {
121
- const service = useService(ProductServiceDefinition);
122
- const isLoading = service.isLoading.get();
123
- return props.children({
124
- isLoading,
125
- });
126
- }
136
+ export const Description = React.forwardRef((props, ref) => {
137
+ const { asChild, children, className, as = AsContent.Plain } = props;
138
+ return (_jsx(CoreProduct.Description, { children: ({ description: richDescription, plainDescription }) => {
139
+ const attributes = {
140
+ 'data-testid': TestIds.productDescription,
141
+ };
142
+ // Determine which description to use based on the 'as' prop
143
+ let description;
144
+ switch (as) {
145
+ case AsContent.Html:
146
+ description = plainDescription || '';
147
+ break;
148
+ case AsContent.Ricos:
149
+ description = JSON.stringify(richDescription) || '';
150
+ break;
151
+ case AsContent.Plain:
152
+ default:
153
+ // For plain text, we'll strip HTML tags from plainDescription
154
+ description = plainDescription
155
+ ? plainDescription.replace(/<[^>]*>/g, '')
156
+ : '';
157
+ break;
158
+ }
159
+ if (asChild) {
160
+ const rendered = renderAsChild({
161
+ children,
162
+ props: { description },
163
+ ref,
164
+ content: description,
165
+ attributes,
166
+ });
167
+ if (rendered)
168
+ return rendered;
169
+ }
170
+ // Default rendering based on format
171
+ if (as === AsContent.Html) {
172
+ return (_jsx("div", { className: className, ...attributes, dangerouslySetInnerHTML: { __html: description } }));
173
+ }
174
+ return (_jsx("div", { className: className, ...attributes, children: description }));
175
+ } }));
176
+ });
177
+ /**
178
+ * Displays the current product price with customizable rendering following the documented API.
179
+ *
180
+ * @component
181
+ * @example
182
+ * ```tsx
183
+ * // Default usage
184
+ * <Product.Price className="text-3xl font-bold text-content-primary data-[discounted]:text-brand-primary" />
185
+ *
186
+ * // asChild with primitive
187
+ * <Product.Price asChild>
188
+ * <span className="text-3xl font-bold text-content-primary" />
189
+ * </Product.Price>
190
+ *
191
+ * // asChild with react component
192
+ * <Product.Price asChild>
193
+ * {React.forwardRef(({price, formattedPrice, ...props}, ref) => (
194
+ * <span ref={ref} {...props} className="text-3xl font-bold text-content-primary">
195
+ * {formattedPrice}
196
+ * </span>
197
+ * ))}
198
+ * </Product.Price>
199
+ * ```
200
+ */
201
+ export const Price = React.forwardRef((props, ref) => {
202
+ const { asChild, children, className } = props;
203
+ return (_jsx(SelectedVariant.Price, { children: ({ price, compareAtPrice }) => {
204
+ const attributes = {
205
+ 'data-testid': TestIds.productPrice,
206
+ 'data-discounted': compareAtPrice !== null,
207
+ };
208
+ const priceData = {
209
+ price,
210
+ formattedPrice: price,
211
+ };
212
+ if (asChild) {
213
+ const rendered = renderAsChild({
214
+ children,
215
+ props: priceData,
216
+ ref,
217
+ content: price,
218
+ attributes,
219
+ });
220
+ if (rendered)
221
+ return rendered;
222
+ }
223
+ return (_jsx("span", { className: className, ...attributes, ref: ref, children: price }));
224
+ } }));
225
+ });
226
+ /**
227
+ * Displays the compare-at (original) price when on sale with customizable rendering following the documented API.
228
+ *
229
+ * @component
230
+ * @example
231
+ * ```tsx
232
+ * // Default usage (only shows when on sale)
233
+ * <Product.CompareAtPrice className="text-lg text-content-faded line-through hidden data-[discounted]:inline" />
234
+ *
235
+ * // asChild with primitive
236
+ * <Product.CompareAtPrice asChild>
237
+ * <span className="text-lg text-content-faded line-through" />
238
+ * </Product.CompareAtPrice>
239
+ *
240
+ * // asChild with react component
241
+ * <Product.CompareAtPrice asChild>
242
+ * {React.forwardRef(({formattedPrice, ...props}, ref) => (
243
+ * <span
244
+ * ref={ref}
245
+ * {...props}
246
+ * className="hidden data-[discounted]:inline text-lg text-content-faded line-through"
247
+ * >
248
+ * Was: {formattedPrice}
249
+ * </span>
250
+ * ))}
251
+ * </Product.CompareAtPrice>
252
+ * ```
253
+ */
254
+ export const CompareAtPrice = React.forwardRef((props, ref) => {
255
+ const { asChild, children, className } = props;
256
+ const testId = TestIds.productCompareAtPrice;
257
+ return (_jsx(SelectedVariant.Price, { children: ({ compareAtPrice }) => {
258
+ const attributes = {
259
+ 'data-testid': testId,
260
+ 'data-discounted': compareAtPrice !== null,
261
+ };
262
+ // Don't render anything if there's no compare-at price
263
+ if (!compareAtPrice) {
264
+ return null;
265
+ }
266
+ const priceData = {
267
+ price: compareAtPrice,
268
+ formattedPrice: compareAtPrice,
269
+ };
270
+ if (asChild) {
271
+ const rendered = renderAsChild({
272
+ children,
273
+ props: priceData,
274
+ ref,
275
+ content: compareAtPrice,
276
+ attributes,
277
+ });
278
+ if (rendered)
279
+ return rendered;
280
+ }
281
+ return (_jsx("span", { className: className, ...attributes, ref: ref, children: compareAtPrice }));
282
+ } }));
283
+ });
284
+ /**
285
+ * Container for product variant selection system.
286
+ * Does not render when there are no variants.
287
+ *
288
+ * @component
289
+ * @example
290
+ * ```tsx
291
+ * // Default usage
292
+ * <Product.Variants>
293
+ * <Product.VariantOptions>
294
+ * <Product.VariantOptionRepeater>
295
+ * <Option.Name className="text-lg font-medium mb-3" />
296
+ * <Option.Choices>
297
+ * <Option.ChoiceRepeater>
298
+ * <Choice.Text className="px-4 py-2 border rounded-lg" />
299
+ * <Choice.Color className="w-10 h-10 rounded-full border-4" />
300
+ * </Option.ChoiceRepeater>
301
+ * </Option.Choices>
302
+ * </Product.VariantOptionRepeater>
303
+ * </Product.VariantOptions>
304
+ * </Product.Variants>
305
+ *
306
+ * // asChild with primitive
307
+ * <Product.Variants asChild>
308
+ * <section className="variant-section">
309
+ * <Product.VariantOptions>
310
+ * // variant options
311
+ * </Product.VariantOptions>
312
+ * </section>
313
+ * </Product.Variants>
314
+ *
315
+ * // asChild with react component
316
+ * <Product.Variants asChild>
317
+ * {React.forwardRef(({hasOptions, ...props}, ref) => (
318
+ * <section ref={ref} {...props} className="variant-section">
319
+ * {hasOptions && <h3>Choose Options</h3>}
320
+ * {props.children}
321
+ * </section>
322
+ * ))}
323
+ * </Product.Variants>
324
+ * ```
325
+ */
326
+ export const Variants = React.forwardRef((props, ref) => {
327
+ const { asChild, children } = props;
328
+ return (_jsx(ProductVariantSelector.Options, { children: ({ hasOptions, options }) => {
329
+ if (!hasOptions)
330
+ return null;
331
+ const contextValue = {
332
+ hasOptions,
333
+ options,
334
+ };
335
+ const attributes = {
336
+ 'data-testid': TestIds.productVariants,
337
+ };
338
+ const content = (_jsx(VariantsContext.Provider, { value: contextValue, children: typeof children === 'function'
339
+ ? null
340
+ : children }));
341
+ if (asChild) {
342
+ const rendered = renderAsChild({
343
+ children,
344
+ props: { hasOptions },
345
+ ref,
346
+ content,
347
+ attributes,
348
+ });
349
+ if (rendered)
350
+ return rendered;
351
+ }
352
+ return (_jsx("div", { ...attributes, ref: ref, children: content }));
353
+ } }));
354
+ });
355
+ /**
356
+ * Component that provides access to variant options.
357
+ *
358
+ * @component
359
+ * @example
360
+ * ```tsx
361
+ * // Default usage
362
+ * <Product.VariantOptions emptyState={<div>No options available</div>}>
363
+ * <Product.VariantOptionRepeater>
364
+ * <Option.Name />
365
+ * <Option.Choices>
366
+ * <Option.ChoiceRepeater>
367
+ * <Choice.Text />
368
+ * </Option.ChoiceRepeater>
369
+ * </Option.Choices>
370
+ * </Product.VariantOptionRepeater>
371
+ * </Product.VariantOptions>
372
+ *
373
+ * // Simple container usage
374
+ * <Product.VariantOptions emptyState={<div>No options</div>}>
375
+ * <div className="options-container">
376
+ * <Product.VariantOptionRepeater>
377
+ * // option content
378
+ * </Product.VariantOptionRepeater>
379
+ * </div>
380
+ * </Product.VariantOptions>
381
+ * ```
382
+ */
383
+ export const VariantOptions = React.forwardRef((props, ref) => {
384
+ const { children, emptyState } = props;
385
+ const { hasOptions } = useVariantsContext();
386
+ if (!hasOptions) {
387
+ return emptyState || null;
388
+ }
389
+ const attributes = {
390
+ 'data-testid': TestIds.productVariantOptions,
391
+ };
392
+ return (_jsx("div", { ...attributes, ref: ref, children: children }));
393
+ });
394
+ /**
395
+ * Repeater component that renders children for each variant option.
396
+ *
397
+ * @component
398
+ */
399
+ export const VariantOptionRepeater = React.forwardRef((props, _ref) => {
400
+ const { children } = props;
401
+ const { hasOptions, options } = useVariantsContext();
402
+ if (!hasOptions)
403
+ return null;
404
+ return (_jsx(_Fragment, { children: options.map((option) => {
405
+ return (_jsx(ProductVariantSelector.Option, { option: option, children: (optionData) => (_jsx(Option.Root, { option: {
406
+ ...optionData,
407
+ mandatory: false,
408
+ }, children: children })) }, option._id));
409
+ }) }));
410
+ });
411
+ /**
412
+ * Container for product modifier system.
413
+ * Does not render when there are no modifiers.
414
+ *
415
+ * @component
416
+ * @example
417
+ * ```tsx
418
+ * // Default usage
419
+ * <Product.Modifiers>
420
+ * <Product.ModifierOptions>
421
+ * <Product.ModifierOptionRepeater>
422
+ * <Option.Name className="text-lg font-medium mb-3" />
423
+ * <Option.Choices>
424
+ * <Option.ChoiceRepeater>
425
+ * <Choice.Text className="px-4 py-2 border rounded-lg" />
426
+ * <Choice.Color className="w-10 h-10 rounded-full border-4" />
427
+ * <Choice.FreeText className="w-full p-3 border rounded-lg resize-none" />
428
+ * </Option.ChoiceRepeater>
429
+ * </Option.Choices>
430
+ * </Product.ModifierOptionRepeater>
431
+ * </Product.ModifierOptions>
432
+ * </Product.Modifiers>
433
+ *
434
+ * // asChild with primitive
435
+ * <Product.Modifiers asChild>
436
+ * <section className="modifier-section">
437
+ * <Product.ModifierOptions>
438
+ * // modifier options
439
+ * </Product.ModifierOptions>
440
+ * </section>
441
+ * </Product.Modifiers>
442
+ *
443
+ * // asChild with react component
444
+ * <Product.Modifiers asChild>
445
+ * {React.forwardRef(({hasModifiers, ...props}, ref) => (
446
+ * <section ref={ref} {...props} className="modifier-section">
447
+ * {hasModifiers && <h3>Customize Your Product</h3>}
448
+ * {props.children}
449
+ * </section>
450
+ * ))}
451
+ * </Product.Modifiers>
452
+ * ```
453
+ */
454
+ export const Modifiers = React.forwardRef((props, ref) => {
455
+ const { asChild, children } = props;
456
+ return (_jsx(ProductModifiers.Modifiers, { children: ({ hasModifiers, modifiers }) => {
457
+ if (!hasModifiers)
458
+ return null;
459
+ const contextValue = {
460
+ hasModifiers,
461
+ modifiers,
462
+ };
463
+ const attributes = {
464
+ 'data-testid': TestIds.productModifiers,
465
+ };
466
+ const content = (_jsx(ModifiersContext.Provider, { value: contextValue, children: typeof children === 'function'
467
+ ? null
468
+ : children }));
469
+ if (asChild) {
470
+ const rendered = renderAsChild({
471
+ children,
472
+ props: { hasModifiers },
473
+ ref,
474
+ content,
475
+ attributes,
476
+ });
477
+ if (rendered)
478
+ return rendered;
479
+ }
480
+ return (_jsx("div", { ...attributes, ref: ref, children: content }));
481
+ } }));
482
+ });
483
+ /**
484
+ * Component that provides access to modifier options.
485
+ *
486
+ * @component
487
+ * @example
488
+ * ```tsx
489
+ * // Default usage
490
+ * <Product.ModifierOptions emptyState={<div>No options available</div>}>
491
+ * <Product.ModifierOptionRepeater>
492
+ * <Option.Name />
493
+ * <Option.Choices>
494
+ * <Option.ChoiceRepeater>
495
+ * <Choice.Text />
496
+ * <Choice.Color />
497
+ * <Choice.FreeText />
498
+ * </Option.ChoiceRepeater>
499
+ * </Option.Choices>
500
+ * </Product.ModifierOptionRepeater>
501
+ * </Product.ModifierOptions>
502
+ *
503
+ * // Simple container usage
504
+ * <Product.ModifierOptions emptyState={<div>No options</div>}>
505
+ * <div className="options-container">
506
+ * <Product.ModifierOptionRepeater>
507
+ * // option content
508
+ * </Product.ModifierOptionRepeater>
509
+ * </div>
510
+ * </Product.ModifierOptions>
511
+ * ```
512
+ */
513
+ export const ModifierOptions = React.forwardRef((props, ref) => {
514
+ const { children, emptyState } = props;
515
+ const { hasModifiers } = useModifiersContext();
516
+ if (!hasModifiers) {
517
+ return emptyState || null;
518
+ }
519
+ const attributes = {
520
+ 'data-testid': TestIds.productModifierOptions,
521
+ };
522
+ return (_jsx("div", { ...attributes, ref: ref, children: children }));
523
+ });
524
+ /**
525
+ * Repeater component that renders children for each modifier option.
526
+ *
527
+ * @component
528
+ */
529
+ export const ModifierOptionRepeater = React.forwardRef((props, _ref) => {
530
+ const { children, allowedTypes = ['color', 'text', 'free-text'] } = props;
531
+ const { hasModifiers, modifiers } = useModifiersContext();
532
+ if (!hasModifiers)
533
+ return null;
534
+ return (_jsx(_Fragment, { children: modifiers.map((modifier) => {
535
+ return (_jsx(ProductModifiers.Modifier, { modifier: modifier, children: (modifierData) => (_jsx(Option.Root, { option: {
536
+ ...modifierData,
537
+ }, allowedTypes: allowedTypes, children: children })) }, modifier._id));
538
+ }) }));
539
+ });
@@ -1,5 +1,5 @@
1
- import { useService } from "@wix/services-manager-react";
2
- import { BuyNowServiceDefinition } from "../services/buy-now-service.js";
1
+ import { useService } from '@wix/services-manager-react';
2
+ import { BuyNowServiceDefinition } from '../../services/buy-now-service.js';
3
3
  /**
4
4
  * A headless component that provides buy now functionality using the render props pattern.
5
5
  *