@wix/headless-stores 0.0.9 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/cjs/dist/enums/index.d.ts +2 -0
  2. package/cjs/dist/enums/index.js +18 -0
  3. package/cjs/dist/enums/social-platform-enums.d.ts +25 -0
  4. package/cjs/dist/enums/social-platform-enums.js +30 -0
  5. package/cjs/dist/enums/sort-enums.d.ts +17 -0
  6. package/cjs/dist/enums/sort-enums.js +21 -0
  7. package/cjs/dist/react/BuyNow.d.ts +2 -4
  8. package/cjs/dist/react/Category.d.ts +15 -0
  9. package/cjs/dist/react/Category.js +22 -0
  10. package/cjs/dist/react/Collection.d.ts +151 -0
  11. package/cjs/dist/react/Collection.js +209 -0
  12. package/cjs/dist/react/FilteredCollection.d.ts +95 -0
  13. package/cjs/dist/react/FilteredCollection.js +150 -0
  14. package/cjs/dist/react/PayNow.d.ts +2 -4
  15. package/cjs/dist/react/Product.d.ts +43 -0
  16. package/cjs/dist/react/Product.js +35 -0
  17. package/cjs/dist/react/ProductActions.d.ts +42 -0
  18. package/cjs/dist/react/ProductActions.js +83 -0
  19. package/cjs/dist/react/ProductModifiers.d.ts +164 -0
  20. package/cjs/dist/react/ProductModifiers.js +168 -0
  21. package/cjs/dist/react/ProductVariantSelector.d.ts +153 -0
  22. package/cjs/dist/react/ProductVariantSelector.js +138 -0
  23. package/cjs/dist/react/RelatedProducts.d.ts +64 -0
  24. package/cjs/dist/react/RelatedProducts.js +73 -0
  25. package/cjs/dist/react/SelectedVariant.d.ts +66 -0
  26. package/cjs/dist/react/SelectedVariant.js +52 -0
  27. package/cjs/dist/react/SocialSharing.d.ts +112 -0
  28. package/cjs/dist/react/SocialSharing.js +86 -0
  29. package/cjs/dist/react/Sort.d.ts +14 -0
  30. package/cjs/dist/react/Sort.js +17 -0
  31. package/cjs/dist/react/index.d.ts +11 -0
  32. package/cjs/dist/react/index.js +34 -0
  33. package/cjs/dist/services/buy-now-service.js +2 -2
  34. package/cjs/dist/services/catalog-options-service.d.ts +30 -0
  35. package/cjs/dist/services/catalog-options-service.js +156 -0
  36. package/cjs/dist/services/catalog-price-range-service.d.ts +23 -0
  37. package/cjs/dist/services/catalog-price-range-service.js +97 -0
  38. package/cjs/dist/services/category-service.d.ts +26 -0
  39. package/cjs/dist/services/category-service.js +71 -0
  40. package/cjs/dist/services/collection-service.d.ts +37 -0
  41. package/cjs/dist/services/collection-service.js +569 -0
  42. package/cjs/dist/services/filter-service.d.ts +56 -0
  43. package/cjs/dist/services/filter-service.js +147 -0
  44. package/cjs/dist/services/product-media-gallery-service.d.ts +25 -0
  45. package/cjs/dist/services/product-media-gallery-service.js +105 -0
  46. package/cjs/dist/services/product-modifiers-service.d.ts +34 -0
  47. package/cjs/dist/services/product-modifiers-service.js +111 -0
  48. package/cjs/dist/services/product-service.d.ts +28 -0
  49. package/cjs/dist/services/product-service.js +68 -0
  50. package/cjs/dist/services/related-products-service.d.ts +25 -0
  51. package/cjs/dist/services/related-products-service.js +54 -0
  52. package/cjs/dist/services/selected-variant-service.d.ts +59 -0
  53. package/cjs/dist/services/selected-variant-service.js +541 -0
  54. package/cjs/dist/services/social-sharing-service.d.ts +41 -0
  55. package/cjs/dist/services/social-sharing-service.js +141 -0
  56. package/cjs/dist/services/sort-service.d.ts +20 -0
  57. package/cjs/dist/services/sort-service.js +32 -0
  58. package/cjs/dist/utils/url-params.d.ts +5 -0
  59. package/cjs/dist/utils/url-params.js +50 -0
  60. package/dist/enums/index.d.ts +2 -0
  61. package/dist/enums/index.js +2 -0
  62. package/dist/enums/social-platform-enums.d.ts +25 -0
  63. package/dist/enums/social-platform-enums.js +27 -0
  64. package/dist/enums/sort-enums.d.ts +17 -0
  65. package/dist/enums/sort-enums.js +18 -0
  66. package/dist/react/BuyNow.d.ts +2 -4
  67. package/dist/react/Category.d.ts +15 -0
  68. package/dist/react/Category.js +18 -0
  69. package/dist/react/Collection.d.ts +151 -0
  70. package/dist/react/Collection.js +201 -0
  71. package/dist/react/FilteredCollection.d.ts +95 -0
  72. package/dist/react/FilteredCollection.js +140 -0
  73. package/dist/react/PayNow.d.ts +2 -4
  74. package/dist/react/Product.d.ts +43 -0
  75. package/dist/react/Product.js +30 -0
  76. package/dist/react/ProductActions.d.ts +42 -0
  77. package/dist/react/ProductActions.js +79 -0
  78. package/dist/react/ProductModifiers.d.ts +164 -0
  79. package/dist/react/ProductModifiers.js +160 -0
  80. package/dist/react/ProductVariantSelector.d.ts +153 -0
  81. package/dist/react/ProductVariantSelector.js +130 -0
  82. package/dist/react/RelatedProducts.d.ts +64 -0
  83. package/dist/react/RelatedProducts.js +65 -0
  84. package/dist/react/SelectedVariant.d.ts +66 -0
  85. package/dist/react/SelectedVariant.js +46 -0
  86. package/dist/react/SocialSharing.d.ts +112 -0
  87. package/dist/react/SocialSharing.js +77 -0
  88. package/dist/react/Sort.d.ts +14 -0
  89. package/dist/react/Sort.js +14 -0
  90. package/dist/react/index.d.ts +11 -0
  91. package/dist/react/index.js +11 -0
  92. package/dist/services/buy-now-service.js +2 -2
  93. package/dist/services/catalog-options-service.d.ts +30 -0
  94. package/dist/services/catalog-options-service.js +152 -0
  95. package/dist/services/catalog-price-range-service.d.ts +23 -0
  96. package/dist/services/catalog-price-range-service.js +93 -0
  97. package/dist/services/category-service.d.ts +26 -0
  98. package/dist/services/category-service.js +67 -0
  99. package/dist/services/collection-service.d.ts +37 -0
  100. package/dist/services/collection-service.js +532 -0
  101. package/dist/services/filter-service.d.ts +56 -0
  102. package/dist/services/filter-service.js +144 -0
  103. package/dist/services/product-media-gallery-service.d.ts +25 -0
  104. package/dist/services/product-media-gallery-service.js +101 -0
  105. package/dist/services/product-modifiers-service.d.ts +34 -0
  106. package/dist/services/product-modifiers-service.js +107 -0
  107. package/dist/services/product-service.d.ts +28 -0
  108. package/dist/services/product-service.js +64 -0
  109. package/dist/services/related-products-service.d.ts +25 -0
  110. package/dist/services/related-products-service.js +50 -0
  111. package/dist/services/selected-variant-service.d.ts +59 -0
  112. package/dist/services/selected-variant-service.js +538 -0
  113. package/dist/services/social-sharing-service.d.ts +41 -0
  114. package/dist/services/social-sharing-service.js +137 -0
  115. package/dist/services/sort-service.d.ts +20 -0
  116. package/dist/services/sort-service.js +29 -0
  117. package/dist/utils/url-params.d.ts +5 -0
  118. package/dist/utils/url-params.js +46 -0
  119. package/package.json +8 -1
  120. package/dist/astro/BuyNowServiceContext.d.ts +0 -2
  121. package/dist/astro/BuyNowServiceContext.js +0 -6
  122. package/dist/astro/ManagerProviderContext.d.ts +0 -2
  123. package/dist/astro/ManagerProviderContext.js +0 -7
  124. package/dist/astro/withBuyButtonService.d.ts +0 -2
  125. package/dist/astro/withBuyButtonService.js +0 -16
  126. package/dist/react/CurrentCartServiceProvider.d.ts +0 -5
  127. package/dist/react/CurrentCartServiceProvider.js +0 -12
  128. package/dist/react/VariantSelectorServiceProvider.d.ts +0 -7
  129. package/dist/react/VariantSelectorServiceProvider.js +0 -22
  130. package/dist/react/hookim/index.d.ts +0 -5
  131. package/dist/react/hookim/index.js +0 -22
  132. package/dist/services/CurrentCartService.d.ts +0 -18
  133. package/dist/services/CurrentCartService.js +0 -9
  134. package/dist/services/VariantSelectorServices.d.ts +0 -8
  135. package/dist/services/VariantSelectorServices.js +0 -20
