@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,235 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { AsChildSlot } from '@wix/headless-utils/react';
|
|
4
|
+
import * as CoreProductListFilters from './core/ProductListFilters.js';
|
|
5
|
+
import { DataComponentTags } from '../data-component-tags.js';
|
|
6
|
+
const CategoryContext = React.createContext(null);
|
|
7
|
+
function useCategoryContext() {
|
|
8
|
+
const context = React.useContext(CategoryContext);
|
|
9
|
+
if (!context) {
|
|
10
|
+
throw new Error('useCategoryContext must be used within a Category.Root component');
|
|
11
|
+
}
|
|
12
|
+
return context;
|
|
13
|
+
}
|
|
14
|
+
var TestIds;
|
|
15
|
+
(function (TestIds) {
|
|
16
|
+
TestIds["categoryRoot"] = "category-root";
|
|
17
|
+
TestIds["categoryItem"] = "category-item";
|
|
18
|
+
TestIds["categoryTrigger"] = "category-trigger";
|
|
19
|
+
TestIds["categoryLabel"] = "category-label";
|
|
20
|
+
TestIds["categoryId"] = "category-id";
|
|
21
|
+
TestIds["categoryRaw"] = "category-raw";
|
|
22
|
+
TestIds["categoryFilter"] = "category-filter";
|
|
23
|
+
})(TestIds || (TestIds = {}));
|
|
24
|
+
/**
|
|
25
|
+
* Root container for a single category item.
|
|
26
|
+
* This component sets up the necessary services for managing category state
|
|
27
|
+
* and provides category context to child components.
|
|
28
|
+
*
|
|
29
|
+
* @order 1
|
|
30
|
+
* @component
|
|
31
|
+
* @example
|
|
32
|
+
* ```tsx
|
|
33
|
+
* import { Category } from '@wix/headless-stores/react';
|
|
34
|
+
*
|
|
35
|
+
* <Category.Root category={category}>
|
|
36
|
+
* <Category.Trigger />
|
|
37
|
+
* <Category.Label />
|
|
38
|
+
* <Category.ID />
|
|
39
|
+
* </Category.Root>
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export const Root = React.forwardRef((props, ref) => {
|
|
43
|
+
const { category, children } = props;
|
|
44
|
+
return (_jsx(CoreProductListFilters.CategoryFilter, { children: ({ selectedCategory, setSelectedCategory }) => {
|
|
45
|
+
// Determine if this category is selected by comparing with selectedCategory
|
|
46
|
+
const isSelected = selectedCategory?._id === category._id;
|
|
47
|
+
const contextValue = {
|
|
48
|
+
category,
|
|
49
|
+
isSelected,
|
|
50
|
+
selectedCategory,
|
|
51
|
+
setSelectedCategory,
|
|
52
|
+
};
|
|
53
|
+
return (_jsx(CategoryContext.Provider, { value: contextValue, children: _jsx(AsChildSlot, { ref: ref, "data-component-tag": DataComponentTags.categoryRoot, "data-testid": TestIds.categoryRoot, children: children }) }));
|
|
54
|
+
} }));
|
|
55
|
+
});
|
|
56
|
+
Root.displayName = 'Category.Root';
|
|
57
|
+
/**
|
|
58
|
+
* Interactive element for selecting or triggering category actions.
|
|
59
|
+
* Provides category data and selection state to custom render functions.
|
|
60
|
+
*
|
|
61
|
+
* @component
|
|
62
|
+
* @example
|
|
63
|
+
* ```tsx
|
|
64
|
+
* // Default usage
|
|
65
|
+
* <Category.Trigger className="px-4 py-2 rounded border hover:bg-surface-hover" />
|
|
66
|
+
*
|
|
67
|
+
* // Custom rendering with forwardRef
|
|
68
|
+
* <Category.Trigger asChild>
|
|
69
|
+
* {React.forwardRef(({category, isSelected, onSelect, ...props}, ref) => (
|
|
70
|
+
* <button
|
|
71
|
+
* ref={ref}
|
|
72
|
+
* {...props}
|
|
73
|
+
* onClick={onSelect}
|
|
74
|
+
* className={`px-4 py-2 rounded transition-colors ${
|
|
75
|
+
* isSelected
|
|
76
|
+
* ? 'bg-brand-primary text-white'
|
|
77
|
+
* : 'border border-surface-subtle hover:bg-surface-hover'
|
|
78
|
+
* }`}
|
|
79
|
+
* >
|
|
80
|
+
* {category.name}
|
|
81
|
+
* </button>
|
|
82
|
+
* ))}
|
|
83
|
+
* </Category.Trigger>
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
export const Trigger = React.forwardRef((props, ref) => {
|
|
87
|
+
const { asChild, children, onSelect, className, ...otherProps } = props;
|
|
88
|
+
const { category, isSelected, setSelectedCategory } = useCategoryContext();
|
|
89
|
+
const handleSelect = () => {
|
|
90
|
+
// Use CategoryFilter's setSelectedCategory function
|
|
91
|
+
if (isSelected) {
|
|
92
|
+
// Deselect by passing null
|
|
93
|
+
setSelectedCategory(null);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
// Select this category
|
|
97
|
+
setSelectedCategory(category);
|
|
98
|
+
}
|
|
99
|
+
if (onSelect) {
|
|
100
|
+
onSelect(category);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, onClick: handleSelect, "data-testid": TestIds.categoryTrigger, "data-selected": isSelected ? 'true' : 'false', customElement: children, customElementProps: {
|
|
104
|
+
category,
|
|
105
|
+
isSelected,
|
|
106
|
+
onSelect: handleSelect,
|
|
107
|
+
}, content: category.name, ...otherProps, children: _jsx("button", { children: category.name }) }));
|
|
108
|
+
});
|
|
109
|
+
/**
|
|
110
|
+
* Displays the category name or label.
|
|
111
|
+
* Provides category name and full category data to custom render functions.
|
|
112
|
+
*
|
|
113
|
+
* @component
|
|
114
|
+
* @example
|
|
115
|
+
* ```tsx
|
|
116
|
+
* // Default usage
|
|
117
|
+
* <Category.Label className="text-lg font-medium text-content-primary" />
|
|
118
|
+
*
|
|
119
|
+
* // Custom rendering with forwardRef
|
|
120
|
+
* <Category.Label asChild>
|
|
121
|
+
* {React.forwardRef(({name, category, ...props}, ref) => (
|
|
122
|
+
* <span ref={ref} {...props} className="text-lg font-medium text-content-primary">
|
|
123
|
+
* {name}
|
|
124
|
+
* {category.numberOfProducts > 0 && (
|
|
125
|
+
* <span className="text-sm text-content-muted ml-2">
|
|
126
|
+
* ({category.numberOfProducts})
|
|
127
|
+
* </span>
|
|
128
|
+
* )}
|
|
129
|
+
* </span>
|
|
130
|
+
* ))}
|
|
131
|
+
* </Category.Label>
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
export const Label = React.forwardRef((props, ref) => {
|
|
135
|
+
const { asChild, children, className } = props;
|
|
136
|
+
const { category, isSelected } = useCategoryContext();
|
|
137
|
+
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.categoryLabel, "data-selected": isSelected ? 'true' : 'false', customElement: children, customElementProps: { name: category.name, category }, content: category.name, children: _jsx("span", { children: category.name }) }));
|
|
138
|
+
});
|
|
139
|
+
/**
|
|
140
|
+
* Provides access to the category ID for advanced use cases.
|
|
141
|
+
* Typically used for tracking, analytics, or hidden form fields.
|
|
142
|
+
*
|
|
143
|
+
* @component
|
|
144
|
+
* @example
|
|
145
|
+
* ```tsx
|
|
146
|
+
* // Default usage (hidden by default)
|
|
147
|
+
* <Category.ID className="hidden" />
|
|
148
|
+
*
|
|
149
|
+
* // Custom rendering with forwardRef
|
|
150
|
+
* <Category.ID asChild>
|
|
151
|
+
* {React.forwardRef(({id, category, ...props}, ref) => (
|
|
152
|
+
* <span
|
|
153
|
+
* ref={ref}
|
|
154
|
+
* {...props}
|
|
155
|
+
* data-category-id={id}
|
|
156
|
+
* className="sr-only"
|
|
157
|
+
* >
|
|
158
|
+
* Category ID: {id}
|
|
159
|
+
* </span>
|
|
160
|
+
* ))}
|
|
161
|
+
* </Category.ID>
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
export const ID = React.forwardRef((props, ref) => {
|
|
165
|
+
const { asChild, children, className } = props;
|
|
166
|
+
const { category, isSelected } = useCategoryContext();
|
|
167
|
+
const id = category._id || '';
|
|
168
|
+
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className || 'sr-only', "data-testid": TestIds.categoryId, "data-selected": isSelected ? 'true' : 'false', customElement: children, customElementProps: { id, category }, content: id, children: _jsx("span", { children: id }) }));
|
|
169
|
+
});
|
|
170
|
+
/**
|
|
171
|
+
* Provides access to the full category data for advanced use cases.
|
|
172
|
+
* Useful for custom implementations that need access to all category properties.
|
|
173
|
+
*
|
|
174
|
+
* @component
|
|
175
|
+
* @example
|
|
176
|
+
* ```tsx
|
|
177
|
+
* // Custom rendering with forwardRef
|
|
178
|
+
* <Category.Raw asChild>
|
|
179
|
+
* {React.forwardRef(({category, ...props}, ref) => (
|
|
180
|
+
* <div
|
|
181
|
+
* ref={ref}
|
|
182
|
+
* {...props}
|
|
183
|
+
* data-category-id={category._id}
|
|
184
|
+
* className="category-raw-data"
|
|
185
|
+
* >
|
|
186
|
+
* <pre>{JSON.stringify(category, null, 2)}</pre>
|
|
187
|
+
* </div>
|
|
188
|
+
* ))}
|
|
189
|
+
* </Category.Raw>
|
|
190
|
+
* ```
|
|
191
|
+
*/
|
|
192
|
+
export const Raw = React.forwardRef((props, ref) => {
|
|
193
|
+
const { asChild, children, className } = props;
|
|
194
|
+
const { category, isSelected } = useCategoryContext();
|
|
195
|
+
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className || 'sr-only', "data-testid": TestIds.categoryRaw, "data-selected": isSelected ? 'true' : 'false', customElement: children, customElementProps: { category, isSelected }, children: _jsx("span", { children: JSON.stringify(category) }) }));
|
|
196
|
+
});
|
|
197
|
+
/**
|
|
198
|
+
* Category filter component that provides category selection functionality.
|
|
199
|
+
* Provides selected category state and selection controls to custom render functions.
|
|
200
|
+
*
|
|
201
|
+
* @component
|
|
202
|
+
* @example
|
|
203
|
+
* ```tsx
|
|
204
|
+
* // Default usage
|
|
205
|
+
* <CategoryFilter className="category-filter" />
|
|
206
|
+
*
|
|
207
|
+
* // With custom label
|
|
208
|
+
* <CategoryFilter label="Current Category:" />
|
|
209
|
+
*
|
|
210
|
+
* // Custom rendering with forwardRef
|
|
211
|
+
* <CategoryFilter asChild>
|
|
212
|
+
* {React.forwardRef(({selectedCategory, setSelectedCategory, ...props}, ref) => (
|
|
213
|
+
* <div ref={ref} {...props} className="custom-category-filter">
|
|
214
|
+
* {selectedCategory && (
|
|
215
|
+
* <span>Selected: {selectedCategory.name}</span>
|
|
216
|
+
* )}
|
|
217
|
+
* <button onClick={() => setSelectedCategory(null)}>
|
|
218
|
+
* Clear Selection
|
|
219
|
+
* </button>
|
|
220
|
+
* </div>
|
|
221
|
+
* ))}
|
|
222
|
+
* </CategoryFilter>
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
export const CategoryFilter = React.forwardRef((props, ref) => {
|
|
226
|
+
const { asChild, children, className } = props;
|
|
227
|
+
const label = props.label || 'Selected:';
|
|
228
|
+
return (_jsx(CoreProductListFilters.CategoryFilter, { children: ({ selectedCategory, setSelectedCategory }) => {
|
|
229
|
+
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.categoryFilter, "data-selected": selectedCategory ? 'true' : 'false', customElement: children, customElementProps: {
|
|
230
|
+
selectedCategory,
|
|
231
|
+
setSelectedCategory,
|
|
232
|
+
}, children: _jsx("div", { children: selectedCategory && (_jsxs("span", { children: [label, " ", selectedCategory.name] })) }) }));
|
|
233
|
+
} }));
|
|
234
|
+
});
|
|
235
|
+
CategoryFilter.displayName = 'CategoryFilter';
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type Category as CategoryType } from './Category.js';
|
|
3
|
+
import { type CategoriesListServiceConfig } from '../services/categories-list-service.js';
|
|
4
|
+
/**
|
|
5
|
+
* Props for CategoryList.Root component
|
|
6
|
+
*/
|
|
7
|
+
export interface CategoryListRootProps {
|
|
8
|
+
/** Optional categories array to initialize the service with */
|
|
9
|
+
categories?: CategoryType[];
|
|
10
|
+
/** Configuration for the categories list service */
|
|
11
|
+
categoriesListConfig?: CategoriesListServiceConfig;
|
|
12
|
+
/** Child components */
|
|
13
|
+
children: React.ReactNode;
|
|
14
|
+
/** Optional empty state content to display when no categories are available */
|
|
15
|
+
emptyState?: React.ReactNode;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Props for CategoryList.Loading component
|
|
19
|
+
*/
|
|
20
|
+
export interface CategoryListLoadingProps {
|
|
21
|
+
/** Child content to display during loading */
|
|
22
|
+
children?: React.ReactNode;
|
|
23
|
+
/** Whether to render as a child component */
|
|
24
|
+
asChild?: boolean;
|
|
25
|
+
/** CSS classes to apply to the default element */
|
|
26
|
+
className?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Props for CategoryList.CategoryRepeater component
|
|
30
|
+
*/
|
|
31
|
+
export interface CategoryListCategoryRepeaterProps {
|
|
32
|
+
/** Child components to repeat for each category */
|
|
33
|
+
children: React.ReactNode;
|
|
34
|
+
/** Maximum nesting depth for hierarchical categories */
|
|
35
|
+
maxDepth?: number;
|
|
36
|
+
/** Whether to render as a child component */
|
|
37
|
+
asChild?: boolean;
|
|
38
|
+
/** CSS classes to apply to the default element */
|
|
39
|
+
className?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Root container that provides category list context to all child components.
|
|
43
|
+
* This component sets up the necessary services for managing categories list state.
|
|
44
|
+
* Automatically connects to ProductList filtering when available.
|
|
45
|
+
*
|
|
46
|
+
* @order 1
|
|
47
|
+
* @component
|
|
48
|
+
* @example
|
|
49
|
+
* ```tsx
|
|
50
|
+
* import { CategoryList } from '@wix/headless-stores/react';
|
|
51
|
+
*
|
|
52
|
+
* function CategoriesPage() {
|
|
53
|
+
* return (
|
|
54
|
+
* <CategoryList.Root categoriesListConfig={categoriesListConfig}>
|
|
55
|
+
* <CategoryList.Loading>Loading...</CategoryList.Loading>
|
|
56
|
+
* <CategoryList.CategoryRepeater>
|
|
57
|
+
* <Category.Label />
|
|
58
|
+
* </CategoryList.CategoryRepeater>
|
|
59
|
+
* </CategoryList.Root>
|
|
60
|
+
* );
|
|
61
|
+
* }
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export declare const Root: {
|
|
65
|
+
(props: CategoryListRootProps): React.ReactNode;
|
|
66
|
+
displayName: string;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Displays loading state while category data is being fetched.
|
|
70
|
+
* Only displays its children when the categories list is currently loading.
|
|
71
|
+
*
|
|
72
|
+
* @component
|
|
73
|
+
* @example
|
|
74
|
+
* ```tsx
|
|
75
|
+
* import { CategoryList } from '@wix/headless-stores/react';
|
|
76
|
+
*
|
|
77
|
+
* function CategoriesLoading() {
|
|
78
|
+
* return (
|
|
79
|
+
* <CategoryList.Loading>
|
|
80
|
+
* <div className="loading-spinner">Loading categories...</div>
|
|
81
|
+
* </CategoryList.Loading>
|
|
82
|
+
* );
|
|
83
|
+
* }
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
export declare const Loading: React.ForwardRefExoticComponent<CategoryListLoadingProps & React.RefAttributes<HTMLDivElement>>;
|
|
87
|
+
/**
|
|
88
|
+
* Repeats for each category in the list, providing individual category context.
|
|
89
|
+
* Maps over all categories and provides each category through a service context.
|
|
90
|
+
* Only renders when categories are successfully loaded.
|
|
91
|
+
*
|
|
92
|
+
* @component
|
|
93
|
+
* @example
|
|
94
|
+
* ```tsx
|
|
95
|
+
* import { CategoryList } from '@wix/headless-stores/react';
|
|
96
|
+
*
|
|
97
|
+
* function CategoriesGrid() {
|
|
98
|
+
* return (
|
|
99
|
+
* <CategoryList.CategoryRepeater maxDepth={3}>
|
|
100
|
+
* <Category.Label />
|
|
101
|
+
* <Category.ID />
|
|
102
|
+
* </CategoryList.CategoryRepeater>
|
|
103
|
+
* );
|
|
104
|
+
* }
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
export declare function CategoryRepeater(props: CategoryListCategoryRepeaterProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import * as CoreCategoryList from './core/CategoryList.js';
|
|
4
|
+
import * as Category from './Category.js';
|
|
5
|
+
import { AsChildSlot } from '@wix/headless-utils/react';
|
|
6
|
+
import { DataComponentTags } from '../data-component-tags.js';
|
|
7
|
+
var TestIds;
|
|
8
|
+
(function (TestIds) {
|
|
9
|
+
TestIds["categoryListRoot"] = "category-list";
|
|
10
|
+
TestIds["categoryRepeater"] = "category-repeater";
|
|
11
|
+
})(TestIds || (TestIds = {}));
|
|
12
|
+
/**
|
|
13
|
+
* Root container that provides category list context to all child components.
|
|
14
|
+
* This component sets up the necessary services for managing categories list state.
|
|
15
|
+
* Automatically connects to ProductList filtering when available.
|
|
16
|
+
*
|
|
17
|
+
* @order 1
|
|
18
|
+
* @component
|
|
19
|
+
* @example
|
|
20
|
+
* ```tsx
|
|
21
|
+
* import { CategoryList } from '@wix/headless-stores/react';
|
|
22
|
+
*
|
|
23
|
+
* function CategoriesPage() {
|
|
24
|
+
* return (
|
|
25
|
+
* <CategoryList.Root categoriesListConfig={categoriesListConfig}>
|
|
26
|
+
* <CategoryList.Loading>Loading...</CategoryList.Loading>
|
|
27
|
+
* <CategoryList.CategoryRepeater>
|
|
28
|
+
* <Category.Label />
|
|
29
|
+
* </CategoryList.CategoryRepeater>
|
|
30
|
+
* </CategoryList.Root>
|
|
31
|
+
* );
|
|
32
|
+
* }
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export const Root = (props) => {
|
|
36
|
+
const { categories, categoriesListConfig, children, emptyState } = props;
|
|
37
|
+
// Create service config, prioritizing categoriesListConfig, then categories prop
|
|
38
|
+
const serviceConfig = categoriesListConfig || (categories ? { categories } : { categories: [] });
|
|
39
|
+
return (_jsx(CoreCategoryList.Root, { categoriesListConfig: serviceConfig, children: _jsxs(AsChildSlot, { "data-testid": TestIds.categoryListRoot, "data-component-tag": DataComponentTags.categoryListRoot, children: [children, emptyState && (_jsx(CoreCategoryList.EmptyState, { children: emptyState }))] }) }));
|
|
40
|
+
};
|
|
41
|
+
Root.displayName = 'CategoryList.Root';
|
|
42
|
+
/**
|
|
43
|
+
* Displays loading state while category data is being fetched.
|
|
44
|
+
* Only displays its children when the categories list is currently loading.
|
|
45
|
+
*
|
|
46
|
+
* @component
|
|
47
|
+
* @example
|
|
48
|
+
* ```tsx
|
|
49
|
+
* import { CategoryList } from '@wix/headless-stores/react';
|
|
50
|
+
*
|
|
51
|
+
* function CategoriesLoading() {
|
|
52
|
+
* return (
|
|
53
|
+
* <CategoryList.Loading>
|
|
54
|
+
* <div className="loading-spinner">Loading categories...</div>
|
|
55
|
+
* </CategoryList.Loading>
|
|
56
|
+
* );
|
|
57
|
+
* }
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export const Loading = React.forwardRef((props, ref) => {
|
|
61
|
+
const { asChild, children, className } = props;
|
|
62
|
+
return (_jsx(CoreCategoryList.Loading, { children: _jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, customElement: children, children: _jsx("h1", { children: "Loading..." }) }) }));
|
|
63
|
+
});
|
|
64
|
+
/**
|
|
65
|
+
* Repeats for each category in the list, providing individual category context.
|
|
66
|
+
* Maps over all categories and provides each category through a service context.
|
|
67
|
+
* Only renders when categories are successfully loaded.
|
|
68
|
+
*
|
|
69
|
+
* @component
|
|
70
|
+
* @example
|
|
71
|
+
* ```tsx
|
|
72
|
+
* import { CategoryList } from '@wix/headless-stores/react';
|
|
73
|
+
*
|
|
74
|
+
* function CategoriesGrid() {
|
|
75
|
+
* return (
|
|
76
|
+
* <CategoryList.CategoryRepeater maxDepth={3}>
|
|
77
|
+
* <Category.Label />
|
|
78
|
+
* <Category.ID />
|
|
79
|
+
* </CategoryList.CategoryRepeater>
|
|
80
|
+
* );
|
|
81
|
+
* }
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
export function CategoryRepeater(props) {
|
|
85
|
+
// const { children, asChild = false, className } = props;
|
|
86
|
+
const { children } = props;
|
|
87
|
+
// Note: maxDepth is not implemented yet as it depends on category hierarchy structure
|
|
88
|
+
return (_jsx(CoreCategoryList.ItemContent, { children: ({ category }) => {
|
|
89
|
+
return (_jsx(Category.Root, { category: category, children: children }, category._id));
|
|
90
|
+
} }));
|
|
91
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { AsChildChildren } from '@wix/headless-utils/react';
|
|
3
|
+
/**
|
|
4
|
+
* Choice data interface
|
|
5
|
+
*/
|
|
6
|
+
export interface Choice {
|
|
7
|
+
colorCode?: string;
|
|
8
|
+
choiceId?: string | null;
|
|
9
|
+
linkedMedia?: any[];
|
|
10
|
+
type?: 'color' | 'text' | 'free-text';
|
|
11
|
+
key?: string;
|
|
12
|
+
name?: string | null;
|
|
13
|
+
addedPrice?: string | null;
|
|
14
|
+
minCharCount?: number;
|
|
15
|
+
maxCharCount?: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Context value interface for individual choice data and behavior
|
|
19
|
+
*/
|
|
20
|
+
export interface ChoiceContextValue {
|
|
21
|
+
/** The choice data object */
|
|
22
|
+
choice: Choice;
|
|
23
|
+
/** Whether this choice should render as text */
|
|
24
|
+
shouldRenderAsText: boolean;
|
|
25
|
+
/** Whether this choice should render as color swatch */
|
|
26
|
+
shouldRenderAsColor: boolean;
|
|
27
|
+
/** Whether this choice should render as free text input */
|
|
28
|
+
shouldRenderAsFreeText: boolean;
|
|
29
|
+
/** Display value for the choice */
|
|
30
|
+
value: string;
|
|
31
|
+
/** Whether this choice is currently selected */
|
|
32
|
+
isSelected: boolean;
|
|
33
|
+
/** Whether this choice is visible based on current selections */
|
|
34
|
+
isVisible: boolean;
|
|
35
|
+
/** Whether this choice is in stock */
|
|
36
|
+
isInStock: boolean;
|
|
37
|
+
/** Whether this choice is available for pre-order */
|
|
38
|
+
isPreOrderEnabled: boolean;
|
|
39
|
+
/** Function to select this choice */
|
|
40
|
+
select: () => void;
|
|
41
|
+
/** Callback for free text value changes */
|
|
42
|
+
onValueChange?: (value: string) => void;
|
|
43
|
+
}
|
|
44
|
+
export declare const ChoiceContext: React.Context<ChoiceContextValue | null>;
|
|
45
|
+
/**
|
|
46
|
+
* Hook to access ChoiceContext with proper error handling
|
|
47
|
+
* @throws {Error} When used outside of a Choice context provider
|
|
48
|
+
* @returns {ChoiceContextValue} The choice context value
|
|
49
|
+
*/
|
|
50
|
+
export declare function useChoiceContext(): ChoiceContextValue;
|
|
51
|
+
export interface RootProps {
|
|
52
|
+
children?: React.ReactNode;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Root component that consumes ChoiceContext provided by Option.ChoiceRepeater.
|
|
56
|
+
*
|
|
57
|
+
* @component
|
|
58
|
+
* @example
|
|
59
|
+
* ```tsx
|
|
60
|
+
* <Choice.Root>
|
|
61
|
+
* <Choice.Text />
|
|
62
|
+
* <Choice.Color />
|
|
63
|
+
* </Choice.Root>
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export declare const Root: React.ForwardRefExoticComponent<RootProps & React.RefAttributes<HTMLDivElement>>;
|
|
67
|
+
/**
|
|
68
|
+
* Props for Choice Text component
|
|
69
|
+
*/
|
|
70
|
+
export interface TextProps {
|
|
71
|
+
/** Whether to render as a child component */
|
|
72
|
+
asChild?: boolean;
|
|
73
|
+
/** Custom render function when using asChild */
|
|
74
|
+
children?: AsChildChildren<{
|
|
75
|
+
id: string;
|
|
76
|
+
value: string;
|
|
77
|
+
}>;
|
|
78
|
+
/** CSS classes to apply to the default element */
|
|
79
|
+
className?: string;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Text-based choice button.
|
|
83
|
+
*
|
|
84
|
+
* @component
|
|
85
|
+
* @example
|
|
86
|
+
* ```tsx
|
|
87
|
+
* // Default usage
|
|
88
|
+
* <Choice.Text className="px-4 py-2 border rounded-lg" />
|
|
89
|
+
*
|
|
90
|
+
* // asChild with primitive
|
|
91
|
+
* <Choice.Text asChild>
|
|
92
|
+
* <button className="px-4 py-2 border rounded-lg" />
|
|
93
|
+
* </Choice.Text>
|
|
94
|
+
*
|
|
95
|
+
* // asChild with react component
|
|
96
|
+
* <Choice.Text asChild>
|
|
97
|
+
* {React.forwardRef(({id, value, ...props}, ref) => (
|
|
98
|
+
* <button ref={ref} {...props} className="px-4 py-2 border rounded-lg">
|
|
99
|
+
* {value}
|
|
100
|
+
* </button>
|
|
101
|
+
* ))}
|
|
102
|
+
* </Choice.Text>
|
|
103
|
+
* ```
|
|
104
|
+
*
|
|
105
|
+
* Data Attributes:
|
|
106
|
+
* - `data-testid="choice-text"` - Applied to choice buttons
|
|
107
|
+
* - `data-selected` - Is Choice selected
|
|
108
|
+
* - `disabled` - Is Choice disabled (not in stock)
|
|
109
|
+
*/
|
|
110
|
+
export declare const Text: React.ForwardRefExoticComponent<TextProps & React.RefAttributes<HTMLButtonElement>>;
|
|
111
|
+
/**
|
|
112
|
+
* Props for Choice Color component
|
|
113
|
+
*/
|
|
114
|
+
export interface ColorProps {
|
|
115
|
+
/** Whether to render as a child component */
|
|
116
|
+
asChild?: boolean;
|
|
117
|
+
/** Custom render function when using asChild */
|
|
118
|
+
children?: AsChildChildren<{
|
|
119
|
+
colorCode: string;
|
|
120
|
+
name: string;
|
|
121
|
+
id: string;
|
|
122
|
+
}>;
|
|
123
|
+
/** CSS classes to apply to the default element */
|
|
124
|
+
className?: string;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Color swatch choice.
|
|
128
|
+
*
|
|
129
|
+
* @component
|
|
130
|
+
* @example
|
|
131
|
+
* ```tsx
|
|
132
|
+
* // Default usage
|
|
133
|
+
* <Choice.Color className="w-10 h-10 rounded-full border-4" />
|
|
134
|
+
*
|
|
135
|
+
* // asChild with primitive
|
|
136
|
+
* <Choice.Color asChild>
|
|
137
|
+
* <button className="w-10 h-10 rounded-full border-4" />
|
|
138
|
+
* </Choice.Color>
|
|
139
|
+
*
|
|
140
|
+
* // asChild with react component
|
|
141
|
+
* <Choice.Color asChild>
|
|
142
|
+
* {React.forwardRef(({colorCode, name, id, ...props}, ref) => (
|
|
143
|
+
* <button
|
|
144
|
+
* ref={ref}
|
|
145
|
+
* {...props}
|
|
146
|
+
* className="w-10 h-10 rounded-full border-4"
|
|
147
|
+
* style={{ backgroundColor: colorCode }}
|
|
148
|
+
* title={name}
|
|
149
|
+
* />
|
|
150
|
+
* ))}
|
|
151
|
+
* </Choice.Color>
|
|
152
|
+
* ```
|
|
153
|
+
*
|
|
154
|
+
* Data Attributes:
|
|
155
|
+
* - `data-testid="choice-color"` - Applied to color swatches
|
|
156
|
+
* - `data-selected` - Is Choice selected
|
|
157
|
+
* - `disabled` - Is Choice disabled (not in stock)
|
|
158
|
+
*/
|
|
159
|
+
export declare const Color: React.ForwardRefExoticComponent<ColorProps & React.RefAttributes<HTMLButtonElement>>;
|
|
160
|
+
/**
|
|
161
|
+
* Props for Choice FreeText component
|
|
162
|
+
*/
|
|
163
|
+
export interface FreeTextProps extends Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, 'children'> {
|
|
164
|
+
/** Whether to render as a child component */
|
|
165
|
+
asChild?: boolean;
|
|
166
|
+
/** Custom render function when using asChild */
|
|
167
|
+
children?: AsChildChildren<{
|
|
168
|
+
minCharCount?: number;
|
|
169
|
+
maxCharCount?: number;
|
|
170
|
+
defaultAddedPrice?: string | null;
|
|
171
|
+
title?: string;
|
|
172
|
+
value?: string;
|
|
173
|
+
onChange?: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
|
|
174
|
+
}>;
|
|
175
|
+
/** CSS classes to apply to the default element */
|
|
176
|
+
className?: string;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Provides a free text input for variant selection.
|
|
180
|
+
*
|
|
181
|
+
* @component
|
|
182
|
+
* @example
|
|
183
|
+
* ```tsx
|
|
184
|
+
* // Default usage
|
|
185
|
+
* <Choice.FreeText className="p-3 border rounded-lg" />
|
|
186
|
+
*
|
|
187
|
+
* // asChild with primitive
|
|
188
|
+
* <Choice.FreeText asChild>
|
|
189
|
+
* <textarea className="p-3 border rounded-lg" />
|
|
190
|
+
* </Choice.FreeText>
|
|
191
|
+
*
|
|
192
|
+
* // asChild with react component
|
|
193
|
+
* <Choice.FreeText asChild>
|
|
194
|
+
* {React.forwardRef(({value, onChange, title, ...props}, ref) => (
|
|
195
|
+
* <textarea
|
|
196
|
+
* ref={ref}
|
|
197
|
+
* {...props}
|
|
198
|
+
* className="p-3 border rounded-lg"
|
|
199
|
+
* value={value}
|
|
200
|
+
* onChange={onChange}
|
|
201
|
+
* placeholder={`Enter custom ${title}...`}
|
|
202
|
+
* />
|
|
203
|
+
* ))}
|
|
204
|
+
* </Choice.FreeText>
|
|
205
|
+
* ```
|
|
206
|
+
*
|
|
207
|
+
* Data Attributes:
|
|
208
|
+
* - `data-testid="choice-free-text"` - Applied to free text input
|
|
209
|
+
* - `data-selected` - Is Choice selected
|
|
210
|
+
*/
|
|
211
|
+
export declare const FreeText: React.ForwardRefExoticComponent<FreeTextProps & React.RefAttributes<HTMLTextAreaElement>>;
|