@wix/headless-stores 0.0.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/astro/actions/package.json +4 -0
- package/cjs/dist/astro/actions/custom-checkout.d.ts +50 -0
- package/cjs/dist/astro/actions/custom-checkout.js +53 -0
- package/cjs/dist/astro/actions/index.d.ts +1 -0
- package/cjs/dist/astro/actions/index.js +1 -0
- package/cjs/dist/data-component-tags.d.ts +8 -0
- package/cjs/dist/data-component-tags.js +9 -0
- package/cjs/dist/enums/index.d.ts +2 -0
- package/cjs/dist/enums/index.js +2 -0
- package/cjs/dist/enums/social-platform-enums.d.ts +25 -0
- package/cjs/dist/enums/social-platform-enums.js +27 -0
- package/cjs/dist/enums/sort-enums.d.ts +17 -0
- package/cjs/dist/enums/sort-enums.js +18 -0
- package/cjs/dist/react/Category.d.ts +242 -0
- package/cjs/dist/react/Category.js +235 -0
- package/cjs/dist/react/CategoryList.d.ts +107 -0
- package/cjs/dist/react/CategoryList.js +91 -0
- package/cjs/dist/react/Choice.d.ts +211 -0
- package/cjs/dist/react/Choice.js +213 -0
- package/cjs/dist/react/Option.d.ts +242 -0
- package/cjs/dist/react/Option.js +346 -0
- package/cjs/dist/react/Product.d.ts +1065 -0
- package/cjs/dist/react/Product.js +1157 -0
- package/cjs/dist/react/ProductList.d.ts +400 -0
- package/cjs/dist/react/ProductList.js +368 -0
- package/cjs/dist/react/core/CategoryList.d.ts +194 -0
- package/cjs/dist/react/core/CategoryList.js +180 -0
- package/cjs/dist/react/core/Product.d.ts +225 -0
- package/cjs/dist/react/core/Product.js +190 -0
- package/cjs/dist/react/core/ProductList.d.ts +235 -0
- package/cjs/dist/react/core/ProductList.js +217 -0
- package/cjs/dist/react/core/ProductListFilters.d.ts +138 -0
- package/cjs/dist/react/core/ProductListFilters.js +242 -0
- package/cjs/dist/react/core/ProductListPagination.d.ts +49 -0
- package/cjs/dist/react/core/ProductListPagination.js +41 -0
- package/cjs/dist/react/core/ProductListSort.d.ts +19 -0
- package/cjs/dist/react/core/ProductListSort.js +52 -0
- package/cjs/dist/react/core/ProductModifiers.d.ts +416 -0
- package/cjs/dist/react/core/ProductModifiers.js +413 -0
- package/cjs/dist/react/core/ProductVariantSelector.d.ts +313 -0
- package/cjs/dist/react/core/ProductVariantSelector.js +291 -0
- package/cjs/dist/react/core/SelectedVariant.d.ts +230 -0
- package/cjs/dist/react/core/SelectedVariant.js +269 -0
- package/cjs/dist/react/index.d.ts +6 -0
- package/cjs/dist/react/index.js +6 -0
- package/cjs/dist/react/types.d.ts +8 -0
- package/cjs/dist/react/types.js +9 -0
- package/cjs/dist/server-actions/custom-checkout-action.d.ts +49 -0
- package/cjs/dist/server-actions/custom-checkout-action.js +64 -0
- package/cjs/dist/server-actions/index.d.ts +1 -0
- package/cjs/dist/server-actions/index.js +1 -0
- package/cjs/dist/services/buy-now-service.d.ts +346 -0
- package/cjs/dist/services/buy-now-service.js +197 -0
- package/cjs/dist/services/categories-list-service.d.ts +164 -0
- package/cjs/dist/services/categories-list-service.js +148 -0
- package/cjs/dist/services/index.d.ts +5 -0
- package/cjs/dist/services/index.js +5 -0
- package/cjs/dist/services/pay-now-service.d.ts +214 -0
- package/cjs/dist/services/pay-now-service.js +156 -0
- package/cjs/dist/services/product-modifiers-service.d.ts +34 -0
- package/cjs/dist/services/product-modifiers-service.js +107 -0
- package/cjs/dist/services/product-service.d.ts +177 -0
- package/cjs/dist/services/product-service.js +190 -0
- package/cjs/dist/services/products-list-search-service.d.ts +1 -0
- package/cjs/dist/services/products-list-search-service.js +1 -0
- package/cjs/dist/services/products-list-service.d.ts +429 -0
- package/cjs/dist/services/products-list-service.js +893 -0
- package/cjs/dist/services/selected-variant-service.d.ts +66 -0
- package/cjs/dist/services/selected-variant-service.js +527 -0
- package/cjs/dist/utils/index.d.ts +1 -0
- package/cjs/dist/utils/index.js +30 -0
- package/cjs/dist/utils/url-params.d.ts +73 -0
- package/cjs/dist/utils/url-params.js +114 -0
- package/cjs/package.json +3 -0
- package/dist/astro/actions/custom-checkout.d.ts +50 -0
- package/dist/astro/actions/custom-checkout.js +53 -0
- package/dist/astro/actions/index.d.ts +1 -0
- package/dist/astro/actions/index.js +1 -0
- package/dist/data-component-tags.d.ts +8 -0
- package/dist/data-component-tags.js +9 -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/Category.d.ts +242 -0
- package/dist/react/Category.js +235 -0
- package/dist/react/CategoryList.d.ts +107 -0
- package/dist/react/CategoryList.js +91 -0
- package/dist/react/Choice.d.ts +211 -0
- package/dist/react/Choice.js +213 -0
- package/dist/react/Option.d.ts +242 -0
- package/dist/react/Option.js +346 -0
- package/dist/react/Product.d.ts +1065 -0
- package/dist/react/Product.js +1157 -0
- package/dist/react/ProductList.d.ts +400 -0
- package/dist/react/ProductList.js +368 -0
- package/dist/react/core/CategoryList.d.ts +194 -0
- package/dist/react/core/CategoryList.js +180 -0
- package/dist/react/core/Product.d.ts +225 -0
- package/dist/react/core/Product.js +190 -0
- package/dist/react/core/ProductList.d.ts +235 -0
- package/dist/react/core/ProductList.js +217 -0
- package/dist/react/core/ProductListFilters.d.ts +138 -0
- package/dist/react/core/ProductListFilters.js +242 -0
- package/dist/react/core/ProductListPagination.d.ts +49 -0
- package/dist/react/core/ProductListPagination.js +41 -0
- package/dist/react/core/ProductListSort.d.ts +19 -0
- package/dist/react/core/ProductListSort.js +52 -0
- package/dist/react/core/ProductModifiers.d.ts +416 -0
- package/dist/react/core/ProductModifiers.js +413 -0
- package/dist/react/core/ProductVariantSelector.d.ts +313 -0
- package/dist/react/core/ProductVariantSelector.js +291 -0
- package/dist/react/core/SelectedVariant.d.ts +230 -0
- package/dist/react/core/SelectedVariant.js +269 -0
- package/dist/react/index.d.ts +6 -0
- package/dist/react/index.js +6 -0
- package/dist/react/types.d.ts +8 -0
- package/dist/react/types.js +9 -0
- package/dist/server-actions/custom-checkout-action.d.ts +49 -0
- package/dist/server-actions/custom-checkout-action.js +64 -0
- package/dist/server-actions/index.d.ts +1 -0
- package/dist/server-actions/index.js +1 -0
- package/dist/services/buy-now-service.d.ts +346 -0
- package/dist/services/buy-now-service.js +197 -0
- package/dist/services/categories-list-service.d.ts +164 -0
- package/dist/services/categories-list-service.js +148 -0
- package/dist/services/index.d.ts +5 -0
- package/dist/services/index.js +5 -0
- package/dist/services/pay-now-service.d.ts +214 -0
- package/dist/services/pay-now-service.js +156 -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 +177 -0
- package/dist/services/product-service.js +190 -0
- package/dist/services/products-list-search-service.d.ts +0 -0
- package/dist/services/products-list-search-service.js +1 -0
- package/dist/services/products-list-service.d.ts +429 -0
- package/dist/services/products-list-service.js +893 -0
- package/dist/services/selected-variant-service.d.ts +66 -0
- package/dist/services/selected-variant-service.js +527 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +30 -0
- package/dist/utils/url-params.d.ts +73 -0
- package/dist/utils/url-params.js +114 -0
- package/package.json +89 -0
- package/react/package.json +4 -0
- package/server-actions/package.json +4 -0
- package/services/package.json +4 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { SelectedVariantServiceConfig } from '../../services/selected-variant-service.js';
|
|
2
|
+
import { type LineItem } from '@wix/headless-ecom/services';
|
|
3
|
+
export interface RootProps {
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
selectedVariantServiceConfig?: SelectedVariantServiceConfig;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Root component that provides the SelectedVariant service context to its children.
|
|
9
|
+
* This component sets up the necessary services for rendering and managing selected variant data.
|
|
10
|
+
*
|
|
11
|
+
* @order 1
|
|
12
|
+
* @component
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* import { SelectedVariant } from '@wix/stores/components';
|
|
16
|
+
*
|
|
17
|
+
* function ProductVariantDisplay() {
|
|
18
|
+
* return (
|
|
19
|
+
* <SelectedVariant.Root selectedVariantServiceConfig={{ fetchInventoryData: true }}>
|
|
20
|
+
* <div>
|
|
21
|
+
* <SelectedVariant.Price>
|
|
22
|
+
* {({ price, compareAtPrice, currency }) => (
|
|
23
|
+
* <div className="price-display">
|
|
24
|
+
* <span className="current-price">{price}</span>
|
|
25
|
+
* {compareAtPrice && (
|
|
26
|
+
* <span className="compare-price">
|
|
27
|
+
* <s>{compareAtPrice}</s>
|
|
28
|
+
* </span>
|
|
29
|
+
* )}
|
|
30
|
+
* <span className="currency">{currency}</span>
|
|
31
|
+
* </div>
|
|
32
|
+
* )}
|
|
33
|
+
* </SelectedVariant.Price>
|
|
34
|
+
* </div>
|
|
35
|
+
* </SelectedVariant.Root>
|
|
36
|
+
* );
|
|
37
|
+
* }
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare function Root(props: RootProps): React.ReactNode;
|
|
41
|
+
/**
|
|
42
|
+
* Props for ProductDetails headless component
|
|
43
|
+
*/
|
|
44
|
+
export interface ProductDetailsProps {
|
|
45
|
+
/** Render prop function that receives product details data */
|
|
46
|
+
children: (props: ProductDetailsRenderProps) => React.ReactNode;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Render props for ProductDetails component
|
|
50
|
+
*/
|
|
51
|
+
export interface ProductDetailsRenderProps {
|
|
52
|
+
/** Product SKU */
|
|
53
|
+
sku: string | null;
|
|
54
|
+
/** Product weight */
|
|
55
|
+
weight: string | null;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Headless component for selected variant details display
|
|
59
|
+
*
|
|
60
|
+
* @component
|
|
61
|
+
* @example
|
|
62
|
+
* ```tsx
|
|
63
|
+
* import { SelectedVariant } from '@wix/stores/components';
|
|
64
|
+
*
|
|
65
|
+
* function VariantDetails() {
|
|
66
|
+
* return (
|
|
67
|
+
* <SelectedVariant.Details>
|
|
68
|
+
* {({ sku, weight }) => (
|
|
69
|
+
* <div>
|
|
70
|
+
* {sku && <div>SKU: {sku}</div>}
|
|
71
|
+
* {weight && <div>Weight: {weight}</div>}
|
|
72
|
+
* </div>
|
|
73
|
+
* )}
|
|
74
|
+
* </SelectedVariant.Details>
|
|
75
|
+
* );
|
|
76
|
+
* }
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export declare function Details(props: ProductDetailsProps): import("react").ReactNode;
|
|
80
|
+
/**
|
|
81
|
+
* Props for Price headless component
|
|
82
|
+
*/
|
|
83
|
+
export interface PriceProps {
|
|
84
|
+
/** Render prop function that receives price data */
|
|
85
|
+
children: (props: PriceRenderProps) => React.ReactNode;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Render props for Price component
|
|
89
|
+
*/
|
|
90
|
+
export interface PriceRenderProps {
|
|
91
|
+
/** Current price (formatted) */
|
|
92
|
+
price: string;
|
|
93
|
+
/** Compare at price (formatted) - null if no compare price */
|
|
94
|
+
compareAtPrice: string | null;
|
|
95
|
+
/** Currency code */
|
|
96
|
+
currency: string;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Headless component for product price display
|
|
100
|
+
*
|
|
101
|
+
* @component
|
|
102
|
+
* @example
|
|
103
|
+
* ```tsx
|
|
104
|
+
* import { SelectedVariant } from '@wix/stores/components';
|
|
105
|
+
*
|
|
106
|
+
* function ProductPrice() {
|
|
107
|
+
* return (
|
|
108
|
+
* <SelectedVariant.Price>
|
|
109
|
+
* {({ price, compareAtPrice, currency }) => (
|
|
110
|
+
* <div className="price-display">
|
|
111
|
+
* <span className="current-price">{price}</span>
|
|
112
|
+
* {compareAtPrice && (
|
|
113
|
+
* <span className="compare-price">
|
|
114
|
+
* <s>{compareAtPrice}</s>
|
|
115
|
+
* </span>
|
|
116
|
+
* )}
|
|
117
|
+
* <span className="currency">{currency}</span>
|
|
118
|
+
* </div>
|
|
119
|
+
* )}
|
|
120
|
+
* </SelectedVariant.Price>
|
|
121
|
+
* );
|
|
122
|
+
* }
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
export declare function Price(props: PriceProps): import("react").ReactNode;
|
|
126
|
+
/**
|
|
127
|
+
* Props for SKU headless component
|
|
128
|
+
*/
|
|
129
|
+
export interface SKUProps {
|
|
130
|
+
/** Render prop function that receives SKU data */
|
|
131
|
+
children: (props: SKURenderProps) => React.ReactNode;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Render props for SKU component
|
|
135
|
+
*/
|
|
136
|
+
export interface SKURenderProps {
|
|
137
|
+
/** Product SKU */
|
|
138
|
+
sku: string | null;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Headless component for product SKU display
|
|
142
|
+
*
|
|
143
|
+
* @component
|
|
144
|
+
* @example
|
|
145
|
+
* ```tsx
|
|
146
|
+
* import { SelectedVariant } from '@wix/stores/components';
|
|
147
|
+
*
|
|
148
|
+
* function ProductSKU() {
|
|
149
|
+
* return (
|
|
150
|
+
* <SelectedVariant.SKU>
|
|
151
|
+
* {({ sku }) => (
|
|
152
|
+
* <div>
|
|
153
|
+
* {sku && (
|
|
154
|
+
* <div className="product-sku">
|
|
155
|
+
* <strong>SKU:</strong> {sku}
|
|
156
|
+
* </div>
|
|
157
|
+
* )}
|
|
158
|
+
* </div>
|
|
159
|
+
* )}
|
|
160
|
+
* </SelectedVariant.SKU>
|
|
161
|
+
* );
|
|
162
|
+
* }
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
export declare function SKU(props: SKUProps): import("react").ReactNode;
|
|
166
|
+
/**
|
|
167
|
+
* Props for Actions headless component
|
|
168
|
+
*/
|
|
169
|
+
export interface ActionsProps {
|
|
170
|
+
/** Render prop function that receives actions data */
|
|
171
|
+
children: (props: ActionsRenderProps) => React.ReactNode;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Render props for Actions component
|
|
175
|
+
*/
|
|
176
|
+
export interface ActionsRenderProps {
|
|
177
|
+
/** Function to add product to cart */
|
|
178
|
+
addToCart: () => Promise<void>;
|
|
179
|
+
/** Function to buy now (clear cart, add product, proceed to checkout) */
|
|
180
|
+
buyNow: () => Promise<void>;
|
|
181
|
+
/** Line items */
|
|
182
|
+
lineItems: LineItem[];
|
|
183
|
+
/** Whether add to cart is available */
|
|
184
|
+
canAddToCart: boolean;
|
|
185
|
+
/** Whether add to cart is currently loading */
|
|
186
|
+
isLoading: boolean;
|
|
187
|
+
/** Whether variant is in stock */
|
|
188
|
+
inStock: boolean;
|
|
189
|
+
/** Whether pre-order is enabled */
|
|
190
|
+
isPreOrderEnabled: boolean;
|
|
191
|
+
/** Pre-order message */
|
|
192
|
+
preOrderMessage: string | null;
|
|
193
|
+
/** Error message if any */
|
|
194
|
+
error: string | null;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Headless component for product actions (add to cart, buy now)
|
|
198
|
+
*
|
|
199
|
+
* @component
|
|
200
|
+
* @example
|
|
201
|
+
* ```tsx
|
|
202
|
+
* import { SelectedVariant } from '@wix/stores/components';
|
|
203
|
+
*
|
|
204
|
+
* function AddToCartButton() {
|
|
205
|
+
* return (
|
|
206
|
+
* <SelectedVariant.Actions>
|
|
207
|
+
* {({ addToCart, buyNow, canAddToCart, isLoading, inStock, error }) => (
|
|
208
|
+
* <div>
|
|
209
|
+
* {error && <div className="error">{error}</div>}
|
|
210
|
+
* {!inStock && <div>Out of stock</div>}
|
|
211
|
+
* <button
|
|
212
|
+
* onClick={addToCart}
|
|
213
|
+
* disabled={!canAddToCart || isLoading}
|
|
214
|
+
* >
|
|
215
|
+
* {isLoading ? 'Adding...' : 'Add to Cart'}
|
|
216
|
+
* </button>
|
|
217
|
+
* <button
|
|
218
|
+
* onClick={buyNow}
|
|
219
|
+
* disabled={!canAddToCart || isLoading}
|
|
220
|
+
* >
|
|
221
|
+
* Buy Now
|
|
222
|
+
* </button>
|
|
223
|
+
* </div>
|
|
224
|
+
* )}
|
|
225
|
+
* </SelectedVariant.Actions>
|
|
226
|
+
* );
|
|
227
|
+
* }
|
|
228
|
+
* ```
|
|
229
|
+
*/
|
|
230
|
+
export declare function Actions(props: ActionsProps): string | number | boolean | Iterable<import("react").ReactNode> | import("react/jsx-runtime").JSX.Element | null | undefined;
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useService, WixServices } from '@wix/services-manager-react';
|
|
3
|
+
import { SelectedVariantServiceDefinition, SelectedVariantService, } from '../../services/selected-variant-service.js';
|
|
4
|
+
import { ProductModifiersServiceDefinition } from '../../services/product-modifiers-service.js';
|
|
5
|
+
import { createServicesMap } from '@wix/services-manager';
|
|
6
|
+
import { Commerce } from '@wix/headless-ecom/react';
|
|
7
|
+
import { CheckoutServiceDefinition, CurrentCartServiceDefinition, } from '@wix/headless-ecom/services';
|
|
8
|
+
/**
|
|
9
|
+
* Root component that provides the SelectedVariant service context to its children.
|
|
10
|
+
* This component sets up the necessary services for rendering and managing selected variant data.
|
|
11
|
+
*
|
|
12
|
+
* @order 1
|
|
13
|
+
* @component
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* import { SelectedVariant } from '@wix/stores/components';
|
|
17
|
+
*
|
|
18
|
+
* function ProductVariantDisplay() {
|
|
19
|
+
* return (
|
|
20
|
+
* <SelectedVariant.Root selectedVariantServiceConfig={{ fetchInventoryData: true }}>
|
|
21
|
+
* <div>
|
|
22
|
+
* <SelectedVariant.Price>
|
|
23
|
+
* {({ price, compareAtPrice, currency }) => (
|
|
24
|
+
* <div className="price-display">
|
|
25
|
+
* <span className="current-price">{price}</span>
|
|
26
|
+
* {compareAtPrice && (
|
|
27
|
+
* <span className="compare-price">
|
|
28
|
+
* <s>{compareAtPrice}</s>
|
|
29
|
+
* </span>
|
|
30
|
+
* )}
|
|
31
|
+
* <span className="currency">{currency}</span>
|
|
32
|
+
* </div>
|
|
33
|
+
* )}
|
|
34
|
+
* </SelectedVariant.Price>
|
|
35
|
+
* </div>
|
|
36
|
+
* </SelectedVariant.Root>
|
|
37
|
+
* );
|
|
38
|
+
* }
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export function Root(props) {
|
|
42
|
+
return (_jsx(WixServices, { servicesMap: createServicesMap().addService(SelectedVariantServiceDefinition, SelectedVariantService, props.selectedVariantServiceConfig), children: props.children }));
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Headless component for selected variant details display
|
|
46
|
+
*
|
|
47
|
+
* @component
|
|
48
|
+
* @example
|
|
49
|
+
* ```tsx
|
|
50
|
+
* import { SelectedVariant } from '@wix/stores/components';
|
|
51
|
+
*
|
|
52
|
+
* function VariantDetails() {
|
|
53
|
+
* return (
|
|
54
|
+
* <SelectedVariant.Details>
|
|
55
|
+
* {({ sku, weight }) => (
|
|
56
|
+
* <div>
|
|
57
|
+
* {sku && <div>SKU: {sku}</div>}
|
|
58
|
+
* {weight && <div>Weight: {weight}</div>}
|
|
59
|
+
* </div>
|
|
60
|
+
* )}
|
|
61
|
+
* </SelectedVariant.Details>
|
|
62
|
+
* );
|
|
63
|
+
* }
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export function Details(props) {
|
|
67
|
+
const selectedVariantService = useService(SelectedVariantServiceDefinition);
|
|
68
|
+
const selectedVariant = selectedVariantService.currentVariant?.get();
|
|
69
|
+
let sku = selectedVariant?.sku || null;
|
|
70
|
+
let weight = selectedVariant?.physicalProperties?.weight?.toString() || null;
|
|
71
|
+
return props.children({
|
|
72
|
+
sku,
|
|
73
|
+
weight,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Headless component for product price display
|
|
78
|
+
*
|
|
79
|
+
* @component
|
|
80
|
+
* @example
|
|
81
|
+
* ```tsx
|
|
82
|
+
* import { SelectedVariant } from '@wix/stores/components';
|
|
83
|
+
*
|
|
84
|
+
* function ProductPrice() {
|
|
85
|
+
* return (
|
|
86
|
+
* <SelectedVariant.Price>
|
|
87
|
+
* {({ price, compareAtPrice, currency }) => (
|
|
88
|
+
* <div className="price-display">
|
|
89
|
+
* <span className="current-price">{price}</span>
|
|
90
|
+
* {compareAtPrice && (
|
|
91
|
+
* <span className="compare-price">
|
|
92
|
+
* <s>{compareAtPrice}</s>
|
|
93
|
+
* </span>
|
|
94
|
+
* )}
|
|
95
|
+
* <span className="currency">{currency}</span>
|
|
96
|
+
* </div>
|
|
97
|
+
* )}
|
|
98
|
+
* </SelectedVariant.Price>
|
|
99
|
+
* );
|
|
100
|
+
* }
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
export function Price(props) {
|
|
104
|
+
const variantService = useService(SelectedVariantServiceDefinition);
|
|
105
|
+
const price = variantService.currentPrice.get();
|
|
106
|
+
const compareAtPrice = variantService.currentCompareAtPrice.get();
|
|
107
|
+
const currency = variantService.currency.get();
|
|
108
|
+
return props.children({
|
|
109
|
+
price,
|
|
110
|
+
compareAtPrice,
|
|
111
|
+
currency,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Headless component for product SKU display
|
|
116
|
+
*
|
|
117
|
+
* @component
|
|
118
|
+
* @example
|
|
119
|
+
* ```tsx
|
|
120
|
+
* import { SelectedVariant } from '@wix/stores/components';
|
|
121
|
+
*
|
|
122
|
+
* function ProductSKU() {
|
|
123
|
+
* return (
|
|
124
|
+
* <SelectedVariant.SKU>
|
|
125
|
+
* {({ sku }) => (
|
|
126
|
+
* <div>
|
|
127
|
+
* {sku && (
|
|
128
|
+
* <div className="product-sku">
|
|
129
|
+
* <strong>SKU:</strong> {sku}
|
|
130
|
+
* </div>
|
|
131
|
+
* )}
|
|
132
|
+
* </div>
|
|
133
|
+
* )}
|
|
134
|
+
* </SelectedVariant.SKU>
|
|
135
|
+
* );
|
|
136
|
+
* }
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
export function SKU(props) {
|
|
140
|
+
const selectedVariantService = useService(SelectedVariantServiceDefinition);
|
|
141
|
+
const selectedVariant = selectedVariantService.currentVariant?.get();
|
|
142
|
+
const sku = selectedVariant?.sku || null;
|
|
143
|
+
return props.children({
|
|
144
|
+
sku,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Headless component for product actions (add to cart, buy now)
|
|
149
|
+
*
|
|
150
|
+
* @component
|
|
151
|
+
* @example
|
|
152
|
+
* ```tsx
|
|
153
|
+
* import { SelectedVariant } from '@wix/stores/components';
|
|
154
|
+
*
|
|
155
|
+
* function AddToCartButton() {
|
|
156
|
+
* return (
|
|
157
|
+
* <SelectedVariant.Actions>
|
|
158
|
+
* {({ addToCart, buyNow, canAddToCart, isLoading, inStock, error }) => (
|
|
159
|
+
* <div>
|
|
160
|
+
* {error && <div className="error">{error}</div>}
|
|
161
|
+
* {!inStock && <div>Out of stock</div>}
|
|
162
|
+
* <button
|
|
163
|
+
* onClick={addToCart}
|
|
164
|
+
* disabled={!canAddToCart || isLoading}
|
|
165
|
+
* >
|
|
166
|
+
* {isLoading ? 'Adding...' : 'Add to Cart'}
|
|
167
|
+
* </button>
|
|
168
|
+
* <button
|
|
169
|
+
* onClick={buyNow}
|
|
170
|
+
* disabled={!canAddToCart || isLoading}
|
|
171
|
+
* >
|
|
172
|
+
* Buy Now
|
|
173
|
+
* </button>
|
|
174
|
+
* </div>
|
|
175
|
+
* )}
|
|
176
|
+
* </SelectedVariant.Actions>
|
|
177
|
+
* );
|
|
178
|
+
* }
|
|
179
|
+
* ```
|
|
180
|
+
*/
|
|
181
|
+
export function Actions(props) {
|
|
182
|
+
const variantService = useService(SelectedVariantServiceDefinition);
|
|
183
|
+
const cartService = useService(CurrentCartServiceDefinition);
|
|
184
|
+
// Try to get checkout service - it may not be available
|
|
185
|
+
let checkoutService = null;
|
|
186
|
+
try {
|
|
187
|
+
checkoutService = useService(CheckoutServiceDefinition);
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
// Checkout service not available
|
|
191
|
+
checkoutService = null;
|
|
192
|
+
}
|
|
193
|
+
// Try to get modifiers service - it may not exist for all products
|
|
194
|
+
let modifiersService = null;
|
|
195
|
+
try {
|
|
196
|
+
modifiersService = useService(ProductModifiersServiceDefinition);
|
|
197
|
+
}
|
|
198
|
+
catch {
|
|
199
|
+
// Modifiers service not available for this product
|
|
200
|
+
modifiersService = null;
|
|
201
|
+
}
|
|
202
|
+
const inStock = variantService.isInStock.get();
|
|
203
|
+
const isPreOrderEnabled = variantService.isPreOrderEnabled.get() && !inStock;
|
|
204
|
+
const preOrderMessage = variantService.preOrderMessage.get();
|
|
205
|
+
const isLoading = variantService.isLoading.get() ||
|
|
206
|
+
(checkoutService ? checkoutService.isLoading.get() : false);
|
|
207
|
+
const error = variantService.error.get() ||
|
|
208
|
+
(checkoutService ? checkoutService.error.get() : null);
|
|
209
|
+
const quantity = variantService.selectedQuantity.get();
|
|
210
|
+
// Check if all required modifiers are filled
|
|
211
|
+
const areAllRequiredModifiersFilled = modifiersService
|
|
212
|
+
? modifiersService.areAllRequiredModifiersFilled()
|
|
213
|
+
: true; // If no modifiers service, assume no required modifiers
|
|
214
|
+
const canAddToCart = (inStock || isPreOrderEnabled) &&
|
|
215
|
+
!isLoading &&
|
|
216
|
+
areAllRequiredModifiersFilled;
|
|
217
|
+
const getModifiersData = () => {
|
|
218
|
+
if (modifiersService) {
|
|
219
|
+
const selectedModifiers = modifiersService.selectedModifiers.get();
|
|
220
|
+
if (Object.keys(selectedModifiers).length > 0) {
|
|
221
|
+
return selectedModifiers;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
const addToCart = async () => {
|
|
226
|
+
const modifiersData = getModifiersData();
|
|
227
|
+
await variantService.addToCart(quantity, modifiersData);
|
|
228
|
+
};
|
|
229
|
+
const buyNowFallback = async () => {
|
|
230
|
+
try {
|
|
231
|
+
// Clear the cart first
|
|
232
|
+
await cartService.clearCart();
|
|
233
|
+
// Add the product to cart
|
|
234
|
+
await addToCart();
|
|
235
|
+
// Proceed to checkout
|
|
236
|
+
await cartService.proceedToCheckout();
|
|
237
|
+
}
|
|
238
|
+
catch (error) {
|
|
239
|
+
console.error('Buy now failed:', error);
|
|
240
|
+
throw error;
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
const getLineItems = () => {
|
|
244
|
+
const modifiersData = getModifiersData();
|
|
245
|
+
return variantService.createLineItems(quantity, modifiersData);
|
|
246
|
+
};
|
|
247
|
+
const commonProps = {
|
|
248
|
+
lineItems: getLineItems(),
|
|
249
|
+
addToCart,
|
|
250
|
+
canAddToCart,
|
|
251
|
+
isLoading,
|
|
252
|
+
inStock,
|
|
253
|
+
isPreOrderEnabled,
|
|
254
|
+
preOrderMessage,
|
|
255
|
+
error,
|
|
256
|
+
};
|
|
257
|
+
if (checkoutService) {
|
|
258
|
+
return (_jsx(Commerce.CheckoutTrigger, { children: ({ createCheckout, isLoading: checkoutLoading, error: checkoutError, }) => props.children({
|
|
259
|
+
...commonProps,
|
|
260
|
+
isLoading: isLoading || checkoutLoading,
|
|
261
|
+
error: error || checkoutError,
|
|
262
|
+
buyNow: () => createCheckout(getLineItems()),
|
|
263
|
+
}) }));
|
|
264
|
+
}
|
|
265
|
+
return props.children({
|
|
266
|
+
...commonProps,
|
|
267
|
+
buyNow: buyNowFallback,
|
|
268
|
+
});
|
|
269
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export * as Product from './Product.js';
|
|
2
|
+
export * as ProductList from './ProductList.js';
|
|
3
|
+
export * as Option from './Option.js';
|
|
4
|
+
export * as Choice from './Choice.js';
|
|
5
|
+
export * as CategoryList from './CategoryList.js';
|
|
6
|
+
export * as Category from './Category.js';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export * as Product from './Product.js';
|
|
2
|
+
export * as ProductList from './ProductList.js';
|
|
3
|
+
export * as Option from './Option.js';
|
|
4
|
+
export * as Choice from './Choice.js';
|
|
5
|
+
export * as CategoryList from './CategoryList.js';
|
|
6
|
+
export * as Category from './Category.js';
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for creating a checkout with a custom line item.
|
|
3
|
+
*/
|
|
4
|
+
export interface CustomLineItemCheckoutOptions {
|
|
5
|
+
/**
|
|
6
|
+
* The name of the product for the custom line item.
|
|
7
|
+
* @example "My Custom Product"
|
|
8
|
+
*/
|
|
9
|
+
productName: string;
|
|
10
|
+
/**
|
|
11
|
+
* A description for the price, which will be displayed to the customer.
|
|
12
|
+
* @example "per month"
|
|
13
|
+
*/
|
|
14
|
+
priceDescription: string;
|
|
15
|
+
/**
|
|
16
|
+
* An array of policies related to this custom item.
|
|
17
|
+
* Each policy should have a title and content.
|
|
18
|
+
*/
|
|
19
|
+
policies?: {
|
|
20
|
+
content: string;
|
|
21
|
+
title: string;
|
|
22
|
+
}[];
|
|
23
|
+
/**
|
|
24
|
+
* The URL to redirect the user to after the checkout is successfully completed.
|
|
25
|
+
*/
|
|
26
|
+
postFlowUrl?: string;
|
|
27
|
+
/**
|
|
28
|
+
* The quantity of the product.
|
|
29
|
+
* @default 1
|
|
30
|
+
*/
|
|
31
|
+
quantity?: number;
|
|
32
|
+
/**
|
|
33
|
+
* The price of the product.
|
|
34
|
+
*/
|
|
35
|
+
price: string;
|
|
36
|
+
/**
|
|
37
|
+
* The currency of the product. It will only take effect after configuring the payment provider to accept this currency.
|
|
38
|
+
*/
|
|
39
|
+
currency: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Creates a factory function to generate checkout URLs for custom line items with a fixed price.
|
|
43
|
+
* This is useful when you have a single product or service with a known price,
|
|
44
|
+
* and you want to dynamically create checkout sessions for it.
|
|
45
|
+
*
|
|
46
|
+
* @param factoryOpts - The options for the factory, including the price.
|
|
47
|
+
* @returns A function that takes `CustomLineItemCheckoutOptions` and returns a checkout URL.
|
|
48
|
+
*/
|
|
49
|
+
export declare function getCustomLineItemCheckoutURLFactory(factoryOpts: CustomLineItemCheckoutOptions): () => Promise<string>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { checkout } from '@wix/ecom';
|
|
2
|
+
import { redirects } from '@wix/redirects';
|
|
3
|
+
import { auth } from '@wix/essentials';
|
|
4
|
+
/**
|
|
5
|
+
* Creates a factory function to generate checkout URLs for custom line items with a fixed price.
|
|
6
|
+
* This is useful when you have a single product or service with a known price,
|
|
7
|
+
* and you want to dynamically create checkout sessions for it.
|
|
8
|
+
*
|
|
9
|
+
* @param factoryOpts - The options for the factory, including the price.
|
|
10
|
+
* @returns A function that takes `CustomLineItemCheckoutOptions` and returns a checkout URL.
|
|
11
|
+
*/
|
|
12
|
+
export function getCustomLineItemCheckoutURLFactory(factoryOpts) {
|
|
13
|
+
/**
|
|
14
|
+
* Generates a checkout URL for a custom line item.
|
|
15
|
+
* @param opts - The options for the custom line item checkout.
|
|
16
|
+
* @returns A promise that resolves to the full URL for the redirect session to the checkout.
|
|
17
|
+
* @throws Will throw an error if the checkout creation or redirect session fails.
|
|
18
|
+
*/
|
|
19
|
+
return async function getCustomLineItemCheckoutURL() {
|
|
20
|
+
try {
|
|
21
|
+
const checkoutResult = await auth.elevate(checkout.createCheckout)({
|
|
22
|
+
customLineItems: [
|
|
23
|
+
{
|
|
24
|
+
productName: {
|
|
25
|
+
original: factoryOpts.productName,
|
|
26
|
+
},
|
|
27
|
+
price: factoryOpts.price,
|
|
28
|
+
quantity: factoryOpts.quantity || 1,
|
|
29
|
+
itemType: {
|
|
30
|
+
preset: checkout.ItemTypePreset.PHYSICAL,
|
|
31
|
+
},
|
|
32
|
+
priceDescription: {
|
|
33
|
+
original: factoryOpts.priceDescription,
|
|
34
|
+
},
|
|
35
|
+
policies: factoryOpts.policies || [],
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
channelType: checkout.ChannelType.WEB,
|
|
39
|
+
...(factoryOpts.currency
|
|
40
|
+
? {
|
|
41
|
+
checkoutInfo: {
|
|
42
|
+
currency: factoryOpts.currency,
|
|
43
|
+
},
|
|
44
|
+
}
|
|
45
|
+
: {}),
|
|
46
|
+
});
|
|
47
|
+
if (!checkoutResult._id) {
|
|
48
|
+
throw new Error(`Failed to create checkout for custom line item ${factoryOpts.productName}`);
|
|
49
|
+
}
|
|
50
|
+
const { redirectSession } = await redirects.createRedirectSession({
|
|
51
|
+
ecomCheckout: { checkoutId: checkoutResult._id },
|
|
52
|
+
callbacks: {
|
|
53
|
+
...(factoryOpts.postFlowUrl
|
|
54
|
+
? { postFlowUrl: factoryOpts.postFlowUrl }
|
|
55
|
+
: {}),
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
return redirectSession?.fullUrl;
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './custom-checkout-action.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './custom-checkout-action.js';
|