@@ -0,0 +1,201 @@
1
+ import { useService } from '@wix/services-manager-react';
2
+ import { CollectionServiceDefinition } from '../services/collection-service';
3
+ import { InventoryAvailabilityStatus, } from '@wix/auto_sdk_stores_products-v-3';
4
+ /**
5
+ * Headless component for product grid
6
+ *
7
+ * @component
8
+ */
9
+ export const Grid = (props) => {
10
+ const service = useService(CollectionServiceDefinition);
11
+ // Debug logging to help identify service issues
12
+ if (!service) {
13
+ console.error('CollectionService is undefined');
14
+ return props.children({
15
+ products: [],
16
+ isLoading: false,
17
+ error: 'Service not available',
18
+ isEmpty: true,
19
+ totalProducts: 0,
20
+ hasProducts: false,
21
+ });
22
+ }
23
+ // Safely access service properties with error handling
24
+ try {
25
+ const productList = service.products?.get() || [];
26
+ const isLoading = service.isLoading?.get() || false;
27
+ const error = service.error?.get() || null;
28
+ const totalProducts = service.totalProducts?.get() || 0;
29
+ const hasProducts = service.hasProducts?.get() || false;
30
+ return props.children({
31
+ products: productList,
32
+ isLoading,
33
+ error,
34
+ isEmpty: !hasProducts && !isLoading,
35
+ totalProducts,
36
+ hasProducts,
37
+ });
38
+ }
39
+ catch (err) {
40
+ console.error('Error accessing service properties:', err);
41
+ return props.children({
42
+ products: [],
43
+ isLoading: false,
44
+ error: 'Failed to load products',
45
+ isEmpty: true,
46
+ totalProducts: 0,
47
+ hasProducts: false,
48
+ });
49
+ }
50
+ };
51
+ /**
52
+ * Headless component for individual product item
53
+ *
54
+ * @component
55
+ */
56
+ export const Item = (props) => {
57
+ const { product } = props;
58
+ // Use actual v3 API structure based on real data
59
+ // Images are in media.main.image, not media.itemsInfo.items
60
+ const image = product?.media?.main?.image || null;
61
+ // Create formatted price since formattedAmount is not available
62
+ const rawAmount = product.actualPriceRange?.minValue?.amount;
63
+ const price = rawAmount ? `$${rawAmount}` : '$0.00';
64
+ // Create formatted compare-at price
65
+ const rawCompareAmount = product.compareAtPriceRange?.minValue?.amount;
66
+ const compareAtPrice = rawCompareAmount ? `$${rawCompareAmount}` : null;
67
+ const availabilityStatus = product.inventory?.availabilityStatus;
68
+ const available = availabilityStatus === InventoryAvailabilityStatus.IN_STOCK ||
69
+ availabilityStatus === InventoryAvailabilityStatus.PARTIALLY_OUT_OF_STOCK;
70
+ const description = typeof product.description === 'string' ? product.description : '';
71
+ return props.children({
72
+ id: product._id || '',
73
+ title: product.name || '',
74
+ slug: product.slug || '',
75
+ image,
76
+ price,
77
+ compareAtPrice,
78
+ description,
79
+ available,
80
+ href: `/store/products/${product.slug}`,
81
+ });
82
+ };
83
+ /**
84
+ * Headless component for load more products functionality
85
+ * Note: V3 API uses simplified loading without traditional pagination
86
+ *
87
+ * @component
88
+ */
89
+ export const LoadMore = (props) => {
90
+ const service = useService(CollectionServiceDefinition);
91
+ // Error handling for undefined service
92
+ if (!service) {
93
+ console.error('CollectionService is undefined in LoadMore');
94
+ return props.children({
95
+ loadMore: async () => { },
96
+ refresh: async () => { },
97
+ isLoading: false,
98
+ hasProducts: false,
99
+ totalProducts: 0,
100
+ hasMoreProducts: false,
101
+ });
102
+ }
103
+ try {
104
+ const isLoading = service.isLoading?.get() || false;
105
+ const hasProducts = service.hasProducts?.get() || false;
106
+ const totalProducts = service.totalProducts?.get() || 0;
107
+ const hasMoreProducts = service.hasMoreProducts?.get() || false;
108
+ return props.children({
109
+ loadMore: service.loadMore || (async () => { }),
110
+ refresh: service.refresh || (async () => { }),
111
+ isLoading,
112
+ hasProducts,
113
+ totalProducts,
114
+ hasMoreProducts,
115
+ });
116
+ }
117
+ catch (err) {
118
+ console.error('Error in LoadMore:', err);
119
+ return props.children({
120
+ loadMore: async () => { },
121
+ refresh: async () => { },
122
+ isLoading: false,
123
+ hasProducts: false,
124
+ totalProducts: 0,
125
+ hasMoreProducts: false,
126
+ });
127
+ }
128
+ };
129
+ /**
130
+ * Headless component for collection header with product count
131
+ *
132
+ * @component
133
+ */
134
+ export const Header = (props) => {
135
+ const service = useService(CollectionServiceDefinition);
136
+ // Error handling for undefined service
137
+ if (!service) {
138
+ console.error('CollectionService is undefined in Header');
139
+ return props.children({
140
+ totalProducts: 0,
141
+ isLoading: false,
142
+ hasProducts: false,
143
+ });
144
+ }
145
+ try {
146
+ const totalProducts = service.totalProducts?.get() || 0;
147
+ const isLoading = service.isLoading?.get() || false;
148
+ const hasProducts = service.hasProducts?.get() || false;
149
+ return props.children({
150
+ totalProducts,
151
+ isLoading,
152
+ hasProducts,
153
+ });
154
+ }
155
+ catch (err) {
156
+ console.error('Error in Header:', err);
157
+ return props.children({
158
+ totalProducts: 0,
159
+ isLoading: false,
160
+ hasProducts: false,
161
+ });
162
+ }
163
+ };
164
+ /**
165
+ * Headless component for collection actions (refresh, load more)
166
+ * Replaces traditional pagination for V3 API
167
+ *
168
+ * @component
169
+ */
170
+ export const Actions = (props) => {
171
+ const service = useService(CollectionServiceDefinition);
172
+ // Error handling for undefined service
173
+ if (!service) {
174
+ console.error('CollectionService is undefined in Actions');
175
+ return props.children({
176
+ refresh: async () => { },
177
+ loadMore: async () => { },
178
+ isLoading: false,
179
+ error: 'Service not available',
180
+ });
181
+ }
182
+ try {
183
+ const isLoading = service.isLoading?.get() || false;
184
+ const error = service.error?.get() || null;
185
+ return props.children({
186
+ refresh: service.refresh || (async () => { }),
187
+ loadMore: service.loadMore || (async () => { }),
188
+ isLoading,
189
+ error,
190
+ });
191
+ }
192
+ catch (err) {
193
+ console.error('Error in Actions:', err);
194
+ return props.children({
195
+ refresh: async () => { },
196
+ loadMore: async () => { },
197
+ isLoading: false,
198
+ error: 'Failed to load actions',
199
+ });
200
+ }
201
+ };
@@ -0,0 +1,95 @@
1
+ import React, { type ReactNode } from 'react';
2
+ import { type AvailableOptions, type FilterServiceAPI, type Filter } from '../services/filter-service';
3
+ import { type V3Product } from '@wix/auto_sdk_stores_products-v-3';
4
+ import { type CollectionServiceAPI } from '../services/collection-service';
5
+ export interface FilteredCollectionProviderProps {
6
+ children: ReactNode;
7
+ }
8
+ /**
9
+ * Headless component for providing a filtered collection
10
+ *
11
+ * @component
12
+ */
13
+ export declare const Provider: React.FC<FilteredCollectionProviderProps>;
14
+ export declare const useFilteredCollection: () => {
15
+ filter: FilterServiceAPI | null;
16
+ collection: CollectionServiceAPI | null;
17
+ };
18
+ export interface FiltersLoadingProps {
19
+ children: (data: {
20
+ isFullyLoaded: boolean;
21
+ }) => ReactNode;
22
+ }
23
+ /**
24
+ * Headless component for displaying a loading state for filters
25
+ *
26
+ * @component
27
+ */
28
+ export declare const FiltersLoading: React.FC<FiltersLoadingProps>;
29
+ export interface FilteredGridProps {
30
+ children: (data: {
31
+ products: V3Product[];
32
+ totalProducts: number;
33
+ isLoading: boolean;
34
+ error: string | null;
35
+ isEmpty: boolean;
36
+ hasMoreProducts: boolean;
37
+ }) => ReactNode;
38
+ }
39
+ /**
40
+ * Headless component for displaying a grid of filtered products
41
+ *
42
+ * @component
43
+ */
44
+ export declare const Grid: React.FC<FilteredGridProps>;
45
+ export interface FilteredItemProps {
46
+ product: V3Product;
47
+ children: (data: {
48
+ title: string;
49
+ image: string | null;
50
+ imageAltText: string | null;
51
+ price: string;
52
+ compareAtPrice: string | null;
53
+ available: boolean;
54
+ slug: string;
55
+ description?: string;
56
+ }) => ReactNode;
57
+ }
58
+ /**
59
+ * Headless component for displaying an individual product item
60
+ *
61
+ * @component
62
+ */
63
+ export declare const Item: React.FC<FilteredItemProps>;
64
+ export interface FilteredLoadMoreProps {
65
+ children: (data: {
66
+ loadMore: () => Promise<void>;
67
+ refresh: () => Promise<void>;
68
+ isLoading: boolean;
69
+ hasProducts: boolean;
70
+ totalProducts: number;
71
+ hasMoreProducts: boolean;
72
+ }) => ReactNode;
73
+ }
74
+ /**
75
+ * Headless component for displaying a load more button
76
+ *
77
+ * @component
78
+ */
79
+ export declare const LoadMore: React.FC<FilteredLoadMoreProps>;
80
+ export interface FilteredFiltersProps {
81
+ children: (data: {
82
+ applyFilters: (filters: Filter) => void;
83
+ clearFilters: () => void;
84
+ currentFilters: Filter;
85
+ allProducts: V3Product[];
86
+ availableOptions: AvailableOptions;
87
+ isFiltered: boolean;
88
+ }) => ReactNode;
89
+ }
90
+ /**
91
+ * Headless component for displaying a filters component
92
+ *
93
+ * @component
94
+ */
95
+ export declare const Filters: React.FC<FilteredFiltersProps>;
@@ -0,0 +1,140 @@
1
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { createContext, useContext } from 'react';
3
+ import { FilterServiceDefinition, } from '../services/filter-service';
4
+ import { useService } from '@wix/services-manager-react';
5
+ import { InventoryAvailabilityStatus, } from '@wix/auto_sdk_stores_products-v-3';
6
+ import { CollectionServiceDefinition, } from '../services/collection-service';
7
+ const FilteredCollectionContext = createContext({ filter: null, collection: null });
8
+ /**
9
+ * Headless component for providing a filtered collection
10
+ *
11
+ * @component
12
+ */
13
+ export const Provider = ({ children, }) => {
14
+ const filter = useService(FilterServiceDefinition);
15
+ const collection = useService(CollectionServiceDefinition);
16
+ return (_jsx(FilteredCollectionContext.Provider, { value: { filter, collection }, children: children }));
17
+ };
18
+ export const useFilteredCollection = () => {
19
+ const context = useContext(FilteredCollectionContext);
20
+ if (!context) {
21
+ throw new Error('useFilteredCollection must be used within a FilteredCollectionProvider');
22
+ }
23
+ return context;
24
+ };
25
+ /**
26
+ * Headless component for displaying a loading state for filters
27
+ *
28
+ * @component
29
+ */
30
+ export const FiltersLoading = ({ children }) => {
31
+ const { filter } = useFilteredCollection();
32
+ const isFullyLoaded = filter.isFullyLoaded.get();
33
+ return _jsx(_Fragment, { children: children({ isFullyLoaded }) });
34
+ };
35
+ /**
36
+ * Headless component for displaying a grid of filtered products
37
+ *
38
+ * @component
39
+ */
40
+ export const Grid = ({ children }) => {
41
+ const { collection } = useFilteredCollection();
42
+ const products = collection.products.get() || [];
43
+ const totalProducts = collection.totalProducts.get();
44
+ const isLoading = collection.isLoading.get();
45
+ const error = collection.error.get();
46
+ const hasProducts = collection.hasProducts.get();
47
+ const hasMoreProducts = collection.hasMoreProducts.get();
48
+ return (_jsx(_Fragment, { children: children({
49
+ products,
50
+ isLoading,
51
+ error,
52
+ isEmpty: !hasProducts,
53
+ totalProducts,
54
+ hasMoreProducts,
55
+ }) }));
56
+ };
57
+ /**
58
+ * Headless component for displaying an individual product item
59
+ *
60
+ * @component
61
+ */
62
+ export const Item = ({ product, children }) => {
63
+ // Safe conversion of product data with type safety guards
64
+ const title = String(product.name || '');
65
+ const image = product.media?.main?.image || null;
66
+ const imageAltText = product.media?.main?.altText || '';
67
+ const price = product.actualPriceRange?.minValue?.formattedAmount ||
68
+ product.actualPriceRange?.maxValue?.formattedAmount ||
69
+ (product.actualPriceRange?.minValue?.amount
70
+ ? `$${product.actualPriceRange.minValue.amount}`
71
+ : '$0.00');
72
+ // Add compare at price
73
+ const compareAtPrice = product.compareAtPriceRange?.minValue?.formattedAmount ||
74
+ (product.compareAtPriceRange?.minValue?.amount
75
+ ? `$${product.compareAtPriceRange.minValue.amount}`
76
+ : null);
77
+ const availabilityStatus = product.inventory?.availabilityStatus;
78
+ const available = availabilityStatus === InventoryAvailabilityStatus.IN_STOCK ||
79
+ availabilityStatus === InventoryAvailabilityStatus.PARTIALLY_OUT_OF_STOCK;
80
+ const slug = String(product.slug || product._id || '');
81
+ const description = product.plainDescription
82
+ ? String(product.plainDescription)
83
+ : undefined;
84
+ return (_jsx(_Fragment, { children: children({
85
+ title,
86
+ image,
87
+ imageAltText,
88
+ price: String(price),
89
+ compareAtPrice,
90
+ available,
91
+ slug,
92
+ description,
93
+ }) }));
94
+ };
95
+ /**
96
+ * Headless component for displaying a load more button
97
+ *
98
+ * @component
99
+ */
100
+ export const LoadMore = ({ children }) => {
101
+ const { collection } = useFilteredCollection();
102
+ const loadMore = collection.loadMore;
103
+ const refresh = collection.refresh;
104
+ const isLoading = collection.isLoading.get();
105
+ const hasProducts = collection.hasProducts.get();
106
+ const totalProducts = collection.totalProducts.get();
107
+ const hasMoreProducts = collection.hasMoreProducts.get();
108
+ return (_jsx(_Fragment, { children: children({
109
+ loadMore,
110
+ refresh,
111
+ isLoading,
112
+ hasProducts,
113
+ totalProducts,
114
+ hasMoreProducts,
115
+ }) }));
116
+ };
117
+ /**
118
+ * Headless component for displaying a filters component
119
+ *
120
+ * @component
121
+ */
122
+ export const Filters = ({ children }) => {
123
+ const { collection, filter } = useFilteredCollection();
124
+ const applyFilters = filter.applyFilters;
125
+ const clearFilters = filter.clearFilters;
126
+ const currentFilters = filter.currentFilters.get();
127
+ const allProducts = collection.products.get();
128
+ const availableOptions = filter.availableOptions.get();
129
+ const isFiltered = currentFilters.priceRange.min !== availableOptions.priceRange.min ||
130
+ currentFilters.priceRange.max !== availableOptions.priceRange.max ||
131
+ Object.keys(currentFilters.selectedOptions).length > 0;
132
+ return (_jsx(_Fragment, { children: children({
133
+ applyFilters,
134
+ clearFilters,
135
+ currentFilters,
136
+ allProducts,
137
+ availableOptions,
138
+ isFiltered,
139
+ }) }));
140
+ };
@@ -1,4 +1,3 @@
1
- export type PayNowRedirectToCheckout = () => void;
2
1
  /**
3
2
  * Props passed to the render function of the PayNow component
4
3
  */
