@wix/headless-stores 0.0.9 → 0.0.11
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/enums/index.d.ts +2 -0
- package/cjs/dist/enums/index.js +18 -0
- package/cjs/dist/enums/social-platform-enums.d.ts +25 -0
- package/cjs/dist/enums/social-platform-enums.js +30 -0
- package/cjs/dist/enums/sort-enums.d.ts +17 -0
- package/cjs/dist/enums/sort-enums.js +21 -0
- package/cjs/dist/react/BuyNow.d.ts +2 -4
- package/cjs/dist/react/Category.d.ts +15 -0
- package/cjs/dist/react/Category.js +22 -0
- package/cjs/dist/react/Collection.d.ts +151 -0
- package/cjs/dist/react/Collection.js +209 -0
- package/cjs/dist/react/FilteredCollection.d.ts +95 -0
- package/cjs/dist/react/FilteredCollection.js +150 -0
- package/cjs/dist/react/PayNow.d.ts +2 -4
- package/cjs/dist/react/Product.d.ts +43 -0
- package/cjs/dist/react/Product.js +35 -0
- package/cjs/dist/react/ProductActions.d.ts +42 -0
- package/cjs/dist/react/ProductActions.js +83 -0
- package/cjs/dist/react/ProductModifiers.d.ts +164 -0
- package/cjs/dist/react/ProductModifiers.js +168 -0
- package/cjs/dist/react/ProductVariantSelector.d.ts +153 -0
- package/cjs/dist/react/ProductVariantSelector.js +138 -0
- package/cjs/dist/react/RelatedProducts.d.ts +64 -0
- package/cjs/dist/react/RelatedProducts.js +73 -0
- package/cjs/dist/react/SelectedVariant.d.ts +66 -0
- package/cjs/dist/react/SelectedVariant.js +52 -0
- package/cjs/dist/react/SocialSharing.d.ts +112 -0
- package/cjs/dist/react/SocialSharing.js +86 -0
- package/cjs/dist/react/Sort.d.ts +14 -0
- package/cjs/dist/react/Sort.js +17 -0
- package/cjs/dist/react/index.d.ts +11 -0
- package/cjs/dist/react/index.js +34 -0
- package/cjs/dist/services/buy-now-service.js +2 -2
- package/cjs/dist/services/catalog-options-service.d.ts +30 -0
- package/cjs/dist/services/catalog-options-service.js +156 -0
- package/cjs/dist/services/catalog-price-range-service.d.ts +23 -0
- package/cjs/dist/services/catalog-price-range-service.js +97 -0
- package/cjs/dist/services/category-service.d.ts +26 -0
- package/cjs/dist/services/category-service.js +71 -0
- package/cjs/dist/services/collection-service.d.ts +37 -0
- package/cjs/dist/services/collection-service.js +569 -0
- package/cjs/dist/services/filter-service.d.ts +56 -0
- package/cjs/dist/services/filter-service.js +147 -0
- package/cjs/dist/services/product-media-gallery-service.d.ts +25 -0
- package/cjs/dist/services/product-media-gallery-service.js +105 -0
- package/cjs/dist/services/product-modifiers-service.d.ts +34 -0
- package/cjs/dist/services/product-modifiers-service.js +111 -0
- package/cjs/dist/services/product-service.d.ts +28 -0
- package/cjs/dist/services/product-service.js +68 -0
- package/cjs/dist/services/related-products-service.d.ts +25 -0
- package/cjs/dist/services/related-products-service.js +54 -0
- package/cjs/dist/services/selected-variant-service.d.ts +59 -0
- package/cjs/dist/services/selected-variant-service.js +541 -0
- package/cjs/dist/services/social-sharing-service.d.ts +41 -0
- package/cjs/dist/services/social-sharing-service.js +141 -0
- package/cjs/dist/services/sort-service.d.ts +20 -0
- package/cjs/dist/services/sort-service.js +32 -0
- package/cjs/dist/utils/url-params.d.ts +5 -0
- package/cjs/dist/utils/url-params.js +50 -0
- package/dist/enums/index.d.ts +2 -0
- package/dist/enums/index.js +2 -0
- package/dist/enums/social-platform-enums.d.ts +25 -0
- package/dist/enums/social-platform-enums.js +27 -0
- package/dist/enums/sort-enums.d.ts +17 -0
- package/dist/enums/sort-enums.js +18 -0
- package/dist/react/BuyNow.d.ts +2 -4
- package/dist/react/Category.d.ts +15 -0
- package/dist/react/Category.js +18 -0
- package/dist/react/Collection.d.ts +151 -0
- package/dist/react/Collection.js +201 -0
- package/dist/react/FilteredCollection.d.ts +95 -0
- package/dist/react/FilteredCollection.js +140 -0
- package/dist/react/PayNow.d.ts +2 -4
- package/dist/react/Product.d.ts +43 -0
- package/dist/react/Product.js +30 -0
- package/dist/react/ProductActions.d.ts +42 -0
- package/dist/react/ProductActions.js +79 -0
- package/dist/react/ProductModifiers.d.ts +164 -0
- package/dist/react/ProductModifiers.js +160 -0
- package/dist/react/ProductVariantSelector.d.ts +153 -0
- package/dist/react/ProductVariantSelector.js +130 -0
- package/dist/react/RelatedProducts.d.ts +64 -0
- package/dist/react/RelatedProducts.js +65 -0
- package/dist/react/SelectedVariant.d.ts +66 -0
- package/dist/react/SelectedVariant.js +46 -0
- package/dist/react/SocialSharing.d.ts +112 -0
- package/dist/react/SocialSharing.js +77 -0
- package/dist/react/Sort.d.ts +14 -0
- package/dist/react/Sort.js +14 -0
- package/dist/react/index.d.ts +11 -0
- package/dist/react/index.js +11 -0
- package/dist/services/buy-now-service.js +2 -2
- package/dist/services/catalog-options-service.d.ts +30 -0
- package/dist/services/catalog-options-service.js +152 -0
- package/dist/services/catalog-price-range-service.d.ts +23 -0
- package/dist/services/catalog-price-range-service.js +93 -0
- package/dist/services/category-service.d.ts +26 -0
- package/dist/services/category-service.js +67 -0
- package/dist/services/collection-service.d.ts +37 -0
- package/dist/services/collection-service.js +532 -0
- package/dist/services/filter-service.d.ts +56 -0
- package/dist/services/filter-service.js +144 -0
- package/dist/services/product-media-gallery-service.d.ts +25 -0
- package/dist/services/product-media-gallery-service.js +101 -0
- package/dist/services/product-modifiers-service.d.ts +34 -0
- package/dist/services/product-modifiers-service.js +107 -0
- package/dist/services/product-service.d.ts +28 -0
- package/dist/services/product-service.js +64 -0
- package/dist/services/related-products-service.d.ts +25 -0
- package/dist/services/related-products-service.js +50 -0
- package/dist/services/selected-variant-service.d.ts +59 -0
- package/dist/services/selected-variant-service.js +538 -0
- package/dist/services/social-sharing-service.d.ts +41 -0
- package/dist/services/social-sharing-service.js +137 -0
- package/dist/services/sort-service.d.ts +20 -0
- package/dist/services/sort-service.js +29 -0
- package/dist/utils/url-params.d.ts +5 -0
- package/dist/utils/url-params.js +46 -0
- package/package.json +8 -1
- package/dist/astro/BuyNowServiceContext.d.ts +0 -2
- package/dist/astro/BuyNowServiceContext.js +0 -6
- package/dist/astro/ManagerProviderContext.d.ts +0 -2
- package/dist/astro/ManagerProviderContext.js +0 -7
- package/dist/astro/withBuyButtonService.d.ts +0 -2
- package/dist/astro/withBuyButtonService.js +0 -16
- package/dist/react/CurrentCartServiceProvider.d.ts +0 -5
- package/dist/react/CurrentCartServiceProvider.js +0 -12
- package/dist/react/VariantSelectorServiceProvider.d.ts +0 -7
- package/dist/react/VariantSelectorServiceProvider.js +0 -22
- package/dist/react/hookim/index.d.ts +0 -5
- package/dist/react/hookim/index.js +0 -22
- package/dist/services/CurrentCartService.d.ts +0 -18
- package/dist/services/CurrentCartService.js +0 -9
- package/dist/services/VariantSelectorServices.d.ts +0 -8
- package/dist/services/VariantSelectorServices.js +0 -20
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { type ConnectedModifier, type ConnectedModifierChoice } from '@wix/auto_sdk_stores_products-v-3';
|
|
2
|
+
/**
|
|
3
|
+
* Props for Modifiers headless component
|
|
4
|
+
*/
|
|
5
|
+
export interface ModifiersProps {
|
|
6
|
+
/** Render prop function that receives modifiers data */
|
|
7
|
+
children: (props: ModifiersRenderProps) => React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Render props for Modifiers component
|
|
11
|
+
*/
|
|
12
|
+
export interface ModifiersRenderProps {
|
|
13
|
+
/** Array of product modifiers */
|
|
14
|
+
modifiers: ConnectedModifier[];
|
|
15
|
+
/** Whether product has modifiers */
|
|
16
|
+
hasModifiers: boolean;
|
|
17
|
+
/** Currently selected modifier values */
|
|
18
|
+
selectedModifiers: Record<string, any>;
|
|
19
|
+
/** Whether all required modifiers are filled */
|
|
20
|
+
areAllRequiredModifiersFilled: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Headless component for all product modifiers
|
|
24
|
+
*/
|
|
25
|
+
export declare const Modifiers: (props: ModifiersProps) => import("react").ReactNode;
|
|
26
|
+
/**
|
|
27
|
+
* Props for Modifier headless component
|
|
28
|
+
*/
|
|
29
|
+
export interface ModifierProps {
|
|
30
|
+
/** Product modifier data */
|
|
31
|
+
modifier: ConnectedModifier;
|
|
32
|
+
/** Render prop function that receives modifier data */
|
|
33
|
+
children: (props: ModifierRenderProps) => React.ReactNode;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Render props for Modifier component
|
|
37
|
+
*/
|
|
38
|
+
export interface ModifierRenderProps {
|
|
39
|
+
/** Modifier name */
|
|
40
|
+
name: string;
|
|
41
|
+
/** Modifier type */
|
|
42
|
+
type: any;
|
|
43
|
+
/** Whether this modifier is mandatory */
|
|
44
|
+
mandatory: boolean;
|
|
45
|
+
/** Array of choices for this modifier (for choice-based modifiers) */
|
|
46
|
+
choices: ConnectedModifierChoice[];
|
|
47
|
+
/** Currently selected value for this modifier */
|
|
48
|
+
selectedValue: any;
|
|
49
|
+
/** Whether this modifier has choices */
|
|
50
|
+
hasChoices: boolean;
|
|
51
|
+
/** Whether this modifier is a free text type */
|
|
52
|
+
isFreeText: boolean;
|
|
53
|
+
/** Maximum characters for free text */
|
|
54
|
+
maxChars?: number;
|
|
55
|
+
/** Placeholder text for free text */
|
|
56
|
+
placeholder?: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Headless component for a specific product modifier
|
|
60
|
+
*
|
|
61
|
+
* @component
|
|
62
|
+
*/
|
|
63
|
+
export declare const Modifier: (props: ModifierProps) => import("react").ReactNode;
|
|
64
|
+
/**
|
|
65
|
+
* Props for ModifierChoice headless component
|
|
66
|
+
*/
|
|
67
|
+
export interface ChoiceProps {
|
|
68
|
+
/** Product modifier data */
|
|
69
|
+
modifier: ConnectedModifier;
|
|
70
|
+
/** Choice data */
|
|
71
|
+
choice: ConnectedModifierChoice;
|
|
72
|
+
/** Render prop function that receives choice data */
|
|
73
|
+
children: (props: ChoiceRenderProps) => React.ReactNode;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Render props for ModifierChoice component
|
|
77
|
+
*/
|
|
78
|
+
export interface ChoiceRenderProps {
|
|
79
|
+
/** Choice value to display */
|
|
80
|
+
value: string;
|
|
81
|
+
/** Choice description (for color options) */
|
|
82
|
+
description: string | undefined;
|
|
83
|
+
/** Whether this choice is currently selected */
|
|
84
|
+
isSelected: boolean;
|
|
85
|
+
/** Function to select this choice */
|
|
86
|
+
onSelect: () => void;
|
|
87
|
+
/** Modifier name */
|
|
88
|
+
modifierName: string;
|
|
89
|
+
/** Choice value */
|
|
90
|
+
choiceValue: string;
|
|
91
|
+
/** Color code for swatch choices */
|
|
92
|
+
colorCode?: string;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Headless component for individual modifier choice selection
|
|
96
|
+
*
|
|
97
|
+
* @component
|
|
98
|
+
*/
|
|
99
|
+
export declare const Choice: (props: ChoiceProps) => import("react").ReactNode;
|
|
100
|
+
/**
|
|
101
|
+
* Props for ModifierFreeText headless component
|
|
102
|
+
*/
|
|
103
|
+
export interface FreeTextProps {
|
|
104
|
+
/** Product modifier data */
|
|
105
|
+
modifier: ConnectedModifier;
|
|
106
|
+
/** Render prop function that receives free text data */
|
|
107
|
+
children: (props: FreeTextRenderProps) => React.ReactNode;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Render props for ModifierFreeText component
|
|
111
|
+
*/
|
|
112
|
+
export interface FreeTextRenderProps {
|
|
113
|
+
/** Current text value */
|
|
114
|
+
value: string;
|
|
115
|
+
/** Function to update text value */
|
|
116
|
+
onChange: (value: string) => void;
|
|
117
|
+
/** Whether this modifier is mandatory */
|
|
118
|
+
mandatory: boolean;
|
|
119
|
+
/** Maximum characters allowed */
|
|
120
|
+
maxChars?: number;
|
|
121
|
+
/** Placeholder text */
|
|
122
|
+
placeholder?: string;
|
|
123
|
+
/** Character count */
|
|
124
|
+
charCount: number;
|
|
125
|
+
/** Whether character limit is exceeded */
|
|
126
|
+
isOverLimit: boolean;
|
|
127
|
+
/** Modifier name */
|
|
128
|
+
modifierName: string;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Headless component for free text modifier input
|
|
132
|
+
*
|
|
133
|
+
* @component
|
|
134
|
+
*/
|
|
135
|
+
export declare const FreeText: (props: FreeTextProps) => import("react").ReactNode;
|
|
136
|
+
/**
|
|
137
|
+
* Props for ModifierToggleFreeText headless component
|
|
138
|
+
*/
|
|
139
|
+
export interface ToggleFreeTextProps {
|
|
140
|
+
/** Product modifier data */
|
|
141
|
+
modifier: ConnectedModifier;
|
|
142
|
+
/** Render prop function that receives toggle data */
|
|
143
|
+
children: (props: ToggleFreeTextRenderProps) => React.ReactNode;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Render props for ModifierToggleFreeText component
|
|
147
|
+
*/
|
|
148
|
+
export interface ToggleFreeTextRenderProps {
|
|
149
|
+
/** Whether the text input is shown */
|
|
150
|
+
isTextInputShown: boolean;
|
|
151
|
+
/** Function to toggle text input visibility */
|
|
152
|
+
onToggle: () => void;
|
|
153
|
+
/** Whether this modifier is mandatory */
|
|
154
|
+
mandatory: boolean;
|
|
155
|
+
/** Modifier name */
|
|
156
|
+
modifierName: string;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Headless component for toggling free text modifier input
|
|
160
|
+
* Used for optional free text modifiers where a checkbox shows/hides the input
|
|
161
|
+
*
|
|
162
|
+
* @component
|
|
163
|
+
*/
|
|
164
|
+
export declare const ToggleFreeText: (props: ToggleFreeTextProps) => import("react").ReactNode;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { useService } from '@wix/services-manager-react';
|
|
3
|
+
import { ProductModifiersServiceDefinition } from '../services/product-modifiers-service';
|
|
4
|
+
import { ModifierRenderType, } from '@wix/auto_sdk_stores_products-v-3';
|
|
5
|
+
/**
|
|
6
|
+
* Custom hook to safely get the modifiers service
|
|
7
|
+
*/
|
|
8
|
+
function useModifiersService() {
|
|
9
|
+
try {
|
|
10
|
+
return useService(ProductModifiersServiceDefinition);
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Headless component for all product modifiers
|
|
18
|
+
*/
|
|
19
|
+
export const Modifiers = (props) => {
|
|
20
|
+
const modifiersService = useModifiersService();
|
|
21
|
+
if (!modifiersService) {
|
|
22
|
+
return props.children({
|
|
23
|
+
modifiers: [],
|
|
24
|
+
hasModifiers: false,
|
|
25
|
+
selectedModifiers: {},
|
|
26
|
+
areAllRequiredModifiersFilled: true,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
const modifiers = modifiersService.modifiers.get();
|
|
30
|
+
const hasModifiers = modifiersService.hasModifiers.get();
|
|
31
|
+
const selectedModifiers = modifiersService.selectedModifiers.get();
|
|
32
|
+
const areAllRequiredModifiersFilled = modifiersService.areAllRequiredModifiersFilled();
|
|
33
|
+
return props.children({
|
|
34
|
+
modifiers,
|
|
35
|
+
hasModifiers,
|
|
36
|
+
selectedModifiers,
|
|
37
|
+
areAllRequiredModifiersFilled,
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Headless component for a specific product modifier
|
|
42
|
+
*
|
|
43
|
+
* @component
|
|
44
|
+
*/
|
|
45
|
+
export const Modifier = (props) => {
|
|
46
|
+
const modifiersService = useModifiersService();
|
|
47
|
+
const { modifier } = props;
|
|
48
|
+
const name = modifier.name || '';
|
|
49
|
+
const type = modifier.modifierRenderType;
|
|
50
|
+
const mandatory = modifier.mandatory || false;
|
|
51
|
+
const choices = modifier.choicesSettings?.choices || [];
|
|
52
|
+
const hasChoices = choices.length > 0;
|
|
53
|
+
const isFreeText = type === ModifierRenderType.FREE_TEXT;
|
|
54
|
+
const freeTextSettings = modifier.freeTextSettings;
|
|
55
|
+
const maxChars = freeTextSettings?.maxLength;
|
|
56
|
+
const placeholder = freeTextSettings?.placeholder;
|
|
57
|
+
const selectedValue = modifiersService?.selectedModifiers.get()[name] || null;
|
|
58
|
+
return props.children({
|
|
59
|
+
name,
|
|
60
|
+
type,
|
|
61
|
+
mandatory,
|
|
62
|
+
choices,
|
|
63
|
+
selectedValue,
|
|
64
|
+
hasChoices,
|
|
65
|
+
isFreeText,
|
|
66
|
+
maxChars,
|
|
67
|
+
placeholder,
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Headless component for individual modifier choice selection
|
|
72
|
+
*
|
|
73
|
+
* @component
|
|
74
|
+
*/
|
|
75
|
+
export const Choice = (props) => {
|
|
76
|
+
const modifiersService = useModifiersService();
|
|
77
|
+
const { modifier, choice } = props;
|
|
78
|
+
const modifierName = modifier.name || '';
|
|
79
|
+
const renderType = modifier.modifierRenderType;
|
|
80
|
+
// For TEXT_CHOICES, use choice.key; for SWATCH_CHOICES, use choice.name
|
|
81
|
+
const choiceValue = renderType === ModifierRenderType.TEXT_CHOICES
|
|
82
|
+
? choice.key || choice.name || ''
|
|
83
|
+
: choice.name || '';
|
|
84
|
+
const value = choice.name || ''; // Display name is always choice.name
|
|
85
|
+
const description = choice.description;
|
|
86
|
+
const colorCode = choice.colorCode;
|
|
87
|
+
const selectedValue = modifiersService?.getModifierValue(modifierName);
|
|
88
|
+
const isSelected = selectedValue?.choiceValue === choiceValue;
|
|
89
|
+
const onSelect = () => {
|
|
90
|
+
modifiersService?.setModifierChoice(modifierName, choiceValue);
|
|
91
|
+
};
|
|
92
|
+
return props.children({
|
|
93
|
+
value,
|
|
94
|
+
description,
|
|
95
|
+
isSelected,
|
|
96
|
+
onSelect,
|
|
97
|
+
modifierName,
|
|
98
|
+
choiceValue,
|
|
99
|
+
colorCode,
|
|
100
|
+
});
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Headless component for free text modifier input
|
|
104
|
+
*
|
|
105
|
+
* @component
|
|
106
|
+
*/
|
|
107
|
+
export const FreeText = (props) => {
|
|
108
|
+
const modifiersService = useModifiersService();
|
|
109
|
+
const { modifier } = props;
|
|
110
|
+
const modifierName = modifier.name || '';
|
|
111
|
+
const mandatory = modifier.mandatory || false;
|
|
112
|
+
const freeTextSettings = modifier.freeTextSettings;
|
|
113
|
+
const maxChars = freeTextSettings?.maxLength;
|
|
114
|
+
const placeholder = freeTextSettings?.placeholder;
|
|
115
|
+
const selectedValue = modifiersService?.getModifierValue(modifierName);
|
|
116
|
+
const value = selectedValue?.freeTextValue || '';
|
|
117
|
+
const charCount = value.length;
|
|
118
|
+
const isOverLimit = maxChars ? charCount > maxChars : false;
|
|
119
|
+
const onChange = (newValue) => {
|
|
120
|
+
if (maxChars && newValue.length > maxChars)
|
|
121
|
+
return;
|
|
122
|
+
modifiersService?.setModifierFreeText(modifierName, newValue);
|
|
123
|
+
};
|
|
124
|
+
return props.children({
|
|
125
|
+
value,
|
|
126
|
+
onChange,
|
|
127
|
+
mandatory,
|
|
128
|
+
maxChars,
|
|
129
|
+
placeholder,
|
|
130
|
+
charCount,
|
|
131
|
+
isOverLimit,
|
|
132
|
+
modifierName,
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* Headless component for toggling free text modifier input
|
|
137
|
+
* Used for optional free text modifiers where a checkbox shows/hides the input
|
|
138
|
+
*
|
|
139
|
+
* @component
|
|
140
|
+
*/
|
|
141
|
+
export const ToggleFreeText = (props) => {
|
|
142
|
+
const modifiersService = useModifiersService();
|
|
143
|
+
const { modifier } = props;
|
|
144
|
+
const modifierName = modifier.name || '';
|
|
145
|
+
const mandatory = modifier.mandatory || false;
|
|
146
|
+
const [isTextInputShown, setIsTextInputShown] = useState(mandatory);
|
|
147
|
+
const onToggle = () => {
|
|
148
|
+
const newState = !isTextInputShown;
|
|
149
|
+
setIsTextInputShown(newState);
|
|
150
|
+
if (!newState) {
|
|
151
|
+
modifiersService?.clearModifier(modifierName);
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
return props.children({
|
|
155
|
+
isTextInputShown,
|
|
156
|
+
onToggle,
|
|
157
|
+
mandatory,
|
|
158
|
+
modifierName,
|
|
159
|
+
});
|
|
160
|
+
};
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { type ConnectedOption, type ConnectedOptionChoice, InventoryAvailabilityStatus } from '@wix/auto_sdk_stores_products-v-3';
|
|
2
|
+
/**
|
|
3
|
+
* Props for Options headless component
|
|
4
|
+
*/
|
|
5
|
+
export interface OptionsProps {
|
|
6
|
+
/** Render prop function that receives options data */
|
|
7
|
+
children: (props: OptionsRenderProps) => React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Render props for Options component
|
|
11
|
+
*/
|
|
12
|
+
export interface OptionsRenderProps {
|
|
13
|
+
/** Array of product options */
|
|
14
|
+
options: ConnectedOption[];
|
|
15
|
+
/** Whether product has options */
|
|
16
|
+
hasOptions: boolean;
|
|
17
|
+
/** Currently selected choices */
|
|
18
|
+
selectedChoices: Record<string, string>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Headless component for all product options
|
|
22
|
+
*
|
|
23
|
+
* @component
|
|
24
|
+
*/
|
|
25
|
+
export declare const Options: (props: OptionsProps) => import("react").ReactNode;
|
|
26
|
+
/**
|
|
27
|
+
* Props for Option headless component
|
|
28
|
+
*/
|
|
29
|
+
export interface OptionProps {
|
|
30
|
+
/** Product option data */
|
|
31
|
+
option: ConnectedOption;
|
|
32
|
+
/** Render prop function that receives option data */
|
|
33
|
+
children: (props: OptionRenderProps) => React.ReactNode;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Render props for Option component
|
|
37
|
+
*/
|
|
38
|
+
export interface OptionRenderProps {
|
|
39
|
+
/** Option name */
|
|
40
|
+
name: string;
|
|
41
|
+
/** Option type */
|
|
42
|
+
type: any;
|
|
43
|
+
/** Array of choices for this option */
|
|
44
|
+
choices: ConnectedOptionChoice[];
|
|
45
|
+
/** Currently selected value for this option */
|
|
46
|
+
selectedValue: string | null;
|
|
47
|
+
/** Whether this option has choices */
|
|
48
|
+
hasChoices: boolean;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Headless component for choices within a specific product option
|
|
52
|
+
*
|
|
53
|
+
* @component
|
|
54
|
+
*/
|
|
55
|
+
export declare const Option: (props: OptionProps) => import("react").ReactNode;
|
|
56
|
+
/**
|
|
57
|
+
* Props for Choice headless component
|
|
58
|
+
*/
|
|
59
|
+
export interface ChoiceProps {
|
|
60
|
+
/** Product option data */
|
|
61
|
+
option: ConnectedOption;
|
|
62
|
+
/** Choice data */
|
|
63
|
+
choice: ConnectedOptionChoice;
|
|
64
|
+
/** Render prop function that receives choice data */
|
|
65
|
+
children: (props: ChoiceRenderProps) => React.ReactNode;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Render props for Choice component
|
|
69
|
+
*/
|
|
70
|
+
export interface ChoiceRenderProps {
|
|
71
|
+
/** Choice value to display */
|
|
72
|
+
value: string;
|
|
73
|
+
/** Choice description (for color options) */
|
|
74
|
+
description: string | undefined;
|
|
75
|
+
/** Whether this choice is currently selected */
|
|
76
|
+
isSelected: boolean;
|
|
77
|
+
/** Whether this choice is visible */
|
|
78
|
+
isVisible: boolean;
|
|
79
|
+
/** Whether this choice is in stock */
|
|
80
|
+
isInStock: boolean;
|
|
81
|
+
/** Whether this choice is available for pre-order */
|
|
82
|
+
isPreOrderEnabled: boolean;
|
|
83
|
+
/** Function to select this choice */
|
|
84
|
+
onSelect: () => void;
|
|
85
|
+
/** Option name */
|
|
86
|
+
optionName: string;
|
|
87
|
+
/** Choice value */
|
|
88
|
+
choiceValue: string;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Headless component for individual choice selection
|
|
92
|
+
*
|
|
93
|
+
* @component
|
|
94
|
+
*/
|
|
95
|
+
export declare const Choice: (props: ChoiceProps) => import("react").ReactNode;
|
|
96
|
+
/**
|
|
97
|
+
* Props for Stock headless component
|
|
98
|
+
*/
|
|
99
|
+
export interface StockProps {
|
|
100
|
+
/** Render prop function that receives stock data */
|
|
101
|
+
children: (props: StockRenderProps) => React.ReactNode;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Render props for Stock component
|
|
105
|
+
*/
|
|
106
|
+
export interface StockRenderProps {
|
|
107
|
+
/** Whether product is in stock */
|
|
108
|
+
inStock: boolean;
|
|
109
|
+
/** Whether pre-order is enabled */
|
|
110
|
+
isPreOrderEnabled: boolean;
|
|
111
|
+
/** Raw inventory availability status */
|
|
112
|
+
availabilityStatus: InventoryAvailabilityStatus | string;
|
|
113
|
+
/** Whether stock tracking is enabled */
|
|
114
|
+
trackInventory: boolean;
|
|
115
|
+
/** Current variant id */
|
|
116
|
+
currentVariantId: string | null;
|
|
117
|
+
/** Available quantity */
|
|
118
|
+
availableQuantity: number | null;
|
|
119
|
+
/** Currently selected quantity */
|
|
120
|
+
selectedQuantity: number;
|
|
121
|
+
/** Function to increment quantity */
|
|
122
|
+
incrementQuantity: () => void;
|
|
123
|
+
/** Function to decrement quantity */
|
|
124
|
+
decrementQuantity: () => void;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Headless component for product stock status
|
|
128
|
+
*
|
|
129
|
+
* @component
|
|
130
|
+
*/
|
|
131
|
+
export declare const Stock: (props: StockProps) => import("react").ReactNode;
|
|
132
|
+
/**
|
|
133
|
+
* Props for Reset headless component
|
|
134
|
+
*/
|
|
135
|
+
export interface ResetProps {
|
|
136
|
+
/** Render prop function that receives reset data */
|
|
137
|
+
children: (props: ResetRenderProps) => React.ReactNode;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Render props for Reset component
|
|
141
|
+
*/
|
|
142
|
+
export interface ResetRenderProps {
|
|
143
|
+
/** Function to reset all selections */
|
|
144
|
+
onReset: () => void;
|
|
145
|
+
/** Whether the reset button should be rendered */
|
|
146
|
+
hasSelections: boolean;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Headless component for resetting variant selections
|
|
150
|
+
*
|
|
151
|
+
* @component
|
|
152
|
+
*/
|
|
153
|
+
export declare const Reset: (props: ResetProps) => import("react").ReactNode;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { useService } from '@wix/services-manager-react';
|
|
2
|
+
import { SelectedVariantServiceDefinition } from '../services/selected-variant-service';
|
|
3
|
+
import { InventoryAvailabilityStatus, } from '@wix/auto_sdk_stores_products-v-3';
|
|
4
|
+
/**
|
|
5
|
+
* Headless component for all product options
|
|
6
|
+
*
|
|
7
|
+
* @component
|
|
8
|
+
*/
|
|
9
|
+
export const Options = (props) => {
|
|
10
|
+
const variantService = useService(SelectedVariantServiceDefinition);
|
|
11
|
+
const selectedChoices = variantService.selectedChoices.get();
|
|
12
|
+
const options = variantService.productOptions.get();
|
|
13
|
+
return props.children({
|
|
14
|
+
options,
|
|
15
|
+
hasOptions: options.length > 0,
|
|
16
|
+
selectedChoices,
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Headless component for choices within a specific product option
|
|
21
|
+
*
|
|
22
|
+
* @component
|
|
23
|
+
*/
|
|
24
|
+
export const Option = (props) => {
|
|
25
|
+
const variantService = useService(SelectedVariantServiceDefinition);
|
|
26
|
+
const selectedChoices = variantService.selectedChoices.get();
|
|
27
|
+
const { option } = props;
|
|
28
|
+
const name = option.name || '';
|
|
29
|
+
const choices = option.choicesSettings?.choices || [];
|
|
30
|
+
const selectedValue = selectedChoices[name] || null;
|
|
31
|
+
return props.children({
|
|
32
|
+
name,
|
|
33
|
+
type: option.optionRenderType,
|
|
34
|
+
choices,
|
|
35
|
+
selectedValue,
|
|
36
|
+
hasChoices: choices.length > 0,
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Headless component for individual choice selection
|
|
41
|
+
*
|
|
42
|
+
* @component
|
|
43
|
+
*/
|
|
44
|
+
export const Choice = (props) => {
|
|
45
|
+
const variantService = useService(SelectedVariantServiceDefinition);
|
|
46
|
+
const selectedChoices = variantService.selectedChoices.get();
|
|
47
|
+
const { option, choice } = props;
|
|
48
|
+
const optionName = option.name || '';
|
|
49
|
+
const choiceValue = choice.name || '';
|
|
50
|
+
const isSelected = selectedChoices[optionName] === choiceValue;
|
|
51
|
+
// Check if this choice is available based on current selections
|
|
52
|
+
const isVisible = variantService.isChoiceAvailable(optionName, choiceValue);
|
|
53
|
+
// Check if this choice results in an in-stock variant
|
|
54
|
+
const isInStock = variantService.isChoiceInStock(optionName, choiceValue);
|
|
55
|
+
// Check if this choice is available for pre-order
|
|
56
|
+
const isPreOrderEnabled = variantService.isChoicePreOrderEnabled(optionName, choiceValue);
|
|
57
|
+
const value = choiceValue;
|
|
58
|
+
const onSelect = () => {
|
|
59
|
+
const newChoices = {
|
|
60
|
+
...selectedChoices,
|
|
61
|
+
[optionName]: choiceValue,
|
|
62
|
+
};
|
|
63
|
+
variantService.setSelectedChoices(newChoices);
|
|
64
|
+
};
|
|
65
|
+
return props.children({
|
|
66
|
+
value,
|
|
67
|
+
description: undefined, // v3 choices don't have separate description field
|
|
68
|
+
isSelected,
|
|
69
|
+
isVisible,
|
|
70
|
+
isInStock,
|
|
71
|
+
isPreOrderEnabled,
|
|
72
|
+
onSelect,
|
|
73
|
+
optionName,
|
|
74
|
+
choiceValue,
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Headless component for product stock status
|
|
79
|
+
*
|
|
80
|
+
* @component
|
|
81
|
+
*/
|
|
82
|
+
export const Stock = (props) => {
|
|
83
|
+
const variantService = useService(SelectedVariantServiceDefinition);
|
|
84
|
+
const inStock = variantService.isInStock.get();
|
|
85
|
+
const isPreOrderEnabled = variantService.isPreOrderEnabled.get();
|
|
86
|
+
const trackInventory = variantService.trackQuantity.get();
|
|
87
|
+
const currentVariantId = variantService.selectedVariantId.get();
|
|
88
|
+
const availableQuantity = variantService.quantityAvailable.get();
|
|
89
|
+
const selectedQuantity = variantService.selectedQuantity.get();
|
|
90
|
+
// const currentVariant = variantService.currentVariant.get();
|
|
91
|
+
// const allVariantsAreOutOfStock = variantService.IsAllVariantsAreOutOfStock();
|
|
92
|
+
// Return raw availability status - UI components will handle display conversion
|
|
93
|
+
const availabilityStatus = inStock
|
|
94
|
+
? InventoryAvailabilityStatus.IN_STOCK
|
|
95
|
+
: InventoryAvailabilityStatus.OUT_OF_STOCK;
|
|
96
|
+
const incrementQuantity = () => {
|
|
97
|
+
variantService.incrementQuantity();
|
|
98
|
+
};
|
|
99
|
+
const decrementQuantity = () => {
|
|
100
|
+
variantService.decrementQuantity();
|
|
101
|
+
};
|
|
102
|
+
return props.children({
|
|
103
|
+
inStock,
|
|
104
|
+
availableQuantity,
|
|
105
|
+
isPreOrderEnabled,
|
|
106
|
+
currentVariantId,
|
|
107
|
+
availabilityStatus,
|
|
108
|
+
trackInventory,
|
|
109
|
+
selectedQuantity,
|
|
110
|
+
incrementQuantity,
|
|
111
|
+
decrementQuantity,
|
|
112
|
+
});
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Headless component for resetting variant selections
|
|
116
|
+
*
|
|
117
|
+
* @component
|
|
118
|
+
*/
|
|
119
|
+
export const Reset = (props) => {
|
|
120
|
+
const variantService = useService(SelectedVariantServiceDefinition);
|
|
121
|
+
const selectedChoices = variantService.selectedChoices.get();
|
|
122
|
+
const hasSelections = Object.keys(selectedChoices).length > 0;
|
|
123
|
+
const onReset = () => {
|
|
124
|
+
variantService.resetSelections();
|
|
125
|
+
};
|
|
126
|
+
return props.children({
|
|
127
|
+
onReset,
|
|
128
|
+
hasSelections,
|
|
129
|
+
});
|
|
130
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type V3Product } from '@wix/auto_sdk_stores_products-v-3';
|
|
3
|
+
/**
|
|
4
|
+
* Props for List headless component
|
|
5
|
+
*/
|
|
6
|
+
export interface ListProps {
|
|
7
|
+
/** Render prop function that receives list data */
|
|
8
|
+
children: (props: ListRenderProps) => React.ReactNode;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Render props for List component
|
|
12
|
+
*/
|
|
13
|
+
export interface ListRenderProps {
|
|
14
|
+
/** Array of related products */
|
|
15
|
+
products: V3Product[];
|
|
16
|
+
/** Whether products are loading */
|
|
17
|
+
isLoading: boolean;
|
|
18
|
+
/** Error message if any */
|
|
19
|
+
error: string | null;
|
|
20
|
+
/** Whether there are products available */
|
|
21
|
+
hasProducts: boolean;
|
|
22
|
+
/** Function to refresh products */
|
|
23
|
+
refresh: () => Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Headless component for displaying related products list
|
|
27
|
+
*
|
|
28
|
+
* @component
|
|
29
|
+
*/
|
|
30
|
+
export declare const List: (props: ListProps) => React.ReactNode;
|
|
31
|
+
/**
|
|
32
|
+
* Props for Item headless component
|
|
33
|
+
*/
|
|
34
|
+
export interface ItemProps {
|
|
35
|
+
/** Product data */
|
|
36
|
+
product: V3Product;
|
|
37
|
+
/** Render prop function that receives item data */
|
|
38
|
+
children: (props: ItemRenderProps) => React.ReactNode;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Render props for Item component
|
|
42
|
+
*/
|
|
43
|
+
export interface ItemRenderProps {
|
|
44
|
+
/** Product title */
|
|
45
|
+
title: string;
|
|
46
|
+
/** Product image URL */
|
|
47
|
+
image: string | null;
|
|
48
|
+
/** Formatted price */
|
|
49
|
+
price: string;
|
|
50
|
+
/** Whether product is available */
|
|
51
|
+
available: boolean;
|
|
52
|
+
/** Product page URL */
|
|
53
|
+
href: string;
|
|
54
|
+
/** Product description */
|
|
55
|
+
description: string;
|
|
56
|
+
/** Function to add product to cart quickly */
|
|
57
|
+
onQuickAdd: () => void;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Headless component for individual related product item
|
|
61
|
+
*
|
|
62
|
+
* @component
|
|
63
|
+
*/
|
|
64
|
+
export declare const Item: (props: ItemProps) => React.ReactNode;
|