@wix/headless-stores 0.0.35 → 0.0.37

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 (131) hide show
  1. package/cjs/dist/react/Category.d.ts +83 -31
  2. package/cjs/dist/react/Category.js +68 -35
  3. package/cjs/dist/react/CategoryList.d.ts +184 -0
  4. package/cjs/dist/react/CategoryList.js +174 -0
  5. package/cjs/dist/react/Product.d.ts +3 -3
  6. package/cjs/dist/react/Product.js +6 -6
  7. package/cjs/dist/react/ProductActions.d.ts +1 -1
  8. package/cjs/dist/react/ProductActions.js +2 -2
  9. package/{dist/react/ProductsList.d.ts → cjs/dist/react/ProductList.d.ts} +71 -38
  10. package/{dist/react/ProductsList.js → cjs/dist/react/ProductList.js} +30 -26
  11. package/cjs/dist/react/ProductListFilters.d.ts +244 -0
  12. package/cjs/dist/react/ProductListFilters.js +216 -0
  13. package/cjs/dist/react/ProductListPagination.d.ts +246 -0
  14. package/cjs/dist/react/ProductListPagination.js +207 -0
  15. package/cjs/dist/react/ProductListSort.d.ts +87 -0
  16. package/cjs/dist/react/ProductListSort.js +85 -0
  17. package/cjs/dist/react/ProductModifiers.d.ts +5 -5
  18. package/cjs/dist/react/ProductModifiers.js +10 -10
  19. package/cjs/dist/react/ProductVariantSelector.d.ts +5 -5
  20. package/cjs/dist/react/ProductVariantSelector.js +13 -10
  21. package/cjs/dist/react/SelectedVariant.d.ts +3 -3
  22. package/cjs/dist/react/SelectedVariant.js +6 -6
  23. package/cjs/dist/react/index.d.ts +7 -9
  24. package/cjs/dist/react/index.js +7 -9
  25. package/cjs/dist/services/buy-now-service.d.ts +208 -0
  26. package/cjs/dist/services/buy-now-service.js +132 -1
  27. package/cjs/dist/services/categories-list-service.d.ts +163 -0
  28. package/cjs/dist/services/categories-list-service.js +148 -0
  29. package/cjs/dist/services/category-service.d.ts +115 -70
  30. package/cjs/dist/services/category-service.js +101 -110
  31. package/cjs/dist/services/index.d.ts +6 -7
  32. package/cjs/dist/services/index.js +5 -16
  33. package/cjs/dist/services/pay-now-service.d.ts +146 -0
  34. package/cjs/dist/services/pay-now-service.js +112 -1
  35. package/cjs/dist/services/product-service.d.ts +71 -0
  36. package/cjs/dist/services/product-service.js +47 -0
  37. package/cjs/dist/services/products-list-filters-service.d.ts +292 -0
  38. package/cjs/dist/services/products-list-filters-service.js +446 -0
  39. package/cjs/dist/services/products-list-pagination-service.d.ts +186 -0
  40. package/cjs/dist/services/products-list-pagination-service.js +179 -0
  41. package/cjs/dist/services/products-list-service.d.ts +138 -52
  42. package/cjs/dist/services/products-list-service.js +98 -51
  43. package/cjs/dist/services/products-list-sort-service.d.ts +117 -0
  44. package/cjs/dist/services/products-list-sort-service.js +144 -0
  45. package/cjs/dist/services/selected-variant-service.js +0 -1
  46. package/cjs/dist/utils/url-params.d.ts +68 -0
  47. package/cjs/dist/utils/url-params.js +72 -4
  48. package/dist/react/Category.d.ts +83 -31
  49. package/dist/react/Category.js +68 -35
  50. package/dist/react/CategoryList.d.ts +184 -0
  51. package/dist/react/CategoryList.js +174 -0
  52. package/dist/react/Product.d.ts +3 -3
  53. package/dist/react/Product.js +6 -6
  54. package/dist/react/ProductActions.d.ts +1 -1
  55. package/dist/react/ProductActions.js +2 -2
  56. package/{cjs/dist/react/ProductsList.d.ts → dist/react/ProductList.d.ts} +71 -38
  57. package/{cjs/dist/react/ProductsList.js → dist/react/ProductList.js} +30 -26
  58. package/dist/react/ProductListFilters.d.ts +244 -0
  59. package/dist/react/ProductListFilters.js +216 -0
  60. package/dist/react/ProductListPagination.d.ts +246 -0
  61. package/dist/react/ProductListPagination.js +207 -0
  62. package/dist/react/ProductListSort.d.ts +87 -0
  63. package/dist/react/ProductListSort.js +85 -0
  64. package/dist/react/ProductModifiers.d.ts +5 -5
  65. package/dist/react/ProductModifiers.js +10 -10
  66. package/dist/react/ProductVariantSelector.d.ts +5 -5
  67. package/dist/react/ProductVariantSelector.js +13 -10
  68. package/dist/react/SelectedVariant.d.ts +3 -3
  69. package/dist/react/SelectedVariant.js +6 -6
  70. package/dist/react/index.d.ts +7 -9
  71. package/dist/react/index.js +7 -9
  72. package/dist/services/buy-now-service.d.ts +208 -0
  73. package/dist/services/buy-now-service.js +132 -1
  74. package/dist/services/categories-list-service.d.ts +163 -0
  75. package/dist/services/categories-list-service.js +148 -0
  76. package/dist/services/category-service.d.ts +115 -70
  77. package/dist/services/category-service.js +101 -110
  78. package/dist/services/index.d.ts +6 -7
  79. package/dist/services/index.js +5 -16
  80. package/dist/services/pay-now-service.d.ts +146 -0
  81. package/dist/services/pay-now-service.js +112 -1
  82. package/dist/services/product-service.d.ts +71 -0
  83. package/dist/services/product-service.js +47 -0
  84. package/dist/services/products-list-filters-service.d.ts +292 -0
  85. package/dist/services/products-list-filters-service.js +446 -0
  86. package/dist/services/products-list-pagination-service.d.ts +186 -0
  87. package/dist/services/products-list-pagination-service.js +179 -0
  88. package/dist/services/products-list-service.d.ts +138 -52
  89. package/dist/services/products-list-service.js +98 -51
  90. package/dist/services/products-list-sort-service.d.ts +117 -0
  91. package/dist/services/products-list-sort-service.js +144 -0
  92. package/dist/services/selected-variant-service.js +0 -1
  93. package/dist/utils/url-params.d.ts +68 -0
  94. package/dist/utils/url-params.js +72 -4
  95. package/package.json +3 -3
  96. package/cjs/dist/react/Collection.d.ts +0 -294
  97. package/cjs/dist/react/Collection.js +0 -345
  98. package/cjs/dist/react/FilteredCollection.d.ts +0 -216
  99. package/cjs/dist/react/FilteredCollection.js +0 -256
  100. package/cjs/dist/react/RelatedProducts.d.ts +0 -169
  101. package/cjs/dist/react/RelatedProducts.js +0 -180
  102. package/cjs/dist/react/Sort.d.ts +0 -37
  103. package/cjs/dist/react/Sort.js +0 -36
  104. package/cjs/dist/services/catalog-service.d.ts +0 -36
  105. package/cjs/dist/services/catalog-service.js +0 -193
  106. package/cjs/dist/services/collection-service.d.ts +0 -124
  107. package/cjs/dist/services/collection-service.js +0 -628
  108. package/cjs/dist/services/filter-service.d.ts +0 -35
  109. package/cjs/dist/services/filter-service.js +0 -119
  110. package/cjs/dist/services/related-products-service.d.ts +0 -100
  111. package/cjs/dist/services/related-products-service.js +0 -127
  112. package/cjs/dist/services/sort-service.d.ts +0 -20
  113. package/cjs/dist/services/sort-service.js +0 -27
  114. package/dist/react/Collection.d.ts +0 -294
  115. package/dist/react/Collection.js +0 -345
  116. package/dist/react/FilteredCollection.d.ts +0 -216
  117. package/dist/react/FilteredCollection.js +0 -256
  118. package/dist/react/RelatedProducts.d.ts +0 -169
  119. package/dist/react/RelatedProducts.js +0 -180
  120. package/dist/react/Sort.d.ts +0 -37
  121. package/dist/react/Sort.js +0 -36
  122. package/dist/services/catalog-service.d.ts +0 -36
  123. package/dist/services/catalog-service.js +0 -193
  124. package/dist/services/collection-service.d.ts +0 -124
  125. package/dist/services/collection-service.js +0 -628
  126. package/dist/services/filter-service.d.ts +0 -35
  127. package/dist/services/filter-service.js +0 -119
  128. package/dist/services/related-products-service.d.ts +0 -100
  129. package/dist/services/related-products-service.js +0 -127
  130. package/dist/services/sort-service.d.ts +0 -20
  131. package/dist/services/sort-service.js +0 -27
