@wix/headless-stores 0.0.51 → 0.0.53
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/astro/actions/custom-checkout.d.ts +1 -1
- package/cjs/dist/astro/actions/custom-checkout.js +2 -2
- package/cjs/dist/astro/actions/index.d.ts +1 -1
- package/cjs/dist/astro/actions/index.js +1 -1
- package/cjs/dist/enums/index.d.ts +2 -2
- package/cjs/dist/enums/index.js +2 -2
- package/cjs/dist/react/Category.d.ts +168 -67
- package/cjs/dist/react/Category.js +166 -50
- package/cjs/dist/react/CategoryList.d.ts +56 -138
- package/cjs/dist/react/CategoryList.js +44 -129
- package/cjs/dist/react/Choice.d.ts +193 -0
- package/cjs/dist/react/Choice.js +259 -0
- package/cjs/dist/react/Option.d.ts +224 -0
- package/cjs/dist/react/Option.js +388 -0
- package/cjs/dist/react/Product.d.ts +339 -96
- package/cjs/dist/react/Product.js +507 -94
- package/cjs/dist/react/{BuyNow.js → core/BuyNow.js} +2 -2
- package/cjs/dist/react/core/Category.d.ts +98 -0
- package/cjs/dist/react/core/Category.js +81 -0
- package/cjs/dist/react/core/CategoryList.d.ts +185 -0
- package/cjs/dist/react/core/CategoryList.js +174 -0
- package/{dist/react → cjs/dist/react/core}/PayNow.js +2 -2
- package/cjs/dist/react/core/Product.d.ts +148 -0
- package/cjs/dist/react/core/Product.js +126 -0
- package/cjs/dist/react/{ProductList.d.ts → core/ProductList.d.ts} +3 -3
- package/cjs/dist/react/{ProductList.js → core/ProductList.js} +10 -10
- package/{dist/react → cjs/dist/react/core}/ProductListFilters.d.ts +3 -3
- package/{dist/react → cjs/dist/react/core}/ProductListFilters.js +7 -7
- package/cjs/dist/react/{ProductListPagination.js → core/ProductListPagination.js} +8 -8
- package/{dist/react → cjs/dist/react/core}/ProductListSort.d.ts +1 -1
- package/cjs/dist/react/{ProductListSort.js → core/ProductListSort.js} +3 -3
- package/{dist/react → cjs/dist/react/core}/ProductModifiers.d.ts +1 -1
- package/{dist/react → cjs/dist/react/core}/ProductModifiers.js +13 -13
- package/{dist/react → cjs/dist/react/core}/ProductVariantSelector.d.ts +2 -2
- package/{dist/react → cjs/dist/react/core}/ProductVariantSelector.js +7 -10
- package/{dist/react → cjs/dist/react/core}/SelectedVariant.d.ts +2 -2
- package/{dist/react → cjs/dist/react/core}/SelectedVariant.js +43 -15
- package/cjs/dist/react/index.d.ts +15 -10
- package/cjs/dist/react/index.js +15 -10
- 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.js +14 -10
- package/cjs/dist/server-actions/index.d.ts +1 -1
- package/cjs/dist/server-actions/index.js +1 -1
- package/cjs/dist/services/buy-now-service.d.ts +1 -1
- package/cjs/dist/services/buy-now-service.js +6 -6
- package/cjs/dist/services/categories-list-service.d.ts +4 -4
- package/cjs/dist/services/categories-list-service.js +10 -10
- package/cjs/dist/services/category-service.d.ts +18 -22
- package/cjs/dist/services/category-service.js +12 -10
- package/cjs/dist/services/index.d.ts +7 -7
- package/cjs/dist/services/index.js +7 -7
- package/cjs/dist/services/pay-now-service.d.ts +1 -1
- package/cjs/dist/services/pay-now-service.js +4 -4
- package/cjs/dist/services/product-modifiers-service.d.ts +3 -3
- package/cjs/dist/services/product-modifiers-service.js +7 -7
- package/cjs/dist/services/product-service.d.ts +4 -4
- package/cjs/dist/services/product-service.js +18 -18
- package/cjs/dist/services/products-list-search-service.d.ts +5 -5
- package/cjs/dist/services/products-list-search-service.js +117 -117
- package/cjs/dist/services/products-list-service.d.ts +4 -4
- package/cjs/dist/services/products-list-service.js +12 -12
- package/cjs/dist/services/selected-variant-service.d.ts +6 -2
- package/cjs/dist/services/selected-variant-service.js +92 -87
- package/cjs/dist/utils/index.d.ts +1 -0
- package/cjs/dist/utils/index.js +5 -4
- package/cjs/dist/utils/renderAsChild.d.ts +96 -0
- package/cjs/dist/utils/renderAsChild.js +66 -0
- package/cjs/dist/utils/renderChildren.d.ts +41 -0
- package/cjs/dist/utils/renderChildren.js +44 -0
- package/cjs/dist/utils/url-params.js +3 -3
- package/dist/astro/actions/custom-checkout.d.ts +1 -1
- package/dist/astro/actions/custom-checkout.js +2 -2
- package/dist/astro/actions/index.d.ts +1 -1
- package/dist/astro/actions/index.js +1 -1
- package/dist/enums/index.d.ts +2 -2
- package/dist/enums/index.js +2 -2
- package/dist/react/Category.d.ts +168 -67
- package/dist/react/Category.js +166 -50
- package/dist/react/CategoryList.d.ts +56 -138
- package/dist/react/CategoryList.js +44 -129
- package/dist/react/Choice.d.ts +193 -0
- package/dist/react/Choice.js +259 -0
- package/dist/react/Option.d.ts +224 -0
- package/dist/react/Option.js +388 -0
- package/dist/react/Product.d.ts +339 -96
- package/dist/react/Product.js +507 -94
- package/dist/react/{BuyNow.js → core/BuyNow.js} +2 -2
- package/dist/react/core/Category.d.ts +98 -0
- package/dist/react/core/Category.js +81 -0
- package/dist/react/core/CategoryList.d.ts +185 -0
- package/dist/react/core/CategoryList.js +174 -0
- package/{cjs/dist/react → dist/react/core}/PayNow.js +2 -2
- package/dist/react/core/Product.d.ts +148 -0
- package/dist/react/core/Product.js +126 -0
- package/dist/react/{ProductList.d.ts → core/ProductList.d.ts} +3 -3
- package/dist/react/{ProductList.js → core/ProductList.js} +10 -10
- package/{cjs/dist/react → dist/react/core}/ProductListFilters.d.ts +3 -3
- package/{cjs/dist/react → dist/react/core}/ProductListFilters.js +7 -7
- package/dist/react/{ProductListPagination.js → core/ProductListPagination.js} +8 -8
- package/{cjs/dist/react → dist/react/core}/ProductListSort.d.ts +1 -1
- package/dist/react/{ProductListSort.js → core/ProductListSort.js} +3 -3
- package/{cjs/dist/react → dist/react/core}/ProductModifiers.d.ts +1 -1
- package/{cjs/dist/react → dist/react/core}/ProductModifiers.js +13 -13
- package/{cjs/dist/react → dist/react/core}/ProductVariantSelector.d.ts +2 -2
- package/{cjs/dist/react → dist/react/core}/ProductVariantSelector.js +7 -10
- package/{cjs/dist/react → dist/react/core}/SelectedVariant.d.ts +2 -2
- package/{cjs/dist/react → dist/react/core}/SelectedVariant.js +43 -15
- package/dist/react/index.d.ts +15 -10
- package/dist/react/index.js +15 -10
- package/dist/react/types.d.ts +8 -0
- package/dist/react/types.js +9 -0
- package/dist/server-actions/custom-checkout-action.js +14 -10
- package/dist/server-actions/index.d.ts +1 -1
- package/dist/server-actions/index.js +1 -1
- package/dist/services/buy-now-service.d.ts +1 -1
- package/dist/services/buy-now-service.js +6 -6
- package/dist/services/categories-list-service.d.ts +4 -4
- package/dist/services/categories-list-service.js +10 -10
- package/dist/services/category-service.d.ts +18 -22
- package/dist/services/category-service.js +12 -10
- package/dist/services/index.d.ts +7 -7
- package/dist/services/index.js +7 -7
- package/dist/services/pay-now-service.d.ts +1 -1
- package/dist/services/pay-now-service.js +4 -4
- package/dist/services/product-modifiers-service.d.ts +3 -3
- package/dist/services/product-modifiers-service.js +7 -7
- package/dist/services/product-service.d.ts +4 -4
- package/dist/services/product-service.js +18 -18
- package/dist/services/products-list-search-service.d.ts +5 -5
- package/dist/services/products-list-search-service.js +117 -117
- package/dist/services/products-list-service.d.ts +4 -4
- package/dist/services/products-list-service.js +12 -12
- package/dist/services/selected-variant-service.d.ts +6 -2
- package/dist/services/selected-variant-service.js +92 -87
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +5 -4
- package/dist/utils/renderAsChild.d.ts +96 -0
- package/dist/utils/renderAsChild.js +66 -0
- package/dist/utils/renderChildren.d.ts +41 -0
- package/dist/utils/renderChildren.js +44 -0
- package/dist/utils/url-params.js +3 -3
- package/package.json +7 -3
- /package/cjs/dist/react/{BuyNow.d.ts → core/BuyNow.d.ts} +0 -0
- /package/cjs/dist/react/{PayNow.d.ts → core/PayNow.d.ts} +0 -0
- /package/cjs/dist/react/{ProductListPagination.d.ts → core/ProductListPagination.d.ts} +0 -0
- /package/dist/react/{BuyNow.d.ts → core/BuyNow.d.ts} +0 -0
- /package/dist/react/{PayNow.d.ts → core/PayNow.d.ts} +0 -0
- /package/dist/react/{ProductListPagination.d.ts → core/ProductListPagination.d.ts} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type Signal, type ReadOnlySignal } from
|
|
2
|
-
import * as productsV3 from
|
|
1
|
+
import { type Signal, type ReadOnlySignal } from '@wix/services-definitions/core-services/signals';
|
|
2
|
+
import * as productsV3 from '@wix/auto_sdk_stores_products-v-3';
|
|
3
3
|
export interface SelectedVariantServiceAPI {
|
|
4
4
|
selectedQuantity: Signal<number>;
|
|
5
5
|
selectedChoices: Signal<Record<string, string>>;
|
|
@@ -28,6 +28,10 @@ export interface SelectedVariantServiceAPI {
|
|
|
28
28
|
finalPrice: () => number;
|
|
29
29
|
isLowStock: () => boolean;
|
|
30
30
|
setSelectedChoices: (choices: Record<string, string>) => void;
|
|
31
|
+
createLineItems: (quantity?: number, modifiers?: Record<string, any>) => Array<{
|
|
32
|
+
catalogReference: any;
|
|
33
|
+
quantity: number;
|
|
34
|
+
}>;
|
|
31
35
|
addToCart: (quantity?: number, modifiers?: Record<string, any>) => Promise<void>;
|
|
32
36
|
setOption: (group: string, value: string) => void;
|
|
33
37
|
setSelectedQuantity: (quantity: number) => void;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import { defineService, implementService } from
|
|
2
|
-
import { SignalsServiceDefinition, } from
|
|
3
|
-
import * as productsV3 from
|
|
4
|
-
import * as inventoryItemsV3 from
|
|
5
|
-
import { CurrentCartServiceDefinition } from
|
|
6
|
-
import {
|
|
7
|
-
|
|
1
|
+
import { defineService, implementService } from '@wix/services-definitions';
|
|
2
|
+
import { SignalsServiceDefinition, } from '@wix/services-definitions/core-services/signals';
|
|
3
|
+
import * as productsV3 from '@wix/auto_sdk_stores_products-v-3';
|
|
4
|
+
import * as inventoryItemsV3 from '@wix/auto_sdk_stores_inventory-items-v-3';
|
|
5
|
+
import { CurrentCartServiceDefinition } from '@wix/headless-ecom/services';
|
|
6
|
+
import { MediaGalleryServiceDefinition } from '@wix/headless-media/services';
|
|
7
|
+
import { ProductServiceDefinition } from './product-service.js';
|
|
8
|
+
export const SelectedVariantServiceDefinition = defineService('selectedVariant');
|
|
8
9
|
export const SelectedVariantService = implementService.withConfig()(SelectedVariantServiceDefinition, ({ getService, config: { fetchInventoryData = true } }) => {
|
|
10
|
+
const mediaService = getService(MediaGalleryServiceDefinition);
|
|
9
11
|
const signalsService = getService(SignalsServiceDefinition);
|
|
10
12
|
const cartService = getService(CurrentCartServiceDefinition);
|
|
11
13
|
const productService = getService(ProductServiceDefinition);
|
|
@@ -15,15 +17,15 @@ export const SelectedVariantService = implementService.withConfig()(SelectedVari
|
|
|
15
17
|
signalsService.effect(() => {
|
|
16
18
|
const product = productService.product.get();
|
|
17
19
|
const selectedChoicesValue = selectedChoices.get() || {};
|
|
18
|
-
|
|
20
|
+
let mediaToDisplay = [];
|
|
19
21
|
const productItemsImages = product?.media?.itemsInfo?.items
|
|
20
22
|
?.map((item) => item)
|
|
21
23
|
.filter(Boolean) ?? [];
|
|
22
24
|
if (productItemsImages.length) {
|
|
23
|
-
|
|
25
|
+
mediaToDisplay = productItemsImages;
|
|
24
26
|
}
|
|
25
27
|
else if (product?.media?.main) {
|
|
26
|
-
|
|
28
|
+
mediaToDisplay = [product.media.main];
|
|
27
29
|
}
|
|
28
30
|
// Get images based on selected choices if available
|
|
29
31
|
let selectedChoicesImages = [];
|
|
@@ -36,9 +38,9 @@ export const SelectedVariantService = implementService.withConfig()(SelectedVari
|
|
|
36
38
|
}
|
|
37
39
|
});
|
|
38
40
|
if (selectedChoicesImages?.length) {
|
|
39
|
-
|
|
41
|
+
mediaToDisplay = selectedChoicesImages;
|
|
40
42
|
}
|
|
41
|
-
|
|
43
|
+
mediaService.setMediaToDisplay(mediaToDisplay ?? []);
|
|
42
44
|
});
|
|
43
45
|
const parsePrice = (amount) => {
|
|
44
46
|
if (!amount)
|
|
@@ -75,7 +77,7 @@ export const SelectedVariantService = implementService.withConfig()(SelectedVari
|
|
|
75
77
|
// Use the correct Wix inventoryItemsV3.queryInventoryItems() API
|
|
76
78
|
const queryResult = await inventoryItemsV3
|
|
77
79
|
.queryInventoryItems()
|
|
78
|
-
.eq(
|
|
80
|
+
.eq('variantId', variantId)
|
|
79
81
|
.find();
|
|
80
82
|
const inventoryItem = queryResult.items?.[0];
|
|
81
83
|
const isTrackingQuantity = inventoryItem?.trackQuantity ?? false;
|
|
@@ -96,7 +98,7 @@ export const SelectedVariantService = implementService.withConfig()(SelectedVari
|
|
|
96
98
|
}
|
|
97
99
|
}
|
|
98
100
|
catch (error) {
|
|
99
|
-
console.error(
|
|
101
|
+
console.error('Failed to fetch inventory quantity:', error);
|
|
100
102
|
// Fallback on error
|
|
101
103
|
quantityAvailable.set(null);
|
|
102
104
|
trackQuantity.set(false);
|
|
@@ -134,13 +136,13 @@ export const SelectedVariantService = implementService.withConfig()(SelectedVari
|
|
|
134
136
|
const quantityAvailable = signalsService.signal(null);
|
|
135
137
|
const trackQuantity = signalsService.signal(false);
|
|
136
138
|
const selectedQuantity = signalsService.signal(1);
|
|
137
|
-
const productId = signalsService.signal(
|
|
139
|
+
const productId = signalsService.signal('');
|
|
138
140
|
const ribbonLabel = signalsService.signal(null);
|
|
139
141
|
const v3Product = signalsService.signal(initialProduct);
|
|
140
142
|
const init = (currentProduct) => {
|
|
141
143
|
if (currentProduct) {
|
|
142
144
|
v3Product.set(currentProduct);
|
|
143
|
-
productId.set(currentProduct._id ||
|
|
145
|
+
productId.set(currentProduct._id || '');
|
|
144
146
|
ribbonLabel.set(currentProduct.ribbon?.name || null);
|
|
145
147
|
const actualPrice = currentProduct.actualPriceRange?.minValue?.amount;
|
|
146
148
|
const compareAtPrice = currentProduct.compareAtPriceRange?.minValue?.amount;
|
|
@@ -152,7 +154,7 @@ export const SelectedVariantService = implementService.withConfig()(SelectedVari
|
|
|
152
154
|
const optionsMap = {};
|
|
153
155
|
currentProduct.options.forEach((option) => {
|
|
154
156
|
if (option.name && option.choicesSettings?.choices) {
|
|
155
|
-
optionsMap[option.name] = option.choicesSettings.choices.map((choice) => choice.name ||
|
|
157
|
+
optionsMap[option.name] = option.choicesSettings.choices.map((choice) => choice.name || '');
|
|
156
158
|
}
|
|
157
159
|
});
|
|
158
160
|
options.set(optionsMap);
|
|
@@ -165,7 +167,7 @@ export const SelectedVariantService = implementService.withConfig()(SelectedVari
|
|
|
165
167
|
}
|
|
166
168
|
else {
|
|
167
169
|
const singleVariant = {
|
|
168
|
-
_id:
|
|
170
|
+
_id: 'default',
|
|
169
171
|
visible: true,
|
|
170
172
|
choices: [],
|
|
171
173
|
price: {
|
|
@@ -178,7 +180,7 @@ export const SelectedVariantService = implementService.withConfig()(SelectedVari
|
|
|
178
180
|
currentProduct.inventory?.availabilityStatus ===
|
|
179
181
|
productsV3.InventoryAvailabilityStatus
|
|
180
182
|
.PARTIALLY_OUT_OF_STOCK,
|
|
181
|
-
preorderEnabled: currentProduct.inventory?.preorderStatus ===
|
|
183
|
+
preorderEnabled: currentProduct.inventory?.preorderStatus === 'ENABLED',
|
|
182
184
|
},
|
|
183
185
|
};
|
|
184
186
|
variants.set([singleVariant]);
|
|
@@ -227,7 +229,7 @@ export const SelectedVariantService = implementService.withConfig()(SelectedVari
|
|
|
227
229
|
else if (prod?.actualPriceRange?.minValue?.amount) {
|
|
228
230
|
rawAmount = prod.actualPriceRange.minValue.amount;
|
|
229
231
|
}
|
|
230
|
-
return rawAmount ? `$${rawAmount}` :
|
|
232
|
+
return rawAmount ? `$${rawAmount}` : '';
|
|
231
233
|
});
|
|
232
234
|
const currentCompareAtPrice = signalsService.computed(() => {
|
|
233
235
|
const variant = currentVariant.get();
|
|
@@ -269,7 +271,7 @@ export const SelectedVariantService = implementService.withConfig()(SelectedVari
|
|
|
269
271
|
});
|
|
270
272
|
const currency = signalsService.computed(() => {
|
|
271
273
|
const prod = v3Product.get();
|
|
272
|
-
return prod?.currency ||
|
|
274
|
+
return prod?.currency || 'USD';
|
|
273
275
|
});
|
|
274
276
|
const selectedVariant = () => {
|
|
275
277
|
const variantId = selectedVariantId.get();
|
|
@@ -292,79 +294,81 @@ export const SelectedVariantService = implementService.withConfig()(SelectedVari
|
|
|
292
294
|
const matchingVariant = findVariantByChoices(variants.get(), choices);
|
|
293
295
|
updateDataFromVariant(matchingVariant);
|
|
294
296
|
};
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
};
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
const
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
const modifierKey = productModifier.key || modifierName;
|
|
331
|
-
if (modifierValue.choiceValue) {
|
|
332
|
-
options[modifierKey] = modifierValue.choiceValue;
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
else if (renderType === productsV3.ModifierRenderType.FREE_TEXT) {
|
|
336
|
-
// For free text modifiers, use the freeTextSettings key
|
|
337
|
-
const freeTextKey = productModifier.freeTextSettings?.key ||
|
|
338
|
-
modifierName;
|
|
339
|
-
if (modifierValue.freeTextValue) {
|
|
340
|
-
customTextFields[freeTextKey] = modifierValue.freeTextValue;
|
|
341
|
-
}
|
|
297
|
+
const createLineItems = (quantity = 1, modifiers) => {
|
|
298
|
+
const prod = v3Product.get();
|
|
299
|
+
const variant = currentVariant.get();
|
|
300
|
+
if (!prod?._id) {
|
|
301
|
+
throw new Error('Product not found');
|
|
302
|
+
}
|
|
303
|
+
// Build catalog reference with modifiers if provided
|
|
304
|
+
const catalogReference = {
|
|
305
|
+
catalogItemId: prod._id,
|
|
306
|
+
appId: '215238eb-22a5-4c36-9e7b-e7c08025e04e',
|
|
307
|
+
options: variant?._id && variant._id !== 'default'
|
|
308
|
+
? {
|
|
309
|
+
variantId: variant._id,
|
|
310
|
+
preOrderRequested: !!variant?.inventoryStatus?.preorderEnabled,
|
|
311
|
+
}
|
|
312
|
+
: undefined,
|
|
313
|
+
};
|
|
314
|
+
// Transform and add modifiers to catalog reference if they exist
|
|
315
|
+
if (modifiers && Object.keys(modifiers).length > 0) {
|
|
316
|
+
const options = {};
|
|
317
|
+
const customTextFields = {};
|
|
318
|
+
// Get product modifiers to determine types and keys
|
|
319
|
+
const productModifiers = prod.modifiers || [];
|
|
320
|
+
Object.values(modifiers).forEach((modifierValue) => {
|
|
321
|
+
const modifierName = modifierValue.modifierName;
|
|
322
|
+
const productModifier = productModifiers.find((m) => m.name === modifierName);
|
|
323
|
+
if (!productModifier)
|
|
324
|
+
return;
|
|
325
|
+
const renderType = productModifier.modifierRenderType;
|
|
326
|
+
if (renderType === productsV3.ModifierRenderType.TEXT_CHOICES ||
|
|
327
|
+
renderType === productsV3.ModifierRenderType.SWATCH_CHOICES) {
|
|
328
|
+
// For choice modifiers, use the modifier key and choice value
|
|
329
|
+
const modifierKey = productModifier.key || modifierName;
|
|
330
|
+
if (modifierValue.choiceValue) {
|
|
331
|
+
options[modifierKey] = modifierValue.choiceValue;
|
|
342
332
|
}
|
|
343
|
-
});
|
|
344
|
-
// Add formatted modifiers to catalog reference
|
|
345
|
-
if (Object.keys(options).length > 0) {
|
|
346
|
-
catalogReference.options = {
|
|
347
|
-
...catalogReference.options,
|
|
348
|
-
options,
|
|
349
|
-
};
|
|
350
333
|
}
|
|
351
|
-
if (
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
334
|
+
else if (renderType === productsV3.ModifierRenderType.FREE_TEXT) {
|
|
335
|
+
// For free text modifiers, use the freeTextSettings key
|
|
336
|
+
const freeTextKey = productModifier.freeTextSettings?.key || modifierName;
|
|
337
|
+
if (modifierValue.freeTextValue) {
|
|
338
|
+
customTextFields[freeTextKey] = modifierValue.freeTextValue;
|
|
339
|
+
}
|
|
356
340
|
}
|
|
341
|
+
});
|
|
342
|
+
// Add formatted modifiers to catalog reference
|
|
343
|
+
if (Object.keys(options).length > 0) {
|
|
344
|
+
catalogReference.options = {
|
|
345
|
+
...catalogReference.options,
|
|
346
|
+
options,
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
if (Object.keys(customTextFields).length > 0) {
|
|
350
|
+
catalogReference.options = {
|
|
351
|
+
...catalogReference.options,
|
|
352
|
+
customTextFields,
|
|
353
|
+
};
|
|
357
354
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
355
|
+
}
|
|
356
|
+
return [
|
|
357
|
+
{
|
|
358
|
+
catalogReference,
|
|
359
|
+
quantity,
|
|
360
|
+
},
|
|
361
|
+
];
|
|
362
|
+
};
|
|
363
|
+
const addToCart = async (quantity = 1, modifiers) => {
|
|
364
|
+
try {
|
|
365
|
+
isLoading.set(true);
|
|
366
|
+
error.set(null);
|
|
367
|
+
const lineItems = createLineItems(quantity, modifiers);
|
|
364
368
|
await cartService.addToCart(lineItems);
|
|
365
369
|
}
|
|
366
370
|
catch (err) {
|
|
367
|
-
error.set(err instanceof Error ? err.message :
|
|
371
|
+
error.set(err instanceof Error ? err.message : 'Failed to add to cart');
|
|
368
372
|
}
|
|
369
373
|
finally {
|
|
370
374
|
isLoading.set(false);
|
|
@@ -496,6 +500,7 @@ export const SelectedVariantService = implementService.withConfig()(SelectedVari
|
|
|
496
500
|
productId,
|
|
497
501
|
ribbonLabel,
|
|
498
502
|
setSelectedChoices,
|
|
503
|
+
createLineItems,
|
|
499
504
|
addToCart,
|
|
500
505
|
setOption,
|
|
501
506
|
selectVariantById,
|
package/dist/utils/index.d.ts
CHANGED
package/dist/utils/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { checkout } from
|
|
2
|
-
import { redirects } from
|
|
3
|
-
const CATLOG_APP_ID_V3 =
|
|
1
|
+
import { checkout } from '@wix/ecom';
|
|
2
|
+
import { redirects } from '@wix/redirects';
|
|
3
|
+
const CATLOG_APP_ID_V3 = '215238eb-22a5-4c36-9e7b-e7c08025e04e';
|
|
4
4
|
export async function getCheckoutUrlForProduct(productId, variantId) {
|
|
5
5
|
const checkoutResult = await checkout.createCheckout({
|
|
6
6
|
lineItems: [
|
|
@@ -18,7 +18,7 @@ export async function getCheckoutUrlForProduct(productId, variantId) {
|
|
|
18
18
|
channelType: checkout.ChannelType.WEB,
|
|
19
19
|
});
|
|
20
20
|
if (!checkoutResult._id) {
|
|
21
|
-
throw new Error(
|
|
21
|
+
throw new Error('Failed to create checkout');
|
|
22
22
|
}
|
|
23
23
|
const { redirectSession } = await redirects.createRedirectSession({
|
|
24
24
|
ecomCheckout: { checkoutId: checkoutResult._id },
|
|
@@ -28,3 +28,4 @@ export async function getCheckoutUrlForProduct(productId, variantId) {
|
|
|
28
28
|
});
|
|
29
29
|
return redirectSession?.fullUrl;
|
|
30
30
|
}
|
|
31
|
+
export * from './renderAsChild.js';
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Function signature for render function pattern
|
|
4
|
+
*/
|
|
5
|
+
export type AsChildRenderFunction<TProps = any> = (props: TProps, ref: React.Ref<HTMLElement>) => React.ReactNode;
|
|
6
|
+
/**
|
|
7
|
+
* Object with render method pattern
|
|
8
|
+
*/
|
|
9
|
+
export type AsChildRenderObject<TProps = any> = {
|
|
10
|
+
render: AsChildRenderFunction<TProps>;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Union type for all supported asChild patterns
|
|
14
|
+
*/
|
|
15
|
+
export type AsChildChildren<TProps = any> = React.ReactElement | AsChildRenderFunction<TProps> | AsChildRenderObject<TProps>;
|
|
16
|
+
/**
|
|
17
|
+
* Generic interface for components that support asChild pattern.
|
|
18
|
+
* This interface can be extended by specific components to add their own props.
|
|
19
|
+
*
|
|
20
|
+
* @template TData - The shape of the data object passed to asChild render functions
|
|
21
|
+
* @template TProps - Additional props specific to the component
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```tsx
|
|
25
|
+
* // For a component that provides name data
|
|
26
|
+
* interface NameProps extends AsChildProps<{ name: string }> {
|
|
27
|
+
* // className is already included from AsChildProps
|
|
28
|
+
* }
|
|
29
|
+
*
|
|
30
|
+
* // For a component that provides description data
|
|
31
|
+
* interface DescriptionProps extends AsChildProps<{ description: string }> {
|
|
32
|
+
* as?: "plain" | "html";
|
|
33
|
+
* // className is already included from AsChildProps
|
|
34
|
+
* }
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export interface AsChildProps<TData extends Record<string, any> = Record<string, any>, TProps = {}> {
|
|
38
|
+
/** When true, renders as a child component instead of default element */
|
|
39
|
+
asChild?: boolean;
|
|
40
|
+
/** Custom render function or React element when using asChild */
|
|
41
|
+
children?: AsChildChildren<TData & TProps>;
|
|
42
|
+
/** CSS classes to apply to the default element */
|
|
43
|
+
className?: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Parameters for the renderAsChild utility function
|
|
47
|
+
*/
|
|
48
|
+
export interface RenderAsChildParams<TProps = any> {
|
|
49
|
+
/** The children to render (React element, function, or render object) */
|
|
50
|
+
children: AsChildChildren<TProps> | undefined;
|
|
51
|
+
/** Props to pass to render functions */
|
|
52
|
+
props: TProps;
|
|
53
|
+
/** Ref to forward to the rendered element */
|
|
54
|
+
ref: React.Ref<HTMLElement>;
|
|
55
|
+
/** Content to pass as children to React elements */
|
|
56
|
+
content?: React.ReactNode;
|
|
57
|
+
/** Additional attributes to merge into cloned React elements */
|
|
58
|
+
attributes?: Record<string, any>;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Utility function to handle asChild prop with different rendering patterns.
|
|
62
|
+
*
|
|
63
|
+
* Supports three rendering patterns:
|
|
64
|
+
* 1. **React Elements**: Clones the element and forwards the ref and attributes
|
|
65
|
+
* ```tsx
|
|
66
|
+
* <Component asChild><div>Content</div></Component>
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* 2. **Render Functions**: Calls the function with props and ref
|
|
70
|
+
* ```tsx
|
|
71
|
+
* <Component asChild>
|
|
72
|
+
* {(props, ref) => <div ref={ref}>{props.content}</div>}
|
|
73
|
+
* </Component>
|
|
74
|
+
* ```
|
|
75
|
+
*
|
|
76
|
+
* 3. **Render Objects**: Calls the render method with props and ref
|
|
77
|
+
* ```tsx
|
|
78
|
+
* <Component asChild>
|
|
79
|
+
* {{ render: (props, ref) => <div ref={ref}>{props.content}</div> }}
|
|
80
|
+
* </Component>
|
|
81
|
+
* ```
|
|
82
|
+
*
|
|
83
|
+
* @param params - Configuration object with children, props, ref, content, and attributes
|
|
84
|
+
* @returns Rendered React node or null if no valid children provided
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```tsx
|
|
88
|
+
* const result = renderAsChild({
|
|
89
|
+
* children: (props, ref) => <h1 ref={ref}>{props.title}</h1>,
|
|
90
|
+
* props: { title: "Hello World" },
|
|
91
|
+
* ref: myRef,
|
|
92
|
+
* attributes: { "data-testid": "my-component" },
|
|
93
|
+
* });
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export declare function renderAsChild<TProps = any>({ children, props, ref, content, attributes, }: RenderAsChildParams<TProps>): React.ReactNode | null;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Utility function to handle asChild prop with different rendering patterns.
|
|
4
|
+
*
|
|
5
|
+
* Supports three rendering patterns:
|
|
6
|
+
* 1. **React Elements**: Clones the element and forwards the ref and attributes
|
|
7
|
+
* ```tsx
|
|
8
|
+
* <Component asChild><div>Content</div></Component>
|
|
9
|
+
* ```
|
|
10
|
+
*
|
|
11
|
+
* 2. **Render Functions**: Calls the function with props and ref
|
|
12
|
+
* ```tsx
|
|
13
|
+
* <Component asChild>
|
|
14
|
+
* {(props, ref) => <div ref={ref}>{props.content}</div>}
|
|
15
|
+
* </Component>
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* 3. **Render Objects**: Calls the render method with props and ref
|
|
19
|
+
* ```tsx
|
|
20
|
+
* <Component asChild>
|
|
21
|
+
* {{ render: (props, ref) => <div ref={ref}>{props.content}</div> }}
|
|
22
|
+
* </Component>
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @param params - Configuration object with children, props, ref, content, and attributes
|
|
26
|
+
* @returns Rendered React node or null if no valid children provided
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* const result = renderAsChild({
|
|
31
|
+
* children: (props, ref) => <h1 ref={ref}>{props.title}</h1>,
|
|
32
|
+
* props: { title: "Hello World" },
|
|
33
|
+
* ref: myRef,
|
|
34
|
+
* attributes: { "data-testid": "my-component" },
|
|
35
|
+
* });
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export function renderAsChild({ children, props, ref, content, attributes, }) {
|
|
39
|
+
// Early return if no children provided
|
|
40
|
+
if (!children)
|
|
41
|
+
return null;
|
|
42
|
+
// Handle React element pattern
|
|
43
|
+
if (React.isValidElement(children)) {
|
|
44
|
+
return React.cloneElement(children, {
|
|
45
|
+
ref,
|
|
46
|
+
children: content,
|
|
47
|
+
...attributes,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
// Handle render function pattern
|
|
51
|
+
if (typeof children === 'function') {
|
|
52
|
+
return children({
|
|
53
|
+
...props,
|
|
54
|
+
...attributes,
|
|
55
|
+
}, ref);
|
|
56
|
+
}
|
|
57
|
+
// Handle render object pattern
|
|
58
|
+
if (children && typeof children === 'object' && 'render' in children) {
|
|
59
|
+
return children.render({
|
|
60
|
+
...props,
|
|
61
|
+
...attributes,
|
|
62
|
+
}, ref);
|
|
63
|
+
}
|
|
64
|
+
// Fallback for unknown patterns
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Parameters for the renderAsChild utility function
|
|
4
|
+
*/
|
|
5
|
+
export interface RenderChildrenParams<THTMLElement = HTMLElement, TProps = any> {
|
|
6
|
+
/** The children to render (React element, function, or render object) */
|
|
7
|
+
children: React.ReactNode | React.ForwardRefRenderFunction<THTMLElement, TProps> | undefined;
|
|
8
|
+
/** Props to pass to render functions */
|
|
9
|
+
props: TProps;
|
|
10
|
+
/** Ref to forward to the rendered element */
|
|
11
|
+
ref: React.Ref<THTMLElement>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Utility function to handle children rendering.
|
|
15
|
+
*
|
|
16
|
+
* Supports three rendering patterns:
|
|
17
|
+
* 1. **React Elements**: Returns the element
|
|
18
|
+
* ```tsx
|
|
19
|
+
* <Component><div>Content</div></Component>
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* 2. **Render Functions**: Calls the function with props and ref
|
|
23
|
+
* ```tsx
|
|
24
|
+
* <Component>
|
|
25
|
+
* {(props, ref) => <div ref={ref}>{props.content}</div>}
|
|
26
|
+
* </Component>
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @param params - Configuration object with children, props, and ref
|
|
30
|
+
* @returns Rendered React node or null if no valid children provided
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```tsx
|
|
34
|
+
* const result = renderChildren({
|
|
35
|
+
* children: (props, ref) => <h1 ref={ref}>{props.title}</h1>,
|
|
36
|
+
* props: { title: "Hello World" },
|
|
37
|
+
* ref: myRef,
|
|
38
|
+
* });
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export declare function renderChildren<THTMLElement = HTMLElement, TProps = any>({ children, props, ref, }: RenderChildrenParams<THTMLElement, TProps>): React.ReactNode | null;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Utility function to handle children rendering.
|
|
4
|
+
*
|
|
5
|
+
* Supports three rendering patterns:
|
|
6
|
+
* 1. **React Elements**: Returns the element
|
|
7
|
+
* ```tsx
|
|
8
|
+
* <Component><div>Content</div></Component>
|
|
9
|
+
* ```
|
|
10
|
+
*
|
|
11
|
+
* 2. **Render Functions**: Calls the function with props and ref
|
|
12
|
+
* ```tsx
|
|
13
|
+
* <Component>
|
|
14
|
+
* {(props, ref) => <div ref={ref}>{props.content}</div>}
|
|
15
|
+
* </Component>
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* @param params - Configuration object with children, props, and ref
|
|
19
|
+
* @returns Rendered React node or null if no valid children provided
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```tsx
|
|
23
|
+
* const result = renderChildren({
|
|
24
|
+
* children: (props, ref) => <h1 ref={ref}>{props.title}</h1>,
|
|
25
|
+
* props: { title: "Hello World" },
|
|
26
|
+
* ref: myRef,
|
|
27
|
+
* });
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export function renderChildren({ children, props, ref, }) {
|
|
31
|
+
// Early return if no children provided
|
|
32
|
+
if (!children)
|
|
33
|
+
return null;
|
|
34
|
+
// Handle React element pattern
|
|
35
|
+
if (React.isValidElement(children)) {
|
|
36
|
+
return children;
|
|
37
|
+
}
|
|
38
|
+
// Handle render function pattern
|
|
39
|
+
if (typeof children === 'function') {
|
|
40
|
+
return children(props, ref);
|
|
41
|
+
}
|
|
42
|
+
// Fallback for unknown patterns
|
|
43
|
+
return null;
|
|
44
|
+
}
|
package/dist/utils/url-params.js
CHANGED
|
@@ -66,7 +66,7 @@ export class URLParamsUtils {
|
|
|
66
66
|
* ```
|
|
67
67
|
*/
|
|
68
68
|
static updateURL(params) {
|
|
69
|
-
if (typeof window ===
|
|
69
|
+
if (typeof window === 'undefined')
|
|
70
70
|
return;
|
|
71
71
|
const url = new URL(window.location.href);
|
|
72
72
|
const urlParams = new URLSearchParams();
|
|
@@ -83,7 +83,7 @@ export class URLParamsUtils {
|
|
|
83
83
|
const newURL = urlParams.toString()
|
|
84
84
|
? `${url.pathname}?${urlParams.toString()}`
|
|
85
85
|
: url.pathname;
|
|
86
|
-
window.history.replaceState({},
|
|
86
|
+
window.history.replaceState({}, '', newURL);
|
|
87
87
|
}
|
|
88
88
|
/**
|
|
89
89
|
* Gets the current URL parameters parsed into a convenient format.
|
|
@@ -107,7 +107,7 @@ export class URLParamsUtils {
|
|
|
107
107
|
* ```
|
|
108
108
|
*/
|
|
109
109
|
static getURLParams() {
|
|
110
|
-
if (typeof window ===
|
|
110
|
+
if (typeof window === 'undefined')
|
|
111
111
|
return {};
|
|
112
112
|
return this.parseSearchParams(new URLSearchParams(window.location.search));
|
|
113
113
|
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/headless-stores",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.53",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"prebuild": "cd ../media && yarn build && cd ../ecom && yarn build",
|
|
7
7
|
"build": "npm run build:esm && npm run build:cjs",
|
|
8
8
|
"build:esm": "tsc -p tsconfig.json",
|
|
9
9
|
"build:cjs": "tsc -p tsconfig.cjs.json",
|
|
10
|
-
"test": "vitest"
|
|
10
|
+
"test": "vitest",
|
|
11
|
+
"lint:fix": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json,md}\"",
|
|
12
|
+
"lint:check": "prettier --check \"src/**/*.{ts,tsx,js,jsx,json,md}\""
|
|
11
13
|
},
|
|
12
14
|
"files": [
|
|
13
15
|
"dist",
|
|
@@ -46,10 +48,12 @@
|
|
|
46
48
|
"@types/node": "^20.9.0",
|
|
47
49
|
"@vitest/ui": "^3.1.4",
|
|
48
50
|
"jsdom": "^26.1.0",
|
|
51
|
+
"prettier": "^3.4.2",
|
|
49
52
|
"typescript": "^5.8.3",
|
|
50
53
|
"vitest": "^3.1.4"
|
|
51
54
|
},
|
|
52
55
|
"dependencies": {
|
|
56
|
+
"@radix-ui/react-slot": "^1.2.3",
|
|
53
57
|
"@wix/auto_sdk_bookings_availability-calendar": "^1.0.155",
|
|
54
58
|
"@wix/auto_sdk_categories_categories": "^1.0.62",
|
|
55
59
|
"@wix/auto_sdk_stores_customizations-v-3": "^1.0.26",
|
|
@@ -58,7 +62,7 @@
|
|
|
58
62
|
"@wix/auto_sdk_stores_read-only-variants-v-3": "^1.0.23",
|
|
59
63
|
"@wix/ecom": "^1.0.1278",
|
|
60
64
|
"@wix/essentials": "^0.1.24",
|
|
61
|
-
"@wix/headless-ecom": "^0.0.
|
|
65
|
+
"@wix/headless-ecom": "^0.0.14",
|
|
62
66
|
"@wix/headless-media": "^0.0.8",
|
|
63
67
|
"@wix/redirects": "^1.0.83",
|
|
64
68
|
"@wix/services-definitions": "^0.1.4",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|