@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.
Files changed (149) hide show
  1. package/cjs/dist/astro/actions/custom-checkout.d.ts +1 -1
  2. package/cjs/dist/astro/actions/custom-checkout.js +2 -2
  3. package/cjs/dist/astro/actions/index.d.ts +1 -1
  4. package/cjs/dist/astro/actions/index.js +1 -1
  5. package/cjs/dist/enums/index.d.ts +2 -2
  6. package/cjs/dist/enums/index.js +2 -2
  7. package/cjs/dist/react/Category.d.ts +168 -67
  8. package/cjs/dist/react/Category.js +166 -50
  9. package/cjs/dist/react/CategoryList.d.ts +56 -138
  10. package/cjs/dist/react/CategoryList.js +44 -129
  11. package/cjs/dist/react/Choice.d.ts +193 -0
  12. package/cjs/dist/react/Choice.js +259 -0
  13. package/cjs/dist/react/Option.d.ts +224 -0
  14. package/cjs/dist/react/Option.js +388 -0
  15. package/cjs/dist/react/Product.d.ts +339 -96
  16. package/cjs/dist/react/Product.js +507 -94
  17. package/cjs/dist/react/{BuyNow.js → core/BuyNow.js} +2 -2
  18. package/cjs/dist/react/core/Category.d.ts +98 -0
  19. package/cjs/dist/react/core/Category.js +81 -0
  20. package/cjs/dist/react/core/CategoryList.d.ts +185 -0
  21. package/cjs/dist/react/core/CategoryList.js +174 -0
  22. package/{dist/react → cjs/dist/react/core}/PayNow.js +2 -2
  23. package/cjs/dist/react/core/Product.d.ts +148 -0
  24. package/cjs/dist/react/core/Product.js +126 -0
  25. package/cjs/dist/react/{ProductList.d.ts → core/ProductList.d.ts} +3 -3
  26. package/cjs/dist/react/{ProductList.js → core/ProductList.js} +10 -10
  27. package/{dist/react → cjs/dist/react/core}/ProductListFilters.d.ts +3 -3
  28. package/{dist/react → cjs/dist/react/core}/ProductListFilters.js +7 -7
  29. package/cjs/dist/react/{ProductListPagination.js → core/ProductListPagination.js} +8 -8
  30. package/{dist/react → cjs/dist/react/core}/ProductListSort.d.ts +1 -1
  31. package/cjs/dist/react/{ProductListSort.js → core/ProductListSort.js} +3 -3
  32. package/{dist/react → cjs/dist/react/core}/ProductModifiers.d.ts +1 -1
  33. package/{dist/react → cjs/dist/react/core}/ProductModifiers.js +13 -13
  34. package/{dist/react → cjs/dist/react/core}/ProductVariantSelector.d.ts +2 -2
  35. package/{dist/react → cjs/dist/react/core}/ProductVariantSelector.js +7 -10
  36. package/{dist/react → cjs/dist/react/core}/SelectedVariant.d.ts +2 -2
  37. package/{dist/react → cjs/dist/react/core}/SelectedVariant.js +43 -15
  38. package/cjs/dist/react/index.d.ts +15 -10
  39. package/cjs/dist/react/index.js +15 -10
  40. package/cjs/dist/react/types.d.ts +8 -0
  41. package/cjs/dist/react/types.js +9 -0
  42. package/cjs/dist/server-actions/custom-checkout-action.js +14 -10
  43. package/cjs/dist/server-actions/index.d.ts +1 -1
  44. package/cjs/dist/server-actions/index.js +1 -1
  45. package/cjs/dist/services/buy-now-service.d.ts +1 -1
  46. package/cjs/dist/services/buy-now-service.js +6 -6
  47. package/cjs/dist/services/categories-list-service.d.ts +4 -4
  48. package/cjs/dist/services/categories-list-service.js +10 -10
  49. package/cjs/dist/services/category-service.d.ts +18 -22
  50. package/cjs/dist/services/category-service.js +12 -10
  51. package/cjs/dist/services/index.d.ts +7 -7
  52. package/cjs/dist/services/index.js +7 -7
  53. package/cjs/dist/services/pay-now-service.d.ts +1 -1
  54. package/cjs/dist/services/pay-now-service.js +4 -4
  55. package/cjs/dist/services/product-modifiers-service.d.ts +3 -3
  56. package/cjs/dist/services/product-modifiers-service.js +7 -7
  57. package/cjs/dist/services/product-service.d.ts +4 -4
  58. package/cjs/dist/services/product-service.js +18 -18
  59. package/cjs/dist/services/products-list-search-service.d.ts +5 -5
  60. package/cjs/dist/services/products-list-search-service.js +117 -117
  61. package/cjs/dist/services/products-list-service.d.ts +4 -4
  62. package/cjs/dist/services/products-list-service.js +12 -12
  63. package/cjs/dist/services/selected-variant-service.d.ts +6 -2
  64. package/cjs/dist/services/selected-variant-service.js +92 -87
  65. package/cjs/dist/utils/index.d.ts +1 -0
  66. package/cjs/dist/utils/index.js +5 -4
  67. package/cjs/dist/utils/renderAsChild.d.ts +96 -0
  68. package/cjs/dist/utils/renderAsChild.js +66 -0
  69. package/cjs/dist/utils/renderChildren.d.ts +41 -0
  70. package/cjs/dist/utils/renderChildren.js +44 -0
  71. package/cjs/dist/utils/url-params.js +3 -3
  72. package/dist/astro/actions/custom-checkout.d.ts +1 -1
  73. package/dist/astro/actions/custom-checkout.js +2 -2
  74. package/dist/astro/actions/index.d.ts +1 -1
  75. package/dist/astro/actions/index.js +1 -1
  76. package/dist/enums/index.d.ts +2 -2
  77. package/dist/enums/index.js +2 -2
  78. package/dist/react/Category.d.ts +168 -67
  79. package/dist/react/Category.js +166 -50
  80. package/dist/react/CategoryList.d.ts +56 -138
  81. package/dist/react/CategoryList.js +44 -129
  82. package/dist/react/Choice.d.ts +193 -0
  83. package/dist/react/Choice.js +259 -0
  84. package/dist/react/Option.d.ts +224 -0
  85. package/dist/react/Option.js +388 -0
  86. package/dist/react/Product.d.ts +339 -96
  87. package/dist/react/Product.js +507 -94
  88. package/dist/react/{BuyNow.js → core/BuyNow.js} +2 -2
  89. package/dist/react/core/Category.d.ts +98 -0
  90. package/dist/react/core/Category.js +81 -0
  91. package/dist/react/core/CategoryList.d.ts +185 -0
  92. package/dist/react/core/CategoryList.js +174 -0
  93. package/{cjs/dist/react → dist/react/core}/PayNow.js +2 -2
  94. package/dist/react/core/Product.d.ts +148 -0
  95. package/dist/react/core/Product.js +126 -0
  96. package/dist/react/{ProductList.d.ts → core/ProductList.d.ts} +3 -3
  97. package/dist/react/{ProductList.js → core/ProductList.js} +10 -10
  98. package/{cjs/dist/react → dist/react/core}/ProductListFilters.d.ts +3 -3
  99. package/{cjs/dist/react → dist/react/core}/ProductListFilters.js +7 -7
  100. package/dist/react/{ProductListPagination.js → core/ProductListPagination.js} +8 -8
  101. package/{cjs/dist/react → dist/react/core}/ProductListSort.d.ts +1 -1
  102. package/dist/react/{ProductListSort.js → core/ProductListSort.js} +3 -3
  103. package/{cjs/dist/react → dist/react/core}/ProductModifiers.d.ts +1 -1
  104. package/{cjs/dist/react → dist/react/core}/ProductModifiers.js +13 -13
  105. package/{cjs/dist/react → dist/react/core}/ProductVariantSelector.d.ts +2 -2
  106. package/{cjs/dist/react → dist/react/core}/ProductVariantSelector.js +7 -10
  107. package/{cjs/dist/react → dist/react/core}/SelectedVariant.d.ts +2 -2
  108. package/{cjs/dist/react → dist/react/core}/SelectedVariant.js +43 -15
  109. package/dist/react/index.d.ts +15 -10
  110. package/dist/react/index.js +15 -10
  111. package/dist/react/types.d.ts +8 -0
  112. package/dist/react/types.js +9 -0
  113. package/dist/server-actions/custom-checkout-action.js +14 -10
  114. package/dist/server-actions/index.d.ts +1 -1
  115. package/dist/server-actions/index.js +1 -1
  116. package/dist/services/buy-now-service.d.ts +1 -1
  117. package/dist/services/buy-now-service.js +6 -6
  118. package/dist/services/categories-list-service.d.ts +4 -4
  119. package/dist/services/categories-list-service.js +10 -10
  120. package/dist/services/category-service.d.ts +18 -22
  121. package/dist/services/category-service.js +12 -10
  122. package/dist/services/index.d.ts +7 -7
  123. package/dist/services/index.js +7 -7
  124. package/dist/services/pay-now-service.d.ts +1 -1
  125. package/dist/services/pay-now-service.js +4 -4
  126. package/dist/services/product-modifiers-service.d.ts +3 -3
  127. package/dist/services/product-modifiers-service.js +7 -7
  128. package/dist/services/product-service.d.ts +4 -4
  129. package/dist/services/product-service.js +18 -18
  130. package/dist/services/products-list-search-service.d.ts +5 -5
  131. package/dist/services/products-list-search-service.js +117 -117
  132. package/dist/services/products-list-service.d.ts +4 -4
  133. package/dist/services/products-list-service.js +12 -12
  134. package/dist/services/selected-variant-service.d.ts +6 -2
  135. package/dist/services/selected-variant-service.js +92 -87
  136. package/dist/utils/index.d.ts +1 -0
  137. package/dist/utils/index.js +5 -4
  138. package/dist/utils/renderAsChild.d.ts +96 -0
  139. package/dist/utils/renderAsChild.js +66 -0
  140. package/dist/utils/renderChildren.d.ts +41 -0
  141. package/dist/utils/renderChildren.js +44 -0
  142. package/dist/utils/url-params.js +3 -3
  143. package/package.json +7 -3
  144. /package/cjs/dist/react/{BuyNow.d.ts → core/BuyNow.d.ts} +0 -0
  145. /package/cjs/dist/react/{PayNow.d.ts → core/PayNow.d.ts} +0 -0
  146. /package/cjs/dist/react/{ProductListPagination.d.ts → core/ProductListPagination.d.ts} +0 -0
  147. /package/dist/react/{BuyNow.d.ts → core/BuyNow.d.ts} +0 -0
  148. /package/dist/react/{PayNow.d.ts → core/PayNow.d.ts} +0 -0
  149. /package/dist/react/{ProductListPagination.d.ts → core/ProductListPagination.d.ts} +0 -0