@@ -1,294 +0,0 @@
1
- import { type V3Product } from "@wix/auto_sdk_stores_products-v-3";
2
- /**
3
- * Props for Grid headless component
4
- */
5
- export interface GridProps {
6
- /** Render prop function that receives product grid data */
7
- children: (props: GridRenderProps) => React.ReactNode;
8
- }
9
- /**
10
- * Render props for Grid component
11
- */
12
- export interface GridRenderProps {
13
- /** Array of products */
14
- products: V3Product[];
15
- /** Whether products are loading */
16
- isLoading: boolean;
17
- /** Error message if any */
18
- error: string | null;
19
- /** Whether there are no products */
20
- isEmpty: boolean;
21
- /** Total number of products */
22
- totalProducts: number;
23
- /** Whether collection has products */
24
- hasProducts: boolean;
25
- }
26
- /**
27
- * Headless component for product grid
28
- *
29
- * @component
30
- * @example
31
- * ```tsx
32
- * import { Collection } from '@wix/stores/components';
33
- *
34
- * function ProductGrid() {
35
- * return (
36
- * <Collection.Grid>
37
- * {({ products, isLoading, error, isEmpty, totalProducts, hasProducts }) => (
38
- * <div>
39
- * {isLoading && <div>Loading products...</div>}
40
- * {error && <div>Error: {error}</div>}
41
- * {isEmpty && <div>No products found</div>}
42
- * {hasProducts && (
43
- * <div>
44
- * <p>Showing {products.length} of {totalProducts} products</p>
45
- * <div className="product-grid">
46
- * {products.map(product => (
47
- * <div key={product.id} className="product-card">
48
- * <h3>{product.name}</h3>
49
- * <p>{product.price?.price} {product.price?.currency}</p>
50
- * </div>
51
- * ))}
52
- * </div>
53
- * </div>
54
- * )}
55
- * </div>
56
- * )}
57
- * </Collection.Grid>
58
- * );
59
- * }
60
- * ```
61
- */
62
- export declare const Grid: (props: GridProps) => import("react").ReactNode;
63
- /**
64
- * Props for Item headless component
65
- */
66
- export interface ItemProps {
67
- /** Product data */
68
- product: V3Product;
69
- /** Render prop function that receives product item data */
70
- children: (props: ItemRenderProps) => React.ReactNode;
71
- }
72
- /**
73
- * Render props for Item component
74
- */
75
- export interface ItemRenderProps {
76
- /** Product ID */
77
- id: string;
78
- /** Product title */
79
- title: string;
80
- /** Product slug for URL */
81
- slug: string;
82
- /** Main product image URL */
83
- image: string | null;
84
- /** Product price */
85
- price: string;
86
- /** Compare at price (for strikethrough) */
87
- compareAtPrice: string | null;
88
- /** Product description */
89
- description: string;
90
- /** Whether product is available */
91
- available: boolean;
92
- }
93
- /**
94
- * Headless component for individual product item
95
- *
96
- * @component
97
- * @example
98
- * ```tsx
99
- * import { Collection } from '@wix/stores/components';
100
- *
101
- * function ProductCard({ product }) {
102
- * return (
103
- * <Collection.Item product={product}>
104
- * {({ id, title, slug, image, price, compareAtPrice, description, available }) => (
105
- * <div className={`product-card ${!available ? 'unavailable' : ''}`}>
106
- * {image && <img src={image} alt={title} />}
107
- * <h3>{title}</h3>
108
- * <p>{description}</p>
109
- * <div className="pricing">
110
- * <span className="price">{price}</span>
111
- * {compareAtPrice && (
112
- * <span className="compare-price"><s>{compareAtPrice}</s></span>
113
- * )}
114
- * </div>
115
- * {!available && <div className="badge">Out of Stock</div>}
116
- * <a href={`/products/${slug}`}>View Product</a>
117
- * </div>
118
- * )}
119
- * </Collection.Item>
120
- * );
121
- * }
122
- * ```
123
- */
124
- export declare const Item: (props: ItemProps) => import("react").ReactNode;
125
- /**
126
- * Props for LoadMore headless component
127
- */
128
- export interface LoadMoreProps {
129
- /** Render prop function that receives load more data */
130
- children: (props: LoadMoreRenderProps) => React.ReactNode;
131
- }
132
- /**
133
- * Render props for LoadMore component
134
- */
135
- export interface LoadMoreRenderProps {
136
- /** Function to load more products */
137
- loadMore: () => Promise<void>;
138
- /** Function to refresh products */
139
- refresh: () => Promise<void>;
140
- /** Whether load more is currently loading */
141
- isLoading: boolean;
142
- /** Whether there are products */
143
- hasProducts: boolean;
144
- /** Total number of products currently loaded */
145
- totalProducts: number;
146
- /** Whether there are more products to load */
147
- hasMoreProducts: boolean;
148
- }
149
- /**
150
- * Headless component for load more products functionality
151
- * Note: V3 API uses simplified loading without traditional pagination
152
- *
153
- * @component
154
- * @example
155
- * ```tsx
156
- * import { Collection } from '@wix/stores/components';
157
- *
158
- * function LoadMoreButton() {
159
- * return (
160
- * <Collection.LoadMore>
161
- * {({ loadMore, refresh, isLoading, hasProducts, totalProducts, hasMoreProducts }) => (
162
- * <div className="load-more-section">
163
- * {hasProducts && (
164
- * <div>
165
- * <p>Loaded {totalProducts} products</p>
166
- * <div className="actions">
167
- * {hasMoreProducts && (
168
- * <button
169
- * onClick={loadMore}
170
- * disabled={isLoading}
171
- * >
172
- * {isLoading ? 'Loading...' : 'Load More Products'}
173
- * </button>
174
- * )}
175
- * <button onClick={refresh}>Refresh Collection</button>
176
- * </div>
177
- * </div>
178
- * )}
179
- * </div>
180
- * )}
181
- * </Collection.LoadMore>
182
- * );
183
- * }
184
- * ```
185
- */
186
- export declare const LoadMore: (props: LoadMoreProps) => import("react").ReactNode;
187
- /**
188
- * Props for Header headless component
189
- */
190
- export interface HeaderProps {
191
- /** Render prop function that receives collection header data */
192
- children: (props: HeaderRenderProps) => React.ReactNode;
193
- }
194
- /**
195
- * Render props for Header component
196
- */
197
- export interface HeaderRenderProps {
198
- /** Total number of products */
199
- totalProducts: number;
200
- /** Whether collection is loading */
201
- isLoading: boolean;
202
- /** Whether collection has products */
203
- hasProducts: boolean;
204
- }
205
- /**
206
- * Headless component for collection header with product count
207
- *
208
- * @component
209
- * @example
210
- * ```tsx
211
- * import { Collection } from '@wix/stores/components';
212
- *
213
- * function CollectionHeader() {
214
- * return (
215
- * <Collection.Header>
216
- * {({ totalProducts, isLoading, hasProducts }) => (
217
- * <div className="collection-header">
218
- * {isLoading && <div>Loading collection...</div>}
219
- * {hasProducts && !isLoading && (
220
- * <h2>Products ({totalProducts} items)</h2>
221
- * )}
222
- * {!hasProducts && !isLoading && (
223
- * <h2>No products found</h2>
224
- * )}
225
- * </div>
226
- * )}
227
- * </Collection.Header>
228
- * );
229
- * }
230
- * ```
231
- */
232
- export declare const Header: (props: HeaderProps) => import("react").ReactNode;
233
- /**
234
- * Props for Actions headless component
235
- */
236
- export interface ActionsProps {
237
- /** Render prop function that receives collection actions data */
238
- children: (props: ActionsRenderProps) => React.ReactNode;
239
- }
240
- /**
241
- * Render props for Actions component
242
- */
243
- export interface ActionsRenderProps {
244
- /** Function to refresh the collection */
245
- refresh: () => Promise<void>;
246
- /** Function to load more products */
247
- loadMore: () => Promise<void>;
248
- /** Whether actions are loading */
249
- isLoading: boolean;
250
- /** Error message if any */
251
- error: string | null;
252
- }
253
- /**
254
- * Headless component for collection actions (refresh, load more)
255
- * Replaces traditional pagination for V3 API
256
- *
257
- * @component
258
- * @example
259
- * ```tsx
260
- * import { Collection } from '@wix/stores/components';
261
- *
262
- * function CollectionActions() {
263
- * return (
264
- * <Collection.Actions>
265
- * {({ refresh, loadMore, isLoading, error }) => (
266
- * <div className="collection-actions">
267
- * {error && (
268
- * <div className="error">
269
- * Error: {error}
270
- * <button onClick={refresh}>Retry</button>
271
- * </div>
272
- * )}
273
- * <div className="action-buttons">
274
- * <button
275
- * onClick={refresh}
276
- * disabled={isLoading}
277
- * >
278
- * {isLoading ? 'Refreshing...' : 'Refresh'}
279
- * </button>
280
- * <button
281
- * onClick={loadMore}
282
- * disabled={isLoading}
283
- * >
284
- * Load More
285
- * </button>
286
- * </div>
287
- * </div>
288
- * )}
289
- * </Collection.Actions>
290
- * );
291
- * }
292
- * ```
293
- */
294
- export declare const Actions: (props: ActionsProps) => import("react").ReactNode;
@@ -1,345 +0,0 @@
1
- import { useService } from "@wix/services-manager-react";
2
- import { CollectionServiceDefinition } from "../services/collection-service.js";
3
- import { InventoryAvailabilityStatus, } from "@wix/auto_sdk_stores_products-v-3";
4
- /**
5
- * Headless component for product grid
6
- *
7
- * @component
8
- * @example
9
- * ```tsx
10
- * import { Collection } from '@wix/stores/components';
11
- *
12
- * function ProductGrid() {
13
- * return (
14
- * <Collection.Grid>
15
- * {({ products, isLoading, error, isEmpty, totalProducts, hasProducts }) => (
16
- * <div>
17
- * {isLoading && <div>Loading products...</div>}
18
- * {error && <div>Error: {error}</div>}
19
- * {isEmpty && <div>No products found</div>}
20
- * {hasProducts && (
21
- * <div>
22
- * <p>Showing {products.length} of {totalProducts} products</p>
23
- * <div className="product-grid">
24
- * {products.map(product => (
25
- * <div key={product.id} className="product-card">
26
- * <h3>{product.name}</h3>
27
- * <p>{product.price?.price} {product.price?.currency}</p>
28
- * </div>
29
- * ))}
30
- * </div>
31
- * </div>
32
- * )}
33
- * </div>
34
- * )}
35
- * </Collection.Grid>
36
- * );
37
- * }
38
- * ```
39
- */
40
- export const Grid = (props) => {
41
- const service = useService(CollectionServiceDefinition);
42
- // Debug logging to help identify service issues
43
- if (!service) {
44
- console.error("CollectionService is undefined");
45
- return props.children({
46
- products: [],
47
- isLoading: false,
48
- error: "Service not available",
49
- isEmpty: true,
50
- totalProducts: 0,
51
- hasProducts: false,
52
- });
53
- }
54
- // Safely access service properties with error handling
55
- try {
56
- const productList = service.products?.get() || [];
57
- const isLoading = service.isLoading?.get() || false;
58
- const error = service.error?.get() || null;
59
- const totalProducts = service.totalProducts?.get() || 0;
60
- const hasProducts = service.hasProducts?.get() || false;
61
- return props.children({
62
- products: productList,
63
- isLoading,
64
- error,
65
- isEmpty: !hasProducts && !isLoading,
66
- totalProducts,
67
- hasProducts,
68
- });
69
- }
70
- catch (err) {
71
- console.error("Error accessing service properties:", err);
72
- return props.children({
73
- products: [],
74
- isLoading: false,
75
- error: "Failed to load products",
76
- isEmpty: true,
77
- totalProducts: 0,
78
- hasProducts: false,
79
- });
80
- }
81
- };
82
- /**
83
- * Headless component for individual product item
84
- *
85
- * @component
86
- * @example
87
- * ```tsx
88
- * import { Collection } from '@wix/stores/components';
89
- *
90
- * function ProductCard({ product }) {
91
- * return (
92
- * <Collection.Item product={product}>
93
- * {({ id, title, slug, image, price, compareAtPrice, description, available }) => (
94
- * <div className={`product-card ${!available ? 'unavailable' : ''}`}>
95
- * {image && <img src={image} alt={title} />}
96
- * <h3>{title}</h3>
97
- * <p>{description}</p>
98
- * <div className="pricing">
99
- * <span className="price">{price}</span>
100
- * {compareAtPrice && (
101
- * <span className="compare-price"><s>{compareAtPrice}</s></span>
102
- * )}
103
- * </div>
104
- * {!available && <div className="badge">Out of Stock</div>}
105
- * <a href={`/products/${slug}`}>View Product</a>
106
- * </div>
107
- * )}
108
- * </Collection.Item>
109
- * );
110
- * }
111
- * ```
112
- */
113
- export const Item = (props) => {
114
- const { product } = props;
115
- // Use actual v3 API structure based on real data
116
- // Images are in media.main.image, not media.itemsInfo.items
117
- const image = product?.media?.main?.image || null;
118
- // Create formatted price since formattedAmount is not available
119
- const rawAmount = product.actualPriceRange?.minValue?.amount;
120
- const price = rawAmount ? `$${rawAmount}` : "$0.00";
121
- // Create formatted compare-at price
122
- const rawCompareAmount = product.compareAtPriceRange?.minValue?.amount;
123
- const compareAtPrice = rawCompareAmount ? `$${rawCompareAmount}` : null;
124
- const availabilityStatus = product.inventory?.availabilityStatus;
125
- const available = availabilityStatus === InventoryAvailabilityStatus.IN_STOCK ||
126
- availabilityStatus === InventoryAvailabilityStatus.PARTIALLY_OUT_OF_STOCK;
127
- const description = typeof product.description === "string" ? product.description : "";
128
- return props.children({
129
- id: product._id || "",
130
- title: product.name || "",
131
- slug: product.slug || "",
132
- image,
133
- price,
134
- compareAtPrice,
135
- description,
136
- available,
137
- });
138
- };
139
- /**
140
- * Headless component for load more products functionality
141
- * Note: V3 API uses simplified loading without traditional pagination
142
- *
143
- * @component
144
- * @example
145
- * ```tsx
146
- * import { Collection } from '@wix/stores/components';
147
- *
148
- * function LoadMoreButton() {
149
- * return (
150
- * <Collection.LoadMore>
151
- * {({ loadMore, refresh, isLoading, hasProducts, totalProducts, hasMoreProducts }) => (
152
- * <div className="load-more-section">
153
- * {hasProducts && (
154
- * <div>
155
- * <p>Loaded {totalProducts} products</p>
156
- * <div className="actions">
157
- * {hasMoreProducts && (
158
- * <button
159
- * onClick={loadMore}
160
- * disabled={isLoading}
161
- * >
162
- * {isLoading ? 'Loading...' : 'Load More Products'}
163
- * </button>
164
- * )}
165
- * <button onClick={refresh}>Refresh Collection</button>
166
- * </div>
167
- * </div>
168
- * )}
169
- * </div>
170
- * )}
171
- * </Collection.LoadMore>
172
- * );
173
- * }
174
- * ```
175
- */
176
- export const LoadMore = (props) => {
177
- const service = useService(CollectionServiceDefinition);
178
- // Error handling for undefined service
179
- if (!service) {
180
- console.error("CollectionService is undefined in LoadMore");
181
- return props.children({
182
- loadMore: async () => { },
183
- refresh: async () => { },
184
- isLoading: false,
185
- hasProducts: false,
186
- totalProducts: 0,
187
- hasMoreProducts: false,
188
- });
189
- }
190
- try {
191
- const isLoading = service.isLoading?.get() || false;
192
- const hasProducts = service.hasProducts?.get() || false;
193
- const totalProducts = service.totalProducts?.get() || 0;
194
- const hasMoreProducts = service.hasMoreProducts?.get() || false;
195
- return props.children({
196
- loadMore: service.loadMore || (async () => { }),
197
- refresh: service.refresh || (async () => { }),
198
- isLoading,
199
- hasProducts,
200
- totalProducts,
201
- hasMoreProducts,
202
- });
203
- }
204
- catch (err) {
205
- console.error("Error in LoadMore:", err);
206
- return props.children({
207
- loadMore: async () => { },
208
- refresh: async () => { },
209
- isLoading: false,
210
- hasProducts: false,
211
- totalProducts: 0,
212
- hasMoreProducts: false,
213
- });
214
- }
215
- };
216
- /**
217
- * Headless component for collection header with product count
218
- *
219
- * @component
220
- * @example
221
- * ```tsx
222
- * import { Collection } from '@wix/stores/components';
223
- *
224
- * function CollectionHeader() {
225
- * return (
226
- * <Collection.Header>
227
- * {({ totalProducts, isLoading, hasProducts }) => (
228
- * <div className="collection-header">
229
- * {isLoading && <div>Loading collection...</div>}
230
- * {hasProducts && !isLoading && (
231
- * <h2>Products ({totalProducts} items)</h2>
232
- * )}
233
- * {!hasProducts && !isLoading && (
234
- * <h2>No products found</h2>
235
- * )}
236
- * </div>
237
- * )}
238
- * </Collection.Header>
239
- * );
240
- * }
241
- * ```
242
- */
243
- export const Header = (props) => {
244
- const service = useService(CollectionServiceDefinition);
245
- // Error handling for undefined service
246
- if (!service) {
247
- console.error("CollectionService is undefined in Header");
248
- return props.children({
249
- totalProducts: 0,
250
- isLoading: false,
251
- hasProducts: false,
252
- });
253
- }
254
- try {
255
- const totalProducts = service.totalProducts?.get() || 0;
256
- const isLoading = service.isLoading?.get() || false;
257
- const hasProducts = service.hasProducts?.get() || false;
258
- return props.children({
259
- totalProducts,
260
- isLoading,
261
- hasProducts,
262
- });
263
- }
264
- catch (err) {
265
- console.error("Error in Header:", err);
266
- return props.children({
267
- totalProducts: 0,
268
- isLoading: false,
269
- hasProducts: false,
270
- });
271
- }
272
- };
273
- /**
274
- * Headless component for collection actions (refresh, load more)
275
- * Replaces traditional pagination for V3 API
276
- *
277
- * @component
278
- * @example
279
- * ```tsx
280
- * import { Collection } from '@wix/stores/components';
281
- *
282
- * function CollectionActions() {
283
- * return (
284
- * <Collection.Actions>
285
- * {({ refresh, loadMore, isLoading, error }) => (
286
- * <div className="collection-actions">
287
- * {error && (
288
- * <div className="error">
289
- * Error: {error}
290
- * <button onClick={refresh}>Retry</button>
291
- * </div>
292
- * )}
293
- * <div className="action-buttons">
294
- * <button
295
- * onClick={refresh}
296
- * disabled={isLoading}
297
- * >
298
- * {isLoading ? 'Refreshing...' : 'Refresh'}
299
- * </button>
300
- * <button
301
- * onClick={loadMore}
302
- * disabled={isLoading}
303
- * >
304
- * Load More
305
- * </button>
306
- * </div>
307
- * </div>
308
- * )}
309
- * </Collection.Actions>
310
- * );
311
- * }
312
- * ```
313
- */
314
- export const Actions = (props) => {
315
- const service = useService(CollectionServiceDefinition);
316
- // Error handling for undefined service
317
- if (!service) {
318
- console.error("CollectionService is undefined in Actions");
319
- return props.children({
320
- refresh: async () => { },
321
- loadMore: async () => { },
322
- isLoading: false,
323
- error: "Service not available",
324
- });
325
- }
326
- try {
327
- const isLoading = service.isLoading?.get() || false;
328
- const error = service.error?.get() || null;
329
- return props.children({
330
- refresh: service.refresh || (async () => { }),
331
- loadMore: service.loadMore || (async () => { }),
332
- isLoading,
333
- error,
334
- });
335
- }
336
- catch (err) {
337
- console.error("Error in Actions:", err);
338
- return props.children({
339
- refresh: async () => { },
340
- loadMore: async () => { },
341
- isLoading: false,
342
- error: "Failed to load actions",
343
- });
344
- }
345
- };