@jay-framework/wix-stores 0.15.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.
@@ -0,0 +1,218 @@
1
+ import {HTMLElementCollectionProxy, HTMLElementProxy, JayContract} from "@jay-framework/runtime";
2
+ import {MediaGalleryViewState, MediaGalleryRefs, MediaGalleryRepeatedRefs} from "./media-gallery.jay-contract";
3
+
4
+ export enum ProductType {
5
+ PHYSICAL,
6
+ DIGITAL
7
+ }
8
+
9
+ export enum StockStatus {
10
+ OUT_OF_STOCK,
11
+ IN_STOCK
12
+ }
13
+
14
+ export interface QuantityOfProductPageViewState {
15
+ quantity: number
16
+ }
17
+
18
+ export enum OptionRenderType {
19
+ TEXT_CHOICES,
20
+ COLOR_SWATCH_CHOICES
21
+ }
22
+
23
+ export enum ChoiceType {
24
+ CHOICE_TEXT,
25
+ ONE_COLOR
26
+ }
27
+
28
+ export interface ChoiceOfOptionOfProductPageViewState {
29
+ choiceId: string,
30
+ choiceType: ChoiceType,
31
+ name: string,
32
+ colorCode: string,
33
+ inStock: boolean,
34
+ isSelected: boolean
35
+ }
36
+
37
+ export interface OptionOfProductPageViewState {
38
+ _id: string,
39
+ name: string,
40
+ optionRenderType: OptionRenderType,
41
+ textChoiceSelection: string,
42
+ choices: Array<ChoiceOfOptionOfProductPageViewState>
43
+ }
44
+
45
+ export interface InfoSectionOfProductPageViewState {
46
+ _id: string,
47
+ title: string,
48
+ plainDescription: string
49
+ }
50
+
51
+ export enum ModifierType {
52
+ TEXT_CHOICES,
53
+ COLOR_SWATCH_CHOICES,
54
+ FREE_TEXT
55
+ }
56
+
57
+ export enum ChoiceType {
58
+ CHOICE_TEXT,
59
+ ONE_COLOR
60
+ }
61
+
62
+ export interface ChoiceOfModifierOfProductPageViewState {
63
+ choiceId: string,
64
+ choiceType: ChoiceType,
65
+ name: string,
66
+ colorCode: string,
67
+ isSelected: boolean
68
+ }
69
+
70
+ export interface ModifierOfProductPageViewState {
71
+ _id: string,
72
+ name: string,
73
+ modifierType: ModifierType,
74
+ textModifierSelection: string,
75
+ textInputLength: number,
76
+ textInputRequired: boolean,
77
+ choices: Array<ChoiceOfModifierOfProductPageViewState>
78
+ }
79
+
80
+ export interface PropOfTagOfSeoDatumOfProductPageViewState {
81
+ key: string,
82
+ value: string
83
+ }
84
+
85
+ export interface MetaOfTagOfSeoDatumOfProductPageViewState {
86
+ key: string,
87
+ value: string
88
+ }
89
+
90
+ export interface TagOfSeoDatumOfProductPageViewState {
91
+ position: string,
92
+ type: string,
93
+ props: Array<PropOfTagOfSeoDatumOfProductPageViewState>,
94
+ meta: Array<MetaOfTagOfSeoDatumOfProductPageViewState>,
95
+ children: string
96
+ }
97
+
98
+ export interface KeywordOfSettingOfSeoDatumOfProductPageViewState {
99
+ term: string,
100
+ isMain: boolean,
101
+ origin: string
102
+ }
103
+
104
+ export interface SettingOfSeoDatumOfProductPageViewState {
105
+ preventAutoRedirect: boolean,
106
+ keywords: Array<KeywordOfSettingOfSeoDatumOfProductPageViewState>
107
+ }
108
+
109
+ export interface SeoDatumOfProductPageViewState {
110
+ tags: Array<TagOfSeoDatumOfProductPageViewState>,
111
+ settings: SettingOfSeoDatumOfProductPageViewState
112
+ }
113
+
114
+ export interface ProductPageViewState {
115
+ _id: string,
116
+ productName: string,
117
+ mediaGallery: MediaGalleryViewState,
118
+ description: string,
119
+ brand: string,
120
+ ribbon: string,
121
+ productType: ProductType,
122
+ sku: string,
123
+ price: string,
124
+ strikethroughPrice: string,
125
+ pricePerUnit: string,
126
+ stockStatus: StockStatus,
127
+ quantity: QuantityOfProductPageViewState,
128
+ actionsEnabled: boolean,
129
+ options: Array<OptionOfProductPageViewState>,
130
+ infoSections: Array<InfoSectionOfProductPageViewState>,
131
+ modifiers: Array<ModifierOfProductPageViewState>,
132
+ seoData: SeoDatumOfProductPageViewState
133
+ }
134
+
135
+ export type ProductPageSlowViewState = Pick<ProductPageViewState, '_id' | 'productName' | 'description' | 'brand' | 'ribbon' | 'productType'> & {
136
+ options: Array<Pick<ProductPageViewState['options'][number], '_id' | 'name' | 'optionRenderType'> & {
137
+ choices: Array<Pick<ProductPageViewState['options'][number]['choices'][number], 'choiceId' | 'choiceType' | 'name' | 'colorCode' | 'inStock'>>;
138
+ }>;
139
+ infoSections: Array<ProductPageViewState['infoSections'][number]>;
140
+ modifiers: Array<Pick<ProductPageViewState['modifiers'][number], '_id' | 'name' | 'modifierType' | 'textInputLength' | 'textInputRequired'> & {
141
+ choices: Array<Pick<ProductPageViewState['modifiers'][number]['choices'][number], 'choiceId' | 'choiceType' | 'name' | 'colorCode'>>;
142
+ }>;
143
+ seoData: ProductPageViewState['seoData'];
144
+ };
145
+
146
+ export type ProductPageFastViewState = Pick<ProductPageViewState, 'sku' | 'price' | 'strikethroughPrice' | 'pricePerUnit' | 'stockStatus' | 'actionsEnabled'> & {
147
+ mediaGallery: ProductPageViewState['mediaGallery'];
148
+ quantity: ProductPageViewState['quantity'];
149
+ options: Array<Pick<ProductPageViewState['options'][number], '_id' | 'textChoiceSelection'> & {
150
+ choices: Array<Pick<ProductPageViewState['options'][number]['choices'][number], 'choiceId' | 'isSelected'>>;
151
+ }>;
152
+ modifiers: Array<Pick<ProductPageViewState['modifiers'][number], '_id' | 'textModifierSelection'> & {
153
+ choices: Array<Pick<ProductPageViewState['modifiers'][number]['choices'][number], 'choiceId' | 'isSelected'>>;
154
+ }>;
155
+ };
156
+
157
+ export type ProductPageInteractiveViewState = Pick<ProductPageViewState, 'sku' | 'price' | 'strikethroughPrice' | 'pricePerUnit' | 'stockStatus' | 'actionsEnabled'> & {
158
+ mediaGallery: ProductPageViewState['mediaGallery'];
159
+ quantity: ProductPageViewState['quantity'];
160
+ options: Array<Pick<ProductPageViewState['options'][number], '_id' | 'textChoiceSelection'> & {
161
+ choices: Array<Pick<ProductPageViewState['options'][number]['choices'][number], 'choiceId' | 'isSelected'>>;
162
+ }>;
163
+ modifiers: Array<Pick<ProductPageViewState['modifiers'][number], '_id' | 'textModifierSelection'> & {
164
+ choices: Array<Pick<ProductPageViewState['modifiers'][number]['choices'][number], 'choiceId' | 'isSelected'>>;
165
+ }>;
166
+ };
167
+
168
+
169
+ export interface ProductPageRefs {
170
+ addToCartButton: HTMLElementProxy<ProductPageViewState, HTMLButtonElement>,
171
+ buyNowButton: HTMLElementProxy<ProductPageViewState, HTMLButtonElement>,
172
+ mediaGallery: MediaGalleryRefs,
173
+ quantity: {
174
+ decrementButton: HTMLElementProxy<QuantityOfProductPageViewState, HTMLButtonElement>,
175
+ incrementButton: HTMLElementProxy<QuantityOfProductPageViewState, HTMLButtonElement>,
176
+ quantity: HTMLElementProxy<QuantityOfProductPageViewState, HTMLInputElement>
177
+ },
178
+ options: {
179
+ textChoice: HTMLElementCollectionProxy<OptionOfProductPageViewState, HTMLSelectElement>,
180
+ choices: {
181
+ choiceButton: HTMLElementCollectionProxy<ChoiceOfOptionOfProductPageViewState, HTMLButtonElement>
182
+ }
183
+ },
184
+ modifiers: {
185
+ textModifier: HTMLElementCollectionProxy<ModifierOfProductPageViewState, HTMLSelectElement>,
186
+ textInput: HTMLElementCollectionProxy<ModifierOfProductPageViewState, HTMLInputElement | HTMLAreaElement>,
187
+ choices: {
188
+ choiceButton: HTMLElementCollectionProxy<ChoiceOfModifierOfProductPageViewState, HTMLButtonElement>
189
+ }
190
+ }
191
+ }
192
+
193
+
194
+ export interface ProductPageRepeatedRefs {
195
+ addToCartButton: HTMLElementCollectionProxy<ProductPageViewState, HTMLButtonElement>,
196
+ buyNowButton: HTMLElementCollectionProxy<ProductPageViewState, HTMLButtonElement>,
197
+ mediaGallery: MediaGalleryRepeatedRefs,
198
+ quantity: {
199
+ decrementButton: HTMLElementCollectionProxy<QuantityOfProductPageViewState, HTMLButtonElement>,
200
+ incrementButton: HTMLElementCollectionProxy<QuantityOfProductPageViewState, HTMLButtonElement>,
201
+ quantity: HTMLElementCollectionProxy<QuantityOfProductPageViewState, HTMLInputElement>
202
+ },
203
+ options: {
204
+ textChoice: HTMLElementCollectionProxy<OptionOfProductPageViewState, HTMLSelectElement>,
205
+ choices: {
206
+ choiceButton: HTMLElementCollectionProxy<ChoiceOfOptionOfProductPageViewState, HTMLButtonElement>
207
+ }
208
+ },
209
+ modifiers: {
210
+ textModifier: HTMLElementCollectionProxy<ModifierOfProductPageViewState, HTMLSelectElement>,
211
+ textInput: HTMLElementCollectionProxy<ModifierOfProductPageViewState, HTMLInputElement | HTMLAreaElement>,
212
+ choices: {
213
+ choiceButton: HTMLElementCollectionProxy<ChoiceOfModifierOfProductPageViewState, HTMLButtonElement>
214
+ }
215
+ }
216
+ }
217
+
218
+ export type ProductPageContract = JayContract<ProductPageViewState, ProductPageRefs, ProductPageSlowViewState, ProductPageFastViewState, ProductPageInteractiveViewState>
@@ -0,0 +1,252 @@
1
+ name: product-search
2
+ tags:
3
+ # Search input (matches Wix searchProducts search.search parameter)
4
+ - tag: searchExpression
5
+ type: [data, interactive]
6
+ dataType: string
7
+ elementType: HTMLInputElement
8
+ description: Search term or expression
9
+
10
+ - tag: searchFields
11
+ type: data
12
+ dataType: string
13
+ description: Comma-separated list of fields to search in (name, description, sku, etc.)
14
+
15
+ - tag: fuzzySearch
16
+ type: data
17
+ dataType: boolean
18
+ description: Whether to enable fuzzy search for typos and declensions
19
+
20
+ - tag: searchButton
21
+ type: interactive
22
+ elementType: HTMLButtonElement
23
+ description: Search submit button
24
+
25
+ - tag: clearSearchButton
26
+ type: interactive
27
+ elementType: HTMLButtonElement
28
+ description: Clear search input button
29
+
30
+ # Search state (fast+interactive for dynamic updates)
31
+ - tag: isSearching
32
+ type: variant
33
+ dataType: boolean
34
+ phase: fast+interactive
35
+ description: Whether search is in progress
36
+
37
+ - tag: hasSearched
38
+ type: variant
39
+ dataType: boolean
40
+ phase: fast+interactive
41
+ description: Whether a search has been performed
42
+
43
+ # Search results (fast+interactive for dynamic loading)
44
+ - tag: searchResults
45
+ type: sub-contract
46
+ repeated: true
47
+ trackBy: _id
48
+ phase: fast+interactive
49
+ description: Product search results (loaded dynamically)
50
+ link: ./product-card
51
+
52
+ - tag: resultCount
53
+ type: data
54
+ dataType: number
55
+ phase: fast+interactive
56
+ description: Total number of search results
57
+
58
+ - tag: hasResults
59
+ type: variant
60
+ dataType: boolean
61
+ phase: fast+interactive
62
+ description: Whether search returned any results
63
+
64
+ # Empty state message
65
+ - tag: emptyStateMessage
66
+ type: data
67
+ dataType: string
68
+ description: Message to show when no results found
69
+
70
+ # Search filters
71
+ - tag: filters
72
+ type: sub-contract
73
+ description: Search result filters
74
+ tags:
75
+ # Price range filter (fast+interactive)
76
+ - tag: priceRange
77
+ type: sub-contract
78
+ phase: fast+interactive
79
+ description: Price range filter
80
+ tags:
81
+ - tag: minPrice
82
+ type: [data, interactive]
83
+ dataType: number
84
+ elementType: HTMLInputElement
85
+ description: Current minimum price filter (works with number input or range slider)
86
+
87
+ - tag: maxPrice
88
+ type: [data, interactive]
89
+ dataType: number
90
+ elementType: HTMLInputElement
91
+ description: Current maximum price filter (works with number input or range slider)
92
+
93
+ - tag: minBound
94
+ type: data
95
+ dataType: number
96
+ description: Absolute minimum price from product catalog (for slider min attribute)
97
+
98
+ - tag: maxBound
99
+ type: data
100
+ dataType: number
101
+ description: Absolute maximum price from product catalog (for slider max attribute)
102
+
103
+ - tag: ranges
104
+ type: sub-contract
105
+ repeated: true
106
+ trackBy: rangeId
107
+ description: Predefined price range options with product counts
108
+ tags:
109
+ - tag: rangeId
110
+ type: data
111
+ dataType: string
112
+ description: Unique range identifier
113
+
114
+ - tag: label
115
+ type: data
116
+ dataType: string
117
+ description: Display label (e.g., "$0 - $100")
118
+
119
+ - tag: minValue
120
+ type: data
121
+ dataType: number
122
+ description: Range minimum (null for "Show all")
123
+
124
+ - tag: maxValue
125
+ type: data
126
+ dataType: number
127
+ description: Range maximum (null for open-ended like "$400+")
128
+
129
+ - tag: productCount
130
+ type: data
131
+ dataType: number
132
+ description: Number of products in this price range
133
+
134
+ - tag: isSelected
135
+ type: [data, interactive]
136
+ dataType: boolean
137
+ elementType: HTMLInputElement
138
+ description: Radio button for this range
139
+
140
+ # Category filter (slow for category list, fast+interactive for selection)
141
+ - tag: categoryFilter
142
+ type: sub-contract
143
+ description: Filter by category
144
+ tags:
145
+ - tag: categories
146
+ type: sub-contract
147
+ repeated: true
148
+ trackBy: categoryId
149
+ description: Available categories for filtering
150
+ tags:
151
+ - tag: categoryId
152
+ type: data
153
+ dataType: string
154
+ description: Category GUID
155
+
156
+ - tag: categoryName
157
+ type: data
158
+ dataType: string
159
+ description: Category name
160
+
161
+ - tag: categorySlug
162
+ type: data
163
+ dataType: string
164
+ description: Category slug for URL
165
+
166
+ - tag: isSelected
167
+ type: [data, interactive]
168
+ dataType: boolean
169
+ elementType: HTMLInputElement
170
+ description: Category checkbox
171
+
172
+ # Availability filter (fast+interactive)
173
+ - tag: inStockOnly
174
+ type: [data, interactive]
175
+ dataType: boolean
176
+ elementType: HTMLInputElement
177
+ description: Show only in-stock products checkbox
178
+
179
+ - tag: clearFilters
180
+ type: interactive
181
+ elementType: HTMLButtonElement
182
+ description: Clear all filters button
183
+
184
+ # Sorting (fast+interactive)
185
+ - tag: sortBy
186
+ type: sub-contract
187
+ phase: fast+interactive
188
+ description: Sort search results
189
+ tags:
190
+ - tag: currentSort
191
+ type: data
192
+ dataType: enum (relevance | priceAsc | priceDesc | newest | nameAsc | nameDesc)
193
+ description: Current sort option
194
+
195
+ - tag: sortDropdown
196
+ type: interactive
197
+ elementType: HTMLSelectElement
198
+ description: Dropdown to select sort option
199
+
200
+ # Load more (replaces pagination)
201
+ - tag: hasMore
202
+ type: variant
203
+ dataType: boolean
204
+ phase: fast+interactive
205
+ description: Whether there are more products to load
206
+
207
+ - tag: loadMoreButton
208
+ type: interactive
209
+ elementType: HTMLButtonElement
210
+ description: Button to load more products
211
+
212
+ - tag: loadedCount
213
+ type: data
214
+ dataType: number
215
+ phase: fast+interactive
216
+ description: Number of products currently loaded
217
+
218
+ - tag: totalCount
219
+ type: data
220
+ dataType: number
221
+ phase: fast+interactive
222
+ description: Total number of products matching search
223
+
224
+ # Search suggestions (fast+interactive)
225
+ - tag: hasSuggestions
226
+ type: variant
227
+ dataType: boolean
228
+ phase: fast+interactive
229
+ description: Whether search suggestions are available
230
+
231
+ - tag: suggestions
232
+ type: sub-contract
233
+ repeated: true
234
+ trackBy: suggestionId
235
+ phase: fast+interactive
236
+ description: Search term suggestions
237
+ tags:
238
+ - tag: suggestionId
239
+ type: data
240
+ dataType: string
241
+ description: Suggested id
242
+
243
+ - tag: suggestionText
244
+ type: data
245
+ dataType: string
246
+ description: Suggested search term
247
+
248
+ - tag: suggestionButton
249
+ type: interactive
250
+ elementType: HTMLButtonElement
251
+ description: Button to use this suggestion
252
+
@@ -0,0 +1,169 @@
1
+ import {HTMLElementCollectionProxy, HTMLElementProxy, JayContract} from "@jay-framework/runtime";
2
+ import {ProductCardViewState, ProductCardRefs, ProductCardRepeatedRefs} from "./product-card.jay-contract";
3
+
4
+ export interface RangeOfPriceRangeOfFilterOfProductSearchViewState {
5
+ rangeId: string,
6
+ label: string,
7
+ minValue: number,
8
+ maxValue: number,
9
+ productCount: number,
10
+ isSelected: boolean
11
+ }
12
+
13
+ export interface PriceRangeOfFilterOfProductSearchViewState {
14
+ minPrice: number,
15
+ maxPrice: number,
16
+ minBound: number,
17
+ maxBound: number,
18
+ ranges: Array<RangeOfPriceRangeOfFilterOfProductSearchViewState>
19
+ }
20
+
21
+ export interface CategoryOfCategoryFilterOfFilterOfProductSearchViewState {
22
+ categoryId: string,
23
+ categoryName: string,
24
+ categorySlug: string,
25
+ isSelected: boolean
26
+ }
27
+
28
+ export interface CategoryFilterOfFilterOfProductSearchViewState {
29
+ categories: Array<CategoryOfCategoryFilterOfFilterOfProductSearchViewState>
30
+ }
31
+
32
+ export interface FilterOfProductSearchViewState {
33
+ priceRange: PriceRangeOfFilterOfProductSearchViewState,
34
+ categoryFilter: CategoryFilterOfFilterOfProductSearchViewState,
35
+ inStockOnly: boolean
36
+ }
37
+
38
+ export enum CurrentSort {
39
+ relevance,
40
+ priceAsc,
41
+ priceDesc,
42
+ newest,
43
+ nameAsc,
44
+ nameDesc
45
+ }
46
+
47
+ export interface SortByOfProductSearchViewState {
48
+ currentSort: CurrentSort
49
+ }
50
+
51
+ export interface SuggestionOfProductSearchViewState {
52
+ suggestionId: string,
53
+ suggestionText: string
54
+ }
55
+
56
+ export interface ProductSearchViewState {
57
+ searchExpression: string,
58
+ searchFields: string,
59
+ fuzzySearch: boolean,
60
+ isSearching: boolean,
61
+ hasSearched: boolean,
62
+ searchResults: Array<ProductCardViewState>,
63
+ resultCount: number,
64
+ hasResults: boolean,
65
+ emptyStateMessage: string,
66
+ filters: FilterOfProductSearchViewState,
67
+ sortBy: SortByOfProductSearchViewState,
68
+ hasMore: boolean,
69
+ loadedCount: number,
70
+ totalCount: number,
71
+ hasSuggestions: boolean,
72
+ suggestions: Array<SuggestionOfProductSearchViewState>
73
+ }
74
+
75
+ export type ProductSearchSlowViewState = Pick<ProductSearchViewState, 'searchFields' | 'fuzzySearch' | 'emptyStateMessage'> & {
76
+ filters: {
77
+ categoryFilter: {
78
+ categories: Array<Pick<ProductSearchViewState['filters']['categoryFilter']['categories'][number], 'categoryId' | 'categoryName' | 'categorySlug'>>;
79
+ };
80
+ };
81
+ };
82
+
83
+ export type ProductSearchFastViewState = Pick<ProductSearchViewState, 'searchExpression' | 'isSearching' | 'hasSearched' | 'resultCount' | 'hasResults' | 'hasMore' | 'loadedCount' | 'totalCount' | 'hasSuggestions'> & {
84
+ searchResults: Array<ProductSearchViewState['searchResults'][number]>;
85
+ filters: Pick<ProductSearchViewState['filters'], 'inStockOnly'> & {
86
+ priceRange: ProductSearchViewState['filters']['priceRange'];
87
+ categoryFilter: {
88
+ categories: Array<Pick<ProductSearchViewState['filters']['categoryFilter']['categories'][number], 'categoryId' | 'isSelected'>>;
89
+ };
90
+ };
91
+ sortBy: ProductSearchViewState['sortBy'];
92
+ suggestions: Array<ProductSearchViewState['suggestions'][number]>;
93
+ };
94
+
95
+ export type ProductSearchInteractiveViewState = Pick<ProductSearchViewState, 'searchExpression' | 'isSearching' | 'hasSearched' | 'resultCount' | 'hasResults' | 'hasMore' | 'loadedCount' | 'totalCount' | 'hasSuggestions'> & {
96
+ searchResults: Array<ProductSearchViewState['searchResults'][number]>;
97
+ filters: Pick<ProductSearchViewState['filters'], 'inStockOnly'> & {
98
+ priceRange: ProductSearchViewState['filters']['priceRange'];
99
+ categoryFilter: {
100
+ categories: Array<Pick<ProductSearchViewState['filters']['categoryFilter']['categories'][number], 'categoryId' | 'isSelected'>>;
101
+ };
102
+ };
103
+ sortBy: ProductSearchViewState['sortBy'];
104
+ suggestions: Array<ProductSearchViewState['suggestions'][number]>;
105
+ };
106
+
107
+
108
+ export interface ProductSearchRefs {
109
+ searchExpression: HTMLElementProxy<ProductSearchViewState, HTMLInputElement>,
110
+ searchButton: HTMLElementProxy<ProductSearchViewState, HTMLButtonElement>,
111
+ clearSearchButton: HTMLElementProxy<ProductSearchViewState, HTMLButtonElement>,
112
+ loadMoreButton: HTMLElementProxy<ProductSearchViewState, HTMLButtonElement>,
113
+ searchResults: ProductCardRepeatedRefs,
114
+ filters: {
115
+ inStockOnly: HTMLElementProxy<FilterOfProductSearchViewState, HTMLInputElement>,
116
+ clearFilters: HTMLElementProxy<FilterOfProductSearchViewState, HTMLButtonElement>,
117
+ priceRange: {
118
+ minPrice: HTMLElementProxy<PriceRangeOfFilterOfProductSearchViewState, HTMLInputElement>,
119
+ maxPrice: HTMLElementProxy<PriceRangeOfFilterOfProductSearchViewState, HTMLInputElement>,
120
+ ranges: {
121
+ isSelected: HTMLElementCollectionProxy<RangeOfPriceRangeOfFilterOfProductSearchViewState, HTMLInputElement>
122
+ }
123
+ },
124
+ categoryFilter: {
125
+ categories: {
126
+ isSelected: HTMLElementCollectionProxy<CategoryOfCategoryFilterOfFilterOfProductSearchViewState, HTMLInputElement>
127
+ }
128
+ }
129
+ },
130
+ sortBy: {
131
+ sortDropdown: HTMLElementProxy<SortByOfProductSearchViewState, HTMLSelectElement>
132
+ },
133
+ suggestions: {
134
+ suggestionButton: HTMLElementCollectionProxy<SuggestionOfProductSearchViewState, HTMLButtonElement>
135
+ }
136
+ }
137
+
138
+
139
+ export interface ProductSearchRepeatedRefs {
140
+ searchExpression: HTMLElementCollectionProxy<ProductSearchViewState, HTMLInputElement>,
141
+ searchButton: HTMLElementCollectionProxy<ProductSearchViewState, HTMLButtonElement>,
142
+ clearSearchButton: HTMLElementCollectionProxy<ProductSearchViewState, HTMLButtonElement>,
143
+ loadMoreButton: HTMLElementCollectionProxy<ProductSearchViewState, HTMLButtonElement>,
144
+ searchResults: ProductCardRepeatedRefs,
145
+ filters: {
146
+ inStockOnly: HTMLElementCollectionProxy<FilterOfProductSearchViewState, HTMLInputElement>,
147
+ clearFilters: HTMLElementCollectionProxy<FilterOfProductSearchViewState, HTMLButtonElement>,
148
+ priceRange: {
149
+ minPrice: HTMLElementCollectionProxy<PriceRangeOfFilterOfProductSearchViewState, HTMLInputElement>,
150
+ maxPrice: HTMLElementCollectionProxy<PriceRangeOfFilterOfProductSearchViewState, HTMLInputElement>,
151
+ ranges: {
152
+ isSelected: HTMLElementCollectionProxy<RangeOfPriceRangeOfFilterOfProductSearchViewState, HTMLInputElement>
153
+ }
154
+ },
155
+ categoryFilter: {
156
+ categories: {
157
+ isSelected: HTMLElementCollectionProxy<CategoryOfCategoryFilterOfFilterOfProductSearchViewState, HTMLInputElement>
158
+ }
159
+ }
160
+ },
161
+ sortBy: {
162
+ sortDropdown: HTMLElementCollectionProxy<SortByOfProductSearchViewState, HTMLSelectElement>
163
+ },
164
+ suggestions: {
165
+ suggestionButton: HTMLElementCollectionProxy<SuggestionOfProductSearchViewState, HTMLButtonElement>
166
+ }
167
+ }
168
+
169
+ export type ProductSearchContract = JayContract<ProductSearchViewState, ProductSearchRefs, ProductSearchSlowViewState, ProductSearchFastViewState, ProductSearchInteractiveViewState>