@@ -6,17 +5,16 @@ export interface PayNowRenderProps {
6
5
  /** Whether the buy now operation is currently loading */
7
6
  isLoading: boolean;
8
7
  /** Function to redirect the user to the checkout page */
9
- redirectToCheckout: PayNowRedirectToCheckout;
8
+ redirectToCheckout: () => void;
10
9
  /** The error message if the buy now operation fails */
11
10
  error: string | null;
12
11
  }
13
- export type PayNowChildren = (props: PayNowRenderProps) => React.ReactNode;
14
12
  /**
15
13
  * Props for the PayNow component
16
14
  */
17
15
  export interface PayNowProps {
18
16
  /** Render function that receives buy now state and actions */
19
- children: PayNowChildren;
17
+ children: (props: PayNowRenderProps) => React.ReactNode;
20
18
  }
21
19
  /**
22
20
  * A headless component that provides pay now functionality using the render props pattern.
@@ -0,0 +1,43 @@
1
+ import type { V3Product } from '@wix/auto_sdk_stores_products-v-3';
2
+ /**
3
+ * Props for ProductName headless component
4
+ */
5
+ export interface ProductNameProps {
6
+ /** Render prop function that receives product name data */
7
+ children: (props: ProductNameRenderProps) => React.ReactNode;
8
+ }
9
+ /**
10
+ * Render props for ProductName component
11
+ */
12
+ export interface ProductNameRenderProps {
13
+ /** Product name */
14
+ name: string;
15
+ }
16
+ /**
17
+ * Headless component for product name display
18
+ *
19
+ * @component
20
+ */
21
+ export declare const Name: (props: ProductNameProps) => import("react").ReactNode;
22
+ /**
23
+ * Props for ProductDescription headless component
24
+ */
25
+ export interface ProductDescriptionProps {
26
+ /** Render prop function that receives product description data */
27
+ children: (props: ProductDescriptionRenderProps) => React.ReactNode;
28
+ }
29
+ /**
30
+ * Render props for ProductDescription component
31
+ */
32
+ export interface ProductDescriptionRenderProps {
33
+ /** Product description (may contain HTML) */
34
+ description: NonNullable<V3Product['description']>;
35
+ /** Product plain description */
36
+ plainDescription: NonNullable<V3Product['plainDescription']>;
37
+ }
38
+ /**
39
+ * Headless component for product description display
40
+ *
41
+ * @component
42
+ */
43
+ export declare const Description: (props: ProductDescriptionProps) => import("react").ReactNode;
@@ -0,0 +1,30 @@
1
+ import { useService } from '@wix/services-manager-react';
2
+ import { ProductServiceDefinition } from '../services/product-service';
3
+ /**
4
+ * Headless component for product name display
5
+ *
6
+ * @component
7
+ */
8
+ export const Name = (props) => {
9
+ const service = useService(ProductServiceDefinition);
10
+ const product = service.product.get();
11
+ const name = product.name;
12
+ return props.children({
13
+ name,
14
+ });
15
+ };
16
+ /**
17
+ * Headless component for product description display
18
+ *
19
+ * @component
20
+ */
21
+ export const Description = (props) => {
22
+ const service = useService(ProductServiceDefinition);
23
+ const product = service.product.get();
24
+ const descriptionRichContent = product.description;
25
+ const plainDescription = product.plainDescription;
26
+ return props.children({
27
+ description: descriptionRichContent,
28
+ plainDescription: plainDescription,
29
+ });
30
+ };
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Props for Actions headless component
3
+ */
4
+ export interface ActionsProps {
5
+ /** Quantity to add (optional) */
6
+ quantity?: number;
7
+ /** Render prop function that receives actions data */
8
+ children: (props: ActionsRenderProps) => React.ReactNode;
9
+ }
10
+ /**
11
+ * Render props for Actions component
12
+ */
13
+ export interface ActionsRenderProps {
14
+ /** Function to add product to cart */
15
+ onAddToCart: () => Promise<void>;
16
+ /** Function to buy now (clear cart, add product, proceed to checkout) */
17
+ onBuyNow: () => Promise<void>;
18
+ /** Function to open cart */
19
+ onOpenCart: () => void;
20
+ /** Whether add to cart is available */
21
+ canAddToCart: boolean;
22
+ /** Whether add to cart is currently loading */
23
+ isLoading: boolean;
24
+ /** Current variant price */
25
+ price: string;
26
+ /** Whether variant is in stock */
27
+ inStock: boolean;
28
+ /** Whether pre-order is enabled */
29
+ isPreOrderEnabled: boolean;
30
+ /** Pre-order message */
31
+ preOrderMessage: string | null;
32
+ /** Error message if any */
33
+ error: string | null;
34
+ /** Available quantity */
35
+ availableQuantity: number | null;
36
+ }
37
+ /**
38
+ * Headless component for product actions (add to cart, buy now)
39
+ *
40
+ * @component
41
+ */
42
+ export declare const Actions: (props: ActionsProps) => import("react").ReactNode;
@@ -0,0 +1,79 @@
1
+ import { useService } from '@wix/services-manager-react';
2
+ import { SelectedVariantServiceDefinition } from '../services/selected-variant-service';
3
+ import { ProductModifiersServiceDefinition } from '../services/product-modifiers-service';
4
+ /**
5
+ * Headless component for product actions (add to cart, buy now)
6
+ *
7
+ * @component
8
+ */
9
+ export const Actions = (props) => {
10
+ const variantService = useService(SelectedVariantServiceDefinition);
11
+ // const cartService = useService(CurrentCartServiceDefinition) as ServiceAPI<
12
+ // typeof CurrentCartServiceDefinition
13
+ // >;
14
+ // Try to get modifiers service - it may not exist for all products
15
+ let modifiersService = null;
16
+ try {
17
+ modifiersService = useService(ProductModifiersServiceDefinition);
18
+ }
19
+ catch {
20
+ // Modifiers service not available for this product
21
+ modifiersService = null;
22
+ }
23
+ const price = variantService.currentPrice.get();
24
+ const inStock = variantService.isInStock.get();
25
+ const isPreOrderEnabled = variantService.isPreOrderEnabled.get();
26
+ const preOrderMessage = variantService.preOrderMessage.get();
27
+ const isLoading = variantService.isLoading.get();
28
+ const error = variantService.error.get();
29
+ const availableQuantity = variantService.quantityAvailable.get();
30
+ const quantity = variantService.selectedQuantity.get();
31
+ // Check if all required modifiers are filled
32
+ const areAllRequiredModifiersFilled = modifiersService
33
+ ? modifiersService.areAllRequiredModifiersFilled()
34
+ : true; // If no modifiers service, assume no required modifiers
35
+ const canAddToCart = (inStock || isPreOrderEnabled) &&
36
+ !isLoading &&
37
+ areAllRequiredModifiersFilled;
38
+ const onAddToCart = async () => {
39
+ // Get modifiers data if available
40
+ let modifiersData;
41
+ if (modifiersService) {
42
+ const selectedModifiers = modifiersService.selectedModifiers.get();
43
+ if (Object.keys(selectedModifiers).length > 0) {
44
+ modifiersData = selectedModifiers;
45
+ }
46
+ }
47
+ await variantService.addToCart(quantity, modifiersData);
48
+ };
49
+ const onBuyNow = async () => {
50
+ try {
51
+ // Clear the cart first
52
+ // await cartService.clearCart();
53
+ // Add the product to cart
54
+ await onAddToCart();
55
+ // Proceed to checkout
56
+ // await cartService.proceedToCheckout();
57
+ }
58
+ catch (error) {
59
+ console.error('Buy now failed:', error);
60
+ throw error;
61
+ }
62
+ };
63
+ const onOpenCart = () => {
64
+ // cartService.openCart();
65
+ };
66
+ return props.children({
67
+ onAddToCart,
68
+ onBuyNow,
69
+ onOpenCart,
70
+ canAddToCart,
71
+ isLoading,
72
+ price,
73
+ inStock,
74
+ isPreOrderEnabled,
75
+ preOrderMessage,
76
+ error,
77
+ availableQuantity,
78
+ });
79
+ };