@wix/headless-stores 0.0.57 → 0.0.58
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/cjs/dist/react/ProductList.js +1 -0
- package/cjs/dist/react/ProductListSort.d.ts +14 -0
- package/cjs/dist/react/ProductListSort.js +14 -0
- package/cjs/dist/react/core/ProductList.d.ts +3 -0
- package/cjs/dist/react/core/ProductList.js +2 -0
- package/cjs/dist/react/core/ProductListFilters.d.ts +8 -180
- package/cjs/dist/react/core/ProductListFilters.js +137 -171
- package/cjs/dist/react/core/ProductListPagination.d.ts +0 -192
- package/cjs/dist/react/core/ProductListPagination.js +2 -160
- package/cjs/dist/react/core/ProductListSort.d.ts +9 -57
- package/cjs/dist/react/core/ProductListSort.js +32 -52
- package/cjs/dist/services/index.d.ts +2 -2
- package/cjs/dist/services/products-list-search-service.d.ts +3 -162
- package/cjs/dist/services/products-list-search-service.js +31 -424
- package/cjs/dist/services/products-list-service.d.ts +86 -4
- package/cjs/dist/services/products-list-service.js +125 -4
- package/dist/react/ProductList.js +1 -0
- package/dist/react/ProductListSort.d.ts +14 -0
- package/dist/react/ProductListSort.js +14 -0
- package/dist/react/core/ProductList.d.ts +3 -0
- package/dist/react/core/ProductList.js +2 -0
- package/dist/react/core/ProductListFilters.d.ts +8 -180
- package/dist/react/core/ProductListFilters.js +137 -171
- package/dist/react/core/ProductListPagination.d.ts +0 -192
- package/dist/react/core/ProductListPagination.js +2 -160
- package/dist/react/core/ProductListSort.d.ts +9 -57
- package/dist/react/core/ProductListSort.js +32 -52
- package/dist/services/index.d.ts +2 -2
- package/dist/services/products-list-search-service.d.ts +3 -162
- package/dist/services/products-list-search-service.js +31 -424
- package/dist/services/products-list-service.d.ts +86 -4
- package/dist/services/products-list-service.js +125 -4
- package/package.json +4 -4
|
@@ -1,54 +1,71 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useService } from '@wix/services-manager-react';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
3
|
+
import { ProductsListServiceDefinition, InventoryStatusType, CategoriesListServiceDefinition, } from '../../services/index.js';
|
|
4
|
+
import { useMemo } from 'react';
|
|
5
|
+
import { Filter as FilterPrimitive, } from '@wix/headless-components/react';
|
|
6
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
7
|
+
import React from 'react';
|
|
8
|
+
// Conversion utilities for platform compatibility
|
|
9
|
+
function getInventoryStatusLabel(status) {
|
|
10
|
+
switch (status) {
|
|
11
|
+
case InventoryStatusType.IN_STOCK:
|
|
12
|
+
return 'In Stock';
|
|
13
|
+
case InventoryStatusType.OUT_OF_STOCK:
|
|
14
|
+
return 'Out of Stock';
|
|
15
|
+
case InventoryStatusType.PARTIALLY_OUT_OF_STOCK:
|
|
16
|
+
return 'Limited Stock';
|
|
17
|
+
default:
|
|
18
|
+
return String(status);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function buildSearchFilterData(availableOptions, availableInventoryStatuses, availableMinPrice, availableMaxPrice) {
|
|
22
|
+
// Build consolidated filter options using search field names
|
|
23
|
+
const filterOptions = [
|
|
24
|
+
// Price range - use a logical key that maps to both min/max fields
|
|
25
|
+
{
|
|
26
|
+
key: 'priceRange',
|
|
27
|
+
label: 'Price Range',
|
|
28
|
+
type: 'range',
|
|
29
|
+
displayType: 'range',
|
|
30
|
+
validValues: [availableMinPrice, availableMaxPrice],
|
|
31
|
+
valueFormatter: (value) => `$${value}`,
|
|
32
|
+
fieldName: [
|
|
33
|
+
'actualPriceRange.minValue.amount',
|
|
34
|
+
'actualPriceRange.maxValue.amount',
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
// Product options (colors, sizes, etc.) - individual filters for each option type
|
|
38
|
+
...availableOptions.map((option) => ({
|
|
39
|
+
key: option.id,
|
|
40
|
+
label: String(option.name),
|
|
41
|
+
type: 'multi',
|
|
42
|
+
displayType: option.optionRenderType === 'SWATCH_CHOICES'
|
|
43
|
+
? 'color'
|
|
44
|
+
: 'text',
|
|
45
|
+
fieldName: 'options.choicesSettings.choices.choiceId',
|
|
46
|
+
fieldType: 'array',
|
|
47
|
+
validValues: option.choices.map((choice) => choice.id),
|
|
48
|
+
valueFormatter: (value) => {
|
|
49
|
+
const choice = option.choices.find((c) => c.id === value);
|
|
50
|
+
const name = choice?.name || String(value);
|
|
51
|
+
return option.optionRenderType === 'SWATCH_CHOICES'
|
|
52
|
+
? name.toLowerCase()
|
|
53
|
+
: name;
|
|
54
|
+
},
|
|
55
|
+
})),
|
|
56
|
+
// Inventory status - use actual search field name
|
|
57
|
+
{
|
|
58
|
+
key: 'inventory.availabilityStatus',
|
|
59
|
+
label: 'Availability',
|
|
60
|
+
type: 'multi',
|
|
61
|
+
displayType: 'text',
|
|
62
|
+
fieldName: 'inventory.availabilityStatus',
|
|
63
|
+
fieldType: 'singular',
|
|
64
|
+
validValues: availableInventoryStatuses,
|
|
65
|
+
valueFormatter: (value) => getInventoryStatusLabel(value),
|
|
66
|
+
},
|
|
67
|
+
];
|
|
68
|
+
return { filterOptions };
|
|
52
69
|
}
|
|
53
70
|
/**
|
|
54
71
|
* Headless component for resetting all filters
|
|
@@ -81,136 +98,85 @@ export function InventoryStatus(props) {
|
|
|
81
98
|
* ```
|
|
82
99
|
*/
|
|
83
100
|
export function ResetTrigger(props) {
|
|
84
|
-
const service = useService(
|
|
85
|
-
const resetFilters = service.
|
|
86
|
-
const isFiltered = service.isFiltered.get();
|
|
101
|
+
const service = useService(ProductsListServiceDefinition);
|
|
102
|
+
const resetFilters = service.resetFilter;
|
|
103
|
+
const isFiltered = service.isFiltered().get();
|
|
87
104
|
return typeof props.children === 'function'
|
|
88
105
|
? props.children({ resetFilters, isFiltered })
|
|
89
106
|
: props.children;
|
|
90
107
|
}
|
|
91
|
-
/**
|
|
92
|
-
* Headless component for managing price range filters (combined min/max)
|
|
93
|
-
*
|
|
94
|
-
* @component
|
|
95
|
-
* @example
|
|
96
|
-
* ```tsx
|
|
97
|
-
* import { ProductList, ProductListFilters } from '@wix/stores/components';
|
|
98
|
-
*
|
|
99
|
-
* function PriceRangeFilter() {
|
|
100
|
-
* return (
|
|
101
|
-
* <ProductList.Root
|
|
102
|
-
* productsListConfig={{ products: [], searchOptions: {}, pagingMetadata: {}, aggregations: {} }}
|
|
103
|
-
* productsListSearchConfig={{ customizations: [] }}
|
|
104
|
-
* >
|
|
105
|
-
* <ProductListFilters.PriceRange>
|
|
106
|
-
* {({ minPrice, maxPrice, setSelectedMinPrice, setSelectedMaxPrice }) => (
|
|
107
|
-
* <div className="price-range">
|
|
108
|
-
* <h4>Price Range:</h4>
|
|
109
|
-
* <div className="price-inputs">
|
|
110
|
-
* <input
|
|
111
|
-
* type="number"
|
|
112
|
-
* value={minPrice}
|
|
113
|
-
* onChange={(e) => setSelectedMinPrice(Number(e.target.value))}
|
|
114
|
-
* placeholder="Min"
|
|
115
|
-
* />
|
|
116
|
-
* <span>to</span>
|
|
117
|
-
* <input
|
|
118
|
-
* type="number"
|
|
119
|
-
* value={maxPrice}
|
|
120
|
-
* onChange={(e) => setSelectedMaxPrice(Number(e.target.value))}
|
|
121
|
-
* placeholder="Max"
|
|
122
|
-
* />
|
|
123
|
-
* </div>
|
|
124
|
-
* </div>
|
|
125
|
-
* )}
|
|
126
|
-
* </ProductListFilters.PriceRange>
|
|
127
|
-
* </ProductList.Root>
|
|
128
|
-
* );
|
|
129
|
-
* }
|
|
130
|
-
* ```
|
|
131
|
-
*/
|
|
132
|
-
export function PriceRange(props) {
|
|
133
|
-
const service = useService(ProductsListSearchServiceDefinition);
|
|
134
|
-
const selectedMinPrice = service.selectedMinPrice.get();
|
|
135
|
-
const selectedMaxPrice = service.selectedMaxPrice.get();
|
|
136
|
-
const availableMinPrice = service.availableMinPrice.get();
|
|
137
|
-
const availableMaxPrice = service.availableMaxPrice.get();
|
|
138
|
-
const setSelectedMinPrice = service.setSelectedMinPrice;
|
|
139
|
-
const setSelectedMaxPrice = service.setSelectedMaxPrice;
|
|
140
|
-
return typeof props.children === 'function'
|
|
141
|
-
? props.children({
|
|
142
|
-
availableMinPrice,
|
|
143
|
-
selectedMinPrice,
|
|
144
|
-
selectedMaxPrice,
|
|
145
|
-
availableMaxPrice,
|
|
146
|
-
setSelectedMinPrice,
|
|
147
|
-
setSelectedMaxPrice,
|
|
148
|
-
})
|
|
149
|
-
: props.children;
|
|
150
|
-
}
|
|
151
108
|
export function CategoryFilter(props) {
|
|
152
|
-
const
|
|
153
|
-
const
|
|
154
|
-
const
|
|
109
|
+
const categoriesService = useService(CategoriesListServiceDefinition);
|
|
110
|
+
const productListService = useService(ProductsListServiceDefinition);
|
|
111
|
+
const categories = categoriesService.categories.get();
|
|
112
|
+
const setSelectedCategory = (category) => {
|
|
113
|
+
const currentFilter = productListService.searchOptions.get().filter || {};
|
|
114
|
+
if (!category) {
|
|
115
|
+
delete currentFilter['allCategoriesInfo.categories'];
|
|
116
|
+
productListService.setFilter(currentFilter);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
productListService.setFilter({
|
|
120
|
+
...currentFilter,
|
|
121
|
+
'allCategoriesInfo.categories': {
|
|
122
|
+
$matchItems: [{ id: { $in: [category._id] } }],
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
};
|
|
126
|
+
const selectedCategoryId = productListService.searchOptions.get().filter['allCategoriesInfo.categories']?.$matchItems?.[0]?.id
|
|
127
|
+
?.$in?.[0];
|
|
128
|
+
const selectedCategory = categories?.find((c) => c._id === selectedCategoryId) || null;
|
|
155
129
|
return typeof props.children === 'function'
|
|
156
130
|
? props.children({ selectedCategory, setSelectedCategory })
|
|
157
131
|
: props.children;
|
|
158
132
|
}
|
|
159
133
|
/**
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
* Only renders when options are available (not loading, no error, and has options).
|
|
163
|
-
* This follows the same collection pattern as ProductList.ItemContent and CategoryList.ItemContent.
|
|
164
|
-
*
|
|
165
|
-
* @component
|
|
166
|
-
* @example
|
|
167
|
-
* ```tsx
|
|
168
|
-
* import { ProductList, ProductListFilters } from '@wix/stores/components';
|
|
169
|
-
*
|
|
170
|
-
* function ProductOptionsFilter() {
|
|
171
|
-
* return (
|
|
172
|
-
* <ProductList.Root
|
|
173
|
-
* productsListConfig={{ products: [], searchOptions: {}, pagingMetadata: {}, aggregations: {} }}
|
|
174
|
-
* productsListSearchConfig={{ customizations: [] }}
|
|
175
|
-
* >
|
|
176
|
-
* <ProductListFilters.ProductOptions>
|
|
177
|
-
* {({ option, selectedChoices, toggleChoice }) => (
|
|
178
|
-
* <div key={option.id}>
|
|
179
|
-
* <h4>{option.name}</h4>
|
|
180
|
-
* {option.choices.map(choice => (
|
|
181
|
-
* <label key={choice.id}>
|
|
182
|
-
* <input
|
|
183
|
-
* type="checkbox"
|
|
184
|
-
* checked={selectedChoices.includes(choice.id)}
|
|
185
|
-
* onChange={() => toggleChoice(choice.id)}
|
|
186
|
-
* />
|
|
187
|
-
* {choice.name}
|
|
188
|
-
* </label>
|
|
189
|
-
* ))}
|
|
190
|
-
* </div>
|
|
191
|
-
* )}
|
|
192
|
-
* </ProductListFilters.ProductOptions>
|
|
193
|
-
* </ProductList.Root>
|
|
194
|
-
* );
|
|
195
|
-
* }
|
|
196
|
-
* ```
|
|
134
|
+
* Internal component that provides filter data for the Filter component.
|
|
135
|
+
* Consolidates data from both search and list services.
|
|
197
136
|
*/
|
|
198
|
-
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
137
|
+
function AllFilters(props) {
|
|
138
|
+
const listService = useService(ProductsListServiceDefinition);
|
|
139
|
+
// Get current filter state
|
|
140
|
+
const currentSearchOptions = listService.searchOptions.get();
|
|
141
|
+
const currentFilter = currentSearchOptions.filter;
|
|
142
|
+
// Get available filter data
|
|
143
|
+
const availableOptions = listService.availableProductOptions.get();
|
|
144
|
+
const availableInventoryStatuses = listService.availableInventoryStatuses.get();
|
|
145
|
+
const availableMinPrice = listService.minPrice.get();
|
|
146
|
+
const availableMaxPrice = listService.maxPrice.get();
|
|
147
|
+
// Get filter state
|
|
148
|
+
const resetFilters = listService.resetFilter;
|
|
149
|
+
const isFiltered = listService.isFiltered().get();
|
|
150
|
+
// Build filter options and handlers
|
|
151
|
+
const searchFilterData = useMemo(() => {
|
|
152
|
+
const { filterOptions } = buildSearchFilterData(availableOptions, availableInventoryStatuses, availableMinPrice, availableMaxPrice);
|
|
153
|
+
const updateFilter = (newFilter) => {
|
|
154
|
+
listService.setFilter(newFilter);
|
|
155
|
+
};
|
|
156
|
+
return {
|
|
157
|
+
filterValue: currentFilter,
|
|
158
|
+
filterOptions,
|
|
159
|
+
updateFilter,
|
|
160
|
+
clearFilters: resetFilters,
|
|
161
|
+
hasFilters: isFiltered,
|
|
162
|
+
};
|
|
163
|
+
}, [
|
|
164
|
+
availableOptions,
|
|
165
|
+
availableInventoryStatuses,
|
|
166
|
+
availableMinPrice,
|
|
167
|
+
availableMaxPrice,
|
|
168
|
+
currentFilter,
|
|
169
|
+
resetFilters,
|
|
170
|
+
isFiltered,
|
|
171
|
+
listService,
|
|
172
|
+
]);
|
|
173
|
+
return typeof props.children === 'function'
|
|
174
|
+
? props.children({ searchFilter: searchFilterData })
|
|
175
|
+
: props.children;
|
|
216
176
|
}
|
|
177
|
+
export const Filter = React.forwardRef(({ children, className, asChild }, ref) => {
|
|
178
|
+
const Comp = asChild ? Slot : 'div';
|
|
179
|
+
return (_jsx(AllFilters, { children: ({ searchFilter }) => {
|
|
180
|
+
return (_jsx(FilterPrimitive.Root, { value: searchFilter.filterValue, onChange: searchFilter.updateFilter, filterOptions: searchFilter.filterOptions, children: _jsx(Comp, { className: className, ref: ref, children: children }) }));
|
|
181
|
+
} }));
|
|
182
|
+
});
|
|
@@ -1,195 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Props for PageSize headless component
|
|
3
|
-
*/
|
|
4
|
-
export interface PageSizeProps {
|
|
5
|
-
/** Content to display (can be a render function receiving page size controls or ReactNode) */
|
|
6
|
-
children: ((props: PageSizeRenderProps) => React.ReactNode) | React.ReactNode;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Render props for PageSize component
|
|
10
|
-
*/
|
|
11
|
-
export interface PageSizeRenderProps {
|
|
12
|
-
/** Current page size (items per page) */
|
|
13
|
-
currentLimit: number;
|
|
14
|
-
/** Function to update the page size */
|
|
15
|
-
setLimit: (limit: number) => void;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Headless component for managing page size (items per page)
|
|
19
|
-
*
|
|
20
|
-
* @component
|
|
21
|
-
* @example
|
|
22
|
-
* ```tsx
|
|
23
|
-
* import { ProductList, ProductListPagination } from '@wix/stores/components';
|
|
24
|
-
*
|
|
25
|
-
* function PageSizeSelector() {
|
|
26
|
-
* return (
|
|
27
|
-
* <ProductList.Root
|
|
28
|
-
* productsListConfig={{ products: [], searchOptions: {}, pagingMetadata: {}, aggregations: {} }}
|
|
29
|
-
* productsListSearchConfig={{ customizations: [] }}
|
|
30
|
-
* >
|
|
31
|
-
* <ProductListPagination.PageSize>
|
|
32
|
-
* {({ currentLimit, setLimit }) => (
|
|
33
|
-
* <div>
|
|
34
|
-
* <label>Items per page:</label>
|
|
35
|
-
* <select
|
|
36
|
-
* value={currentLimit}
|
|
37
|
-
* onChange={(e) => setLimit(Number(e.target.value))}
|
|
38
|
-
* >
|
|
39
|
-
* <option value={10}>10</option>
|
|
40
|
-
* <option value={20}>20</option>
|
|
41
|
-
* <option value={50}>50</option>
|
|
42
|
-
* </select>
|
|
43
|
-
* </div>
|
|
44
|
-
* )}
|
|
45
|
-
* </ProductListPagination.PageSize>
|
|
46
|
-
* </ProductList.Root>
|
|
47
|
-
* );
|
|
48
|
-
* }
|
|
49
|
-
* ```
|
|
50
|
-
*/
|
|
51
|
-
export declare function PageSize(props: PageSizeProps): import("react").ReactNode;
|
|
52
|
-
/**
|
|
53
|
-
* Props for NextPageTrigger headless component
|
|
54
|
-
*/
|
|
55
|
-
export interface NextPageTriggerProps {
|
|
56
|
-
/** Content to display (can be a render function receiving next page controls or ReactNode) */
|
|
57
|
-
children: ((props: NextPageTriggerRenderProps) => React.ReactNode) | React.ReactNode;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Render props for NextPageTrigger component
|
|
61
|
-
*/
|
|
62
|
-
export interface NextPageTriggerRenderProps {
|
|
63
|
-
/** Function to navigate to the next page */
|
|
64
|
-
nextPage: () => void;
|
|
65
|
-
/** Whether there is a next page available */
|
|
66
|
-
hasNextPage: boolean;
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Headless component for navigating to the next page
|
|
70
|
-
*
|
|
71
|
-
* @component
|
|
72
|
-
* @example
|
|
73
|
-
* ```tsx
|
|
74
|
-
* import { ProductList, ProductListPagination } from '@wix/stores/components';
|
|
75
|
-
*
|
|
76
|
-
* function NextPageButton() {
|
|
77
|
-
* return (
|
|
78
|
-
* <ProductList.Root
|
|
79
|
-
* productsListConfig={{ products: [], searchOptions: {}, pagingMetadata: {}, aggregations: {} }}
|
|
80
|
-
* productsListSearchConfig={{ customizations: [] }}
|
|
81
|
-
* >
|
|
82
|
-
* <ProductListPagination.NextPageTrigger>
|
|
83
|
-
* {({ nextPage, hasNextPage }) => (
|
|
84
|
-
* <button
|
|
85
|
-
* onClick={nextPage}
|
|
86
|
-
* disabled={!hasNextPage}
|
|
87
|
-
* className={hasNextPage ? 'enabled' : 'disabled'}
|
|
88
|
-
* >
|
|
89
|
-
* Next →
|
|
90
|
-
* </button>
|
|
91
|
-
* )}
|
|
92
|
-
* </ProductListPagination.NextPageTrigger>
|
|
93
|
-
* </ProductList.Root>
|
|
94
|
-
* );
|
|
95
|
-
* }
|
|
96
|
-
* ```
|
|
97
|
-
*/
|
|
98
|
-
export declare function NextPageTrigger(props: NextPageTriggerProps): import("react").ReactNode;
|
|
99
|
-
/**
|
|
100
|
-
* Props for PreviousPageTrigger headless component
|
|
101
|
-
*/
|
|
102
|
-
export interface PreviousPageTriggerProps {
|
|
103
|
-
/** Content to display (can be a render function receiving previous page controls or ReactNode) */
|
|
104
|
-
children: ((props: PreviousPageTriggerRenderProps) => React.ReactNode) | React.ReactNode;
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Render props for PreviousPageTrigger component
|
|
108
|
-
*/
|
|
109
|
-
export interface PreviousPageTriggerRenderProps {
|
|
110
|
-
/** Function to navigate to the previous page */
|
|
111
|
-
prevPage: () => void;
|
|
112
|
-
/** Whether there is a previous page available */
|
|
113
|
-
hasPrevPage: boolean;
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Headless component for navigating to the previous page
|
|
117
|
-
*
|
|
118
|
-
* @component
|
|
119
|
-
* @example
|
|
120
|
-
* ```tsx
|
|
121
|
-
* import { ProductList, ProductListPagination } from '@wix/stores/components';
|
|
122
|
-
*
|
|
123
|
-
* function PrevPageButton() {
|
|
124
|
-
* return (
|
|
125
|
-
* <ProductList.Root
|
|
126
|
-
* productsListConfig={{ products: [], searchOptions: {}, pagingMetadata: {}, aggregations: {} }}
|
|
127
|
-
* productsListSearchConfig={{ customizations: [] }}
|
|
128
|
-
* >
|
|
129
|
-
* <ProductListPagination.PreviousPageTrigger>
|
|
130
|
-
* {({ prevPage, hasPrevPage }) => (
|
|
131
|
-
* <button
|
|
132
|
-
* onClick={prevPage}
|
|
133
|
-
* disabled={!hasPrevPage}
|
|
134
|
-
* className={hasPrevPage ? 'enabled' : 'disabled'}
|
|
135
|
-
* >
|
|
136
|
-
* ← Previous
|
|
137
|
-
* </button>
|
|
138
|
-
* )}
|
|
139
|
-
* </ProductListPagination.PreviousPageTrigger>
|
|
140
|
-
* </ProductList.Root>
|
|
141
|
-
* );
|
|
142
|
-
* }
|
|
143
|
-
* ```
|
|
144
|
-
*/
|
|
145
|
-
export declare function PreviousPageTrigger(props: PreviousPageTriggerProps): import("react").ReactNode;
|
|
146
|
-
/**
|
|
147
|
-
* Props for FirstPageTrigger headless component
|
|
148
|
-
*/
|
|
149
|
-
export interface FirstPageTriggerProps {
|
|
150
|
-
/** Content to display (can be a render function receiving first page controls or ReactNode) */
|
|
151
|
-
children: ((props: FirstPageTriggerRenderProps) => React.ReactNode) | React.ReactNode;
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Render props for FirstPageTrigger component
|
|
155
|
-
*/
|
|
156
|
-
export interface FirstPageTriggerRenderProps {
|
|
157
|
-
/** Function to navigate to the first page */
|
|
158
|
-
navigateToFirstPage: () => void;
|
|
159
|
-
/** Whether there is a previous page (indicating not on first page) */
|
|
160
|
-
hasPrevPage: boolean;
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Headless component for navigating to the first page
|
|
164
|
-
*
|
|
165
|
-
* @component
|
|
166
|
-
* @example
|
|
167
|
-
* ```tsx
|
|
168
|
-
* import { ProductList, ProductListPagination } from '@wix/stores/components';
|
|
169
|
-
*
|
|
170
|
-
* function FirstPageButton() {
|
|
171
|
-
* return (
|
|
172
|
-
* <ProductList.Root
|
|
173
|
-
* productsListConfig={{ products: [], searchOptions: {}, pagingMetadata: {}, aggregations: {} }}
|
|
174
|
-
* productsListSearchConfig={{ customizations: [] }}
|
|
175
|
-
* >
|
|
176
|
-
* <ProductListPagination.FirstPageTrigger>
|
|
177
|
-
* {({ navigateToFirstPage, hasPrevPage }) => (
|
|
178
|
-
* <button
|
|
179
|
-
* onClick={navigateToFirstPage}
|
|
180
|
-
* disabled={!hasPrevPage}
|
|
181
|
-
* title="Go to first page"
|
|
182
|
-
* >
|
|
183
|
-
* ⏮ First
|
|
184
|
-
* </button>
|
|
185
|
-
* )}
|
|
186
|
-
* </ProductListPagination.FirstPageTrigger>
|
|
187
|
-
* </ProductList.Root>
|
|
188
|
-
* );
|
|
189
|
-
* }
|
|
190
|
-
* ```
|
|
191
|
-
*/
|
|
192
|
-
export declare function FirstPageTrigger(props: FirstPageTriggerProps): import("react").ReactNode;
|
|
193
1
|
/**
|
|
194
2
|
* Props for LoadMoreTrigger headless component
|
|
195
3
|
*/
|