@wix/headless-stores 0.0.9 → 0.0.10
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/react/Category.d.ts +17 -0
- package/cjs/dist/react/Category.js +37 -0
- package/cjs/dist/react/Collection.d.ts +141 -0
- package/cjs/dist/react/Collection.js +198 -0
- package/cjs/dist/react/FilteredCollection.d.ts +65 -0
- package/cjs/dist/react/FilteredCollection.js +117 -0
- package/cjs/dist/react/Product.d.ts +70 -0
- package/cjs/dist/react/Product.js +56 -0
- package/cjs/dist/react/ProductMediaGallery.d.ts +128 -0
- package/cjs/dist/react/ProductMediaGallery.js +100 -0
- package/cjs/dist/react/ProductModifiers.d.ts +156 -0
- package/cjs/dist/react/ProductModifiers.js +159 -0
- package/cjs/dist/react/ProductVariantSelector.d.ts +169 -0
- package/cjs/dist/react/ProductVariantSelector.js +166 -0
- package/cjs/dist/react/RelatedProducts.d.ts +60 -0
- package/cjs/dist/react/RelatedProducts.js +68 -0
- package/cjs/dist/react/SocialSharing.d.ts +119 -0
- package/cjs/dist/react/SocialSharing.js +80 -0
- package/cjs/dist/react/Sort.d.ts +17 -0
- package/cjs/dist/react/Sort.js +41 -0
- package/cjs/dist/react/index.d.ts +10 -0
- package/cjs/dist/react/index.js +33 -0
- package/cjs/dist/services/catalog-options-service.d.ts +30 -0
- package/cjs/dist/services/catalog-options-service.js +162 -0
- package/cjs/dist/services/catalog-price-range-service.d.ts +23 -0
- package/cjs/dist/services/catalog-price-range-service.js +95 -0
- package/cjs/dist/services/category-service.d.ts +25 -0
- package/cjs/dist/services/category-service.js +67 -0
- package/cjs/dist/services/collection-service.d.ts +37 -0
- package/cjs/dist/services/collection-service.js +454 -0
- package/cjs/dist/services/filter-service.d.ts +56 -0
- package/cjs/dist/services/filter-service.js +155 -0
- package/cjs/dist/services/product-media-gallery-service.d.ts +25 -0
- package/cjs/dist/services/product-media-gallery-service.js +105 -0
- package/cjs/dist/services/product-modifiers-service.d.ts +36 -0
- package/cjs/dist/services/product-modifiers-service.js +104 -0
- package/cjs/dist/services/product-service.d.ts +27 -0
- package/cjs/dist/services/product-service.js +51 -0
- package/cjs/dist/services/related-products-service.d.ts +25 -0
- package/cjs/dist/services/related-products-service.js +54 -0
- package/cjs/dist/services/selected-variant-service.d.ts +51 -0
- package/cjs/dist/services/selected-variant-service.js +396 -0
- package/cjs/dist/services/social-sharing-service.d.ts +41 -0
- package/cjs/dist/services/social-sharing-service.js +157 -0
- package/cjs/dist/services/sort-service.d.ts +19 -0
- package/cjs/dist/services/sort-service.js +37 -0
- package/cjs/dist/utils/url-params.d.ts +5 -0
- package/cjs/dist/utils/url-params.js +50 -0
- package/dist/react/Category.d.ts +17 -0
- package/dist/react/Category.js +31 -0
- package/dist/react/Collection.d.ts +141 -0
- package/dist/react/Collection.js +190 -0
- package/dist/react/FilteredCollection.d.ts +65 -0
- package/dist/react/FilteredCollection.js +107 -0
- package/dist/react/Product.d.ts +70 -0
- package/dist/react/Product.js +50 -0
- package/dist/react/ProductMediaGallery.d.ts +128 -0
- package/dist/react/ProductMediaGallery.js +92 -0
- package/dist/react/ProductModifiers.d.ts +156 -0
- package/dist/react/ProductModifiers.js +151 -0
- package/dist/react/ProductVariantSelector.d.ts +169 -0
- package/dist/react/ProductVariantSelector.js +157 -0
- package/dist/react/RelatedProducts.d.ts +60 -0
- package/dist/react/RelatedProducts.js +60 -0
- package/dist/react/SocialSharing.d.ts +119 -0
- package/dist/react/SocialSharing.js +71 -0
- package/dist/react/Sort.d.ts +17 -0
- package/dist/react/Sort.js +36 -0
- package/dist/react/index.d.ts +10 -0
- package/dist/react/index.js +10 -0
- package/dist/services/catalog-options-service.d.ts +30 -0
- package/dist/services/catalog-options-service.js +158 -0
- package/dist/services/catalog-price-range-service.d.ts +23 -0
- package/dist/services/catalog-price-range-service.js +91 -0
- package/dist/services/category-service.d.ts +25 -0
- package/dist/services/category-service.js +63 -0
- package/dist/services/collection-service.d.ts +37 -0
- package/dist/services/collection-service.js +417 -0
- package/dist/services/filter-service.d.ts +56 -0
- package/dist/services/filter-service.js +152 -0
- package/dist/services/product-media-gallery-service.d.ts +25 -0
- package/dist/services/product-media-gallery-service.js +101 -0
- package/dist/services/product-modifiers-service.d.ts +36 -0
- package/dist/services/product-modifiers-service.js +100 -0
- package/dist/services/product-service.d.ts +27 -0
- package/dist/services/product-service.js +47 -0
- package/dist/services/related-products-service.d.ts +25 -0
- package/dist/services/related-products-service.js +50 -0
- package/dist/services/selected-variant-service.d.ts +51 -0
- package/dist/services/selected-variant-service.js +392 -0
- package/dist/services/social-sharing-service.d.ts +41 -0
- package/dist/services/social-sharing-service.js +153 -0
- package/dist/services/sort-service.d.ts +19 -0
- package/dist/services/sort-service.js +34 -0
- package/dist/utils/url-params.d.ts +5 -0
- package/dist/utils/url-params.js +46 -0
- package/package.json +2 -1
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Details = exports.Description = exports.Name = void 0;
|
|
4
|
+
const services_manager_react_1 = require("@wix/services-manager-react");
|
|
5
|
+
const product_service_1 = require("../services/product-service");
|
|
6
|
+
const selected_variant_service_1 = require("../services/selected-variant-service");
|
|
7
|
+
/**
|
|
8
|
+
* Headless component for product name display
|
|
9
|
+
*/
|
|
10
|
+
const Name = (props) => {
|
|
11
|
+
const service = (0, services_manager_react_1.useService)(product_service_1.ProductServiceDefinition);
|
|
12
|
+
const product = service.product.get();
|
|
13
|
+
const name = product?.name || "";
|
|
14
|
+
return props.children({
|
|
15
|
+
name,
|
|
16
|
+
hasName: !!name,
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
exports.Name = Name;
|
|
20
|
+
/**
|
|
21
|
+
* Headless component for product description display
|
|
22
|
+
*/
|
|
23
|
+
const Description = (props) => {
|
|
24
|
+
const service = (0, services_manager_react_1.useService)(product_service_1.ProductServiceDefinition);
|
|
25
|
+
const product = service.product.get();
|
|
26
|
+
// Handle v3 description which can be string or RichContent
|
|
27
|
+
const rawDescription = product?.description;
|
|
28
|
+
const description = typeof rawDescription === "string" ? rawDescription : "";
|
|
29
|
+
const hasDescription = !!description;
|
|
30
|
+
const isHtml = description.includes("<") && description.includes(">");
|
|
31
|
+
return props.children({
|
|
32
|
+
description,
|
|
33
|
+
hasDescription,
|
|
34
|
+
isHtml,
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
exports.Description = Description;
|
|
38
|
+
/**
|
|
39
|
+
* Headless component for product details display
|
|
40
|
+
*/
|
|
41
|
+
const Details = (props) => {
|
|
42
|
+
const selectedVariantService = (0, services_manager_react_1.useService)(selected_variant_service_1.SelectedVariantServiceDefinition);
|
|
43
|
+
const selectedVariant = selectedVariantService.currentVariant?.get();
|
|
44
|
+
let sku = selectedVariant?.sku || null;
|
|
45
|
+
let weight = selectedVariant?.physicalProperties?.weight?.toString() || null;
|
|
46
|
+
let dimensions = null;
|
|
47
|
+
return props.children({
|
|
48
|
+
sku,
|
|
49
|
+
weight,
|
|
50
|
+
dimensions,
|
|
51
|
+
hasSku: !!sku,
|
|
52
|
+
hasWeight: !!weight,
|
|
53
|
+
hasDimensions: false,
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
exports.Details = Details;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Props for Viewport headless component
|
|
3
|
+
*/
|
|
4
|
+
export interface ViewportProps {
|
|
5
|
+
/** Render prop function that receives viewport data */
|
|
6
|
+
children: (props: ViewportRenderProps) => React.ReactNode;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Render props for Viewport component
|
|
10
|
+
*/
|
|
11
|
+
export interface ViewportRenderProps {
|
|
12
|
+
/** Current selected image */
|
|
13
|
+
image: any | null;
|
|
14
|
+
/** Image URL */
|
|
15
|
+
src: string | null;
|
|
16
|
+
/** Alt text for image */
|
|
17
|
+
alt: string;
|
|
18
|
+
/** Whether image is loading */
|
|
19
|
+
isLoading: boolean;
|
|
20
|
+
/** Current image index */
|
|
21
|
+
currentIndex: number;
|
|
22
|
+
/** Total number of images */
|
|
23
|
+
totalImages: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Headless component for displaying the main viewport image
|
|
27
|
+
*/
|
|
28
|
+
export declare const Viewport: (props: ViewportProps) => import("react").ReactNode;
|
|
29
|
+
/**
|
|
30
|
+
* Props for Thumbnail headless component
|
|
31
|
+
*/
|
|
32
|
+
export interface ThumbnailProps {
|
|
33
|
+
/** Index of the media item */
|
|
34
|
+
index: number;
|
|
35
|
+
/** Render prop function that receives thumbnail data */
|
|
36
|
+
children: (props: ThumbnailRenderProps) => React.ReactNode;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Render props for Thumbnail component
|
|
40
|
+
*/
|
|
41
|
+
export interface ThumbnailRenderProps {
|
|
42
|
+
/** Media item data */
|
|
43
|
+
item: any | null;
|
|
44
|
+
/** Thumbnail image URL */
|
|
45
|
+
src: string | null;
|
|
46
|
+
/** Whether this thumbnail is currently active */
|
|
47
|
+
isActive: boolean;
|
|
48
|
+
/** Function to select this image */
|
|
49
|
+
onSelect: () => void;
|
|
50
|
+
/** Index of this thumbnail */
|
|
51
|
+
index: number;
|
|
52
|
+
/** Alt text for thumbnail */
|
|
53
|
+
alt: string;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Headless component for individual media thumbnail
|
|
57
|
+
*/
|
|
58
|
+
export declare const Thumbnail: (props: ThumbnailProps) => import("react").ReactNode;
|
|
59
|
+
/**
|
|
60
|
+
* Props for Next headless component
|
|
61
|
+
*/
|
|
62
|
+
export interface NextProps {
|
|
63
|
+
/** Render prop function that receives next navigation data */
|
|
64
|
+
children: (props: NextRenderProps) => React.ReactNode;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Render props for Next component
|
|
68
|
+
*/
|
|
69
|
+
export interface NextRenderProps {
|
|
70
|
+
/** Function to go to next image */
|
|
71
|
+
onNext: () => void;
|
|
72
|
+
/** Whether there is a next image available */
|
|
73
|
+
canGoNext: boolean;
|
|
74
|
+
/** Current image index */
|
|
75
|
+
currentIndex: number;
|
|
76
|
+
/** Total number of images */
|
|
77
|
+
totalImages: number;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Headless component for next image navigation
|
|
81
|
+
*/
|
|
82
|
+
export declare const Next: (props: NextProps) => import("react").ReactNode;
|
|
83
|
+
/**
|
|
84
|
+
* Props for Previous headless component
|
|
85
|
+
*/
|
|
86
|
+
export interface PreviousProps {
|
|
87
|
+
/** Render prop function that receives previous navigation data */
|
|
88
|
+
children: (props: PreviousRenderProps) => React.ReactNode;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Render props for Previous component
|
|
92
|
+
*/
|
|
93
|
+
export interface PreviousRenderProps {
|
|
94
|
+
/** Function to go to previous image */
|
|
95
|
+
onPrevious: () => void;
|
|
96
|
+
/** Whether there is a previous image available */
|
|
97
|
+
canGoPrevious: boolean;
|
|
98
|
+
/** Current image index */
|
|
99
|
+
currentIndex: number;
|
|
100
|
+
/** Total number of images */
|
|
101
|
+
totalImages: number;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Headless component for previous image navigation
|
|
105
|
+
*/
|
|
106
|
+
export declare const Previous: (props: PreviousProps) => import("react").ReactNode;
|
|
107
|
+
/**
|
|
108
|
+
* Props for Indicator headless component
|
|
109
|
+
*/
|
|
110
|
+
export interface IndicatorProps {
|
|
111
|
+
/** Render prop function that receives indicator data */
|
|
112
|
+
children: (props: IndicatorRenderProps) => React.ReactNode;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Render props for Indicator component
|
|
116
|
+
*/
|
|
117
|
+
export interface IndicatorRenderProps {
|
|
118
|
+
/** Current image index (1-based for display) */
|
|
119
|
+
current: number;
|
|
120
|
+
/** Total number of images */
|
|
121
|
+
total: number;
|
|
122
|
+
/** Whether gallery has images */
|
|
123
|
+
hasImages: boolean;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Headless component for media gallery indicator/counter
|
|
127
|
+
*/
|
|
128
|
+
export declare const Indicator: (props: IndicatorProps) => import("react").ReactNode;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Indicator = exports.Previous = exports.Next = exports.Thumbnail = exports.Viewport = void 0;
|
|
4
|
+
const services_manager_react_1 = require("@wix/services-manager-react");
|
|
5
|
+
const product_media_gallery_service_1 = require("../services/product-media-gallery-service");
|
|
6
|
+
/**
|
|
7
|
+
* Headless component for displaying the main viewport image
|
|
8
|
+
*/
|
|
9
|
+
const Viewport = (props) => {
|
|
10
|
+
const mediaService = (0, services_manager_react_1.useService)(product_media_gallery_service_1.ProductMediaGalleryServiceDefinition);
|
|
11
|
+
const currentIndex = mediaService.selectedImageIndex.get();
|
|
12
|
+
const isLoading = mediaService.isLoading.get();
|
|
13
|
+
const totalImages = mediaService.totalImages.get();
|
|
14
|
+
const productName = mediaService.productName.get();
|
|
15
|
+
const relevantImages = mediaService.relevantImages.get();
|
|
16
|
+
// Get the current image from the relevant images array
|
|
17
|
+
const src = relevantImages[currentIndex] || null;
|
|
18
|
+
const alt = productName || "Product image";
|
|
19
|
+
return props.children({
|
|
20
|
+
image: src,
|
|
21
|
+
src,
|
|
22
|
+
alt,
|
|
23
|
+
isLoading,
|
|
24
|
+
currentIndex,
|
|
25
|
+
totalImages,
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
exports.Viewport = Viewport;
|
|
29
|
+
/**
|
|
30
|
+
* Headless component for individual media thumbnail
|
|
31
|
+
*/
|
|
32
|
+
const Thumbnail = (props) => {
|
|
33
|
+
const mediaService = (0, services_manager_react_1.useService)(product_media_gallery_service_1.ProductMediaGalleryServiceDefinition);
|
|
34
|
+
const product = mediaService.product.get();
|
|
35
|
+
const currentIndex = mediaService.selectedImageIndex.get();
|
|
36
|
+
const productName = mediaService.productName.get();
|
|
37
|
+
const relevantImages = mediaService.relevantImages.get();
|
|
38
|
+
// Get the image source from the centralized relevant images
|
|
39
|
+
const src = relevantImages[props.index] || null;
|
|
40
|
+
const isActive = currentIndex === props.index;
|
|
41
|
+
const alt = `${productName || "Product"} image ${props.index + 1}`;
|
|
42
|
+
const onSelect = () => {
|
|
43
|
+
mediaService.setSelectedImageIndex(props.index);
|
|
44
|
+
};
|
|
45
|
+
return props.children({
|
|
46
|
+
item: product?.media?.main || null,
|
|
47
|
+
src,
|
|
48
|
+
isActive,
|
|
49
|
+
onSelect,
|
|
50
|
+
index: props.index,
|
|
51
|
+
alt,
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
exports.Thumbnail = Thumbnail;
|
|
55
|
+
/**
|
|
56
|
+
* Headless component for next image navigation
|
|
57
|
+
*/
|
|
58
|
+
const Next = (props) => {
|
|
59
|
+
const mediaService = (0, services_manager_react_1.useService)(product_media_gallery_service_1.ProductMediaGalleryServiceDefinition);
|
|
60
|
+
const currentIndex = mediaService.selectedImageIndex.get();
|
|
61
|
+
const totalImages = mediaService.totalImages.get();
|
|
62
|
+
const canGoNext = currentIndex < totalImages - 1;
|
|
63
|
+
return props.children({
|
|
64
|
+
onNext: mediaService.nextImage,
|
|
65
|
+
canGoNext,
|
|
66
|
+
currentIndex,
|
|
67
|
+
totalImages,
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
exports.Next = Next;
|
|
71
|
+
/**
|
|
72
|
+
* Headless component for previous image navigation
|
|
73
|
+
*/
|
|
74
|
+
const Previous = (props) => {
|
|
75
|
+
const mediaService = (0, services_manager_react_1.useService)(product_media_gallery_service_1.ProductMediaGalleryServiceDefinition);
|
|
76
|
+
const currentIndex = mediaService.selectedImageIndex.get();
|
|
77
|
+
const totalImages = mediaService.totalImages.get();
|
|
78
|
+
const canGoPrevious = currentIndex > 0;
|
|
79
|
+
return props.children({
|
|
80
|
+
onPrevious: mediaService.previousImage,
|
|
81
|
+
canGoPrevious,
|
|
82
|
+
currentIndex,
|
|
83
|
+
totalImages,
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
exports.Previous = Previous;
|
|
87
|
+
/**
|
|
88
|
+
* Headless component for media gallery indicator/counter
|
|
89
|
+
*/
|
|
90
|
+
const Indicator = (props) => {
|
|
91
|
+
const mediaService = (0, services_manager_react_1.useService)(product_media_gallery_service_1.ProductMediaGalleryServiceDefinition);
|
|
92
|
+
const currentIndex = mediaService.selectedImageIndex.get();
|
|
93
|
+
const totalImages = mediaService.totalImages.get();
|
|
94
|
+
return props.children({
|
|
95
|
+
current: currentIndex + 1,
|
|
96
|
+
total: totalImages,
|
|
97
|
+
hasImages: totalImages > 0,
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
exports.Indicator = Indicator;
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { productsV3 } from "@wix/stores";
|
|
2
|
+
/**
|
|
3
|
+
* Props for Modifiers headless component
|
|
4
|
+
*/
|
|
5
|
+
export interface ModifiersProps {
|
|
6
|
+
/** Render prop function that receives modifiers data */
|
|
7
|
+
children: (props: ModifiersRenderProps) => React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Render props for Modifiers component
|
|
11
|
+
*/
|
|
12
|
+
export interface ModifiersRenderProps {
|
|
13
|
+
/** Array of product modifiers */
|
|
14
|
+
modifiers: productsV3.ConnectedModifier[];
|
|
15
|
+
/** Whether product has modifiers */
|
|
16
|
+
hasModifiers: boolean;
|
|
17
|
+
/** Currently selected modifier values */
|
|
18
|
+
selectedModifiers: Record<string, any>;
|
|
19
|
+
/** Whether all required modifiers are filled */
|
|
20
|
+
areAllRequiredModifiersFilled: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Headless component for all product modifiers
|
|
24
|
+
*/
|
|
25
|
+
export declare const Modifiers: (props: ModifiersProps) => import("react").ReactNode;
|
|
26
|
+
/**
|
|
27
|
+
* Props for Modifier headless component
|
|
28
|
+
*/
|
|
29
|
+
export interface ModifierProps {
|
|
30
|
+
/** Product modifier data */
|
|
31
|
+
modifier: productsV3.ConnectedModifier;
|
|
32
|
+
/** Render prop function that receives modifier data */
|
|
33
|
+
children: (props: ModifierRenderProps) => React.ReactNode;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Render props for Modifier component
|
|
37
|
+
*/
|
|
38
|
+
export interface ModifierRenderProps {
|
|
39
|
+
/** Modifier name */
|
|
40
|
+
name: string;
|
|
41
|
+
/** Modifier type */
|
|
42
|
+
type: any;
|
|
43
|
+
/** Whether this modifier is mandatory */
|
|
44
|
+
mandatory: boolean;
|
|
45
|
+
/** Array of choices for this modifier (for choice-based modifiers) */
|
|
46
|
+
choices: productsV3.ConnectedModifierChoice[];
|
|
47
|
+
/** Currently selected value for this modifier */
|
|
48
|
+
selectedValue: any;
|
|
49
|
+
/** Whether this modifier has choices */
|
|
50
|
+
hasChoices: boolean;
|
|
51
|
+
/** Whether this modifier is a free text type */
|
|
52
|
+
isFreeText: boolean;
|
|
53
|
+
/** Maximum characters for free text */
|
|
54
|
+
maxChars?: number;
|
|
55
|
+
/** Placeholder text for free text */
|
|
56
|
+
placeholder?: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Headless component for a specific product modifier
|
|
60
|
+
*/
|
|
61
|
+
export declare const Modifier: (props: ModifierProps) => import("react").ReactNode;
|
|
62
|
+
/**
|
|
63
|
+
* Props for ModifierChoice headless component
|
|
64
|
+
*/
|
|
65
|
+
export interface ChoiceProps {
|
|
66
|
+
/** Product modifier data */
|
|
67
|
+
modifier: productsV3.ConnectedModifier;
|
|
68
|
+
/** Choice data */
|
|
69
|
+
choice: productsV3.ConnectedModifierChoice;
|
|
70
|
+
/** Render prop function that receives choice data */
|
|
71
|
+
children: (props: ChoiceRenderProps) => React.ReactNode;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Render props for ModifierChoice component
|
|
75
|
+
*/
|
|
76
|
+
export interface ChoiceRenderProps {
|
|
77
|
+
/** Choice value to display */
|
|
78
|
+
value: string;
|
|
79
|
+
/** Choice description (for color options) */
|
|
80
|
+
description: string | undefined;
|
|
81
|
+
/** Whether this choice is currently selected */
|
|
82
|
+
isSelected: boolean;
|
|
83
|
+
/** Function to select this choice */
|
|
84
|
+
onSelect: () => void;
|
|
85
|
+
/** Modifier name */
|
|
86
|
+
modifierName: string;
|
|
87
|
+
/** Choice value */
|
|
88
|
+
choiceValue: string;
|
|
89
|
+
/** Color code for swatch choices */
|
|
90
|
+
colorCode?: string;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Headless component for individual modifier choice selection
|
|
94
|
+
*/
|
|
95
|
+
export declare const Choice: (props: ChoiceProps) => import("react").ReactNode;
|
|
96
|
+
/**
|
|
97
|
+
* Props for ModifierFreeText headless component
|
|
98
|
+
*/
|
|
99
|
+
export interface FreeTextProps {
|
|
100
|
+
/** Product modifier data */
|
|
101
|
+
modifier: productsV3.ConnectedModifier;
|
|
102
|
+
/** Render prop function that receives free text data */
|
|
103
|
+
children: (props: FreeTextRenderProps) => React.ReactNode;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Render props for ModifierFreeText component
|
|
107
|
+
*/
|
|
108
|
+
export interface FreeTextRenderProps {
|
|
109
|
+
/** Current text value */
|
|
110
|
+
value: string;
|
|
111
|
+
/** Function to update text value */
|
|
112
|
+
onChange: (value: string) => void;
|
|
113
|
+
/** Whether this modifier is mandatory */
|
|
114
|
+
mandatory: boolean;
|
|
115
|
+
/** Maximum characters allowed */
|
|
116
|
+
maxChars?: number;
|
|
117
|
+
/** Placeholder text */
|
|
118
|
+
placeholder?: string;
|
|
119
|
+
/** Character count */
|
|
120
|
+
charCount: number;
|
|
121
|
+
/** Whether character limit is exceeded */
|
|
122
|
+
isOverLimit: boolean;
|
|
123
|
+
/** Modifier name */
|
|
124
|
+
modifierName: string;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Headless component for free text modifier input
|
|
128
|
+
*/
|
|
129
|
+
export declare const FreeText: (props: FreeTextProps) => import("react").ReactNode;
|
|
130
|
+
/**
|
|
131
|
+
* Props for ModifierToggleFreeText headless component
|
|
132
|
+
*/
|
|
133
|
+
export interface ToggleFreeTextProps {
|
|
134
|
+
/** Product modifier data */
|
|
135
|
+
modifier: productsV3.ConnectedModifier;
|
|
136
|
+
/** Render prop function that receives toggle data */
|
|
137
|
+
children: (props: ToggleFreeTextRenderProps) => React.ReactNode;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Render props for ModifierToggleFreeText component
|
|
141
|
+
*/
|
|
142
|
+
export interface ToggleFreeTextRenderProps {
|
|
143
|
+
/** Whether the text input is shown */
|
|
144
|
+
isTextInputShown: boolean;
|
|
145
|
+
/** Function to toggle text input visibility */
|
|
146
|
+
onToggle: () => void;
|
|
147
|
+
/** Whether this modifier is mandatory */
|
|
148
|
+
mandatory: boolean;
|
|
149
|
+
/** Modifier name */
|
|
150
|
+
modifierName: string;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Headless component for toggling free text modifier input
|
|
154
|
+
* Used for optional free text modifiers where a checkbox shows/hides the input
|
|
155
|
+
*/
|
|
156
|
+
export declare const ToggleFreeText: (props: ToggleFreeTextProps) => import("react").ReactNode;
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ToggleFreeText = exports.FreeText = exports.Choice = exports.Modifier = exports.Modifiers = void 0;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const services_manager_react_1 = require("@wix/services-manager-react");
|
|
6
|
+
const product_modifiers_service_1 = require("../services/product-modifiers-service");
|
|
7
|
+
/**
|
|
8
|
+
* Custom hook to safely get the modifiers service
|
|
9
|
+
*/
|
|
10
|
+
function useModifiersService() {
|
|
11
|
+
try {
|
|
12
|
+
return (0, services_manager_react_1.useService)(product_modifiers_service_1.ProductModifiersServiceDefinition);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Headless component for all product modifiers
|
|
20
|
+
*/
|
|
21
|
+
const Modifiers = (props) => {
|
|
22
|
+
const modifiersService = useModifiersService();
|
|
23
|
+
if (!modifiersService) {
|
|
24
|
+
return props.children({
|
|
25
|
+
modifiers: [],
|
|
26
|
+
hasModifiers: false,
|
|
27
|
+
selectedModifiers: {},
|
|
28
|
+
areAllRequiredModifiersFilled: true,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
const modifiers = modifiersService.modifiers.get();
|
|
32
|
+
const hasModifiers = modifiersService.hasModifiers.get();
|
|
33
|
+
const selectedModifiers = modifiersService.selectedModifiers.get();
|
|
34
|
+
const areAllRequiredModifiersFilled = modifiersService.areAllRequiredModifiersFilled();
|
|
35
|
+
return props.children({
|
|
36
|
+
modifiers,
|
|
37
|
+
hasModifiers,
|
|
38
|
+
selectedModifiers,
|
|
39
|
+
areAllRequiredModifiersFilled,
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
exports.Modifiers = Modifiers;
|
|
43
|
+
/**
|
|
44
|
+
* Headless component for a specific product modifier
|
|
45
|
+
*/
|
|
46
|
+
const Modifier = (props) => {
|
|
47
|
+
const modifiersService = useModifiersService();
|
|
48
|
+
const { modifier } = props;
|
|
49
|
+
const name = modifier.name || "";
|
|
50
|
+
const type = modifier.modifierRenderType;
|
|
51
|
+
const mandatory = modifier.mandatory || false;
|
|
52
|
+
const choices = modifier.choicesSettings?.choices || [];
|
|
53
|
+
const hasChoices = choices.length > 0;
|
|
54
|
+
const isFreeText = type === "FREE_TEXT";
|
|
55
|
+
const freeTextSettings = modifier.freeTextSettings;
|
|
56
|
+
const maxChars = freeTextSettings?.maxLength;
|
|
57
|
+
const placeholder = freeTextSettings?.placeholder;
|
|
58
|
+
const selectedValue = modifiersService?.selectedModifiers.get()[name] || null;
|
|
59
|
+
return props.children({
|
|
60
|
+
name,
|
|
61
|
+
type,
|
|
62
|
+
mandatory,
|
|
63
|
+
choices,
|
|
64
|
+
selectedValue,
|
|
65
|
+
hasChoices,
|
|
66
|
+
isFreeText,
|
|
67
|
+
maxChars,
|
|
68
|
+
placeholder,
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
exports.Modifier = Modifier;
|
|
72
|
+
/**
|
|
73
|
+
* Headless component for individual modifier choice selection
|
|
74
|
+
*/
|
|
75
|
+
const Choice = (props) => {
|
|
76
|
+
const modifiersService = useModifiersService();
|
|
77
|
+
const { modifier, choice } = props;
|
|
78
|
+
const modifierName = modifier.name || "";
|
|
79
|
+
const renderType = modifier.modifierRenderType;
|
|
80
|
+
// For TEXT_CHOICES, use choice.key; for SWATCH_CHOICES, use choice.name
|
|
81
|
+
const choiceValue = renderType === "TEXT_CHOICES"
|
|
82
|
+
? (choice.key || choice.name || "")
|
|
83
|
+
: (choice.name || "");
|
|
84
|
+
const value = choice.name || ""; // Display name is always choice.name
|
|
85
|
+
const description = choice.description;
|
|
86
|
+
const colorCode = choice.colorCode;
|
|
87
|
+
const selectedValue = modifiersService?.getModifierValue(modifierName);
|
|
88
|
+
const isSelected = selectedValue?.choiceValue === choiceValue;
|
|
89
|
+
const onSelect = () => {
|
|
90
|
+
modifiersService?.setModifierChoice(modifierName, choiceValue);
|
|
91
|
+
};
|
|
92
|
+
return props.children({
|
|
93
|
+
value,
|
|
94
|
+
description,
|
|
95
|
+
isSelected,
|
|
96
|
+
onSelect,
|
|
97
|
+
modifierName,
|
|
98
|
+
choiceValue,
|
|
99
|
+
colorCode,
|
|
100
|
+
});
|
|
101
|
+
};
|
|
102
|
+
exports.Choice = Choice;
|
|
103
|
+
/**
|
|
104
|
+
* Headless component for free text modifier input
|
|
105
|
+
*/
|
|
106
|
+
const FreeText = (props) => {
|
|
107
|
+
const modifiersService = useModifiersService();
|
|
108
|
+
const { modifier } = props;
|
|
109
|
+
const modifierName = modifier.name || "";
|
|
110
|
+
const mandatory = modifier.mandatory || false;
|
|
111
|
+
const freeTextSettings = modifier.freeTextSettings;
|
|
112
|
+
const maxChars = freeTextSettings?.maxLength;
|
|
113
|
+
const placeholder = freeTextSettings?.placeholder;
|
|
114
|
+
const selectedValue = modifiersService?.getModifierValue(modifierName);
|
|
115
|
+
const value = selectedValue?.freeTextValue || "";
|
|
116
|
+
const charCount = value.length;
|
|
117
|
+
const isOverLimit = maxChars ? charCount > maxChars : false;
|
|
118
|
+
const onChange = (newValue) => {
|
|
119
|
+
if (maxChars && newValue.length > maxChars)
|
|
120
|
+
return;
|
|
121
|
+
modifiersService?.setModifierFreeText(modifierName, newValue);
|
|
122
|
+
};
|
|
123
|
+
return props.children({
|
|
124
|
+
value,
|
|
125
|
+
onChange,
|
|
126
|
+
mandatory,
|
|
127
|
+
maxChars,
|
|
128
|
+
placeholder,
|
|
129
|
+
charCount,
|
|
130
|
+
isOverLimit,
|
|
131
|
+
modifierName,
|
|
132
|
+
});
|
|
133
|
+
};
|
|
134
|
+
exports.FreeText = FreeText;
|
|
135
|
+
/**
|
|
136
|
+
* Headless component for toggling free text modifier input
|
|
137
|
+
* Used for optional free text modifiers where a checkbox shows/hides the input
|
|
138
|
+
*/
|
|
139
|
+
const ToggleFreeText = (props) => {
|
|
140
|
+
const modifiersService = useModifiersService();
|
|
141
|
+
const { modifier } = props;
|
|
142
|
+
const modifierName = modifier.name || "";
|
|
143
|
+
const mandatory = modifier.mandatory || false;
|
|
144
|
+
const [isTextInputShown, setIsTextInputShown] = (0, react_1.useState)(mandatory);
|
|
145
|
+
const onToggle = () => {
|
|
146
|
+
const newState = !isTextInputShown;
|
|
147
|
+
setIsTextInputShown(newState);
|
|
148
|
+
if (!newState) {
|
|
149
|
+
modifiersService?.clearModifier(modifierName);
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
return props.children({
|
|
153
|
+
isTextInputShown,
|
|
154
|
+
onToggle,
|
|
155
|
+
mandatory,
|
|
156
|
+
modifierName,
|
|
157
|
+
});
|
|
158
|
+
};
|
|
159
|
+
exports.ToggleFreeText = ToggleFreeText;
|