@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.
- package/README.md +184 -0
- package/dist/actions/get-categories.jay-action +8 -0
- package/dist/actions/get-product-by-slug.jay-action +10 -0
- package/dist/actions/search-products.jay-action +33 -0
- package/dist/contracts/category-list.jay-contract +50 -0
- package/dist/contracts/category-list.jay-contract.d.ts +40 -0
- package/dist/contracts/category-page.jay-contract +193 -0
- package/dist/contracts/category-page.jay-contract.d.ts +124 -0
- package/dist/contracts/media-gallery.jay-contract +22 -0
- package/dist/contracts/media-gallery.jay-contract.d.ts +53 -0
- package/dist/contracts/media.jay-contract +5 -0
- package/dist/contracts/media.jay-contract.d.ts +25 -0
- package/dist/contracts/product-card.jay-contract +182 -0
- package/dist/contracts/product-card.jay-contract.d.ts +120 -0
- package/dist/contracts/product-options.jay-contract +66 -0
- package/dist/contracts/product-options.jay-contract.d.ts +57 -0
- package/dist/contracts/product-page.jay-contract +151 -0
- package/dist/contracts/product-page.jay-contract.d.ts +218 -0
- package/dist/contracts/product-search.jay-contract +252 -0
- package/dist/contracts/product-search.jay-contract.d.ts +169 -0
- package/dist/index.client.js +649 -0
- package/dist/index.d.ts +943 -0
- package/dist/index.js +1140 -0
- package/package.json +66 -0
- package/plugin.yaml +34 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import {HTMLElementCollectionProxy, JayContract} from "@jay-framework/runtime";
|
|
2
|
+
import {MediaViewState, MediaRefs, MediaRepeatedRefs} from "./media.jay-contract";
|
|
3
|
+
|
|
4
|
+
export enum Selected {
|
|
5
|
+
selected,
|
|
6
|
+
notSelected
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface AvailableMediaOfMediaGalleryViewState {
|
|
10
|
+
mediaId: string,
|
|
11
|
+
media: MediaViewState,
|
|
12
|
+
selected: Selected
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface MediaGalleryViewState {
|
|
16
|
+
selectedMedia: MediaViewState,
|
|
17
|
+
availableMedia: Array<AvailableMediaOfMediaGalleryViewState>
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type MediaGallerySlowViewState = {
|
|
21
|
+
selectedMedia: MediaGalleryViewState['selectedMedia'];
|
|
22
|
+
availableMedia: Array<Pick<MediaGalleryViewState['availableMedia'][number], 'mediaId'> & {
|
|
23
|
+
media: MediaGalleryViewState['availableMedia'][number]['media'];
|
|
24
|
+
}>;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type MediaGalleryFastViewState = {
|
|
28
|
+
availableMedia: Array<Pick<MediaGalleryViewState['availableMedia'][number], 'mediaId' | 'selected'>>;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export type MediaGalleryInteractiveViewState = {
|
|
32
|
+
availableMedia: Array<Pick<MediaGalleryViewState['availableMedia'][number], 'mediaId' | 'selected'>>;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
export interface MediaGalleryRefs {
|
|
37
|
+
selectedMedia: MediaRefs,
|
|
38
|
+
availableMedia: {
|
|
39
|
+
selected: HTMLElementCollectionProxy<AvailableMediaOfMediaGalleryViewState, HTMLImageElement | HTMLDivElement>,
|
|
40
|
+
media: MediaRefs
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
export interface MediaGalleryRepeatedRefs {
|
|
46
|
+
selectedMedia: MediaRepeatedRefs,
|
|
47
|
+
availableMedia: {
|
|
48
|
+
selected: HTMLElementCollectionProxy<AvailableMediaOfMediaGalleryViewState, HTMLImageElement | HTMLDivElement>,
|
|
49
|
+
media: MediaRepeatedRefs
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export type MediaGalleryContract = JayContract<MediaGalleryViewState, MediaGalleryRefs, MediaGallerySlowViewState, MediaGalleryFastViewState, MediaGalleryInteractiveViewState>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
name: media
|
|
2
|
+
tags:
|
|
3
|
+
- {tag: url, type: data, dataType: string, description: Media Url}
|
|
4
|
+
- {tag: mediaType, type: variant, dataType: "enum (IMAGE | VIDEO)", description: Media type}
|
|
5
|
+
- {tag: thumbnail_50x50, type: data, dataType: string, description: Media Thumbnail Url }
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {JayContract} from "@jay-framework/runtime";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export enum MediaType {
|
|
5
|
+
IMAGE,
|
|
6
|
+
VIDEO
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface MediaViewState {
|
|
10
|
+
url: string,
|
|
11
|
+
mediaType: MediaType,
|
|
12
|
+
thumbnail_50x50: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type MediaSlowViewState = Pick<MediaViewState, 'url' | 'mediaType' | 'thumbnail_50x50'>;
|
|
16
|
+
|
|
17
|
+
export type MediaFastViewState = {};
|
|
18
|
+
|
|
19
|
+
export type MediaInteractiveViewState = {};
|
|
20
|
+
|
|
21
|
+
export interface MediaRefs {}
|
|
22
|
+
|
|
23
|
+
export interface MediaRepeatedRefs {}
|
|
24
|
+
|
|
25
|
+
export type MediaContract = JayContract<MediaViewState, MediaRefs, MediaSlowViewState, MediaFastViewState, MediaInteractiveViewState>
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
name: product-card
|
|
2
|
+
tags:
|
|
3
|
+
# Product basic info (from Wix Stores Product API)
|
|
4
|
+
- tag: _id
|
|
5
|
+
type: data
|
|
6
|
+
dataType: string
|
|
7
|
+
description: Product GUID
|
|
8
|
+
|
|
9
|
+
- tag: name
|
|
10
|
+
type: data
|
|
11
|
+
dataType: string
|
|
12
|
+
required: true
|
|
13
|
+
description: Product name
|
|
14
|
+
|
|
15
|
+
- tag: slug
|
|
16
|
+
type: data
|
|
17
|
+
dataType: string
|
|
18
|
+
description: Product slug for URL
|
|
19
|
+
|
|
20
|
+
- tag: productUrl
|
|
21
|
+
type: data
|
|
22
|
+
dataType: string
|
|
23
|
+
description: Full URL path to product page (e.g., /products/my-product or /products/polgat/my-product)
|
|
24
|
+
|
|
25
|
+
- tag: categoryPrefix
|
|
26
|
+
type: data
|
|
27
|
+
dataType: string
|
|
28
|
+
description: Category prefix name for the product (e.g., the display name of the root category). Empty when no prefix is configured.
|
|
29
|
+
|
|
30
|
+
- tag: productLink
|
|
31
|
+
type: interactive
|
|
32
|
+
elementType: HTMLAnchorElement
|
|
33
|
+
description: Link to product page
|
|
34
|
+
|
|
35
|
+
# Media (from Wix Stores Product API)
|
|
36
|
+
- tag: mainMedia
|
|
37
|
+
type: sub-contract
|
|
38
|
+
description: Main product media
|
|
39
|
+
tags:
|
|
40
|
+
- tag: url
|
|
41
|
+
type: data
|
|
42
|
+
dataType: string
|
|
43
|
+
description: Media URL
|
|
44
|
+
|
|
45
|
+
- tag: altText
|
|
46
|
+
type: data
|
|
47
|
+
dataType: string
|
|
48
|
+
description: Media alt text
|
|
49
|
+
|
|
50
|
+
- tag: mediaType
|
|
51
|
+
type: data
|
|
52
|
+
dataType: enum (IMAGE | VIDEO)
|
|
53
|
+
description: Media type
|
|
54
|
+
|
|
55
|
+
- tag: thumbnail
|
|
56
|
+
type: sub-contract
|
|
57
|
+
description: Thumbnail image optimized for listings
|
|
58
|
+
tags:
|
|
59
|
+
- tag: url
|
|
60
|
+
type: data
|
|
61
|
+
dataType: string
|
|
62
|
+
description: Thumbnail URL
|
|
63
|
+
|
|
64
|
+
- tag: altText
|
|
65
|
+
type: data
|
|
66
|
+
dataType: string
|
|
67
|
+
description: Thumbnail alt text
|
|
68
|
+
|
|
69
|
+
- tag: width
|
|
70
|
+
type: data
|
|
71
|
+
dataType: number
|
|
72
|
+
description: Thumbnail width in pixels
|
|
73
|
+
|
|
74
|
+
- tag: height
|
|
75
|
+
type: data
|
|
76
|
+
dataType: number
|
|
77
|
+
description: Thumbnail height in pixels
|
|
78
|
+
|
|
79
|
+
# Price information
|
|
80
|
+
- tag: price
|
|
81
|
+
type: data
|
|
82
|
+
dataType: string
|
|
83
|
+
phase: fast+interactive
|
|
84
|
+
description: The product or variant price
|
|
85
|
+
|
|
86
|
+
- tag: strikethroughPrice
|
|
87
|
+
type: data
|
|
88
|
+
dataType: string
|
|
89
|
+
phase: fast+interactive
|
|
90
|
+
description: A Strikethrough product price for sales
|
|
91
|
+
|
|
92
|
+
- tag: hasDiscount
|
|
93
|
+
type: variant
|
|
94
|
+
dataType: boolean
|
|
95
|
+
description: Whether product has a discount (compareAtPrice > actualPrice)
|
|
96
|
+
|
|
97
|
+
# Inventory (from Wix Stores Product API)
|
|
98
|
+
- tag: inventory
|
|
99
|
+
type: sub-contract
|
|
100
|
+
description: Product inventory information
|
|
101
|
+
tags:
|
|
102
|
+
- tag: availabilityStatus
|
|
103
|
+
type: variant
|
|
104
|
+
dataType: enum (IN_STOCK | OUT_OF_STOCK | PARTIALLY_OUT_OF_STOCK)
|
|
105
|
+
description: Current availability status
|
|
106
|
+
|
|
107
|
+
- tag: preorderStatus
|
|
108
|
+
type: data
|
|
109
|
+
dataType: enum (ENABLED | DISABLED | PARTIALLY_ENABLED)
|
|
110
|
+
description: Current preorder status
|
|
111
|
+
|
|
112
|
+
# Product ribbon (from Wix Stores Product API)
|
|
113
|
+
- tag: ribbon
|
|
114
|
+
type: sub-contract
|
|
115
|
+
description: Product ribbon/badge
|
|
116
|
+
tags:
|
|
117
|
+
- tag: _id
|
|
118
|
+
type: data
|
|
119
|
+
dataType: string
|
|
120
|
+
description: Ribbon GUID
|
|
121
|
+
|
|
122
|
+
- tag: name
|
|
123
|
+
type: data
|
|
124
|
+
dataType: string
|
|
125
|
+
description: Ribbon text (e.g., "New", "Sale", "Best Seller")
|
|
126
|
+
|
|
127
|
+
- tag: hasRibbon
|
|
128
|
+
type: variant
|
|
129
|
+
dataType: boolean
|
|
130
|
+
description: Whether product has a ribbon/badge
|
|
131
|
+
|
|
132
|
+
# Brand (from Wix Stores Product API)
|
|
133
|
+
- tag: brand
|
|
134
|
+
type: sub-contract
|
|
135
|
+
description: Product brand
|
|
136
|
+
tags:
|
|
137
|
+
- tag: _id
|
|
138
|
+
type: data
|
|
139
|
+
dataType: string
|
|
140
|
+
description: Brand GUID
|
|
141
|
+
|
|
142
|
+
- tag: name
|
|
143
|
+
type: data
|
|
144
|
+
dataType: string
|
|
145
|
+
description: Brand name
|
|
146
|
+
|
|
147
|
+
# Additional product metadata
|
|
148
|
+
- tag: productType
|
|
149
|
+
type: data
|
|
150
|
+
dataType: enum (PHYSICAL | DIGITAL)
|
|
151
|
+
description: Product type
|
|
152
|
+
|
|
153
|
+
# Quick actions
|
|
154
|
+
- tag: addToCartButton
|
|
155
|
+
type: interactive
|
|
156
|
+
elementType: HTMLButtonElement
|
|
157
|
+
description: Quick add to cart button (for SIMPLE products with no options)
|
|
158
|
+
|
|
159
|
+
- tag: isAddingToCart
|
|
160
|
+
type: variant
|
|
161
|
+
dataType: boolean
|
|
162
|
+
phase: fast+interactive
|
|
163
|
+
description: Whether add to cart is in progress
|
|
164
|
+
|
|
165
|
+
# Quick-add behavior
|
|
166
|
+
- tag: quickAddType
|
|
167
|
+
type: variant
|
|
168
|
+
dataType: enum (SIMPLE | SINGLE_OPTION | NEEDS_CONFIGURATION)
|
|
169
|
+
description: |
|
|
170
|
+
SIMPLE = no options, show Add to Cart button
|
|
171
|
+
SINGLE_OPTION = one option, show choices on hover (click = add to cart)
|
|
172
|
+
NEEDS_CONFIGURATION = multiple options or modifiers, link to product page
|
|
173
|
+
|
|
174
|
+
- tag: quickOption
|
|
175
|
+
type: sub-contract
|
|
176
|
+
description: Primary option for quick selection (only when quickAddType = SINGLE_OPTION)
|
|
177
|
+
link: ./product-options
|
|
178
|
+
|
|
179
|
+
- tag: viewOptionsButton
|
|
180
|
+
type: interactive
|
|
181
|
+
elementType: HTMLButtonElement
|
|
182
|
+
description: Button to navigate to product page (when quickAddType = NEEDS_CONFIGURATION)
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import {HTMLElementCollectionProxy, HTMLElementProxy, JayContract} from "@jay-framework/runtime";
|
|
2
|
+
import {ProductOptionsViewState, ProductOptionsRefs, ProductOptionsRepeatedRefs} from "./product-options.jay-contract";
|
|
3
|
+
|
|
4
|
+
export enum MediaType {
|
|
5
|
+
IMAGE,
|
|
6
|
+
VIDEO
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface MainMediaOfProductCardViewState {
|
|
10
|
+
url: string,
|
|
11
|
+
altText: string,
|
|
12
|
+
mediaType: MediaType
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ThumbnailOfProductCardViewState {
|
|
16
|
+
url: string,
|
|
17
|
+
altText: string,
|
|
18
|
+
width: number,
|
|
19
|
+
height: number
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export enum AvailabilityStatus {
|
|
23
|
+
IN_STOCK,
|
|
24
|
+
OUT_OF_STOCK,
|
|
25
|
+
PARTIALLY_OUT_OF_STOCK
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export enum PreorderStatus {
|
|
29
|
+
ENABLED,
|
|
30
|
+
DISABLED,
|
|
31
|
+
PARTIALLY_ENABLED
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface InventoryOfProductCardViewState {
|
|
35
|
+
availabilityStatus: AvailabilityStatus,
|
|
36
|
+
preorderStatus: PreorderStatus
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface RibbonOfProductCardViewState {
|
|
40
|
+
_id: string,
|
|
41
|
+
name: string
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface BrandOfProductCardViewState {
|
|
45
|
+
_id: string,
|
|
46
|
+
name: string
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export enum ProductType {
|
|
50
|
+
PHYSICAL,
|
|
51
|
+
DIGITAL
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export enum QuickAddType {
|
|
55
|
+
SIMPLE,
|
|
56
|
+
SINGLE_OPTION,
|
|
57
|
+
NEEDS_CONFIGURATION
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface ProductCardViewState {
|
|
61
|
+
_id: string,
|
|
62
|
+
name: string,
|
|
63
|
+
slug: string,
|
|
64
|
+
productUrl: string,
|
|
65
|
+
categoryPrefix: string,
|
|
66
|
+
mainMedia: MainMediaOfProductCardViewState,
|
|
67
|
+
thumbnail: ThumbnailOfProductCardViewState,
|
|
68
|
+
price: string,
|
|
69
|
+
strikethroughPrice: string,
|
|
70
|
+
hasDiscount: boolean,
|
|
71
|
+
inventory: InventoryOfProductCardViewState,
|
|
72
|
+
ribbon: RibbonOfProductCardViewState,
|
|
73
|
+
hasRibbon: boolean,
|
|
74
|
+
brand: BrandOfProductCardViewState,
|
|
75
|
+
productType: ProductType,
|
|
76
|
+
isAddingToCart: boolean,
|
|
77
|
+
quickAddType: QuickAddType,
|
|
78
|
+
quickOption: ProductOptionsViewState
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export type ProductCardSlowViewState = Pick<ProductCardViewState, '_id' | 'name' | 'slug' | 'productUrl' | 'categoryPrefix' | 'hasDiscount' | 'hasRibbon' | 'productType' | 'quickAddType'> & {
|
|
82
|
+
mainMedia: ProductCardViewState['mainMedia'];
|
|
83
|
+
thumbnail: ProductCardViewState['thumbnail'];
|
|
84
|
+
inventory: ProductCardViewState['inventory'];
|
|
85
|
+
ribbon: ProductCardViewState['ribbon'];
|
|
86
|
+
brand: ProductCardViewState['brand'];
|
|
87
|
+
quickOption: Pick<ProductCardViewState['quickOption'], '_id' | 'name' | 'optionRenderType'> & {
|
|
88
|
+
choices: Array<Pick<ProductCardViewState['quickOption']['choices'][number], 'choiceId' | 'name' | 'choiceType' | 'colorCode' | 'variantId'>>;
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export type ProductCardFastViewState = Pick<ProductCardViewState, 'price' | 'strikethroughPrice' | 'isAddingToCart'> & {
|
|
93
|
+
quickOption: {
|
|
94
|
+
choices: Array<Pick<ProductCardViewState['quickOption']['choices'][number], 'choiceId' | 'inStock' | 'isSelected'>>;
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export type ProductCardInteractiveViewState = Pick<ProductCardViewState, 'price' | 'strikethroughPrice' | 'isAddingToCart'> & {
|
|
99
|
+
quickOption: {
|
|
100
|
+
choices: Array<Pick<ProductCardViewState['quickOption']['choices'][number], 'choiceId' | 'inStock' | 'isSelected'>>;
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
export interface ProductCardRefs {
|
|
106
|
+
productLink: HTMLElementProxy<ProductCardViewState, HTMLAnchorElement>,
|
|
107
|
+
addToCartButton: HTMLElementProxy<ProductCardViewState, HTMLButtonElement>,
|
|
108
|
+
viewOptionsButton: HTMLElementProxy<ProductCardViewState, HTMLButtonElement>,
|
|
109
|
+
quickOption: ProductOptionsRefs
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
export interface ProductCardRepeatedRefs {
|
|
114
|
+
productLink: HTMLElementCollectionProxy<ProductCardViewState, HTMLAnchorElement>,
|
|
115
|
+
addToCartButton: HTMLElementCollectionProxy<ProductCardViewState, HTMLButtonElement>,
|
|
116
|
+
viewOptionsButton: HTMLElementCollectionProxy<ProductCardViewState, HTMLButtonElement>,
|
|
117
|
+
quickOption: ProductOptionsRepeatedRefs
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export type ProductCardContract = JayContract<ProductCardViewState, ProductCardRefs, ProductCardSlowViewState, ProductCardFastViewState, ProductCardInteractiveViewState>
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
name: product-options
|
|
2
|
+
description: Shared product option structure for quick selection and full product page
|
|
3
|
+
|
|
4
|
+
tags:
|
|
5
|
+
- tag: _id
|
|
6
|
+
type: data
|
|
7
|
+
dataType: string
|
|
8
|
+
description: Option GUID
|
|
9
|
+
|
|
10
|
+
- tag: name
|
|
11
|
+
type: data
|
|
12
|
+
dataType: string
|
|
13
|
+
description: "Option name (e.g., \"Size\", \"Color\")"
|
|
14
|
+
|
|
15
|
+
- tag: optionRenderType
|
|
16
|
+
type: variant
|
|
17
|
+
dataType: enum (TEXT_CHOICES | COLOR_SWATCH_CHOICES)
|
|
18
|
+
description: How the option should be rendered
|
|
19
|
+
|
|
20
|
+
- tag: choices
|
|
21
|
+
type: sub-contract
|
|
22
|
+
repeated: true
|
|
23
|
+
trackBy: choiceId
|
|
24
|
+
description: Available choices for this option
|
|
25
|
+
tags:
|
|
26
|
+
- tag: choiceId
|
|
27
|
+
type: data
|
|
28
|
+
dataType: string
|
|
29
|
+
description: Choice GUID
|
|
30
|
+
|
|
31
|
+
- tag: name
|
|
32
|
+
type: data
|
|
33
|
+
dataType: string
|
|
34
|
+
description: "Choice display name (e.g., \"XL\", \"Red\")"
|
|
35
|
+
|
|
36
|
+
- tag: choiceType
|
|
37
|
+
type: variant
|
|
38
|
+
dataType: enum (CHOICE_TEXT | ONE_COLOR)
|
|
39
|
+
description: Type of choice (text or color swatch)
|
|
40
|
+
|
|
41
|
+
- tag: colorCode
|
|
42
|
+
type: data
|
|
43
|
+
dataType: string
|
|
44
|
+
description: Color code in HEX format (for color swatches)
|
|
45
|
+
|
|
46
|
+
- tag: inStock
|
|
47
|
+
type: variant
|
|
48
|
+
dataType: boolean
|
|
49
|
+
phase: fast+interactive
|
|
50
|
+
description: Whether this choice has available stock
|
|
51
|
+
|
|
52
|
+
- tag: variantId
|
|
53
|
+
type: data
|
|
54
|
+
dataType: string
|
|
55
|
+
description: The variant ID to use when adding to cart (for single-option products)
|
|
56
|
+
|
|
57
|
+
- tag: isSelected
|
|
58
|
+
type: variant
|
|
59
|
+
dataType: boolean
|
|
60
|
+
phase: fast+interactive
|
|
61
|
+
description: Whether this choice is currently selected
|
|
62
|
+
|
|
63
|
+
- tag: choiceButton
|
|
64
|
+
type: interactive
|
|
65
|
+
elementType: HTMLButtonElement
|
|
66
|
+
description: Button to select this choice (click adds to cart for quick-add)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import {HTMLElementCollectionProxy, JayContract} from "@jay-framework/runtime";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export enum OptionRenderType {
|
|
5
|
+
TEXT_CHOICES,
|
|
6
|
+
COLOR_SWATCH_CHOICES
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export enum ChoiceType {
|
|
10
|
+
CHOICE_TEXT,
|
|
11
|
+
ONE_COLOR
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface ChoiceOfProductOptionsViewState {
|
|
15
|
+
choiceId: string,
|
|
16
|
+
name: string,
|
|
17
|
+
choiceType: ChoiceType,
|
|
18
|
+
colorCode: string,
|
|
19
|
+
inStock: boolean,
|
|
20
|
+
variantId: string,
|
|
21
|
+
isSelected: boolean
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface ProductOptionsViewState {
|
|
25
|
+
_id: string,
|
|
26
|
+
name: string,
|
|
27
|
+
optionRenderType: OptionRenderType,
|
|
28
|
+
choices: Array<ChoiceOfProductOptionsViewState>
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export type ProductOptionsSlowViewState = Pick<ProductOptionsViewState, '_id' | 'name' | 'optionRenderType'> & {
|
|
32
|
+
choices: Array<Pick<ProductOptionsViewState['choices'][number], 'choiceId' | 'name' | 'choiceType' | 'colorCode' | 'variantId'>>;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export type ProductOptionsFastViewState = {
|
|
36
|
+
choices: Array<Pick<ProductOptionsViewState['choices'][number], 'choiceId' | 'inStock' | 'isSelected'>>;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export type ProductOptionsInteractiveViewState = {
|
|
40
|
+
choices: Array<Pick<ProductOptionsViewState['choices'][number], 'choiceId' | 'inStock' | 'isSelected'>>;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
export interface ProductOptionsRefs {
|
|
45
|
+
choices: {
|
|
46
|
+
choiceButton: HTMLElementCollectionProxy<ChoiceOfProductOptionsViewState, HTMLButtonElement>
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
export interface ProductOptionsRepeatedRefs {
|
|
52
|
+
choices: {
|
|
53
|
+
choiceButton: HTMLElementCollectionProxy<ChoiceOfProductOptionsViewState, HTMLButtonElement>
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export type ProductOptionsContract = JayContract<ProductOptionsViewState, ProductOptionsRefs, ProductOptionsSlowViewState, ProductOptionsFastViewState, ProductOptionsInteractiveViewState>
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
name: product-page
|
|
2
|
+
tags:
|
|
3
|
+
- {tag: _id, type: data, dataType: string, description: Product GUID}
|
|
4
|
+
- {tag: productName, type: data, dataType: string, required: true, description: Product name}
|
|
5
|
+
|
|
6
|
+
- tag: mediaGallery
|
|
7
|
+
type: sub-contract
|
|
8
|
+
phase: fast+interactive
|
|
9
|
+
link: ./media-gallery
|
|
10
|
+
|
|
11
|
+
- {tag: description, type: data, dataType: string, description: Product description}
|
|
12
|
+
- {tag: brand, type: data, dataType: string, description: Brand name}
|
|
13
|
+
- {tag: ribbon, type: data, dataType: string, description: "Ribbon text (e.g., \"New\", \"Sale\")"}
|
|
14
|
+
- {tag: productType, type: variant, dataType: "enum (PHYSICAL | DIGITAL)", description: Product type }
|
|
15
|
+
|
|
16
|
+
- {tag: sku, type: data, dataType: string, phase: fast+interactive, description: Product SKU, or chosen variant SKU}
|
|
17
|
+
- {tag: price, type: data, dataType: string, phase: fast+interactive, description: The product or variant price}
|
|
18
|
+
- {tag: strikethroughPrice, type: data, dataType: string, phase: fast+interactive, description: A Strikethrough product price for sales}
|
|
19
|
+
- {tag: pricePerUnit, type: data, dataType: string, phase: fast+interactive, description: formatted price per unit, if used}
|
|
20
|
+
- {tag: stockStatus, type: variant, dataType: "enum (OUT_OF_STOCK | IN_STOCK)", phase: fast+interactive, description: indicator if the product or current variant are in stock }
|
|
21
|
+
|
|
22
|
+
- tag: quantity
|
|
23
|
+
type: sub-contract
|
|
24
|
+
description: Quantity selection controls
|
|
25
|
+
tags:
|
|
26
|
+
- {tag: decrementButton, type: interactive, elementType: HTMLButtonElement, description: Button to decrease quantity}
|
|
27
|
+
- {tag: incrementButton, type: interactive, elementType: HTMLButtonElement, description: Button to increase quantity}
|
|
28
|
+
- {tag: quantity, type: [data, interactive], dataType: number, elementType: HTMLInputElement, description: Selected Quantity and Direct quantity input field}
|
|
29
|
+
|
|
30
|
+
# Call to action
|
|
31
|
+
- {tag: addToCartButton, type: interactive, elementType: HTMLButtonElement, required: true, description: Add product to cart button}
|
|
32
|
+
- {tag: buyNowButton, type: interactive, elementType: HTMLButtonElement, required: true, description: Buy now button}
|
|
33
|
+
- {tag: actionsEnabled, type: variant, dataType: boolean, phase: fast+interactive, description: should the add to cart and buy now buttons be enabled}
|
|
34
|
+
|
|
35
|
+
- tag: options
|
|
36
|
+
type: sub-contract
|
|
37
|
+
repeated: true
|
|
38
|
+
trackBy: _id
|
|
39
|
+
description: Product customization options that generate variants
|
|
40
|
+
tags:
|
|
41
|
+
- {tag: _id, type: data, dataType: string, description: "Option GUID (customization ID)"}
|
|
42
|
+
- {tag: name, type: data, dataType: string, description: "Option name (e.g., \"Color\", \"Size\")"}
|
|
43
|
+
- {tag: optionRenderType, type: variant, dataType: "enum (TEXT_CHOICES | COLOR_SWATCH_CHOICES)", description: How the option should be rendered}
|
|
44
|
+
- {tag: textChoice, type: interactive, elementType: HTMLSelectElement, description: dropdown for text choice}
|
|
45
|
+
- {tag: textChoiceSelection, type: data, dataType: string, phase: fast+interactive, description: the selected text option}
|
|
46
|
+
|
|
47
|
+
- tag: choices
|
|
48
|
+
type: sub-contract
|
|
49
|
+
repeated: true
|
|
50
|
+
trackBy: choiceId
|
|
51
|
+
description: Available choices for this option
|
|
52
|
+
tags:
|
|
53
|
+
- {tag: choiceId, type: data, dataType: string, description: Choice GUID}
|
|
54
|
+
- {tag: choiceType, type: variant, dataType: "enum (CHOICE_TEXT | ONE_COLOR)", description: Type of choice}
|
|
55
|
+
- {tag: name, type: data, dataType: string, description: "Choice name (e.g., \"Red\", \"Large\")"}
|
|
56
|
+
- {tag: colorCode, type: data, dataType: string, description: Color code in HEX format (for color choices)}
|
|
57
|
+
- {tag: inStock, type: data, dataType: boolean, description: Whether at least one variant with this choice is in stock}
|
|
58
|
+
- {tag: isSelected, type: variant, dataType: boolean, phase: fast+interactive, description: Whether this choice is currently selected (UI state)}
|
|
59
|
+
- {tag: choiceButton, type: interactive, elementType: HTMLButtonElement, description: Button to select this choice}
|
|
60
|
+
|
|
61
|
+
# Additional info sections (from Wix Stores API)
|
|
62
|
+
- tag: infoSections
|
|
63
|
+
type: sub-contract
|
|
64
|
+
repeated: true
|
|
65
|
+
trackBy: _id
|
|
66
|
+
description: Additional product information sections
|
|
67
|
+
tags:
|
|
68
|
+
- {tag: _id, type: data, dataType: string, description: Info section GUID}
|
|
69
|
+
- {tag: title, type: data, dataType: string, description: Info section title}
|
|
70
|
+
- {tag: plainDescription, type: data, dataType: string, description: Info section description in HTML}
|
|
71
|
+
|
|
72
|
+
- tag: modifiers
|
|
73
|
+
type: sub-contract
|
|
74
|
+
repeated: true
|
|
75
|
+
trackBy: _id
|
|
76
|
+
description: Product customization options that do not generate variants
|
|
77
|
+
tags:
|
|
78
|
+
- {tag: _id, type: data, dataType: string, description: "modifier id"}
|
|
79
|
+
- {tag: name, type: data, dataType: string, description: "modifier name (e.g., \"Color\", \"Size\")"}
|
|
80
|
+
- {tag: modifierType, type: variant, dataType: "enum (TEXT_CHOICES | COLOR_SWATCH_CHOICES | FREE_TEXT)", description: What type of modifier to use?}
|
|
81
|
+
- {tag: textModifier, type: interactive, elementType: HTMLSelectElement, description: dropdown for text modifier}
|
|
82
|
+
- {tag: textModifierSelection, type: data, dataType: string, phase: fast+interactive, description: the selected text modifier}
|
|
83
|
+
- {tag: textInput, type: interactive, elementType: HTMLInputElement | HTMLAreaElement, description: text input for free text}
|
|
84
|
+
- {tag: textInputLength, type: data, dataType: number, description: the limit on the length of free text}
|
|
85
|
+
- {tag: textInputRequired, type: data, dataType: boolean, description: Is the free text input required?}
|
|
86
|
+
|
|
87
|
+
- tag: choices
|
|
88
|
+
type: sub-contract
|
|
89
|
+
repeated: true
|
|
90
|
+
trackBy: choiceId
|
|
91
|
+
description: Available choices for this Modifier
|
|
92
|
+
tags:
|
|
93
|
+
- {tag: choiceId, type: data, dataType: string, description: Choice GUID}
|
|
94
|
+
- {tag: choiceType, type: variant, dataType: "enum (CHOICE_TEXT | ONE_COLOR)", description: Type of choice}
|
|
95
|
+
- {tag: name, type: data, dataType: string, description: "Choice name (e.g., \"Red\", \"Large\")"}
|
|
96
|
+
- {tag: colorCode, type: data, dataType: string, description: Color code in HEX format (for color choices)}
|
|
97
|
+
- {tag: isSelected, type: variant, dataType: boolean, phase: fast+interactive, description: Whether this choice is currently selected (UI state)}
|
|
98
|
+
- {tag: choiceButton, type: interactive, elementType: HTMLButtonElement, description: Button to select this choice}
|
|
99
|
+
|
|
100
|
+
- tag: seoData
|
|
101
|
+
type: sub-contract
|
|
102
|
+
description: Product SEO data.
|
|
103
|
+
tags:
|
|
104
|
+
- tag: tags
|
|
105
|
+
type: sub-contract
|
|
106
|
+
repeated: true
|
|
107
|
+
trackBy: position
|
|
108
|
+
description: SEO tag information.
|
|
109
|
+
tags:
|
|
110
|
+
- {tag: position, type: data, dataType: string, description: the number of the tag, as two digit string.}
|
|
111
|
+
- {tag: type, type: data, dataType: string, description: SEO tag type.}
|
|
112
|
+
- tag: props
|
|
113
|
+
type: sub-contract
|
|
114
|
+
repeated: true
|
|
115
|
+
trackBy: key
|
|
116
|
+
description: A Key Value pair of SEO properties.
|
|
117
|
+
tags:
|
|
118
|
+
- tag: key
|
|
119
|
+
type: data
|
|
120
|
+
dataType: string
|
|
121
|
+
- tag: value
|
|
122
|
+
type: data
|
|
123
|
+
dataType: string
|
|
124
|
+
- tag: meta
|
|
125
|
+
type: sub-contract
|
|
126
|
+
repeated: true
|
|
127
|
+
trackBy: key
|
|
128
|
+
description: SEO tag metadata
|
|
129
|
+
tags:
|
|
130
|
+
- tag: key
|
|
131
|
+
type: data
|
|
132
|
+
dataType: string
|
|
133
|
+
- tag: value
|
|
134
|
+
type: data
|
|
135
|
+
dataType: string
|
|
136
|
+
- {tag: children, type: data, dataType: string, description: SEO tag inner content.}
|
|
137
|
+
|
|
138
|
+
- tag: settings
|
|
139
|
+
type: sub-contract
|
|
140
|
+
description: SEO general settings.
|
|
141
|
+
tags:
|
|
142
|
+
- {tag: preventAutoRedirect, type: data, dataType: boolean, description: Whether the automatical redirect visits from the old URL to the new one is enabled.}
|
|
143
|
+
- tag: keywords
|
|
144
|
+
type: sub-contract
|
|
145
|
+
repeated: true
|
|
146
|
+
trackBy: term
|
|
147
|
+
description: User-selected keyword terms for a specific page.
|
|
148
|
+
tags:
|
|
149
|
+
- {tag: term, type: data, dataType: string, description: Keyword value.}
|
|
150
|
+
- {tag: isMain, type: data, dataType: boolean, description: Whether the keyword is the main focus keyword.}
|
|
151
|
+
- {tag: origin, type: data, dataType: string, description: The source that added the keyword terms to the SEO settings. }
|