@@ -1,5 +1,5 @@
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";
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 "@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 { ProductServiceDefinition } from "./product-service.js";
7
- export const SelectedVariantServiceDefinition = defineService("selectedVariant");
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
- // let mediaToDisplay: productsV3.ProductMedia[] = [];
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
- // mediaToDisplay = productItemsImages;
25
+ mediaToDisplay = productItemsImages;
24
26
  }
25
27
  else if (product?.media?.main) {
26
- // mediaToDisplay = [product.media.main];
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
- // mediaToDisplay = selectedChoicesImages;
41
+ mediaToDisplay = selectedChoicesImages;
40
42
  }
41
- // mediaService.setMediaToDisplay(mediaToDisplay ?? []);
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("variantId", variantId)
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("Failed to fetch inventory quantity:", 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: "default",
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 === "ENABLED",
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 || "USD";
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 addToCart = async (quantity = 1, modifiers) => {
296
- try {
297
- isLoading.set(true);
298
- error.set(null);
299
- const prod = v3Product.get();
300
- const variant = currentVariant.get();
301
- if (!prod?._id) {
302
- throw new Error("Product not found");
303
- }
304
- // Build catalog reference with modifiers if provided
305
- const catalogReference = {
306
- catalogItemId: prod._id,
307
- appId: "215238eb-22a5-4c36-9e7b-e7c08025e04e",
308
- options: variant?._id && variant._id !== "default"
309
- ? {
310
- variantId: variant._id,
311
- preOrderRequested: !!variant?.inventoryStatus?.preorderEnabled,
312
- }
313
- : undefined,
314
- };
315
- // Transform and add modifiers to catalog reference if they exist
316
- if (modifiers && Object.keys(modifiers).length > 0) {
317
- const options = {};
318
- const customTextFields = {};
319
- // Get product modifiers to determine types and keys
320
- const productModifiers = prod.modifiers || [];
321
- Object.values(modifiers).forEach((modifierValue) => {
322
- const modifierName = modifierValue.modifierName;
323
- const productModifier = productModifiers.find((m) => m.name === modifierName);
324
- if (!productModifier)
325
- return;
326
- const renderType = productModifier.modifierRenderType;
327
- if (renderType === productsV3.ModifierRenderType.TEXT_CHOICES ||
328
- renderType === productsV3.ModifierRenderType.SWATCH_CHOICES) {
329
- // For choice modifiers, use the modifier key and choice value
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 (Object.keys(customTextFields).length > 0) {
352
- catalogReference.options = {
353
- ...catalogReference.options,
354
- customTextFields,
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
- const lineItems = [
359
- {
360
- catalogReference,
361
- quantity,
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 : "Failed to add to cart");
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,
@@ -1 +1,2 @@
1
1
  export declare function getCheckoutUrlForProduct(productId: string, variantId?: string): Promise<string>;
2
+ export * from './renderAsChild.js';
@@ -1,6 +1,6 @@
1
- import { checkout } from "@wix/ecom";
2
- import { redirects } from "@wix/redirects";
3
- const CATLOG_APP_ID_V3 = "215238eb-22a5-4c36-9e7b-e7c08025e04e";
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("Failed to create checkout");
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
+ }
@@ -66,7 +66,7 @@ export class URLParamsUtils {
66
66
  * ```
67
67
  */
68
68
  static updateURL(params) {
69
- if (typeof window === "undefined")
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({}, "", newURL);
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 === "undefined")
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.51",
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.11",
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