@dropins/storefront-pdp 3.2.0 → 3.3.0-beta.1
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/CHANGELOG.md +18 -0
- package/api/graphql/ProductOptionFragment.graphql.d.ts +1 -1
- package/api.js +5 -5
- package/api.js.map +1 -1
- package/chunks/components.js +1 -1
- package/chunks/components.js.map +1 -1
- package/components/Swatches/Swatches.d.ts +6 -0
- package/containers/ProductAttributes.js +1 -1
- package/containers/ProductAttributes.js.map +1 -1
- package/containers/ProductDetails/ProductDetails.d.ts +1 -0
- package/containers/ProductDetails.js +1 -1
- package/containers/ProductDetails.js.map +1 -1
- package/containers/ProductGallery.js +1 -1
- package/containers/ProductGallery.js.map +1 -1
- package/containers/ProductOptions.js +1 -1
- package/containers/ProductOptions.js.map +1 -1
- package/containers/ProductPrice.js +1 -1
- package/containers/ProductQuantity.js +1 -1
- package/containers/ProductQuantity.js.map +1 -1
- package/data/models/product-model.d.ts +5 -1
- package/data/models/values-model.d.ts +2 -0
- package/fragments.js +1 -0
- package/fragments.js.map +1 -1
- package/i18n/en_US.json.d.ts +3 -0
- package/lib/bundle-option-quantities.d.ts +16 -0
- package/package.json +1 -1
- package/render.js +3 -2
- package/render.js.map +1 -1
package/chunks/components.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components.js","sources":["../../node_modules/@adobe-commerce/elsie/src/icons/ChevronDown.svg","../../node_modules/@adobe-commerce/elsie/src/icons/Close.svg","/@dropins/storefront-pdp/src/components/Carousel/Carousel.tsx","/@dropins/storefront-pdp/src/components/Product/Product.tsx","/@dropins/storefront-pdp/src/components/GalleryGrid/GalleryGrid.tsx","/@dropins/storefront-pdp/src/components/PriceRange/PriceRange.tsx","/@dropins/storefront-pdp/src/components/Overlay/Overlay.tsx","/@dropins/storefront-pdp/src/components/Swatches/Swatches.tsx","/@dropins/storefront-pdp/src/components/Zoom/Zoom.tsx","/@dropins/storefront-pdp/src/components/Header/Header.tsx","/@dropins/storefront-pdp/src/components/Price/Price.tsx","/@dropins/storefront-pdp/src/components/PriceTiers/PriceTiers.tsx","/@dropins/storefront-pdp/src/components/GiftCardOptions/GiftCardOptions.tsx","/@dropins/storefront-pdp/src/components/DownloadableOptions/DownloadableOptions.tsx"],"sourcesContent":["import * as React from \"react\";\nconst SvgChevronDown = (props) => /* @__PURE__ */ React.createElement(\"svg\", { width: 24, height: 24, viewBox: \"0 0 24 24\", fill: \"none\", xmlns: \"http://www.w3.org/2000/svg\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { vectorEffect: \"non-scaling-stroke\", d: \"M7.74512 9.87701L12.0001 14.132L16.2551 9.87701\", stroke: \"currentColor\", strokeWidth: 1, strokeLinecap: \"square\", strokeLinejoin: \"round\" }));\nexport default SvgChevronDown;\n","import * as React from \"react\";\nconst SvgClose = (props) => /* @__PURE__ */ React.createElement(\"svg\", { width: 24, height: 24, viewBox: \"0 0 24 24\", fill: \"none\", xmlns: \"http://www.w3.org/2000/svg\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { vectorEffect: \"non-scaling-stroke\", d: \"M18.3599 5.64001L5.62988 18.37\", stroke: \"currentColor\" }), /* @__PURE__ */ React.createElement(\"path\", { vectorEffect: \"non-scaling-stroke\", d: \"M18.3599 18.37L5.62988 5.64001\", stroke: \"currentColor\" }));\nexport default SvgClose;\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2023 Adobe\n * All Rights Reserved.\n * __________________\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n */\n\nimport { FunctionComponent, VNode } from 'preact';\nimport {\n HTMLAttributes,\n Children,\n useState,\n useRef,\n useEffect,\n useMemo,\n useCallback,\n useLayoutEffect,\n} from 'preact/compat';\nimport { classes, debounce } from '@adobe-commerce/elsie/lib';\nimport { Button, Icon } from '@adobe-commerce/elsie/components';\nimport { ChevronDown } from '@adobe-commerce/elsie/icons';\nimport { useText } from '@adobe-commerce/elsie/i18n';\n\nimport '@/pdp/components/Carousel/Carousel.css';\n\ntype Show = number;\n\nconst PEAK_WIDTH = 24;\nconst THUMB_GAP = 16;\nconst ICON_SIZE = '32';\n\nenum GapSize {\n small = 16,\n medium = 24,\n large = 64,\n}\n\nexport interface CarouselProps\n extends Omit<HTMLAttributes<HTMLDivElement>, 'controls'> {\n children: VNode[] | VNode;\n thumbnails?: VNode[] | VNode;\n show?: Show | { small: Show; medium: Show; large: Show };\n gap?: 'small' | 'medium' | 'large' | null;\n scrollbar?: boolean;\n peak?: boolean;\n arrows?: boolean;\n controls?: 'thumbnailsRow' | 'thumbnailsColumn' | 'dots' | null;\n arrowsOnMainImage?: boolean;\n loop?: boolean;\n direction?: 'horizontal';\n style?: Record<string, string | number>;\n width?: string;\n height?: string;\n defaultIndex?: number;\n infinite?: boolean;\n isZoomed?: boolean;\n}\n\nexport const Carousel: FunctionComponent<CarouselProps> = ({\n show = 1,\n scrollbar = false,\n peak = false,\n arrows = false,\n controls = 'dots',\n arrowsOnMainImage = false,\n loop = false,\n gap = null,\n direction = 'horizontal',\n width = '100%',\n height = '100%',\n defaultIndex = 0,\n className,\n children,\n thumbnails = null,\n isZoomed,\n ...props\n}) => {\n // i18n\n const Label = useText('PDP.Carousel.label').label;\n const SlideLabel = useText('PDP.Carousel.Slide.label').label;\n const PreviousLabel = useText('PDP.Carousel.Previous.label').label;\n const NextLabel = useText('PDP.Carousel.Next.label').label;\n const ControlsLabel = useText('PDP.Carousel.Controls.label').label;\n const ControlsBtnLabel = useText('PDP.Carousel.Controls.Button.label').label;\n\n // States\n const [perPage, setPerPage] = useState(() => getPerPageFromBreakpoint(show));\n\n // Constants\n const length = Math.ceil(Children.count(children) / perPage);\n\n const peakWidth = peak ? PEAK_WIDTH : 0;\n const gapWidth = gap ? GapSize[gap] : 0;\n const rest = Children.count(children) % perPage;\n\n // States\n const [current, setCurrent] = useState(\n loop ? (isRTL() ? defaultIndex - 1 : defaultIndex + 1) : defaultIndex\n );\n\n // Thumbnails (refs for each thumbnail item)\n const thumbnailsRefs = useRef<HTMLLabelElement[]>([]);\n const [thumbWidth, setThumbWidth] = useState(0);\n const [thumbHeight, setThumbHeight] = useState(0);\n\n // VNodes\n const thumbnailSlides = useMemo<VNode[]>(() => {\n return Children.toArray(thumbnails);\n }, [thumbnails]);\n\n // Slides\n const slides = useMemo<VNode[][]>(() => {\n const returnValue = Children.toArray(children).reduce((acc, child, i) => {\n if (i % perPage === 0) {\n return [...acc, [child]];\n }\n\n return [...acc.slice(0, -1), [...acc[acc.length - 1], child]];\n }, [] as VNode[][]);\n\n if (!loop || returnValue.length === 1) {\n return returnValue;\n }\n\n if (loop && !(Children.count(children) % perPage !== 0)) {\n return [returnValue[length - 1]]\n .concat(returnValue)\n .concat([returnValue[0], returnValue[1]]);\n }\n\n return [Children.toArray(children).slice(-perPage)]\n .concat(returnValue)\n .concat([returnValue[0], returnValue[1]]);\n }, [children, perPage, length, loop]);\n\n // Wrapper\n const wrapperRef = useRef<HTMLDivElement>(null);\n const thumbnailsWrapperRef = useRef<HTMLDivElement>(null);\n\n const thumbnailControls =\n controls === 'thumbnailsRow' || controls === 'thumbnailsColumn';\n\n // Observe Resize (responsive)\n useEffect(() => {\n const wrapper = wrapperRef.current;\n\n if (!wrapper) return; // Guard clause in case the ref is not set yet\n\n const handleResize = debounce(() => {\n setThumbWidth(wrapper.offsetWidth ?? 0);\n setThumbHeight(wrapper.offsetHeight ?? 0);\n const width = window.innerWidth;\n const newPerPage = getPerPageFromBreakpoint(show, width);\n\n if (newPerPage !== perPage) {\n setPerPage(newPerPage);\n }\n }, 50);\n\n const observer = new ResizeObserver(handleResize);\n observer.observe(wrapper);\n\n return () => {\n observer.unobserve(wrapper);\n };\n }, [perPage, show]);\n\n // Scrolling logic controls\n const handleThumbnailsScroll = useCallback(\n (nextSlideIndex: number) => {\n const nextItem = loop ? nextSlideIndex - 1 : nextSlideIndex;\n const thumbnailRef = thumbnailsRefs?.current[0];\n const oneItemWidth = thumbnailRef?.offsetWidth + THUMB_GAP;\n const oneItemHeight = thumbnailRef?.offsetHeight + THUMB_GAP;\n const thumbnailsWrapper = thumbnailsWrapperRef.current!;\n\n const isRow = controls === 'thumbnailsRow';\n const isColumn = controls === 'thumbnailsColumn';\n const offset = isRow\n ? thumbnailsWrapper?.offsetWidth\n : thumbnailsWrapper?.offsetHeight;\n const oneItemSize = isRow ? oneItemWidth : oneItemHeight;\n\n if ((isRow || isColumn) && offset) {\n const visibleThumbnails = Math.floor(\n (isRow\n ? thumbnailsWrapper.clientWidth\n : thumbnailsWrapper.clientHeight) / oneItemSize\n );\n const centerOffset = Math.floor(visibleThumbnails / 2);\n const targetScrollPosition = (nextItem - centerOffset) * oneItemSize;\n thumbnailsWrapper.style.scrollBehavior = 'smooth';\n\n if (isRow) {\n thumbnailsWrapper.scrollLeft = isRTL()\n ? -(\n thumbnailsWrapper.scrollWidth -\n thumbnailsWrapper.clientWidth -\n targetScrollPosition\n )\n : targetScrollPosition;\n } else {\n thumbnailsWrapper.scrollTop = targetScrollPosition;\n }\n }\n },\n [controls, loop]\n );\n\n useEffect(() => {\n handleThumbnailsScroll(current);\n }, [current, handleThumbnailsScroll]);\n\n // Navigation\n const handleScrollTo = useCallback(\n (nextSlideIndex: number, smooth?: boolean, reset?: boolean) => {\n if (thumbnailControls) {\n handleThumbnailsScroll(nextSlideIndex);\n }\n\n const wrapper = wrapperRef.current!;\n const realWidth = peakWidth\n ? wrapper.offsetWidth - peakWidth\n : wrapper.offsetWidth - peakWidth + gapWidth;\n\n const items = Array.from(wrapper.querySelectorAll('[data-index]')).filter(\n (element) => {\n const dataIndex = Number(element.getAttribute('data-index')!);\n return !isNaN(dataIndex) && dataIndex > -1;\n }\n );\n\n const item = items[nextSlideIndex];\n\n if (!item) {\n return;\n }\n\n if (reset) {\n const futureIndex = nextSlideIndex === 0 ? length : 0;\n const scrollWidth =\n realWidth * (length + (rest ? rest : perPage) / perPage);\n\n if (isRTL()) {\n if (\n wrapper.scrollLeft <= 0 &&\n wrapper.scrollLeft > -(realWidth - 5)\n ) {\n handleScrollTo(1, true);\n return;\n }\n if (\n wrapper.scrollLeft < realWidth - scrollWidth &&\n wrapper.scrollLeft >= -scrollWidth\n ) {\n handleScrollTo(length, true);\n return;\n }\n\n wrapper.style.scrollBehavior = 'auto';\n wrapper.scrollLeft = futureIndex === 0 ? 0 : -scrollWidth;\n handleScrollTo(futureIndex === 0 ? 1 : length, true);\n } else {\n if (wrapper.scrollLeft >= 0 && wrapper.scrollLeft < realWidth - 5) {\n handleScrollTo(1, true);\n return;\n }\n\n if (\n wrapper.scrollLeft > scrollWidth - realWidth &&\n wrapper.scrollLeft <= scrollWidth\n ) {\n handleScrollTo(length, true);\n return;\n }\n\n wrapper.style.scrollBehavior = 'auto';\n wrapper.scrollLeft = futureIndex === 0 ? 0 : scrollWidth;\n handleScrollTo(futureIndex === 0 ? 1 : length, true);\n return;\n }\n }\n\n const diff =\n ((wrapper.offsetWidth - gapWidth) / perPage) *\n slides[nextSlideIndex].length -\n peakWidth;\n\n wrapper.style.scrollBehavior = smooth ? 'smooth' : 'auto';\n wrapper.scrollLeft = isRTL()\n ? -(slides[nextSlideIndex].length === perPage\n ? realWidth * nextSlideIndex\n : realWidth * (nextSlideIndex - 1) - diff)\n : slides[nextSlideIndex].length === perPage\n ? realWidth * nextSlideIndex\n : realWidth * (nextSlideIndex - 1) + diff;\n return;\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n gapWidth,\n length,\n peakWidth,\n perPage,\n rest,\n slides,\n handleThumbnailsScroll,\n controls,\n ]\n );\n\n const handleGoToPrev = useCallback(() => {\n if (loop) {\n const nextSlideIndex = current - 1;\n handleScrollTo(\n nextSlideIndex,\n true,\n isRTL() ? current === length - 1 : current === 1\n );\n return;\n }\n\n const nextSlideIndex = current <= 0 ? 0 : current - 1;\n handleScrollTo(nextSlideIndex, true);\n }, [current, handleScrollTo, loop]); //eslint-disable-line react-hooks/exhaustive-deps\n\n const handleGoToNext = useCallback(() => {\n const lastSlideIndex = slides.length - 1;\n\n if (loop) {\n const nextSlideIndex = current + 1;\n handleScrollTo(\n nextSlideIndex,\n true,\n isRTL() ? current === 0 : current === length\n );\n return;\n }\n\n const nextSlideIndex =\n current >= lastSlideIndex ? lastSlideIndex : current + 1;\n\n handleScrollTo(nextSlideIndex, true);\n }, [slides.length, loop, current, handleScrollTo, length]);\n\n // Navigate with keyboard\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'ArrowLeft') {\n isRTL() ? handleGoToNext() : handleGoToPrev();\n }\n\n if (event.key === 'ArrowRight') {\n isRTL() ? handleGoToPrev() : handleGoToNext();\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n\n return () => {\n window.removeEventListener('keydown', handleKeyDown);\n };\n }, [handleGoToNext, handleGoToPrev]);\n\n // Set default index\n useLayoutEffect(() => {\n handleScrollTo(loop ? defaultIndex + 1 : defaultIndex, false);\n }, [defaultIndex, handleScrollTo, loop, thumbWidth]);\n\n // Track scrolling (swipes)\n const handleOnScroll = debounce(() => {\n const wrapper = wrapperRef.current!;\n const realWidth = peakWidth\n ? wrapper.offsetWidth - peakWidth\n : wrapper.offsetWidth - peakWidth + gapWidth;\n\n const dividing = Math.abs(wrapper.scrollLeft) / realWidth;\n const nextSlideIndex = Math.abs(\n Math.round(dividing) - dividing < 1\n ? Math.round(dividing)\n : Math.ceil(dividing)\n );\n\n if (thumbnailControls) {\n handleThumbnailsScroll(nextSlideIndex);\n }\n\n if (loop) {\n const totalWidth =\n realWidth * (length + (rest ? rest : perPage) / perPage);\n const scrollOffset = isRTL() ? -wrapper.scrollLeft : wrapper.scrollLeft;\n\n if (Math.ceil(Math.abs(scrollOffset)) >= Math.ceil(totalWidth) - 5) {\n wrapper.style.scrollBehavior = 'auto';\n wrapper.scrollLeft = isRTL()\n ? -wrapper.offsetWidth +\n (Math.ceil(scrollOffset) - Math.ceil(totalWidth) - peakWidth)\n : wrapper.offsetWidth +\n (Math.ceil(scrollOffset) - Math.ceil(totalWidth) - peakWidth);\n return;\n }\n\n if (Math.abs(scrollOffset) === 0) {\n wrapper.style.scrollBehavior = 'auto';\n\n wrapper.scrollLeft = isRTL()\n ? -(totalWidth - wrapper.offsetWidth + peakWidth)\n : totalWidth - wrapper.offsetWidth + peakWidth;\n return;\n }\n }\n\n if (current !== nextSlideIndex) {\n setCurrent(nextSlideIndex);\n }\n }, 100);\n\n useEffect(() => {\n const wrapper = wrapperRef.current;\n wrapper?.addEventListener('scroll', handleOnScroll);\n\n return () => {\n wrapper?.removeEventListener('scroll', handleOnScroll);\n };\n }, [handleOnScroll]);\n\n // thumbnails is column -> container is row reverse, controls is column\n // thumbnails is row -> container is column, controls is row\n const getArrow = (\n forThumbnails: boolean,\n direction: string,\n callback: () => void\n ) => {\n return (\n <Button\n className={classes([\n ['pdp-carousel__button', !forThumbnails],\n [`pdp-carousel__button--${direction}`, !forThumbnails],\n [`pdp-carousel__button--${controls}`, forThumbnails],\n ])}\n style={{\n '--height': `${thumbHeight}px`,\n }}\n variant=\"tertiary\"\n aria-label={direction === 'next' ? NextLabel : PreviousLabel}\n onClick={callback}\n disabled={\n loop\n ? false\n : direction === 'next'\n ? current >= slides.length - 1\n : current < 1\n }\n >\n <Icon\n className={classes([\n ['pdp-carousel__button__icon', !forThumbnails],\n [`pdp-carousel__button__icon--${direction}`, !forThumbnails],\n [\n `pdp-carousel__button__icon--${controls}--${direction}`,\n forThumbnails,\n ],\n ])}\n size={ICON_SIZE}\n source={ChevronDown}\n />\n </Button>\n );\n };\n\n const prevArrow =\n arrows &&\n slides.length != 1 &&\n getArrow(thumbnailControls, 'prev', handleGoToPrev);\n\n const nextArrow =\n arrows &&\n slides.length != 1 &&\n getArrow(thumbnailControls, 'next', handleGoToNext);\n\n const prevArrowMainImage =\n arrows && slides.length != 1 && getArrow(false, 'prev', handleGoToPrev);\n\n const nextArrowMainImage =\n arrows && slides.length != 1 && getArrow(false, 'next', handleGoToNext);\n\n return (\n <div\n role=\"region\"\n aria-roledescription={Label}\n className={classes([\n 'pdp-carousel',\n ['pdp-carousel--main-image-controls', arrowsOnMainImage],\n ['pdp-carousel--arrows', arrows && !thumbnailControls],\n [`pdp-carousel--${controls}`, thumbnailControls],\n className,\n ])}\n style={{\n '--flex-carousel':\n controls === 'thumbnailsColumn' ? 'row-reverse' : 'column',\n '--gap': thumbnailControls ? '0' : 'var(--spacing-small)',\n '--width': width,\n }}\n {...props}\n >\n {/* Slideshow */}\n <div\n ref={wrapperRef}\n className={classes([\n 'pdp-carousel__wrapper',\n `pdp-carousel__wrapper--${direction}`,\n ['pdp-carousel__wrapper--scrollbar', scrollbar],\n ['pdp-carousel__wrapper--peak', peak],\n ])}\n style={{\n '--total-width': controls === 'thumbnailsColumn' ? `81.6%` : `100%`,\n '--height': controls === 'thumbnailsColumn' ? 'auto' : height,\n '--gap': gap ? `var(--spacing-${gap})` : '0px',\n '--per-page': perPage,\n }}\n tabIndex={0}\n >\n {slides.map((page, index) => {\n const orphan = page.length < perPage;\n\n return (\n <div\n key={index}\n role=\"group\"\n aria-roledescription={SlideLabel}\n data-index={index}\n className={classes([\n 'pdp-carousel__slide',\n `pdp-carousel__slide--${direction}`,\n ['pdp-carousel__slide--active', current === index],\n ['pdp-carousel__slide--orphan', orphan],\n ['pdp-carousel__slide--hidden', thumbWidth === 0],\n ])}\n style={{\n '--length': page.length,\n }}\n >\n {page}\n </div>\n );\n })}\n </div>\n\n {/* Previous and next arrows for Carousel without thumbnails */}\n {!thumbnailControls && (\n <>\n {prevArrow}\n {nextArrow}\n </>\n )}\n\n {thumbnailControls && arrowsOnMainImage && (\n <>\n {prevArrowMainImage}\n {nextArrowMainImage}\n </>\n )}\n\n {/* Controls */}\n {controls && slides.length != 1 && (\n <div\n className={classes([\n [\n `pdp-carousel__controls__container--${controls}`,\n thumbnailControls,\n ],\n [\n 'pdp-carousel__controls__container--no-arrows',\n !arrows || arrowsOnMainImage,\n ],\n ])}\n style={{\n '--width': controls === 'thumbnailsRow' ? `${thumbWidth}px` : width,\n '--height': `${thumbHeight}px`,\n '--nr-thumbnails': thumbnailSlides.length,\n }}\n >\n {(thumbnailControls || isZoomed) && !arrowsOnMainImage && prevArrow}\n\n <div\n ref={thumbnailsWrapperRef}\n className={classes([\n [\n `pdp-carousel__controls__wrapper--${controls}`,\n thumbnailControls,\n ],\n [`pdp-carousel__controls__wrapper`, thumbnailControls],\n ])}\n >\n <div\n role=\"group\"\n aria-label={ControlsLabel}\n className={classes([\n 'pdp-carousel__controls',\n [`pdp-carousel__controls--${controls}`, thumbnailControls],\n ])}\n >\n {(loop ? slides.slice(0, length) : slides).map((_, key) => {\n const buttonsLength = loop ? length : slides.length;\n const active = loop ? current - 1 === key : current === key;\n\n if (!thumbnailControls) {\n return (\n <button\n key={key}\n aria-label={ControlsBtnLabel.replace(\n '{key}',\n String(key + 1)\n ).replace('{total}', String(buttonsLength))}\n onClick={() => {\n handleScrollTo(loop ? key + 1 : key, true);\n }}\n className={classes([\n 'pdp-carousel__controls__button',\n ['pdp-carousel__controls__button--active', active],\n ])}\n />\n );\n }\n return (\n <label\n className={classes(['pdp-carousel__thumbnail__container'])}\n key={key}\n ref={(el: HTMLLabelElement | null) => {\n if (el) {\n thumbnailsRefs.current[key] = el;\n }\n }}\n >\n <input\n type=\"radio\"\n name={'carousel-thumbnails'}\n aria-label={ControlsBtnLabel.replace(\n '{key}',\n String(key + 1)\n ).replace('{total}', String(buttonsLength))}\n checked={active && thumbWidth !== 0}\n onChange={() => {\n handleScrollTo(loop ? key + 1 : key, true);\n }}\n {...props}\n className={classes([\n 'pdp-carousel__thumbnail',\n [\n 'pdp-carousel__thumbnail--selected',\n active && thumbWidth !== 0,\n ],\n ])}\n />\n\n <span\n className={classes(['pdp-carousel__thumbnail__span'])}\n >\n {thumbnailSlides[key]}\n </span>\n </label>\n );\n })}\n </div>\n </div>\n\n {(thumbnailControls || isZoomed) && !arrowsOnMainImage && nextArrow}\n </div>\n )}\n </div>\n );\n};\n\n// Utilities\nfunction getPerPageFromBreakpoint(\n breakpoints: { small: number; medium: number; large: number } | number,\n width = 0\n) {\n if (typeof breakpoints === 'number') return breakpoints;\n\n const { small, medium, large } = breakpoints;\n const breakpointsMap = [\n { breakpoint: 1024, value: large },\n { breakpoint: 786, value: medium },\n { breakpoint: 0, value: small },\n ];\n\n const matchingBreakpoint = breakpointsMap.find(\n ({ breakpoint }) => width > breakpoint\n );\n\n return matchingBreakpoint ? matchingBreakpoint.value : small;\n}\n\nfunction isRTL() {\n return document.documentElement.dir === 'rtl';\n}\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2023 Adobe\n * All Rights Reserved.\n * __________________\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n */\n\nimport { FunctionComponent, VNode } from 'preact';\nimport { HTMLAttributes, useState } from 'preact/compat';\nimport { classes, VComponent } from '@adobe-commerce/elsie/lib';\nimport { useText } from '@adobe-commerce/elsie/i18n';\n\nimport { Carousel, GalleryGrid, Overlay, Zoom } from '@/pdp/components';\nimport '@/pdp/components/Product/Product.css';\n\nimport { CarouselConfig } from '@/pdp/containers';\n\ninterface ProductCarouselConfig extends CarouselConfig {\n thumbnails: VNode[];\n}\n\nexport interface ProductProps\n extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n title?: VNode;\n breadcrumbs?: VNode;\n galleryContent?: VNode;\n infoContent?: VNode;\n productContent?: VNode;\n shortDescription?: VNode;\n description?: VNode;\n attributes?: VNode;\n images: VNode[];\n options?: VNode;\n giftCardOptions?: VNode;\n downloadableOptions?: VNode;\n sku?: VNode;\n price?: VNode;\n specialPrice?: VNode;\n outOfStock: boolean;\n actions?: VNode;\n quantity?: VNode;\n carouselConfig?: ProductCarouselConfig;\n zoomType?: 'zoom' | 'overlay';\n closeButton?: boolean;\n}\n\nexport const Product: FunctionComponent<ProductProps> = ({\n title,\n breadcrumbs,\n galleryContent,\n infoContent,\n productContent,\n sku,\n outOfStock,\n shortDescription,\n description,\n attributes,\n images,\n options,\n giftCardOptions,\n downloadableOptions,\n price,\n specialPrice,\n className,\n children,\n quantity,\n actions,\n carouselConfig,\n zoomType = 'overlay',\n closeButton = true,\n ...props\n}) => {\n // i18n\n const RegularPriceLabel = useText('PDP.Product.RegularPrice.label').label;\n const SpecialPriceLabel = useText('PDP.Product.SpecialPrice.label').label;\n const OutOfStockLabel = useText('PDP.Product.OutOfStock.label').label;\n const ImagesLabel = useText('PDP.Product.Image.label').label;\n\n const [zoom, setZoom] = useState<number | null>(null);\n\n const galleryImages = images?.length ? (\n images.map((image, key) => {\n const alt =\n title?.props?.children &&\n ImagesLabel?.replace('{product}', title.props.children.toString())\n .replace('{key}', String(key + 1))\n .replace('{total}', String(images.length));\n return zoomType === 'zoom' ? (\n <Zoom closeButton={closeButton}>\n <VComponent\n key={key}\n node={image}\n loading={key === 0 ? 'eager' : 'lazy'}\n alt={alt}\n />\n </Zoom>\n ) : (\n <VComponent\n key={key}\n node={image}\n loading={key === 0 ? 'eager' : 'lazy'}\n alt={alt}\n onClick={() => setZoom(key)}\n />\n );\n })\n ) : (\n <img\n src=\"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\"\n className=\"pdp-product__images__placeholder\"\n aria-hidden\n />\n );\n\n const localThumbnailsImages = carouselConfig?.thumbnails?.length ? (\n carouselConfig.thumbnails.map((image, key) => (\n <VComponent\n key={key}\n node={image}\n loading={carouselConfig?.thumbnailsLoadingMode || 'lazy'}\n alt={\n title?.props?.children &&\n ImagesLabel?.replace('{product}', title.props.children.toString())\n .replace('{key}', String(key + 1))\n .replace('{total}', String(images.length))\n }\n />\n ))\n ) : (\n <img\n src=\"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\"\n className=\"pdp-product__images__placeholder\"\n aria-hidden\n />\n );\n\n return (\n <div {...props} className={classes(['pdp-product', className])}>\n {breadcrumbs && (\n <VComponent node={breadcrumbs} className=\"pdp-product__breadcrumbs\" />\n )}\n <div className=\"pdp-product__column-container pdp-product__gallery-column\">\n <div className=\"pdp-product__column-body\">\n {carouselConfig?.controls?.desktop ? (\n <Carousel\n className=\"pdp-product__overlay__carousel\"\n arrows={images?.length > 1}\n controls={\n images?.length > 1 ? carouselConfig.controls.desktop : 'dots'\n }\n arrowsOnMainImage={carouselConfig?.arrowsOnMainImage}\n loop={carouselConfig?.loopable && images?.length > 1}\n peak={\n (carouselConfig?.thumbnails?.length > 1 &&\n carouselConfig?.peak?.desktop) ||\n false\n }\n gap={carouselConfig?.gap || null}\n width=\"100%\"\n height=\"100%\"\n defaultIndex={zoom || 0}\n thumbnails={localThumbnailsImages}\n >\n {galleryImages}\n </Carousel>\n ) : (\n <GalleryGrid className=\"pdp-product__images\" gap=\"small\">\n {galleryImages}\n </GalleryGrid>\n )}\n </div>\n {galleryContent && (\n <VComponent\n node={galleryContent}\n className=\"pdp-product__gallery-content\"\n />\n )}\n </div>\n\n <div className=\"pdp-product__column-container pdp-product__content-column\">\n <div className=\"pdp-product__column-body\">\n <div className=\"pdp-product__header\">\n {title && (\n <VComponent node={title} className=\"pdp-product__title\" />\n )}\n\n {sku && <VComponent node={sku} className=\"pdp-product__sku\" />}\n </div>\n\n <div className=\"pdp-product__prices\">\n {specialPrice && (\n <VComponent\n node={specialPrice}\n className={classes([\n 'pdp-product__price-special',\n 'pdp-product__price',\n ])}\n aria-label={SpecialPriceLabel}\n role=\"text\"\n />\n )}\n {price && (\n <VComponent\n node={price}\n className={classes([\n 'pdp-product__price-regular',\n 'pdp-product__price--grey',\n ])}\n aria-label={RegularPriceLabel}\n role=\"text\"\n />\n )}\n </div>\n\n {/* Small Screen Gallery */}\n {carouselConfig?.controls?.mobile &&\n carouselConfig?.controls?.mobile === 'thumbnailsRow' ? (\n <Carousel\n className=\"pdp-product__images pdp-product__images--carousel pdp-product__images--carousel--thumbnails\"\n width=\"100%\"\n height=\"auto\"\n arrows={images?.length > 1}\n controls={images?.length > 1 ? 'thumbnailsRow' : null}\n loop={carouselConfig?.loopable && images?.length > 1}\n peak={\n (carouselConfig?.thumbnails?.length > 1 &&\n carouselConfig?.peak?.mobile) ||\n false\n }\n gap={carouselConfig?.gap || null}\n thumbnails={localThumbnailsImages}\n >\n {galleryImages}\n </Carousel>\n ) : (\n <Carousel\n className=\"pdp-product__images pdp-product__images--carousel\"\n peak={carouselConfig?.peak?.mobile && images?.length > 1}\n gap={carouselConfig?.gap || null}\n width=\"100%\"\n height=\"auto\"\n arrows={images?.length > 1}\n controls={images?.length > 1 ? 'dots' : null}\n loop={carouselConfig?.loopable && images?.length > 1}\n >\n {galleryImages}\n </Carousel>\n )}\n\n <div\n className={classes([\n 'pdp-product__actions',\n [`pdp-product__actions--out-of-stock`, outOfStock],\n ])}\n >\n {outOfStock && (\n <div className=\"pdp-product__out-of-stock__text\">\n {OutOfStockLabel}\n </div>\n )}\n\n {options && (\n <VComponent\n node={options}\n className={classes(['pdp-product__options'])}\n />\n )}\n\n {giftCardOptions && (\n <VComponent\n node={giftCardOptions}\n className={classes(['pdp-product__gift-card-options'])}\n />\n )}\n\n {downloadableOptions && (\n <VComponent\n node={downloadableOptions}\n className={classes(['pdp-product__downloadable-options'])}\n />\n )}\n\n {quantity && (\n <div className=\"pdp-product__quantity\">\n <VComponent node={quantity} />\n </div>\n )}\n\n {actions && (\n <VComponent\n node={actions}\n className={classes(['pdp-product__buttons'])}\n />\n )}\n </div>\n\n {shortDescription && (\n <VComponent\n node={shortDescription}\n className={classes(['pdp-product__short_description'])}\n />\n )}\n\n {description && (\n <VComponent\n node={description}\n className={classes(['pdp-product__description'])}\n />\n )}\n\n {attributes ? (\n <div className=\"pdp-product__attributes\">{attributes}</div>\n ) : null}\n </div>\n {infoContent && (\n <VComponent\n node={infoContent}\n className=\"pdp-product__info-content\"\n />\n )}\n </div>\n\n {productContent && (\n <VComponent node={productContent} className=\"pdp-product__content\" />\n )}\n\n {/* Zoom Overlay */}\n {zoom === null ? null : (\n <Overlay\n className=\"pdp-product__overlay\"\n onClose={() => setZoom(null)}\n centered\n >\n <Carousel\n className=\"pdp-product__overlay__carousel\"\n arrows={images?.length > 1}\n width=\"100%\"\n height=\"100%\"\n defaultIndex={zoom || 0}\n loop={carouselConfig?.loopable && images?.length > 1}\n controls={images?.length > 1 ? 'dots' : null}\n isZoomed\n >\n {galleryImages}\n </Carousel>\n </Overlay>\n )}\n </div>\n );\n};\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2023 Adobe\n * All Rights Reserved.\n * __________________\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n */\n\nimport { FunctionComponent, VNode } from 'preact';\nimport { HTMLAttributes, Children } from 'preact/compat';\nimport { classes, VComponent } from '@adobe-commerce/elsie/lib';\nimport '@/pdp/components/GalleryGrid/GalleryGrid.css';\n\nexport interface GalleryGridProps extends HTMLAttributes<HTMLDivElement> {\n children: VNode[] | VNode;\n gap?: 'small' | 'medium' | 'large' | null;\n style?: Record<string, string | number>;\n}\n\nexport const GalleryGrid: FunctionComponent<GalleryGridProps> = ({\n children,\n gap = null,\n className,\n style,\n ...props\n}) => {\n const count = Children.count(children);\n\n return (\n <div\n {...props}\n className={classes(['pdp-gallery-grid', className])}\n style={{\n '--gap': gap ? `var(--spacing-${gap})` : '0px',\n ...style,\n }}\n >\n {Children.map(\n children,\n (child: VNode<HTMLAttributes<HTMLElement>>, key) => (\n <div key={count + key} className=\"pdp-gallery-grid__item\">\n <VComponent\n key={child.props.src}\n node={child}\n loading={key === 0 ? 'eager' : 'lazy'}\n />\n </div>\n )\n )}\n </div>\n );\n};\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2023 Adobe\n * All Rights Reserved.\n * __________________\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n */\n\nimport { HTMLAttributes } from 'preact/compat';\nimport '@/pdp/components/PriceRange/PriceRange.css';\nimport { FunctionalComponent } from 'preact';\nimport { Price } from '@adobe-commerce/elsie/components';\n\nexport interface PriceRangeProps extends HTMLAttributes<HTMLDivElement> {\n locale?: string;\n variant?: 'default' | 'strikethrough';\n currency?: string;\n\n // Simple product\n amount?: number;\n sale?: boolean;\n\n // Complex product (range)\n minimumAmount?: number;\n maximumAmount?: number;\n}\n\nexport const PriceRange: FunctionalComponent<PriceRangeProps> = ({\n amount,\n currency,\n locale,\n variant,\n sale,\n minimumAmount,\n maximumAmount,\n className,\n ...props\n}) => {\n return (\n <>\n {amount || minimumAmount === maximumAmount ? (\n <div className={'pdp-price-range'} {...props}>\n <Price\n amount={amount ? amount : minimumAmount}\n currency={currency}\n locale={locale}\n variant={variant}\n sale={sale}\n className={className}\n />\n </div>\n ) : (\n <div className={'pdp-price-range'} {...props}>\n <Price\n amount={minimumAmount}\n currency={currency}\n locale={locale}\n className={className}\n />\n <span className=\"pdp-price-range__label\">{'-'}</span>\n <Price\n amount={maximumAmount}\n currency={currency}\n locale={locale}\n className={className}\n />\n </div>\n )}\n </>\n );\n};\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2023 Adobe\n * All Rights Reserved.\n * __________________\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n */\n\nimport { FunctionComponent } from 'preact';\nimport { HTMLAttributes, useCallback, useEffect, useRef } from 'preact/compat';\nimport { classes } from '@adobe-commerce/elsie/lib';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { Close as CloseSVG } from '@adobe-commerce/elsie/icons';\nimport { Button } from '@adobe-commerce/elsie/components';\n\nimport '@/pdp/components/Overlay/Overlay.css';\n\nexport interface OverlayProps extends HTMLAttributes<HTMLDivElement> {\n centered?: boolean;\n onClose?: () => void;\n}\n\nexport const Overlay: FunctionComponent<OverlayProps> = ({\n centered,\n onClose,\n className,\n children,\n ...props\n}) => {\n // i18n\n const CloseLabel = useText('PDP.Overlay.Close.label').label;\n const overlayRef = useRef<HTMLInputElement>(null);\n const handleOnClose = useCallback(() => {\n onClose?.();\n }, [onClose]);\n\n // Close on ESC\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n handleOnClose();\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [handleOnClose]);\n\n // Prevent document scrolling\n useEffect(() => {\n const input = overlayRef.current;\n input?.focus();\n\n const scrollingElement = document.scrollingElement as HTMLElement;\n\n const defaultOverflowValue = scrollingElement.style.overflow;\n\n scrollingElement.style.overflow = 'hidden';\n\n return () => {\n scrollingElement.style.overflow = defaultOverflowValue;\n };\n }, []);\n\n return (\n <div\n {...props}\n className={classes([\n 'pdp-overlay',\n ['pdp-overlay--centered', centered],\n className,\n ])}\n ref={overlayRef}\n role=\"dialog\"\n aria-describedby=\"overlay-content\"\n tabindex={0}\n >\n <div className=\"pdp-overlay__content\" id=\"overlay-content\">\n {children}\n </div>\n <Button\n aria-label={CloseLabel}\n variant=\"tertiary\"\n className=\"pdp-overlay__close-button\"\n onClick={handleOnClose}\n icon={<CloseSVG />}\n />\n </div>\n );\n};\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2023 Adobe\n * All Rights Reserved.\n * __________________\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n */\n\nimport { FunctionComponent, VNode } from 'preact';\nimport {\n HTMLAttributes,\n useState,\n useMemo,\n useCallback,\n useEffect,\n JSX,\n ChangeEvent,\n} from 'preact/compat';\nimport { classes } from '@adobe-commerce/elsie/lib';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport {\n ColorSwatch,\n ImageSwatch,\n TextSwatch,\n Picker,\n PickerOption,\n ImageNodeRenderProps,\n Checkbox,\n} from '@adobe-commerce/elsie/components';\n\nimport type {\n ProductOptionSelectionEntry,\n ProductOptionSelectionMap,\n} from '@/pdp/lib/product-option-selection';\n\nimport '@/pdp/components/Swatches/Swatches.css';\n\nexport type {\n ProductOptionSelectionEntry as SelectionEntry,\n ProductOptionSelectionMap as Selection,\n} from '@/pdp/lib/product-option-selection';\n\nconst supportedTypes = ['text', 'image', 'color', 'dropdown'];\n\nconst mapToPickerOptions = (items: OptionValue[]): PickerOption[] => {\n return items.map((item: OptionValue) => ({\n ...item,\n text: item.label,\n disabled: !item.inStock,\n }));\n};\n\ntype OptionValue = {\n id: string;\n label: string;\n inStock: boolean;\n value: string;\n selected?: boolean;\n};\n\nexport type Option = {\n id: string;\n type: (typeof supportedTypes)[number];\n label: string;\n required?: boolean;\n multiple?: boolean;\n items: OptionValue[];\n};\n\nfunction optionUIDsToSelection(\n optionUIDs: string[],\n options: Array<Option>\n): ProductOptionSelectionMap {\n return options.reduce((accum, option) => {\n const selectedItems = option.items.filter((item) =>\n optionUIDs.includes(item.id)\n );\n if (selectedItems.length === 0) {\n return accum;\n }\n\n if (option.multiple) {\n return {\n ...accum,\n [option.id]: {\n label: selectedItems.map((i) => i.label).join(', '),\n values: selectedItems.map((i) => i.id),\n },\n };\n }\n\n const item = selectedItems[0];\n return {\n ...accum,\n [option.id]: { label: item.label, value: item.id },\n };\n }, {} as ProductOptionSelectionMap);\n}\n\nfunction getSingleSelectedValue(\n entry: ProductOptionSelectionEntry | undefined\n): string | undefined {\n if (!entry || !('value' in entry)) {\n return undefined;\n }\n return entry.value;\n}\n\nexport interface SwatchesProps extends HTMLAttributes<HTMLDivElement> {\n options: Array<Option>;\n hideSelectedValue?: boolean;\n disablePreselections?: boolean;\n defaultOptions?: string[];\n selectionsToUpdate?: Option[];\n onValues?: (uids: ProductOptionSelectionMap, current: string) => void;\n onErrors?: (errors: { [id: string]: string }) => void;\n selectedUIDs?: string[];\n imageSwatchNode?: VNode | ((props: ImageNodeRenderProps) => JSX.Element);\n}\n\nexport const Swatches: FunctionComponent<SwatchesProps> = ({\n options,\n hideSelectedValue,\n disablePreselections,\n selectedUIDs,\n onValues,\n onErrors,\n defaultOptions,\n selectionsToUpdate,\n className,\n children,\n imageSwatchNode,\n ...props\n}) => {\n // i18n\n const RequiredLabel = useText('PDP.Swatches.Required.label').label;\n const ChooseOptionLabel = useText('PDP.Swatches.ChooseOption.label').label;\n\n const [selections, setSelections] = useState<ProductOptionSelectionMap>(\n () => {\n let accum: ProductOptionSelectionMap =\n defaultOptions?.length && options?.length\n ? optionUIDsToSelection(defaultOptions, options)\n : {};\n\n options?.forEach((option) => {\n if (accum[option.id]) {\n return;\n }\n\n const { items } = option;\n\n if (option.multiple) {\n const picked = items?.filter(\n (item) =>\n Boolean(defaultOptions?.includes(item.id)) || item.selected\n );\n if (picked?.length) {\n accum = {\n ...accum,\n [option.id]: {\n label: picked.map((i) => i.label).join(', '),\n values: picked.map((i) => i.id),\n },\n };\n }\n return;\n }\n\n const defaultSelection = items?.find((item) =>\n defaultOptions?.includes(item.id)\n );\n const selected = items?.find((item) => item.selected);\n\n if (defaultSelection) {\n accum = {\n ...accum,\n [option.id]: {\n label: defaultSelection.label,\n value: defaultSelection.id,\n },\n };\n } else if (selected) {\n accum = {\n ...accum,\n [option.id]: { label: selected.label, value: selected.id },\n };\n }\n });\n\n return accum;\n }\n );\n\n // set selected options from props\n useEffect(() => {\n if (selectedUIDs) {\n const selection = optionUIDsToSelection(selectedUIDs, options);\n // if the internal state is already the same as the props, do nothing\n if (JSON.stringify(selection) === JSON.stringify(selections)) return;\n\n setSelections((prev) => {\n let next = {\n ...prev,\n ...selection,\n };\n onValues?.(next, selectedUIDs?.[0] ?? '');\n return next;\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [selectedUIDs]);\n\n // this only applies for the case with anchor options\n // update selections in the swatches if they are updated in the parent component\n useEffect(() => {\n selectionsToUpdate?.forEach((selectionToUpdate) => {\n setSelections((prev) => {\n const selectedItems = selectionToUpdate?.items?.filter(\n (item) => item.selected\n );\n if (!selectedItems?.length) return prev;\n\n if (selectionToUpdate.multiple) {\n const next = {\n ...prev,\n [selectionToUpdate.id]: {\n label: selectedItems.map((i) => i.label).join(', '),\n values: selectedItems.map((i) => i.id),\n },\n };\n return next;\n }\n\n const selectedItem = selectedItems[0];\n const next = {\n ...prev,\n [selectionToUpdate.id]: {\n label: selectedItem.label,\n value: selectedItem.id,\n },\n };\n return next;\n });\n });\n }, [selectionsToUpdate, setSelections]);\n\n // Update invalid options\n useMemo(() => {\n const errors = options?.reduce((accum, option) => {\n const entry = selections[option.id];\n let satisfied = false;\n\n if (option.multiple) {\n satisfied = Boolean(\n entry && 'values' in entry && entry.values.length > 0\n );\n } else {\n option?.items?.forEach((item) => {\n if (entry && 'value' in entry && entry.value === item.id) {\n satisfied = true;\n }\n });\n }\n\n if (option.required && !satisfied) {\n accum[option.id] = RequiredLabel;\n }\n return accum;\n }, {} as { [id: string]: string });\n\n onErrors?.(errors);\n\n return errors;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [selections]);\n\n const handleOnSelection = useCallback(\n (optionGroupId: string, label: string, itemUid: string) => {\n setSelections((prev) => {\n let next: ProductOptionSelectionMap = {\n ...prev,\n ...(optionGroupId && { [optionGroupId]: { label, value: itemUid } }),\n };\n\n if (label === ChooseOptionLabel) {\n const rest = { ...next };\n delete rest[optionGroupId];\n next = rest;\n }\n\n onValues?.(next, itemUid);\n\n return next;\n });\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [onValues]\n );\n\n const handleMultiToggle = useCallback(\n (\n optionGroupId: string,\n itemId: string,\n checked: boolean,\n groupItems: OptionValue[]\n ) => {\n setSelections((prev) => {\n const prevEntry = prev[optionGroupId];\n const prevValues: string[] =\n prevEntry && 'values' in prevEntry\n ? [...prevEntry.values]\n : prevEntry && 'value' in prevEntry && prevEntry.value\n ? [prevEntry.value]\n : [];\n\n const nextValues = checked\n ? [...new Set([...prevValues, itemId])]\n : prevValues.filter((v) => v !== itemId);\n\n const labelById = new Map(\n groupItems.map((i) => [i.id, i.label] as const)\n );\n const nextLabel = nextValues\n .map((uid) => labelById.get(uid))\n .filter(Boolean)\n .join(', ');\n\n const next: ProductOptionSelectionMap = { ...prev };\n if (nextValues.length === 0) {\n delete next[optionGroupId];\n } else {\n next[optionGroupId] = { label: nextLabel, values: nextValues };\n }\n onValues?.(next, itemId);\n return next;\n });\n },\n [onValues]\n );\n\n // Function to handle the picker selection\n const handlePickerSelect = useCallback(\n (optionId: string, selection: any) => {\n const label = selection.selectedOptions[0]?.label ?? '';\n handleOnSelection(optionId, label, selection.value);\n },\n [handleOnSelection]\n );\n\n const renderOptionControl = useCallback(\n ({\n items,\n id,\n required,\n type,\n selected,\n label,\n multiple,\n }: {\n items: OptionValue[];\n id: string;\n required?: boolean | null;\n type: string;\n selected?: string;\n label: string;\n multiple?: boolean;\n }) => {\n const uniqueId = `pdp-swatch-${id}=${Math.random().toString(36)}`;\n\n if (multiple) {\n const entry = selections[id];\n const selectedIds = new Set(\n entry && 'values' in entry ? entry.values : []\n );\n\n return (\n items?.length > 0 && (\n <div\n className={classes([\n 'pdp-swatches__options',\n 'pdp-swatches__options--checkboxes',\n ])}\n >\n {items?.map((option: OptionValue) => (\n <Checkbox\n key={option.id}\n name={`pdp-bundle-multi__${id}__${option.id}`}\n label={option.label}\n checked={selectedIds.has(option.id)}\n disabled={!option.inStock}\n onChange={(e: ChangeEvent<HTMLInputElement>) =>\n handleMultiToggle(\n id,\n option.id,\n e.currentTarget.checked,\n items\n )\n }\n />\n ))}\n </div>\n )\n );\n }\n\n return (\n items?.length > 0 && (\n <div className={classes(['pdp-swatches__options'])}>\n {type?.toLowerCase() === 'dropdown' ? (\n <Picker\n id={uniqueId}\n name={id}\n aria-label={label}\n placeholder={\n disablePreselections ? ChooseOptionLabel : undefined\n }\n handleSelect={(event) => handlePickerSelect(id, event.target)}\n options={mapToPickerOptions(items)}\n value={selected}\n />\n ) : (\n items?.map((option: OptionValue) => {\n const common = {\n key: option.id,\n id: `${uniqueId}-${option.id}`,\n name: id,\n value: option.value,\n label: option.label,\n groupAriaLabel: label,\n selected: selected === option.id,\n outOfStock: !option.inStock,\n // API may return null, we default to true as all swatches are required.\n // we still comply to this in case the api return \"false\".\n required: required === null ? true : required,\n onValue: () => {\n handleOnSelection(id, option.label, option.id);\n },\n };\n\n switch (type) {\n case 'text':\n return <TextSwatch {...common} label={option.label} />;\n\n case 'image':\n return (\n <ImageSwatch\n {...common}\n src={option.value}\n alt={option.label}\n imageNode={imageSwatchNode}\n />\n );\n\n case 'color':\n return (\n <ColorSwatch\n {...common}\n size=\"large\"\n color={option.value}\n />\n );\n\n default:\n console.warn(`Invalid swatch type ${type}`);\n return null;\n }\n })\n )}\n </div>\n )\n );\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n ChooseOptionLabel,\n handleOnSelection,\n handlePickerSelect,\n handleMultiToggle,\n selections,\n ]\n );\n\n return (\n <div {...props} className={classes(['pdp-swatches', className])}>\n {options?.map(({ type, label, id, multiple, required, items }) => {\n // Only render supported types\n if (!supportedTypes.includes(type)) {\n console.warn(`Invalid swatch type ${type}`);\n }\n\n return (\n <div\n key={`swatch-item-${id}`}\n id={`swatch-item-${id}`}\n data-slot-key={`product-swatch--${id}`}\n className=\"pdp-swatches__field\"\n >\n <div className=\"pdp-swatches__field__label\">\n {selections[id]\n ? hideSelectedValue\n ? `${label}`\n : `${label}: ${selections[id].label}`\n : label}\n </div>\n\n {renderOptionControl({\n id,\n type,\n required,\n items,\n label,\n multiple,\n selected: getSingleSelectedValue(selections[id]),\n })}\n </div>\n );\n })}\n </div>\n );\n};\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2024 Adobe\n * All Rights Reserved.\n * __________________\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n */\nimport { cloneElement, FunctionComponent, VNode } from 'preact';\nimport {\n Children,\n useEffect,\n useState,\n useRef,\n useCallback,\n} from 'preact/compat';\n\nimport '@/pdp/components/Zoom/Zoom.css';\nimport { Button } from '@adobe-commerce/elsie/components';\nimport { Close as CloseSVG } from '@adobe-commerce/elsie/icons';\nimport { useText } from '@adobe-commerce/elsie/i18n';\n\nexport interface ZoomProps {\n children: VNode[] | VNode;\n scale?: number;\n closeButton?: boolean;\n}\n\nexport const Zoom: FunctionComponent<ZoomProps> = ({\n children,\n scale = 2.0,\n closeButton = true,\n}) => {\n const [zoomed, setZoomed] = useState(false);\n const [figureClassName, setFigureClassName] = useState('pdp-zoom');\n const [drag, setDrag] = useState(false);\n const [dragStart, setDragStart] = useState({ x: 0, y: 0 });\n const [dragStartPosition, setDragStartPosition] = useState({ x: 0, y: 0 });\n const [position, setPosition] = useState({ x: 0, y: 0 });\n\n const containerRef = useRef<HTMLElement>(null);\n const cachedBoundsRef = useRef<DOMRect | null>(null);\n const animationFrameRef = useRef<number | null>(null);\n const lastTransformRef = useRef<string>('none');\n\n const touchStartRef = useRef<{ x: number; y: number; time: number } | null>(\n null\n );\n const isSwipingRef = useRef<boolean>(false);\n const lastValidTouchRef = useRef<{ clientX: number; clientY: number } | null>(\n null\n );\n\n const updatePosition = useCallback(\n (event: MouseEvent | TouchEvent) => {\n const updatePositionLogic = () => {\n let zoomer: DOMRect;\n\n if (cachedBoundsRef.current && containerRef.current) {\n zoomer = cachedBoundsRef.current;\n } else if (containerRef.current) {\n zoomer = containerRef.current.getBoundingClientRect();\n cachedBoundsRef.current = zoomer;\n } else {\n zoomer = (\n event.currentTarget as HTMLElement\n )?.getBoundingClientRect();\n }\n\n const overlap = (100 - 100 / scale) / 2;\n let coordinates: { clientX: number; clientY: number } | null = null;\n\n if ('touches' in event) {\n if (event.touches.length > 0) {\n coordinates = event.touches[0];\n lastValidTouchRef.current = {\n clientX: coordinates.clientX,\n clientY: coordinates.clientY,\n };\n } else if (event.type === 'touchend' && touchStartRef.current) {\n coordinates = {\n clientX: touchStartRef.current.x,\n clientY: touchStartRef.current.y,\n };\n } else if (lastValidTouchRef.current) {\n coordinates = lastValidTouchRef.current;\n } else {\n return;\n }\n } else if (event instanceof MouseEvent) {\n coordinates = event;\n } else {\n return;\n }\n\n const relativeX =\n ((coordinates.clientX - zoomer.left) / zoomer.width) * 100;\n const relativeY =\n ((coordinates.clientY - zoomer.top) / zoomer.height) * 100;\n\n const x = ((50 - relativeX) * (scale - 1)) / scale;\n const y = ((50 - relativeY) * (scale - 1)) / scale;\n\n setPosition({\n x: Math.max(-overlap, Math.min(x, overlap)) || 0,\n y: Math.max(-overlap, Math.min(y, overlap)) || 0,\n });\n };\n\n if (typeof process !== 'undefined' && process.env?.NODE_ENV === 'test') {\n updatePositionLogic();\n } else {\n if (animationFrameRef.current) {\n cancelAnimationFrame(animationFrameRef.current);\n }\n animationFrameRef.current = requestAnimationFrame(updatePositionLogic);\n }\n },\n [scale]\n );\n\n useEffect(() => {\n cachedBoundsRef.current = null;\n }, [zoomed]);\n\n const startDrag = (event: TouchEvent) => {\n if (!zoomed || event.type !== 'touchstart') return;\n setDragStart({ x: event.touches[0].clientX, y: event.touches[0].clientY });\n setDragStartPosition({ x: position.x, y: position.y });\n setDrag(true);\n };\n\n const dragMove = (event: TouchEvent) => {\n if (!drag || event.type !== 'touchmove') return;\n const zoomer = (\n event.currentTarget as HTMLElement\n )?.getBoundingClientRect();\n const overlap = (100 - 100 / scale) / 2;\n const movedX = event.touches[0].clientX - dragStart.x;\n const movedY = event.touches[0].clientY - dragStart.y;\n const movedXPercent = (movedX * 100) / (zoomer.width * scale);\n const movedYPercent = (movedY * 100) / (zoomer.height * scale);\n const x = dragStartPosition.x + movedXPercent;\n const y = dragStartPosition.y + movedYPercent;\n setPosition({\n x: Math.max(-overlap, Math.min(x, overlap)) || 0,\n y: Math.max(-overlap, Math.min(y, overlap)) || 0,\n });\n event.preventDefault();\n };\n\n const handleTouchStart = (event: TouchEvent) => {\n if (closeButton) {\n touchStartRef.current = {\n x: event.touches[0].clientX,\n y: event.touches[0].clientY,\n time: Date.now(),\n };\n\n lastValidTouchRef.current = {\n clientX: event.touches[0].clientX,\n clientY: event.touches[0].clientY,\n };\n\n isSwipingRef.current = false;\n\n if (zoomed) {\n startDrag(event);\n }\n } else {\n if (drag) return;\n\n !zoomed && updatePosition(event);\n\n setZoomed(!zoomed);\n\n event.preventDefault();\n }\n };\n\n const handleTouchMove = (event: TouchEvent) => {\n if (event.touches.length === 0) return;\n\n lastValidTouchRef.current = {\n clientX: event.touches[0].clientX,\n clientY: event.touches[0].clientY,\n };\n\n if (closeButton) {\n if (!touchStartRef.current) return;\n\n if (drag) {\n dragMove(event);\n return;\n }\n\n const touchX = event.touches[0].clientX;\n const touchY = event.touches[0].clientY;\n const deltaX = Math.abs(touchX - touchStartRef.current.x);\n const deltaY = Math.abs(touchY - touchStartRef.current.y);\n\n if (deltaX > 10 || deltaY > 10) {\n isSwipingRef.current = true;\n }\n }\n\n if (zoomed) {\n updatePosition(event);\n }\n };\n\n const handleTouchEnd = (event: TouchEvent) => {\n if (closeButton) {\n if (!touchStartRef.current) return;\n\n const tapDuration = Date.now() - touchStartRef.current.time;\n\n if (!isSwipingRef.current && tapDuration < 300 && !drag) {\n setZoomed(true);\n updatePosition(event);\n event.preventDefault();\n }\n\n setDrag(false);\n touchStartRef.current = null;\n } else {\n setZoomed(false);\n }\n };\n\n const handleClick = (event: MouseEvent) => {\n if ('touches' in event) return;\n\n if (drag) return;\n\n if (zoomed) {\n !closeButton && setZoomed(false);\n } else {\n setZoomed(true);\n updatePosition(event);\n }\n event.preventDefault();\n };\n\n const handleMove = (event: MouseEvent) => {\n if ('touches' in event) return;\n\n if (zoomed) {\n updatePosition(event);\n }\n };\n\n const handleLeave = (event: MouseEvent) => {\n if ('touches' in event) return;\n\n if (closeButton) {\n setDrag(false);\n return;\n }\n setZoomed(false);\n };\n\n const closeButtonClick = (event: MouseEvent | TouchEvent) => {\n setZoomed(false);\n event.stopPropagation();\n };\n\n const transformStyle = zoomed\n ? `scale(${scale}) translateX(${position.x}%) translateY(${position.y}%)`\n : 'none';\n\n const CloseLabel = useText('PDP.Zoom.Close.label').label;\n const child = Children.only(children) as any;\n\n useEffect(() => {\n const handleGalleryChange = () => {\n if (zoomed) {\n setZoomed(false);\n setPosition({ x: 0, y: 0 });\n setDrag(false);\n }\n };\n\n const gallery = document.querySelector('#gallery');\n if (gallery) {\n gallery.addEventListener('click', handleGalleryChange);\n return () => gallery.removeEventListener('click', handleGalleryChange);\n }\n }, [zoomed]);\n\n const ImageClone = cloneElement(child, {\n ...child.props,\n draggable: false,\n style: {\n ...child.props?.style,\n '--transform': transformStyle,\n },\n });\n\n useEffect(() => {\n const className = zoomed\n ? `pdp-zoom ${closeButton ? 'pdp-zoom--no-effects' : 'pdp-zoom--zoomed'}`\n : 'pdp-zoom';\n setFigureClassName(className);\n }, [zoomed, closeButton]);\n\n useEffect(() => {\n if (lastTransformRef.current === transformStyle) return;\n lastTransformRef.current = transformStyle;\n\n const updateTransforms = () => {\n if (!containerRef.current) return;\n\n const images = containerRef.current.querySelectorAll('img');\n images.forEach((img) => {\n if (zoomed && transformStyle !== 'none') {\n img.style.setProperty('transform', transformStyle, 'important');\n } else {\n img.style.removeProperty('transform');\n }\n });\n };\n\n requestAnimationFrame(updateTransforms);\n }, [transformStyle, zoomed]);\n\n useEffect(() => {\n return () => {\n if (animationFrameRef.current) {\n cancelAnimationFrame(animationFrameRef.current);\n }\n };\n }, []);\n\n return (\n <figure\n ref={containerRef}\n className={figureClassName}\n onClick={handleClick}\n onMouseMove={handleMove}\n onMouseLeave={handleLeave}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n >\n {ImageClone}\n {closeButton && zoomed && (\n <Button\n aria-label={CloseLabel}\n variant=\"tertiary\"\n className=\"pdp-zoom__close-button\"\n icon={<CloseSVG />}\n onClick={closeButtonClick}\n />\n )}\n </figure>\n );\n};\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2024 Adobe\n * All Rights Reserved.\n * __________________\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n */\n\nimport { FunctionComponent, VNode } from 'preact';\nimport { HTMLAttributes } from 'preact/compat';\nimport { classes, VComponent } from '@adobe-commerce/elsie/lib';\nimport '@/pdp/components/Header/Header.css';\n\nexport interface HeaderProps\n extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n title: VNode;\n sku: VNode;\n hideSku?: boolean;\n /** When provided, displayed as variant name (e.g. when all options are selected on a configurable product) */\n variantName?: VNode;\n /** When provided, displayed as variant SKU (e.g. when all options are selected on a configurable product) */\n variantSku?: VNode;\n}\n\nexport const Header: FunctionComponent<HeaderProps> = ({\n className,\n title,\n sku,\n hideSku = false,\n variantName,\n variantSku,\n children,\n ...props\n}) => {\n return (\n <div {...props} className={classes(['pdp-header', className])}>\n <div className=\"pdp-header__title\">\n <VComponent node={title} />\n </div>\n {!hideSku && (\n <div className=\"pdp-header__sku\">\n <VComponent node={sku} />\n </div>\n )}\n {(variantName || variantSku) && (\n <div className=\"pdp-header__variant\">\n {variantName && (\n <span className=\"pdp-header__variant-name\">\n <VComponent node={variantName} />\n </span>\n )}\n {variantName && variantSku && (\n <span className=\"pdp-header__variant-separator\"> – </span>\n )}\n {variantSku && (\n <span className=\"pdp-header__variant-sku\">\n <VComponent node={variantSku} />\n </span>\n )}\n </div>\n )}\n </div>\n );\n};\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2024 Adobe\n * All Rights Reserved.\n * __________________\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n */\nimport { FunctionComponent, VNode } from 'preact';\n\nimport { HTMLAttributes } from 'preact/compat';\nimport { classes, VComponent } from '@adobe-commerce/elsie/lib';\nimport '@/pdp/components/Price/Price.css';\nimport { useText } from '@adobe-commerce/elsie/i18n';\n\nexport interface PriceProps extends HTMLAttributes<HTMLDivElement> {\n price?: VNode;\n specialPrice?: VNode;\n tiers?: VNode;\n}\n\nexport const Price: FunctionComponent<PriceProps> = ({\n className,\n price,\n specialPrice,\n tiers,\n children,\n ...props\n}) => {\n const RegularPriceLabel = useText('PDP.Product.RegularPrice.label').label;\n const SpecialPriceLabel = useText('PDP.Product.SpecialPrice.label').label;\n const TierPriceLabel = useText('PDP.Product.TierPrice.label').label;\n\n return (\n <div {...props} className={classes(['pdp-price', className])}>\n {specialPrice && (\n <VComponent\n node={specialPrice}\n className={classes([\n 'pdp-price__amount-special',\n 'pdp-price__amount',\n ])}\n aria-label={SpecialPriceLabel}\n role=\"text\"\n />\n )}\n {price && (\n <VComponent\n node={price}\n className={classes([\n 'pdp-price__amount-regular',\n 'pdp-price__amount--grey',\n ])}\n aria-label={RegularPriceLabel}\n role=\"text\"\n />\n )}\n {tiers && (\n <VComponent\n node={tiers}\n className={classes(['pdp-price__tiers'])}\n aria-label={TierPriceLabel}\n role=\"text\"\n />\n )}\n </div>\n );\n};\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2023 Adobe\n * All Rights Reserved.\n * __________________\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n */\n\nimport { HTMLAttributes } from 'preact/compat';\nimport '@/pdp/components/PriceTiers/PriceTiers.css';\nimport { FunctionalComponent } from 'preact';\nimport { Price } from '@adobe-commerce/elsie/components';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { Tier } from '@/pdp/data/models';\n\nexport interface PriceTiersProps extends HTMLAttributes<HTMLDivElement> {\n locale?: string;\n tiers: Tier[];\n regularPrice?: number; // Base price to calculate savings percentage\n}\n\nexport const PriceTiers: FunctionalComponent<PriceTiersProps> = ({\n locale,\n tiers,\n regularPrice,\n ...props\n}) => {\n const TierPricingLabel = useText('PDP.Product.TierPricing.label').label;\n\n if (!tiers || tiers.length === 0) {\n return null;\n }\n\n return (\n <div className=\"pdp-price-tiers\" {...props}>\n {tiers.map((tier, index) => {\n const tierPrice = tier?.tier?.amount ?? 0;\n const quantity = tier?.quantity ?? 0;\n const currency = tier?.tier?.currency ?? '';\n\n let savingsPercent = 0;\n if (regularPrice && tierPrice && tierPrice < regularPrice) {\n savingsPercent = Math.round(\n ((regularPrice - tierPrice) / regularPrice) * 100\n );\n }\n\n const textBeforePrice = TierPricingLabel.replace(\n '{quantity}',\n quantity.toString()\n ).split('{price}')[0];\n\n const textAfterPrice = TierPricingLabel.replace(\n '{quantity}',\n quantity.toString()\n )\n .split('{price}')[1]\n .replace(\n '{percent}',\n savingsPercent > 0 ? savingsPercent.toString() : '0'\n );\n\n return (\n <div key={index} className=\"pdp-price-tiers__tier\">\n <span className=\"pdp-price-tiers__text\">\n {textBeforePrice}\n <Price\n amount={tierPrice}\n currency={currency}\n locale={locale}\n className=\"pdp-price-tiers__price\"\n />\n {textAfterPrice}\n </span>\n </div>\n );\n })}\n </div>\n );\n};\n","import { FunctionComponent } from 'preact';\nimport { useState, useEffect, useMemo, useCallback } from 'preact/hooks';\nimport { HTMLAttributes } from 'preact/compat';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport {\n Field,\n Input,\n TextArea,\n Picker,\n PickerOption,\n} from '@adobe-commerce/elsie/components';\nimport { classes } from '@adobe-commerce/elsie/lib';\nimport { Option, OptionField } from '@/pdp/data/models/values-model';\nimport './GiftCardOptions.css';\n\nenum ComponentType {\n INPUT = 'input',\n TEXTAREA = 'textarea',\n PICKER = 'picker',\n}\n\nexport interface GiftCardOptionsProps extends HTMLAttributes<HTMLDivElement> {\n options: Option[];\n currency?: string;\n optionValues: OptionField[];\n onOptionChange: (uid: string, value: string) => void;\n onValidationChange: (valid: boolean) => void;\n}\n\n// Utility functions\nconst getInputType = (validationType: string): string => {\n switch (validationType) {\n case 'number':\n return 'number';\n case 'email':\n return 'email';\n default:\n return 'text';\n }\n};\n\nconst getComponentType = (option: Option): ComponentType => {\n if (option.name === 'giftcard/giftcard_message') {\n return ComponentType.TEXTAREA;\n }\n\n if (option.name === 'giftcard/giftcard_amount') {\n return ComponentType.PICKER;\n }\n\n return ComponentType.INPUT;\n};\n\nconst mapToPickerOptions = (\n values: (string | number)[],\n hasCustomAmountField: boolean,\n chooseAmountText: string,\n otherAmountText: string\n): PickerOption[] => {\n const options: PickerOption[] = [\n {\n text: chooseAmountText,\n value: '0',\n disabled: false,\n },\n ...values.map((value) => ({\n text: value.toString(),\n value: value.toString(),\n disabled: false,\n })),\n ...(hasCustomAmountField\n ? [\n {\n text: otherAmountText,\n value: 'other',\n disabled: false,\n },\n ]\n : []),\n ];\n return options;\n};\n\nconst validate = (\n option: Option,\n value: string,\n errorMessages: {\n RequiredFieldError: string;\n NumberError: string;\n MinError: string;\n MaxError: string;\n MinLengthError: string;\n MaxLengthError: string;\n EmailError: string;\n InvalidValueError: string;\n }\n) => {\n const { validationRule } = option;\n\n if (option.name === 'giftcard/giftcard_amount') {\n if (\n validationRule.required &&\n (value === '0' || !value || value.trim() === '')\n ) {\n return errorMessages.RequiredFieldError;\n }\n if (value === '0') {\n return errorMessages.RequiredFieldError;\n }\n if (value === 'other') {\n return '';\n }\n } else if (validationRule.required && (!value || value.trim() === '')) {\n return errorMessages.RequiredFieldError;\n }\n\n if (!value || value.trim() === '') {\n return '';\n }\n\n switch (validationRule.type) {\n case 'email': {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (!emailRegex.test(value)) {\n return errorMessages.EmailError;\n }\n break;\n }\n\n case 'number': {\n const num = Number(value);\n if (isNaN(num)) {\n return errorMessages.NumberError;\n }\n\n // Check min value\n if (validationRule.min !== undefined && num < validationRule.min) {\n return errorMessages.MinError.replace(\n '{min}',\n validationRule.min.toString()\n );\n }\n\n // Check max value\n if (validationRule.max !== undefined && num > validationRule.max) {\n return errorMessages.MaxError.replace(\n '{max}',\n validationRule.max.toString()\n );\n }\n\n // Check allowed values\n if (validationRule.values) {\n const isValidValue = validationRule.values.some((val) =>\n typeof val === 'number' ? val === num : val === value\n );\n if (!isValidValue) {\n return errorMessages.InvalidValueError.replace(\n '{values}',\n validationRule.values.join(', ')\n );\n }\n }\n break;\n }\n\n case 'string': {\n const length = value.length;\n\n // Check min length\n if (\n validationRule.minLength !== undefined &&\n length < validationRule.minLength\n ) {\n return errorMessages.MinLengthError.replace(\n '{min_length}',\n validationRule.minLength.toString()\n );\n }\n\n // Check max length\n if (\n validationRule.maxLength !== undefined &&\n length > validationRule.maxLength\n ) {\n return errorMessages.MaxLengthError.replace(\n '{max_length}',\n validationRule.maxLength.toString()\n );\n }\n break;\n }\n }\n\n return '';\n};\n\nexport const GiftCardOptions: FunctionComponent<GiftCardOptionsProps> = ({\n options,\n currency,\n optionValues,\n onOptionChange,\n onValidationChange,\n}) => {\n const ChooseAmount = useText(\n 'PDP.Product.GiftCardOptions.ChooseAmount.label'\n ).label;\n const OtherAmount = useText(\n 'PDP.Product.GiftCardOptions.OtherAmount.label'\n ).label;\n const RequiredFieldError = useText(\n 'PDP.Product.GiftCardOptions.RequiredFieldError.label'\n ).label;\n const NumberError = useText(\n 'PDP.Product.GiftCardOptions.NumberError.label'\n ).label;\n const MinError = useText('PDP.Product.GiftCardOptions.MinError.label').label;\n const MaxError = useText('PDP.Product.GiftCardOptions.MaxError.label').label;\n const MinLengthError = useText(\n 'PDP.Product.GiftCardOptions.MinLengthError.label'\n ).label;\n const MaxLengthError = useText(\n 'PDP.Product.GiftCardOptions.MaxLengthError.label'\n ).label;\n const EmailError = useText(\n 'PDP.Product.GiftCardOptions.EmailError.label'\n ).label;\n const InvalidValueError = useText(\n 'PDP.Product.GiftCardOptions.InvalidValueError.label'\n ).label;\n\n const [errors, setErrors] = useState<Record<string, string>>({});\n const [showCustomAmount, setShowCustomAmount] = useState(false);\n\n // Helper function to find option by name\n const findOptionByName = useCallback(\n (name: string): Option | undefined => {\n return options.find((option) => option.name === name);\n },\n [options]\n );\n\n // Memoize error messages to avoid recreating them on every render\n const errorMessages = useMemo(\n () => ({\n RequiredFieldError,\n NumberError,\n MinError,\n MaxError,\n MinLengthError,\n MaxLengthError,\n EmailError,\n InvalidValueError,\n }),\n [\n RequiredFieldError,\n NumberError,\n MinError,\n MaxError,\n MinLengthError,\n MaxLengthError,\n EmailError,\n InvalidValueError,\n ]\n );\n\n // Run initial validation only when options or optionValues change\n useEffect(() => {\n const valid = options.every((option) => {\n // Skip validation for custom gift card amount when it's not shown\n if (\n option.name === 'giftcard/custom_giftcard_amount' &&\n !showCustomAmount\n ) {\n return true;\n }\n\n const field = optionValues.find((f) => f.id === option.uid);\n const value = field?.value || '';\n return validate(option, value, errorMessages) === '';\n });\n\n onValidationChange(valid);\n }, [\n options,\n optionValues,\n onValidationChange,\n errorMessages,\n showCustomAmount,\n ]);\n\n useEffect(() => {\n const giftCardAmountOption = findOptionByName('giftcard/giftcard_amount');\n const customAmountOption = findOptionByName(\n 'giftcard/custom_giftcard_amount'\n );\n\n const giftCardAmountField = optionValues.find(\n (f) => f.id === giftCardAmountOption?.uid\n );\n\n const selectedValue = giftCardAmountField?.value || '';\n const wasShowingCustomAmount = showCustomAmount;\n\n // If there's no gift card amount option, always show custom amount\n // Otherwise, show custom amount only when \"other\" is selected\n const willShowCustomAmount = giftCardAmountOption\n ? selectedValue === 'other'\n : !!customAmountOption;\n\n setShowCustomAmount(willShowCustomAmount);\n\n // Reset custom amount value when switching away from \"other\"\n if (wasShowingCustomAmount && !willShowCustomAmount && customAmountOption) {\n onOptionChange(customAmountOption.uid, '');\n }\n }, [optionValues, findOptionByName, showCustomAmount, onOptionChange]);\n\n const handleChange = (option: Option, value: string) => {\n const error = validate(option, value, errorMessages);\n setErrors((prev: Record<string, string>) => ({\n ...prev,\n [option.uid]: error,\n }));\n\n onOptionChange(option.uid, value);\n };\n\n const handleBlur = (option: Option, value: string) => {\n const error = validate(option, value, errorMessages);\n setErrors((prev: Record<string, string>) => ({\n ...prev,\n [option.uid]: error,\n }));\n };\n\n const handlePickerSelect = (option: Option, event: any) => {\n const selectedValue = event.target.value;\n handleChange(option, selectedValue);\n };\n\n const renderField = (option: Option) => {\n const field = optionValues.find((f) => f.id === option.uid);\n const value = field?.value;\n const error = errors[option.uid];\n const componentType = getComponentType(option);\n const hasCustomAmountField = !!findOptionByName(\n 'giftcard/custom_giftcard_amount'\n );\n\n // Add currency to custom gift card amount label\n let label = option.label;\n if (option.name === 'giftcard/custom_giftcard_amount' && currency) {\n label = `${option.label} ${currency}`;\n }\n\n return (\n <Field\n key={option.uid}\n label={label}\n className={classes([\n 'pdp-gift-card-options__option-field',\n componentType === ComponentType.TEXTAREA &&\n 'pdp-gift-card-options__option-field--full-width',\n ])}\n error={error}\n >\n {(() => {\n if (componentType === ComponentType.TEXTAREA) {\n return (\n <TextArea\n value={value}\n label={option.label}\n onChange={(e: any) =>\n handleChange(option, (e.target as HTMLTextAreaElement).value)\n }\n onBlur={(e: any) =>\n handleBlur(option, (e.target as HTMLTextAreaElement).value)\n }\n aria-invalid={!!error}\n />\n );\n }\n\n if (componentType === ComponentType.PICKER) {\n return (\n <Picker\n aria-label={option.label}\n label={option.label}\n handleSelect={(event) => handlePickerSelect(option, event)}\n options={mapToPickerOptions(\n option.validationRule.values || [],\n hasCustomAmountField,\n ChooseAmount,\n OtherAmount\n )}\n value={value}\n aria-invalid={!!error}\n />\n );\n }\n\n return (\n <Input\n type={getInputType(option.validationRule.type)}\n value={value}\n onChange={(e) =>\n handleChange(option, (e.target as HTMLInputElement).value)\n }\n onBlur={(e) =>\n handleBlur(option, (e.target as HTMLInputElement).value)\n }\n aria-invalid={!!error}\n />\n );\n })()}\n </Field>\n );\n };\n\n return (\n <div className=\"pdp-gift-card-options__grid\">\n {/* Row 1: Gift card amount and custom amount */}\n <div className=\"pdp-gift-card-options__row\">\n {findOptionByName('giftcard/giftcard_amount') &&\n renderField(findOptionByName('giftcard/giftcard_amount')!)}\n {findOptionByName('giftcard/custom_giftcard_amount') &&\n showCustomAmount &&\n renderField(findOptionByName('giftcard/custom_giftcard_amount')!)}\n </div>\n\n {/* Row 2: Sender name and email */}\n <div className=\"pdp-gift-card-options__row\">\n {findOptionByName('giftcard/giftcard_sender_name') &&\n renderField(findOptionByName('giftcard/giftcard_sender_name')!)}\n {findOptionByName('giftcard/giftcard_sender_email') &&\n renderField(findOptionByName('giftcard/giftcard_sender_email')!)}\n </div>\n\n {/* Row 3: Recipient name and email */}\n <div className=\"pdp-gift-card-options__row\">\n {findOptionByName('giftcard/giftcard_recipient_name') &&\n renderField(findOptionByName('giftcard/giftcard_recipient_name')!)}\n {findOptionByName('giftcard/giftcard_recipient_email') &&\n renderField(findOptionByName('giftcard/giftcard_recipient_email')!)}\n </div>\n\n {/* Row 4: Gift card message */}\n <div className=\"pdp-gift-card-options__row\">\n {findOptionByName('giftcard/giftcard_message') &&\n renderField(findOptionByName('giftcard/giftcard_message')!)}\n </div>\n </div>\n );\n};\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2023 Adobe\n * All Rights Reserved.\n * __________________\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n */\n\nimport { FunctionComponent } from 'preact';\nimport { HTMLAttributes, useState, useCallback } from 'preact/compat';\nimport { classes } from '@adobe-commerce/elsie/lib';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { Price } from '@adobe-commerce/elsie/components';\n\nimport '@/pdp/components/DownloadableOptions/DownloadableOptions.css';\n\nexport type DownloadableLink = {\n uid: string;\n price: number;\n sample_url: string | null;\n label: string;\n number_of_downloads: number;\n};\n\nexport type DownloadableSample = {\n uid: string;\n label: string;\n url: string;\n};\n\nexport type DownloadableValue = {\n links: DownloadableLink[];\n samples: DownloadableSample[];\n purchaseSeparately: boolean;\n};\n\nexport interface DownloadableOptionsProps\n extends Omit<HTMLAttributes<HTMLDivElement>, 'value'> {\n label: string;\n value: DownloadableValue;\n onLinkChange?: (uid: string, selected: boolean) => void;\n currency?: string;\n locale?: string;\n}\n\nexport const DownloadableOptions: FunctionComponent<\n DownloadableOptionsProps\n> = ({ label, value, onLinkChange, currency, locale, className, ...props }) => {\n const SampleLabel = useText('PDP.DownloadableOptions.Sample.label').label;\n const ViewSampleLabel = useText('PDP.DownloadableOptions.ViewSample.label');\n\n const { links, samples, purchaseSeparately } = value;\n\n const initialSelected = purchaseSeparately\n ? new Set<string>()\n : new Set(links.map((link) => link.uid));\n\n const [selected, setSelected] = useState<Set<string>>(initialSelected);\n\n const handleToggle = useCallback(\n (uid: string, isSelected: boolean, isDisabled: boolean) => {\n if (!purchaseSeparately || isDisabled) {\n return;\n }\n\n setSelected((prev) => {\n const next = new Set(prev);\n if (isSelected) {\n next.add(uid);\n } else {\n next.delete(uid);\n }\n return next;\n });\n onLinkChange?.(uid, isSelected);\n },\n [onLinkChange, purchaseSeparately]\n );\n\n const renderLink = (link: DownloadableLink) => {\n const isSelected = purchaseSeparately && selected.has(link.uid);\n\n return (\n <div\n key={link.uid}\n className={`pdp-downloadable-options__item ${\n isSelected ? 'pdp-downloadable-options__item--selected' : ''\n } ${\n !purchaseSeparately ? 'pdp-downloadable-options__item--disabled' : ''\n }`}\n >\n <button\n type=\"button\"\n className=\"pdp-downloadable-options__clickable\"\n aria-pressed={isSelected}\n disabled={!purchaseSeparately}\n onClick={() =>\n purchaseSeparately &&\n handleToggle(link.uid, !isSelected, !purchaseSeparately)\n }\n onKeyDown={(e) => {\n if (purchaseSeparately && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault();\n handleToggle(link.uid, !isSelected, !purchaseSeparately);\n }\n }}\n >\n <div className=\"pdp-downloadable-options__content\">\n <div className=\"pdp-downloadable-options__header\">\n <span className=\"pdp-downloadable-options__title\">\n {link.label}\n </span>\n <Price\n amount={link.price}\n currency={currency}\n locale={locale}\n className=\"pdp-downloadable-options__price\"\n />\n </div>\n </div>\n </button>\n {link.sample_url && (\n <a\n href={link.sample_url}\n className=\"pdp-downloadable-options__sample-button\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label={ViewSampleLabel.label.replace('{label}', link.label)}\n >\n {SampleLabel}\n </a>\n )}\n </div>\n );\n };\n\n const renderSample = (sample: DownloadableSample) => {\n return (\n <div\n key={sample.uid}\n className=\"pdp-downloadable-options__item pdp-downloadable-options__item--sample\"\n >\n <button\n type=\"button\"\n className=\"pdp-downloadable-options__clickable\"\n aria-pressed={false}\n disabled={true}\n >\n <div className=\"pdp-downloadable-options__content\">\n <div className=\"pdp-downloadable-options__header\">\n <span className=\"pdp-downloadable-options__title\">\n {sample.label}\n </span>\n </div>\n </div>\n </button>\n <a\n href={sample.url}\n className=\"pdp-downloadable-options__sample-button\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label={`${SampleLabel} ${sample.label}`}\n >\n {SampleLabel}\n </a>\n </div>\n );\n };\n\n return (\n <div\n {...props}\n className={classes(['pdp-downloadable-options', className])}\n data-slot-key=\"product-downloadable-options\"\n >\n <div className=\"pdp-downloadable-options__field\">\n <div className=\"pdp-downloadable-options__field__label\">{label}</div>\n\n <div className=\"pdp-downloadable-options__list\">\n {links.map((link) => renderLink(link))}\n {samples.map((sample) => renderSample(sample))}\n </div>\n </div>\n </div>\n );\n};\n"],"names":["SvgChevronDown","props","React","SvgClose","PEAK_WIDTH","THUMB_GAP","ICON_SIZE","GapSize","Carousel","show","scrollbar","peak","arrows","controls","arrowsOnMainImage","loop","gap","direction","width","height","defaultIndex","className","children","thumbnails","isZoomed","Label","useText","SlideLabel","PreviousLabel","NextLabel","ControlsLabel","ControlsBtnLabel","perPage","setPerPage","useState","getPerPageFromBreakpoint","length","Children","peakWidth","gapWidth","rest","current","setCurrent","isRTL","thumbnailsRefs","useRef","thumbWidth","setThumbWidth","thumbHeight","setThumbHeight","thumbnailSlides","useMemo","slides","returnValue","acc","child","i","wrapperRef","thumbnailsWrapperRef","thumbnailControls","useEffect","wrapper","handleResize","debounce","newPerPage","observer","handleThumbnailsScroll","useCallback","nextSlideIndex","nextItem","thumbnailRef","oneItemWidth","oneItemHeight","thumbnailsWrapper","isRow","isColumn","offset","oneItemSize","visibleThumbnails","centerOffset","targetScrollPosition","handleScrollTo","smooth","reset","realWidth","element","dataIndex","futureIndex","scrollWidth","diff","handleGoToPrev","handleGoToNext","lastSlideIndex","handleKeyDown","event","useLayoutEffect","handleOnScroll","dividing","totalWidth","scrollOffset","getArrow","forThumbnails","callback","jsx","Button","classes","Icon","ChevronDown","prevArrow","nextArrow","prevArrowMainImage","nextArrowMainImage","jsxs","page","index","orphan","Fragment","_","key","buttonsLength","active","el","breakpoints","small","medium","large","matchingBreakpoint","breakpoint","Product","title","breadcrumbs","galleryContent","infoContent","productContent","sku","outOfStock","shortDescription","description","attributes","images","options","giftCardOptions","downloadableOptions","price","specialPrice","quantity","actions","carouselConfig","zoomType","closeButton","RegularPriceLabel","SpecialPriceLabel","OutOfStockLabel","ImagesLabel","zoom","setZoom","galleryImages","image","alt","_a","Zoom","VComponent","localThumbnailsImages","_b","_c","_d","GalleryGrid","_e","_f","_g","_h","_i","Overlay","style","count","PriceRange","amount","currency","locale","variant","sale","minimumAmount","maximumAmount","Price","centered","onClose","CloseLabel","overlayRef","handleOnClose","input","scrollingElement","defaultOverflowValue","CloseSVG","supportedTypes","mapToPickerOptions","items","item","optionUIDsToSelection","optionUIDs","accum","option","selectedItems","getSingleSelectedValue","entry","Swatches","hideSelectedValue","disablePreselections","selectedUIDs","onValues","onErrors","defaultOptions","selectionsToUpdate","imageSwatchNode","RequiredLabel","ChooseOptionLabel","selections","setSelections","picked","defaultSelection","selected","selection","prev","next","selectionToUpdate","selectedItem","errors","satisfied","handleOnSelection","optionGroupId","label","itemUid","handleMultiToggle","itemId","checked","groupItems","prevEntry","prevValues","nextValues","v","labelById","nextLabel","uid","handlePickerSelect","optionId","renderOptionControl","id","required","type","multiple","uniqueId","selectedIds","Checkbox","e","Picker","common","TextSwatch","ImageSwatch","ColorSwatch","scale","zoomed","setZoomed","figureClassName","setFigureClassName","drag","setDrag","dragStart","setDragStart","dragStartPosition","setDragStartPosition","position","setPosition","containerRef","cachedBoundsRef","animationFrameRef","lastTransformRef","touchStartRef","isSwipingRef","lastValidTouchRef","updatePosition","updatePositionLogic","zoomer","overlap","coordinates","relativeX","relativeY","x","y","startDrag","dragMove","movedX","movedY","movedXPercent","movedYPercent","handleTouchStart","handleTouchMove","touchX","touchY","deltaX","deltaY","handleTouchEnd","tapDuration","handleClick","handleMove","handleLeave","closeButtonClick","transformStyle","handleGalleryChange","gallery","ImageClone","cloneElement","img","Header","hideSku","variantName","variantSku","tiers","TierPriceLabel","PriceTiers","regularPrice","TierPricingLabel","tier","tierPrice","savingsPercent","textBeforePrice","textAfterPrice","getInputType","validationType","getComponentType","values","hasCustomAmountField","chooseAmountText","otherAmountText","value","validate","errorMessages","validationRule","num","val","GiftCardOptions","optionValues","onOptionChange","onValidationChange","ChooseAmount","OtherAmount","RequiredFieldError","NumberError","MinError","MaxError","MinLengthError","MaxLengthError","EmailError","InvalidValueError","setErrors","showCustomAmount","setShowCustomAmount","findOptionByName","name","valid","field","f","giftCardAmountOption","customAmountOption","giftCardAmountField","selectedValue","wasShowingCustomAmount","willShowCustomAmount","handleChange","error","handleBlur","renderField","componentType","Field","TextArea","Input","DownloadableOptions","onLinkChange","SampleLabel","ViewSampleLabel","links","samples","purchaseSeparately","initialSelected","link","setSelected","handleToggle","isSelected","isDisabled","renderLink","renderSample","sample"],"mappings":"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","x_google_ignoreList":[0,1]}
|
|
1
|
+
{"version":3,"file":"components.js","sources":["../../node_modules/@adobe-commerce/elsie/src/icons/ChevronDown.svg","../../node_modules/@adobe-commerce/elsie/src/icons/Close.svg","/@dropins/storefront-pdp/src/components/Carousel/Carousel.tsx","/@dropins/storefront-pdp/src/components/Product/Product.tsx","/@dropins/storefront-pdp/src/components/GalleryGrid/GalleryGrid.tsx","/@dropins/storefront-pdp/src/components/PriceRange/PriceRange.tsx","/@dropins/storefront-pdp/src/components/Overlay/Overlay.tsx","/@dropins/storefront-pdp/src/components/Swatches/Swatches.tsx","/@dropins/storefront-pdp/src/components/Zoom/Zoom.tsx","/@dropins/storefront-pdp/src/components/Header/Header.tsx","/@dropins/storefront-pdp/src/components/Price/Price.tsx","/@dropins/storefront-pdp/src/components/PriceTiers/PriceTiers.tsx","/@dropins/storefront-pdp/src/components/GiftCardOptions/GiftCardOptions.tsx","/@dropins/storefront-pdp/src/components/DownloadableOptions/DownloadableOptions.tsx"],"sourcesContent":["import * as React from \"react\";\nconst SvgChevronDown = (props) => /* @__PURE__ */ React.createElement(\"svg\", { width: 24, height: 24, viewBox: \"0 0 24 24\", fill: \"none\", xmlns: \"http://www.w3.org/2000/svg\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { vectorEffect: \"non-scaling-stroke\", d: \"M7.74512 9.87701L12.0001 14.132L16.2551 9.87701\", stroke: \"currentColor\", strokeWidth: 1, strokeLinecap: \"square\", strokeLinejoin: \"round\" }));\nexport default SvgChevronDown;\n","import * as React from \"react\";\nconst SvgClose = (props) => /* @__PURE__ */ React.createElement(\"svg\", { width: 24, height: 24, viewBox: \"0 0 24 24\", fill: \"none\", xmlns: \"http://www.w3.org/2000/svg\", ...props }, /* @__PURE__ */ React.createElement(\"path\", { vectorEffect: \"non-scaling-stroke\", d: \"M18.3599 5.64001L5.62988 18.37\", stroke: \"currentColor\" }), /* @__PURE__ */ React.createElement(\"path\", { vectorEffect: \"non-scaling-stroke\", d: \"M18.3599 18.37L5.62988 5.64001\", stroke: \"currentColor\" }));\nexport default SvgClose;\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2023 Adobe\n * All Rights Reserved.\n * __________________\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n */\n\nimport { FunctionComponent, VNode } from 'preact';\nimport {\n HTMLAttributes,\n Children,\n useState,\n useRef,\n useEffect,\n useMemo,\n useCallback,\n useLayoutEffect,\n} from 'preact/compat';\nimport { classes, debounce } from '@adobe-commerce/elsie/lib';\nimport { Button, Icon } from '@adobe-commerce/elsie/components';\nimport { ChevronDown } from '@adobe-commerce/elsie/icons';\nimport { useText } from '@adobe-commerce/elsie/i18n';\n\nimport '@/pdp/components/Carousel/Carousel.css';\n\ntype Show = number;\n\nconst PEAK_WIDTH = 24;\nconst THUMB_GAP = 16;\nconst ICON_SIZE = '32';\n\nenum GapSize {\n small = 16,\n medium = 24,\n large = 64,\n}\n\nexport interface CarouselProps\n extends Omit<HTMLAttributes<HTMLDivElement>, 'controls'> {\n children: VNode[] | VNode;\n thumbnails?: VNode[] | VNode;\n show?: Show | { small: Show; medium: Show; large: Show };\n gap?: 'small' | 'medium' | 'large' | null;\n scrollbar?: boolean;\n peak?: boolean;\n arrows?: boolean;\n controls?: 'thumbnailsRow' | 'thumbnailsColumn' | 'dots' | null;\n arrowsOnMainImage?: boolean;\n loop?: boolean;\n direction?: 'horizontal';\n style?: Record<string, string | number>;\n width?: string;\n height?: string;\n defaultIndex?: number;\n infinite?: boolean;\n isZoomed?: boolean;\n}\n\nexport const Carousel: FunctionComponent<CarouselProps> = ({\n show = 1,\n scrollbar = false,\n peak = false,\n arrows = false,\n controls = 'dots',\n arrowsOnMainImage = false,\n loop = false,\n gap = null,\n direction = 'horizontal',\n width = '100%',\n height = '100%',\n defaultIndex = 0,\n className,\n children,\n thumbnails = null,\n isZoomed,\n ...props\n}) => {\n // i18n\n const Label = useText('PDP.Carousel.label').label;\n const SlideLabel = useText('PDP.Carousel.Slide.label').label;\n const PreviousLabel = useText('PDP.Carousel.Previous.label').label;\n const NextLabel = useText('PDP.Carousel.Next.label').label;\n const ControlsLabel = useText('PDP.Carousel.Controls.label').label;\n const ControlsBtnLabel = useText('PDP.Carousel.Controls.Button.label').label;\n\n // States\n const [perPage, setPerPage] = useState(() => getPerPageFromBreakpoint(show));\n\n // Constants\n const length = Math.ceil(Children.count(children) / perPage);\n\n const peakWidth = peak ? PEAK_WIDTH : 0;\n const gapWidth = gap ? GapSize[gap] : 0;\n const rest = Children.count(children) % perPage;\n\n // States\n const [current, setCurrent] = useState(\n loop ? (isRTL() ? defaultIndex - 1 : defaultIndex + 1) : defaultIndex\n );\n\n // Thumbnails (refs for each thumbnail item)\n const thumbnailsRefs = useRef<HTMLLabelElement[]>([]);\n const [thumbWidth, setThumbWidth] = useState(0);\n const [thumbHeight, setThumbHeight] = useState(0);\n\n // VNodes\n const thumbnailSlides = useMemo<VNode[]>(() => {\n return Children.toArray(thumbnails);\n }, [thumbnails]);\n\n // Slides\n const slides = useMemo<VNode[][]>(() => {\n const returnValue = Children.toArray(children).reduce((acc, child, i) => {\n if (i % perPage === 0) {\n return [...acc, [child]];\n }\n\n return [...acc.slice(0, -1), [...acc[acc.length - 1], child]];\n }, [] as VNode[][]);\n\n if (!loop || returnValue.length === 1) {\n return returnValue;\n }\n\n if (loop && !(Children.count(children) % perPage !== 0)) {\n return [returnValue[length - 1]]\n .concat(returnValue)\n .concat([returnValue[0], returnValue[1]]);\n }\n\n return [Children.toArray(children).slice(-perPage)]\n .concat(returnValue)\n .concat([returnValue[0], returnValue[1]]);\n }, [children, perPage, length, loop]);\n\n // Wrapper\n const wrapperRef = useRef<HTMLDivElement>(null);\n const thumbnailsWrapperRef = useRef<HTMLDivElement>(null);\n\n const thumbnailControls =\n controls === 'thumbnailsRow' || controls === 'thumbnailsColumn';\n\n // Observe Resize (responsive)\n useEffect(() => {\n const wrapper = wrapperRef.current;\n\n if (!wrapper) return; // Guard clause in case the ref is not set yet\n\n const handleResize = debounce(() => {\n setThumbWidth(wrapper.offsetWidth ?? 0);\n setThumbHeight(wrapper.offsetHeight ?? 0);\n const width = window.innerWidth;\n const newPerPage = getPerPageFromBreakpoint(show, width);\n\n if (newPerPage !== perPage) {\n setPerPage(newPerPage);\n }\n }, 50);\n\n const observer = new ResizeObserver(handleResize);\n observer.observe(wrapper);\n\n return () => {\n observer.unobserve(wrapper);\n };\n }, [perPage, show]);\n\n // Scrolling logic controls\n const handleThumbnailsScroll = useCallback(\n (nextSlideIndex: number) => {\n const nextItem = loop ? nextSlideIndex - 1 : nextSlideIndex;\n const thumbnailRef = thumbnailsRefs?.current[0];\n const oneItemWidth = thumbnailRef?.offsetWidth + THUMB_GAP;\n const oneItemHeight = thumbnailRef?.offsetHeight + THUMB_GAP;\n const thumbnailsWrapper = thumbnailsWrapperRef.current!;\n\n const isRow = controls === 'thumbnailsRow';\n const isColumn = controls === 'thumbnailsColumn';\n const offset = isRow\n ? thumbnailsWrapper?.offsetWidth\n : thumbnailsWrapper?.offsetHeight;\n const oneItemSize = isRow ? oneItemWidth : oneItemHeight;\n\n if ((isRow || isColumn) && offset) {\n const visibleThumbnails = Math.floor(\n (isRow\n ? thumbnailsWrapper.clientWidth\n : thumbnailsWrapper.clientHeight) / oneItemSize\n );\n const centerOffset = Math.floor(visibleThumbnails / 2);\n const targetScrollPosition = (nextItem - centerOffset) * oneItemSize;\n thumbnailsWrapper.style.scrollBehavior = 'smooth';\n\n if (isRow) {\n thumbnailsWrapper.scrollLeft = isRTL()\n ? -(\n thumbnailsWrapper.scrollWidth -\n thumbnailsWrapper.clientWidth -\n targetScrollPosition\n )\n : targetScrollPosition;\n } else {\n thumbnailsWrapper.scrollTop = targetScrollPosition;\n }\n }\n },\n [controls, loop]\n );\n\n useEffect(() => {\n handleThumbnailsScroll(current);\n }, [current, handleThumbnailsScroll]);\n\n // Navigation\n const handleScrollTo = useCallback(\n (nextSlideIndex: number, smooth?: boolean, reset?: boolean) => {\n if (thumbnailControls) {\n handleThumbnailsScroll(nextSlideIndex);\n }\n\n const wrapper = wrapperRef.current!;\n const realWidth = peakWidth\n ? wrapper.offsetWidth - peakWidth\n : wrapper.offsetWidth - peakWidth + gapWidth;\n\n const items = Array.from(wrapper.querySelectorAll('[data-index]')).filter(\n (element) => {\n const dataIndex = Number(element.getAttribute('data-index')!);\n return !isNaN(dataIndex) && dataIndex > -1;\n }\n );\n\n const item = items[nextSlideIndex];\n\n if (!item) {\n return;\n }\n\n if (reset) {\n const futureIndex = nextSlideIndex === 0 ? length : 0;\n const scrollWidth =\n realWidth * (length + (rest ? rest : perPage) / perPage);\n\n if (isRTL()) {\n if (\n wrapper.scrollLeft <= 0 &&\n wrapper.scrollLeft > -(realWidth - 5)\n ) {\n handleScrollTo(1, true);\n return;\n }\n if (\n wrapper.scrollLeft < realWidth - scrollWidth &&\n wrapper.scrollLeft >= -scrollWidth\n ) {\n handleScrollTo(length, true);\n return;\n }\n\n wrapper.style.scrollBehavior = 'auto';\n wrapper.scrollLeft = futureIndex === 0 ? 0 : -scrollWidth;\n handleScrollTo(futureIndex === 0 ? 1 : length, true);\n } else {\n if (wrapper.scrollLeft >= 0 && wrapper.scrollLeft < realWidth - 5) {\n handleScrollTo(1, true);\n return;\n }\n\n if (\n wrapper.scrollLeft > scrollWidth - realWidth &&\n wrapper.scrollLeft <= scrollWidth\n ) {\n handleScrollTo(length, true);\n return;\n }\n\n wrapper.style.scrollBehavior = 'auto';\n wrapper.scrollLeft = futureIndex === 0 ? 0 : scrollWidth;\n handleScrollTo(futureIndex === 0 ? 1 : length, true);\n return;\n }\n }\n\n const diff =\n ((wrapper.offsetWidth - gapWidth) / perPage) *\n slides[nextSlideIndex].length -\n peakWidth;\n\n wrapper.style.scrollBehavior = smooth ? 'smooth' : 'auto';\n wrapper.scrollLeft = isRTL()\n ? -(slides[nextSlideIndex].length === perPage\n ? realWidth * nextSlideIndex\n : realWidth * (nextSlideIndex - 1) - diff)\n : slides[nextSlideIndex].length === perPage\n ? realWidth * nextSlideIndex\n : realWidth * (nextSlideIndex - 1) + diff;\n return;\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n gapWidth,\n length,\n peakWidth,\n perPage,\n rest,\n slides,\n handleThumbnailsScroll,\n controls,\n ]\n );\n\n const handleGoToPrev = useCallback(() => {\n if (loop) {\n const nextSlideIndex = current - 1;\n handleScrollTo(\n nextSlideIndex,\n true,\n isRTL() ? current === length - 1 : current === 1\n );\n return;\n }\n\n const nextSlideIndex = current <= 0 ? 0 : current - 1;\n handleScrollTo(nextSlideIndex, true);\n }, [current, handleScrollTo, loop]); //eslint-disable-line react-hooks/exhaustive-deps\n\n const handleGoToNext = useCallback(() => {\n const lastSlideIndex = slides.length - 1;\n\n if (loop) {\n const nextSlideIndex = current + 1;\n handleScrollTo(\n nextSlideIndex,\n true,\n isRTL() ? current === 0 : current === length\n );\n return;\n }\n\n const nextSlideIndex =\n current >= lastSlideIndex ? lastSlideIndex : current + 1;\n\n handleScrollTo(nextSlideIndex, true);\n }, [slides.length, loop, current, handleScrollTo, length]);\n\n // Navigate with keyboard\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'ArrowLeft') {\n isRTL() ? handleGoToNext() : handleGoToPrev();\n }\n\n if (event.key === 'ArrowRight') {\n isRTL() ? handleGoToPrev() : handleGoToNext();\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n\n return () => {\n window.removeEventListener('keydown', handleKeyDown);\n };\n }, [handleGoToNext, handleGoToPrev]);\n\n // Set default index\n useLayoutEffect(() => {\n handleScrollTo(loop ? defaultIndex + 1 : defaultIndex, false);\n }, [defaultIndex, handleScrollTo, loop, thumbWidth]);\n\n // Track scrolling (swipes)\n const handleOnScroll = debounce(() => {\n const wrapper = wrapperRef.current!;\n const realWidth = peakWidth\n ? wrapper.offsetWidth - peakWidth\n : wrapper.offsetWidth - peakWidth + gapWidth;\n\n const dividing = Math.abs(wrapper.scrollLeft) / realWidth;\n const nextSlideIndex = Math.abs(\n Math.round(dividing) - dividing < 1\n ? Math.round(dividing)\n : Math.ceil(dividing)\n );\n\n if (thumbnailControls) {\n handleThumbnailsScroll(nextSlideIndex);\n }\n\n if (loop) {\n const totalWidth =\n realWidth * (length + (rest ? rest : perPage) / perPage);\n const scrollOffset = isRTL() ? -wrapper.scrollLeft : wrapper.scrollLeft;\n\n if (Math.ceil(Math.abs(scrollOffset)) >= Math.ceil(totalWidth) - 5) {\n wrapper.style.scrollBehavior = 'auto';\n wrapper.scrollLeft = isRTL()\n ? -wrapper.offsetWidth +\n (Math.ceil(scrollOffset) - Math.ceil(totalWidth) - peakWidth)\n : wrapper.offsetWidth +\n (Math.ceil(scrollOffset) - Math.ceil(totalWidth) - peakWidth);\n return;\n }\n\n if (Math.abs(scrollOffset) === 0) {\n wrapper.style.scrollBehavior = 'auto';\n\n wrapper.scrollLeft = isRTL()\n ? -(totalWidth - wrapper.offsetWidth + peakWidth)\n : totalWidth - wrapper.offsetWidth + peakWidth;\n return;\n }\n }\n\n if (current !== nextSlideIndex) {\n setCurrent(nextSlideIndex);\n }\n }, 100);\n\n useEffect(() => {\n const wrapper = wrapperRef.current;\n wrapper?.addEventListener('scroll', handleOnScroll);\n\n return () => {\n wrapper?.removeEventListener('scroll', handleOnScroll);\n };\n }, [handleOnScroll]);\n\n // thumbnails is column -> container is row reverse, controls is column\n // thumbnails is row -> container is column, controls is row\n const getArrow = (\n forThumbnails: boolean,\n direction: string,\n callback: () => void\n ) => {\n return (\n <Button\n className={classes([\n ['pdp-carousel__button', !forThumbnails],\n [`pdp-carousel__button--${direction}`, !forThumbnails],\n [`pdp-carousel__button--${controls}`, forThumbnails],\n ])}\n style={{\n '--height': `${thumbHeight}px`,\n }}\n variant=\"tertiary\"\n aria-label={direction === 'next' ? NextLabel : PreviousLabel}\n onClick={callback}\n disabled={\n loop\n ? false\n : direction === 'next'\n ? current >= slides.length - 1\n : current < 1\n }\n >\n <Icon\n className={classes([\n ['pdp-carousel__button__icon', !forThumbnails],\n [`pdp-carousel__button__icon--${direction}`, !forThumbnails],\n [\n `pdp-carousel__button__icon--${controls}--${direction}`,\n forThumbnails,\n ],\n ])}\n size={ICON_SIZE}\n source={ChevronDown}\n />\n </Button>\n );\n };\n\n const prevArrow =\n arrows &&\n slides.length != 1 &&\n getArrow(thumbnailControls, 'prev', handleGoToPrev);\n\n const nextArrow =\n arrows &&\n slides.length != 1 &&\n getArrow(thumbnailControls, 'next', handleGoToNext);\n\n const prevArrowMainImage =\n arrows && slides.length != 1 && getArrow(false, 'prev', handleGoToPrev);\n\n const nextArrowMainImage =\n arrows && slides.length != 1 && getArrow(false, 'next', handleGoToNext);\n\n return (\n <div\n role=\"region\"\n aria-roledescription={Label}\n className={classes([\n 'pdp-carousel',\n ['pdp-carousel--main-image-controls', arrowsOnMainImage],\n ['pdp-carousel--arrows', arrows && !thumbnailControls],\n [`pdp-carousel--${controls}`, thumbnailControls],\n className,\n ])}\n style={{\n '--flex-carousel':\n controls === 'thumbnailsColumn' ? 'row-reverse' : 'column',\n '--gap': thumbnailControls ? '0' : 'var(--spacing-small)',\n '--width': width,\n }}\n {...props}\n >\n {/* Slideshow */}\n <div\n ref={wrapperRef}\n className={classes([\n 'pdp-carousel__wrapper',\n `pdp-carousel__wrapper--${direction}`,\n ['pdp-carousel__wrapper--scrollbar', scrollbar],\n ['pdp-carousel__wrapper--peak', peak],\n ])}\n style={{\n '--total-width': controls === 'thumbnailsColumn' ? `81.6%` : `100%`,\n '--height': controls === 'thumbnailsColumn' ? 'auto' : height,\n '--gap': gap ? `var(--spacing-${gap})` : '0px',\n '--per-page': perPage,\n }}\n tabIndex={0}\n >\n {slides.map((page, index) => {\n const orphan = page.length < perPage;\n\n return (\n <div\n key={index}\n role=\"group\"\n aria-roledescription={SlideLabel}\n data-index={index}\n className={classes([\n 'pdp-carousel__slide',\n `pdp-carousel__slide--${direction}`,\n ['pdp-carousel__slide--active', current === index],\n ['pdp-carousel__slide--orphan', orphan],\n ['pdp-carousel__slide--hidden', thumbWidth === 0],\n ])}\n style={{\n '--length': page.length,\n }}\n >\n {page}\n </div>\n );\n })}\n </div>\n\n {/* Previous and next arrows for Carousel without thumbnails */}\n {!thumbnailControls && (\n <>\n {prevArrow}\n {nextArrow}\n </>\n )}\n\n {thumbnailControls && arrowsOnMainImage && (\n <>\n {prevArrowMainImage}\n {nextArrowMainImage}\n </>\n )}\n\n {/* Controls */}\n {controls && slides.length != 1 && (\n <div\n className={classes([\n [\n `pdp-carousel__controls__container--${controls}`,\n thumbnailControls,\n ],\n [\n 'pdp-carousel__controls__container--no-arrows',\n !arrows || arrowsOnMainImage,\n ],\n ])}\n style={{\n '--width': controls === 'thumbnailsRow' ? `${thumbWidth}px` : width,\n '--height': `${thumbHeight}px`,\n '--nr-thumbnails': thumbnailSlides.length,\n }}\n >\n {(thumbnailControls || isZoomed) && !arrowsOnMainImage && prevArrow}\n\n <div\n ref={thumbnailsWrapperRef}\n className={classes([\n [\n `pdp-carousel__controls__wrapper--${controls}`,\n thumbnailControls,\n ],\n [`pdp-carousel__controls__wrapper`, thumbnailControls],\n ])}\n >\n <div\n role=\"group\"\n aria-label={ControlsLabel}\n className={classes([\n 'pdp-carousel__controls',\n [`pdp-carousel__controls--${controls}`, thumbnailControls],\n ])}\n >\n {(loop ? slides.slice(0, length) : slides).map((_, key) => {\n const buttonsLength = loop ? length : slides.length;\n const active = loop ? current - 1 === key : current === key;\n\n if (!thumbnailControls) {\n return (\n <button\n key={key}\n aria-label={ControlsBtnLabel.replace(\n '{key}',\n String(key + 1)\n ).replace('{total}', String(buttonsLength))}\n onClick={() => {\n handleScrollTo(loop ? key + 1 : key, true);\n }}\n className={classes([\n 'pdp-carousel__controls__button',\n ['pdp-carousel__controls__button--active', active],\n ])}\n />\n );\n }\n return (\n <label\n className={classes(['pdp-carousel__thumbnail__container'])}\n key={key}\n ref={(el: HTMLLabelElement | null) => {\n if (el) {\n thumbnailsRefs.current[key] = el;\n }\n }}\n >\n <input\n type=\"radio\"\n name={'carousel-thumbnails'}\n aria-label={ControlsBtnLabel.replace(\n '{key}',\n String(key + 1)\n ).replace('{total}', String(buttonsLength))}\n checked={active && thumbWidth !== 0}\n onChange={() => {\n handleScrollTo(loop ? key + 1 : key, true);\n }}\n {...props}\n className={classes([\n 'pdp-carousel__thumbnail',\n [\n 'pdp-carousel__thumbnail--selected',\n active && thumbWidth !== 0,\n ],\n ])}\n />\n\n <span\n className={classes(['pdp-carousel__thumbnail__span'])}\n >\n {thumbnailSlides[key]}\n </span>\n </label>\n );\n })}\n </div>\n </div>\n\n {(thumbnailControls || isZoomed) && !arrowsOnMainImage && nextArrow}\n </div>\n )}\n </div>\n );\n};\n\n// Utilities\nfunction getPerPageFromBreakpoint(\n breakpoints: { small: number; medium: number; large: number } | number,\n width = 0\n) {\n if (typeof breakpoints === 'number') return breakpoints;\n\n const { small, medium, large } = breakpoints;\n const breakpointsMap = [\n { breakpoint: 1024, value: large },\n { breakpoint: 786, value: medium },\n { breakpoint: 0, value: small },\n ];\n\n const matchingBreakpoint = breakpointsMap.find(\n ({ breakpoint }) => width > breakpoint\n );\n\n return matchingBreakpoint ? matchingBreakpoint.value : small;\n}\n\nfunction isRTL() {\n return document.documentElement.dir === 'rtl';\n}\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2023 Adobe\n * All Rights Reserved.\n * __________________\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n */\n\nimport { FunctionComponent, VNode } from 'preact';\nimport { HTMLAttributes, useState } from 'preact/compat';\nimport { classes, VComponent } from '@adobe-commerce/elsie/lib';\nimport { useText } from '@adobe-commerce/elsie/i18n';\n\nimport { Carousel, GalleryGrid, Overlay, Zoom } from '@/pdp/components';\nimport '@/pdp/components/Product/Product.css';\n\nimport { CarouselConfig } from '@/pdp/containers';\n\ninterface ProductCarouselConfig extends CarouselConfig {\n thumbnails: VNode[];\n}\n\nexport interface ProductProps\n extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n title?: VNode;\n breadcrumbs?: VNode;\n galleryContent?: VNode;\n infoContent?: VNode;\n productContent?: VNode;\n shortDescription?: VNode;\n description?: VNode;\n attributes?: VNode;\n images: VNode[];\n options?: VNode;\n giftCardOptions?: VNode;\n downloadableOptions?: VNode;\n sku?: VNode;\n price?: VNode;\n specialPrice?: VNode;\n outOfStock: boolean;\n actions?: VNode;\n quantity?: VNode;\n carouselConfig?: ProductCarouselConfig;\n zoomType?: 'zoom' | 'overlay';\n closeButton?: boolean;\n}\n\nexport const Product: FunctionComponent<ProductProps> = ({\n title,\n breadcrumbs,\n galleryContent,\n infoContent,\n productContent,\n sku,\n outOfStock,\n shortDescription,\n description,\n attributes,\n images,\n options,\n giftCardOptions,\n downloadableOptions,\n price,\n specialPrice,\n className,\n children,\n quantity,\n actions,\n carouselConfig,\n zoomType = 'overlay',\n closeButton = true,\n ...props\n}) => {\n // i18n\n const RegularPriceLabel = useText('PDP.Product.RegularPrice.label').label;\n const SpecialPriceLabel = useText('PDP.Product.SpecialPrice.label').label;\n const OutOfStockLabel = useText('PDP.Product.OutOfStock.label').label;\n const ImagesLabel = useText('PDP.Product.Image.label').label;\n\n const [zoom, setZoom] = useState<number | null>(null);\n\n const galleryImages = images?.length ? (\n images.map((image, key) => {\n const alt =\n title?.props?.children &&\n ImagesLabel?.replace('{product}', title.props.children.toString())\n .replace('{key}', String(key + 1))\n .replace('{total}', String(images.length));\n return zoomType === 'zoom' ? (\n <Zoom closeButton={closeButton}>\n <VComponent\n key={key}\n node={image}\n loading={key === 0 ? 'eager' : 'lazy'}\n alt={alt}\n />\n </Zoom>\n ) : (\n <VComponent\n key={key}\n node={image}\n loading={key === 0 ? 'eager' : 'lazy'}\n alt={alt}\n onClick={() => setZoom(key)}\n />\n );\n })\n ) : (\n <img\n src=\"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\"\n className=\"pdp-product__images__placeholder\"\n aria-hidden\n />\n );\n\n const localThumbnailsImages = carouselConfig?.thumbnails?.length ? (\n carouselConfig.thumbnails.map((image, key) => (\n <VComponent\n key={key}\n node={image}\n loading={carouselConfig?.thumbnailsLoadingMode || 'lazy'}\n alt={\n title?.props?.children &&\n ImagesLabel?.replace('{product}', title.props.children.toString())\n .replace('{key}', String(key + 1))\n .replace('{total}', String(images.length))\n }\n />\n ))\n ) : (\n <img\n src=\"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\"\n className=\"pdp-product__images__placeholder\"\n aria-hidden\n />\n );\n\n return (\n <div {...props} className={classes(['pdp-product', className])}>\n {breadcrumbs && (\n <VComponent node={breadcrumbs} className=\"pdp-product__breadcrumbs\" />\n )}\n <div className=\"pdp-product__column-container pdp-product__gallery-column\">\n <div className=\"pdp-product__column-body\">\n {carouselConfig?.controls?.desktop ? (\n <Carousel\n className=\"pdp-product__overlay__carousel\"\n arrows={images?.length > 1}\n controls={\n images?.length > 1 ? carouselConfig.controls.desktop : 'dots'\n }\n arrowsOnMainImage={carouselConfig?.arrowsOnMainImage}\n loop={carouselConfig?.loopable && images?.length > 1}\n peak={\n (carouselConfig?.thumbnails?.length > 1 &&\n carouselConfig?.peak?.desktop) ||\n false\n }\n gap={carouselConfig?.gap || null}\n width=\"100%\"\n height=\"100%\"\n defaultIndex={zoom || 0}\n thumbnails={localThumbnailsImages}\n >\n {galleryImages}\n </Carousel>\n ) : (\n <GalleryGrid className=\"pdp-product__images\" gap=\"small\">\n {galleryImages}\n </GalleryGrid>\n )}\n </div>\n {galleryContent && (\n <VComponent\n node={galleryContent}\n className=\"pdp-product__gallery-content\"\n />\n )}\n </div>\n\n <div className=\"pdp-product__column-container pdp-product__content-column\">\n <div className=\"pdp-product__column-body\">\n <div className=\"pdp-product__header\">\n {title && (\n <VComponent node={title} className=\"pdp-product__title\" />\n )}\n\n {sku && <VComponent node={sku} className=\"pdp-product__sku\" />}\n </div>\n\n <div className=\"pdp-product__prices\">\n {specialPrice && (\n <VComponent\n node={specialPrice}\n className={classes([\n 'pdp-product__price-special',\n 'pdp-product__price',\n ])}\n aria-label={SpecialPriceLabel}\n role=\"text\"\n />\n )}\n {price && (\n <VComponent\n node={price}\n className={classes([\n 'pdp-product__price-regular',\n 'pdp-product__price--grey',\n ])}\n aria-label={RegularPriceLabel}\n role=\"text\"\n />\n )}\n </div>\n\n {/* Small Screen Gallery */}\n {carouselConfig?.controls?.mobile &&\n carouselConfig?.controls?.mobile === 'thumbnailsRow' ? (\n <Carousel\n className=\"pdp-product__images pdp-product__images--carousel pdp-product__images--carousel--thumbnails\"\n width=\"100%\"\n height=\"auto\"\n arrows={images?.length > 1}\n controls={images?.length > 1 ? 'thumbnailsRow' : null}\n loop={carouselConfig?.loopable && images?.length > 1}\n peak={\n (carouselConfig?.thumbnails?.length > 1 &&\n carouselConfig?.peak?.mobile) ||\n false\n }\n gap={carouselConfig?.gap || null}\n thumbnails={localThumbnailsImages}\n >\n {galleryImages}\n </Carousel>\n ) : (\n <Carousel\n className=\"pdp-product__images pdp-product__images--carousel\"\n peak={carouselConfig?.peak?.mobile && images?.length > 1}\n gap={carouselConfig?.gap || null}\n width=\"100%\"\n height=\"auto\"\n arrows={images?.length > 1}\n controls={images?.length > 1 ? 'dots' : null}\n loop={carouselConfig?.loopable && images?.length > 1}\n >\n {galleryImages}\n </Carousel>\n )}\n\n <div\n className={classes([\n 'pdp-product__actions',\n [`pdp-product__actions--out-of-stock`, outOfStock],\n ])}\n >\n {outOfStock && (\n <div className=\"pdp-product__out-of-stock__text\">\n {OutOfStockLabel}\n </div>\n )}\n\n {options && (\n <VComponent\n node={options}\n className={classes(['pdp-product__options'])}\n />\n )}\n\n {giftCardOptions && (\n <VComponent\n node={giftCardOptions}\n className={classes(['pdp-product__gift-card-options'])}\n />\n )}\n\n {downloadableOptions && (\n <VComponent\n node={downloadableOptions}\n className={classes(['pdp-product__downloadable-options'])}\n />\n )}\n\n {quantity && (\n <div className=\"pdp-product__quantity\">\n <VComponent node={quantity} />\n </div>\n )}\n\n {actions && (\n <VComponent\n node={actions}\n className={classes(['pdp-product__buttons'])}\n />\n )}\n </div>\n\n {shortDescription && (\n <VComponent\n node={shortDescription}\n className={classes(['pdp-product__short_description'])}\n />\n )}\n\n {description && (\n <VComponent\n node={description}\n className={classes(['pdp-product__description'])}\n />\n )}\n\n {attributes ? (\n <div className=\"pdp-product__attributes\">{attributes}</div>\n ) : null}\n </div>\n {infoContent && (\n <VComponent\n node={infoContent}\n className=\"pdp-product__info-content\"\n />\n )}\n </div>\n\n {productContent && (\n <VComponent node={productContent} className=\"pdp-product__content\" />\n )}\n\n {/* Zoom Overlay */}\n {zoom === null ? null : (\n <Overlay\n className=\"pdp-product__overlay\"\n onClose={() => setZoom(null)}\n centered\n >\n <Carousel\n className=\"pdp-product__overlay__carousel\"\n arrows={images?.length > 1}\n width=\"100%\"\n height=\"100%\"\n defaultIndex={zoom || 0}\n loop={carouselConfig?.loopable && images?.length > 1}\n controls={images?.length > 1 ? 'dots' : null}\n isZoomed\n >\n {galleryImages}\n </Carousel>\n </Overlay>\n )}\n </div>\n );\n};\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2023 Adobe\n * All Rights Reserved.\n * __________________\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n */\n\nimport { FunctionComponent, VNode } from 'preact';\nimport { HTMLAttributes, Children } from 'preact/compat';\nimport { classes, VComponent } from '@adobe-commerce/elsie/lib';\nimport '@/pdp/components/GalleryGrid/GalleryGrid.css';\n\nexport interface GalleryGridProps extends HTMLAttributes<HTMLDivElement> {\n children: VNode[] | VNode;\n gap?: 'small' | 'medium' | 'large' | null;\n style?: Record<string, string | number>;\n}\n\nexport const GalleryGrid: FunctionComponent<GalleryGridProps> = ({\n children,\n gap = null,\n className,\n style,\n ...props\n}) => {\n const count = Children.count(children);\n\n return (\n <div\n {...props}\n className={classes(['pdp-gallery-grid', className])}\n style={{\n '--gap': gap ? `var(--spacing-${gap})` : '0px',\n ...style,\n }}\n >\n {Children.map(\n children,\n (child: VNode<HTMLAttributes<HTMLElement>>, key) => (\n <div key={count + key} className=\"pdp-gallery-grid__item\">\n <VComponent\n key={child.props.src}\n node={child}\n loading={key === 0 ? 'eager' : 'lazy'}\n />\n </div>\n )\n )}\n </div>\n );\n};\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2023 Adobe\n * All Rights Reserved.\n * __________________\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n */\n\nimport { HTMLAttributes } from 'preact/compat';\nimport '@/pdp/components/PriceRange/PriceRange.css';\nimport { FunctionalComponent } from 'preact';\nimport { Price } from '@adobe-commerce/elsie/components';\n\nexport interface PriceRangeProps extends HTMLAttributes<HTMLDivElement> {\n locale?: string;\n variant?: 'default' | 'strikethrough';\n currency?: string;\n\n // Simple product\n amount?: number;\n sale?: boolean;\n\n // Complex product (range)\n minimumAmount?: number;\n maximumAmount?: number;\n}\n\nexport const PriceRange: FunctionalComponent<PriceRangeProps> = ({\n amount,\n currency,\n locale,\n variant,\n sale,\n minimumAmount,\n maximumAmount,\n className,\n ...props\n}) => {\n return (\n <>\n {amount || minimumAmount === maximumAmount ? (\n <div className={'pdp-price-range'} {...props}>\n <Price\n amount={amount ? amount : minimumAmount}\n currency={currency}\n locale={locale}\n variant={variant}\n sale={sale}\n className={className}\n />\n </div>\n ) : (\n <div className={'pdp-price-range'} {...props}>\n <Price\n amount={minimumAmount}\n currency={currency}\n locale={locale}\n className={className}\n />\n <span className=\"pdp-price-range__label\">{'-'}</span>\n <Price\n amount={maximumAmount}\n currency={currency}\n locale={locale}\n className={className}\n />\n </div>\n )}\n </>\n );\n};\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2023 Adobe\n * All Rights Reserved.\n * __________________\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n */\n\nimport { FunctionComponent } from 'preact';\nimport { HTMLAttributes, useCallback, useEffect, useRef } from 'preact/compat';\nimport { classes } from '@adobe-commerce/elsie/lib';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { Close as CloseSVG } from '@adobe-commerce/elsie/icons';\nimport { Button } from '@adobe-commerce/elsie/components';\n\nimport '@/pdp/components/Overlay/Overlay.css';\n\nexport interface OverlayProps extends HTMLAttributes<HTMLDivElement> {\n centered?: boolean;\n onClose?: () => void;\n}\n\nexport const Overlay: FunctionComponent<OverlayProps> = ({\n centered,\n onClose,\n className,\n children,\n ...props\n}) => {\n // i18n\n const CloseLabel = useText('PDP.Overlay.Close.label').label;\n const overlayRef = useRef<HTMLInputElement>(null);\n const handleOnClose = useCallback(() => {\n onClose?.();\n }, [onClose]);\n\n // Close on ESC\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n handleOnClose();\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [handleOnClose]);\n\n // Prevent document scrolling\n useEffect(() => {\n const input = overlayRef.current;\n input?.focus();\n\n const scrollingElement = document.scrollingElement as HTMLElement;\n\n const defaultOverflowValue = scrollingElement.style.overflow;\n\n scrollingElement.style.overflow = 'hidden';\n\n return () => {\n scrollingElement.style.overflow = defaultOverflowValue;\n };\n }, []);\n\n return (\n <div\n {...props}\n className={classes([\n 'pdp-overlay',\n ['pdp-overlay--centered', centered],\n className,\n ])}\n ref={overlayRef}\n role=\"dialog\"\n aria-describedby=\"overlay-content\"\n tabindex={0}\n >\n <div className=\"pdp-overlay__content\" id=\"overlay-content\">\n {children}\n </div>\n <Button\n aria-label={CloseLabel}\n variant=\"tertiary\"\n className=\"pdp-overlay__close-button\"\n onClick={handleOnClose}\n icon={<CloseSVG />}\n />\n </div>\n );\n};\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2023 Adobe\n * All Rights Reserved.\n * __________________\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n */\n\nimport { FunctionComponent, VNode } from 'preact';\nimport {\n HTMLAttributes,\n useState,\n useMemo,\n useCallback,\n useEffect,\n JSX,\n ChangeEvent,\n} from 'preact/compat';\nimport { classes } from '@adobe-commerce/elsie/lib';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport {\n ColorSwatch,\n ImageSwatch,\n TextSwatch,\n Picker,\n PickerOption,\n ImageNodeRenderProps,\n Checkbox,\n Incrementer,\n} from '@adobe-commerce/elsie/components';\n\nimport type {\n ProductOptionSelectionEntry,\n ProductOptionSelectionMap,\n} from '@/pdp/lib/product-option-selection';\n\nimport '@/pdp/components/Swatches/Swatches.css';\n\nexport type {\n ProductOptionSelectionEntry as SelectionEntry,\n ProductOptionSelectionMap as Selection,\n} from '@/pdp/lib/product-option-selection';\n\nconst supportedTypes = ['text', 'image', 'color', 'dropdown'];\n\nconst mapToPickerOptions = (items: OptionValue[]): PickerOption[] => {\n return items.map((item: OptionValue) => ({\n ...item,\n text: item.label,\n disabled: !item.inStock,\n }));\n};\n\ntype OptionValue = {\n id: string;\n label: string;\n inStock: boolean;\n value: string;\n selected?: boolean;\n quantity?: number;\n canEditQuantity?: boolean;\n};\n\nfunction isBundleOptionGroup(\n typename: Option['typename'] | undefined\n): boolean {\n return typename === 'ProductViewOptionValueProduct';\n}\n\nfunction hasBundleQuantityControl(\n option: OptionValue | undefined,\n typename: Option['typename'] | undefined\n): boolean {\n if (!option || !isBundleOptionGroup(typename)) {\n return false;\n }\n return true;\n}\n\nexport type Option = {\n id: string;\n type: (typeof supportedTypes)[number];\n typename?:\n | 'ProductViewOptionValueProduct'\n | 'ProductViewOptionValueSwatch'\n | 'ProductViewOptionValueConfiguration';\n label: string;\n required?: boolean;\n multiple?: boolean;\n items: OptionValue[];\n};\n\nfunction optionUIDsToSelection(\n optionUIDs: string[],\n options: Array<Option>\n): ProductOptionSelectionMap {\n return options.reduce((accum, option) => {\n const selectedItems = option.items.filter((item) =>\n optionUIDs.includes(item.id)\n );\n if (selectedItems.length === 0) {\n return accum;\n }\n\n if (option.multiple) {\n return {\n ...accum,\n [option.id]: {\n label: selectedItems.map((i) => i.label).join(', '),\n values: selectedItems.map((i) => i.id),\n },\n };\n }\n\n const item = selectedItems[0];\n return {\n ...accum,\n [option.id]: { label: item.label, value: item.id },\n };\n }, {} as ProductOptionSelectionMap);\n}\n\nfunction getSingleSelectedValue(\n entry: ProductOptionSelectionEntry | undefined\n): string | undefined {\n if (!entry || !('value' in entry)) {\n return undefined;\n }\n return entry.value;\n}\n\nexport interface SwatchesProps extends HTMLAttributes<HTMLDivElement> {\n options: Array<Option>;\n hideSelectedValue?: boolean;\n disablePreselections?: boolean;\n defaultOptions?: string[];\n selectionsToUpdate?: Option[];\n onValues?: (uids: ProductOptionSelectionMap, current: string) => void;\n onErrors?: (errors: { [id: string]: string }) => void;\n /** Per bundle option value UID quantities for selected bundle children. */\n bundleOptionQuantities?: Record<string, number>;\n onBundleOptionQuantityChange?: (\n optionValueId: string,\n quantity: number\n ) => void;\n selectedUIDs?: string[];\n imageSwatchNode?: VNode | ((props: ImageNodeRenderProps) => JSX.Element);\n}\n\nexport const Swatches: FunctionComponent<SwatchesProps> = ({\n options,\n hideSelectedValue,\n disablePreselections,\n selectedUIDs,\n onValues,\n onErrors,\n bundleOptionQuantities,\n onBundleOptionQuantityChange,\n defaultOptions,\n selectionsToUpdate,\n className,\n children,\n imageSwatchNode,\n ...props\n}) => {\n // i18n\n const RequiredLabel = useText('PDP.Swatches.Required.label').label;\n const ChooseOptionLabel = useText('PDP.Swatches.ChooseOption.label').label;\n const BundleOptionQuantityLabel = useText(\n 'PDP.Swatches.BundleOptionQuantity.label'\n ).label;\n\n const [selections, setSelections] = useState<ProductOptionSelectionMap>(\n () => {\n let accum: ProductOptionSelectionMap =\n defaultOptions?.length && options?.length\n ? optionUIDsToSelection(defaultOptions, options)\n : {};\n\n options?.forEach((option) => {\n if (accum[option.id]) {\n return;\n }\n\n const { items } = option;\n\n if (option.multiple) {\n const picked = items?.filter(\n (item) =>\n Boolean(defaultOptions?.includes(item.id)) || item.selected\n );\n if (picked?.length) {\n accum = {\n ...accum,\n [option.id]: {\n label: picked.map((i) => i.label).join(', '),\n values: picked.map((i) => i.id),\n },\n };\n }\n return;\n }\n\n const defaultSelection = items?.find((item) =>\n defaultOptions?.includes(item.id)\n );\n const selected = items?.find((item) => item.selected);\n\n if (defaultSelection) {\n accum = {\n ...accum,\n [option.id]: {\n label: defaultSelection.label,\n value: defaultSelection.id,\n },\n };\n } else if (selected) {\n accum = {\n ...accum,\n [option.id]: { label: selected.label, value: selected.id },\n };\n }\n });\n\n return accum;\n }\n );\n\n // set selected options from props\n useEffect(() => {\n if (selectedUIDs) {\n const selection = optionUIDsToSelection(selectedUIDs, options);\n // if the internal state is already the same as the props, do nothing\n if (JSON.stringify(selection) === JSON.stringify(selections)) return;\n\n setSelections((prev) => {\n let next = {\n ...prev,\n ...selection,\n };\n onValues?.(next, selectedUIDs?.[0] ?? '');\n return next;\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [selectedUIDs]);\n\n // this only applies for the case with anchor options\n // update selections in the swatches if they are updated in the parent component\n useEffect(() => {\n selectionsToUpdate?.forEach((selectionToUpdate) => {\n setSelections((prev) => {\n const selectedItems = selectionToUpdate?.items?.filter(\n (item) => item.selected\n );\n if (!selectedItems?.length) return prev;\n\n if (selectionToUpdate.multiple) {\n const next = {\n ...prev,\n [selectionToUpdate.id]: {\n label: selectedItems.map((i) => i.label).join(', '),\n values: selectedItems.map((i) => i.id),\n },\n };\n return next;\n }\n\n const selectedItem = selectedItems[0];\n const next = {\n ...prev,\n [selectionToUpdate.id]: {\n label: selectedItem.label,\n value: selectedItem.id,\n },\n };\n return next;\n });\n });\n }, [selectionsToUpdate, setSelections]);\n\n // Update invalid options\n useMemo(() => {\n const errors = options?.reduce((accum, option) => {\n const entry = selections[option.id];\n let satisfied = false;\n\n if (option.multiple) {\n satisfied = Boolean(\n entry && 'values' in entry && entry.values.length > 0\n );\n } else {\n option?.items?.forEach((item) => {\n if (entry && 'value' in entry && entry.value === item.id) {\n satisfied = true;\n }\n });\n }\n\n if (option.required && !satisfied) {\n accum[option.id] = RequiredLabel;\n }\n return accum;\n }, {} as { [id: string]: string });\n\n onErrors?.(errors);\n\n return errors;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [selections]);\n\n const handleOnSelection = useCallback(\n (optionGroupId: string, label: string, itemUid: string) => {\n setSelections((prev) => {\n let next: ProductOptionSelectionMap = {\n ...prev,\n ...(optionGroupId && { [optionGroupId]: { label, value: itemUid } }),\n };\n\n if (label === ChooseOptionLabel) {\n const rest = { ...next };\n delete rest[optionGroupId];\n next = rest;\n }\n\n onValues?.(next, itemUid);\n\n return next;\n });\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [onValues]\n );\n\n const handleMultiToggle = useCallback(\n (\n optionGroupId: string,\n itemId: string,\n checked: boolean,\n groupItems: OptionValue[]\n ) => {\n setSelections((prev) => {\n const prevEntry = prev[optionGroupId];\n const prevValues: string[] =\n prevEntry && 'values' in prevEntry\n ? [...prevEntry.values]\n : prevEntry && 'value' in prevEntry && prevEntry.value\n ? [prevEntry.value]\n : [];\n\n const nextValues = checked\n ? [...new Set([...prevValues, itemId])]\n : prevValues.filter((v) => v !== itemId);\n\n const labelById = new Map(\n groupItems.map((i) => [i.id, i.label] as const)\n );\n const nextLabel = nextValues\n .map((uid) => labelById.get(uid))\n .filter(Boolean)\n .join(', ');\n\n const next: ProductOptionSelectionMap = { ...prev };\n if (nextValues.length === 0) {\n delete next[optionGroupId];\n } else {\n next[optionGroupId] = { label: nextLabel, values: nextValues };\n }\n onValues?.(next, itemId);\n return next;\n });\n },\n [onValues]\n );\n\n // Function to handle the picker selection\n const handlePickerSelect = useCallback(\n (optionId: string, selection: any) => {\n const label = selection.selectedOptions[0]?.label ?? '';\n handleOnSelection(optionId, label, selection.value);\n },\n [handleOnSelection]\n );\n\n const renderBundleOptionQuantity = useCallback(\n (option: OptionValue, typename: Option['typename'] | undefined) => {\n if (!hasBundleQuantityControl(option, typename)) {\n return null;\n }\n\n const defaultQuantity =\n option.quantity && option.quantity > 0 ? option.quantity : 1;\n const quantityValue =\n bundleOptionQuantities?.[option.id] ?? defaultQuantity;\n const ariaLabel = BundleOptionQuantityLabel.replace(\n '{option}',\n option.label\n );\n\n return (\n <Incrementer\n key={`bundle-qty-${option.id}`}\n name={`bundle-option-quantity__${option.id}`}\n className=\"pdp-swatches__bundle-option__quantity\"\n min={1}\n value={String(quantityValue)}\n disabled={!option.canEditQuantity}\n aria-label={ariaLabel}\n onValue={(value) => {\n const quantity = Math.max(1, Number(value) || 1);\n onBundleOptionQuantityChange?.(option.id, quantity);\n }}\n />\n );\n },\n [\n BundleOptionQuantityLabel,\n bundleOptionQuantities,\n onBundleOptionQuantityChange,\n ]\n );\n\n const renderOptionControl = useCallback(\n ({\n items,\n id,\n required,\n type,\n selected,\n label,\n multiple,\n typename,\n }: {\n items: OptionValue[];\n id: string;\n required?: boolean | null;\n type: string;\n selected?: string;\n label: string;\n multiple?: boolean;\n typename?: Option['typename'];\n }) => {\n const uniqueId = `pdp-swatch-${id}=${Math.random().toString(36)}`;\n\n if (multiple) {\n const entry = selections[id];\n const selectedIds = new Set(\n entry && 'values' in entry ? entry.values : []\n );\n\n return (\n items?.length > 0 && (\n <div\n className={classes([\n 'pdp-swatches__options',\n 'pdp-swatches__options--checkboxes',\n ])}\n >\n {items?.map((option: OptionValue) => (\n <div key={option.id} className=\"pdp-swatches__bundle-option\">\n <Checkbox\n name={`pdp-bundle-multi__${id}__${option.id}`}\n label={option.label}\n checked={selectedIds.has(option.id)}\n disabled={!option.inStock}\n onChange={(e: ChangeEvent<HTMLInputElement>) =>\n handleMultiToggle(\n id,\n option.id,\n e.currentTarget.checked,\n items\n )\n }\n />\n {selectedIds.has(option.id) &&\n hasBundleQuantityControl(option, typename) &&\n renderBundleOptionQuantity(option, typename)}\n </div>\n ))}\n </div>\n )\n );\n }\n\n const selectedItem = items?.find((item) => item.id === selected);\n const bundleOptions = isBundleOptionGroup(typename);\n\n return (\n items?.length > 0 && (\n <div\n className={classes([\n 'pdp-swatches__options',\n bundleOptions && 'pdp-swatches__options--bundle',\n ])}\n >\n {type?.toLowerCase() === 'dropdown' ? (\n <>\n <Picker\n id={uniqueId}\n name={id}\n aria-label={label}\n placeholder={\n disablePreselections ? ChooseOptionLabel : undefined\n }\n handleSelect={(event) => handlePickerSelect(id, event.target)}\n options={mapToPickerOptions(items)}\n value={selected}\n />\n {hasBundleQuantityControl(selectedItem, typename) &&\n renderBundleOptionQuantity(selectedItem, typename)}\n </>\n ) : (\n items?.map((option: OptionValue) => {\n const common = {\n key: option.id,\n id: `${uniqueId}-${option.id}`,\n name: id,\n value: option.value,\n label: option.label,\n groupAriaLabel: label,\n selected: selected === option.id,\n outOfStock: !option.inStock,\n // API may return null, we default to true as all swatches are required.\n // we still comply to this in case the api return \"false\".\n required: required === null ? true : required,\n onValue: () => {\n handleOnSelection(id, option.label, option.id);\n },\n };\n\n let swatch: JSX.Element | null;\n switch (type) {\n case 'text':\n swatch = <TextSwatch {...common} label={option.label} />;\n break;\n\n case 'image':\n swatch = (\n <ImageSwatch\n {...common}\n src={option.value}\n alt={option.label}\n imageNode={imageSwatchNode}\n />\n );\n break;\n\n case 'color':\n swatch = (\n <ColorSwatch\n {...common}\n size=\"large\"\n color={option.value}\n />\n );\n break;\n\n default:\n console.warn(`Invalid swatch type ${type}`);\n return null;\n }\n\n if (!bundleOptions) {\n return swatch;\n }\n\n return (\n <div key={option.id} className=\"pdp-swatches__bundle-option\">\n {swatch}\n {option.id === selected &&\n hasBundleQuantityControl(option, typename) &&\n renderBundleOptionQuantity(option, typename)}\n </div>\n );\n })\n )}\n </div>\n )\n );\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n ChooseOptionLabel,\n handleOnSelection,\n handlePickerSelect,\n handleMultiToggle,\n renderBundleOptionQuantity,\n selections,\n ]\n );\n\n return (\n <div {...props} className={classes(['pdp-swatches', className])}>\n {options?.map(\n ({ type, label, id, multiple, required, items, typename }) => {\n // Only render supported types\n if (!supportedTypes.includes(type)) {\n console.warn(`Invalid swatch type ${type}`);\n }\n\n return (\n <div\n key={`swatch-item-${id}`}\n id={`swatch-item-${id}`}\n data-slot-key={`product-swatch--${id}`}\n className=\"pdp-swatches__field\"\n >\n <div className=\"pdp-swatches__field__label\">\n {selections[id]\n ? hideSelectedValue\n ? `${label}`\n : `${label}: ${selections[id].label}`\n : label}\n </div>\n\n {renderOptionControl({\n id,\n type,\n typename,\n required,\n items,\n label,\n multiple,\n selected: getSingleSelectedValue(selections[id]),\n })}\n </div>\n );\n }\n )}\n </div>\n );\n};\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2024 Adobe\n * All Rights Reserved.\n * __________________\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n */\nimport { cloneElement, FunctionComponent, VNode } from 'preact';\nimport {\n Children,\n useEffect,\n useState,\n useRef,\n useCallback,\n} from 'preact/compat';\n\nimport '@/pdp/components/Zoom/Zoom.css';\nimport { Button } from '@adobe-commerce/elsie/components';\nimport { Close as CloseSVG } from '@adobe-commerce/elsie/icons';\nimport { useText } from '@adobe-commerce/elsie/i18n';\n\nexport interface ZoomProps {\n children: VNode[] | VNode;\n scale?: number;\n closeButton?: boolean;\n}\n\nexport const Zoom: FunctionComponent<ZoomProps> = ({\n children,\n scale = 2.0,\n closeButton = true,\n}) => {\n const [zoomed, setZoomed] = useState(false);\n const [figureClassName, setFigureClassName] = useState('pdp-zoom');\n const [drag, setDrag] = useState(false);\n const [dragStart, setDragStart] = useState({ x: 0, y: 0 });\n const [dragStartPosition, setDragStartPosition] = useState({ x: 0, y: 0 });\n const [position, setPosition] = useState({ x: 0, y: 0 });\n\n const containerRef = useRef<HTMLElement>(null);\n const cachedBoundsRef = useRef<DOMRect | null>(null);\n const animationFrameRef = useRef<number | null>(null);\n const lastTransformRef = useRef<string>('none');\n\n const touchStartRef = useRef<{ x: number; y: number; time: number } | null>(\n null\n );\n const isSwipingRef = useRef<boolean>(false);\n const lastValidTouchRef = useRef<{ clientX: number; clientY: number } | null>(\n null\n );\n\n const updatePosition = useCallback(\n (event: MouseEvent | TouchEvent) => {\n const updatePositionLogic = () => {\n let zoomer: DOMRect;\n\n if (cachedBoundsRef.current && containerRef.current) {\n zoomer = cachedBoundsRef.current;\n } else if (containerRef.current) {\n zoomer = containerRef.current.getBoundingClientRect();\n cachedBoundsRef.current = zoomer;\n } else {\n zoomer = (\n event.currentTarget as HTMLElement\n )?.getBoundingClientRect();\n }\n\n const overlap = (100 - 100 / scale) / 2;\n let coordinates: { clientX: number; clientY: number } | null = null;\n\n if ('touches' in event) {\n if (event.touches.length > 0) {\n coordinates = event.touches[0];\n lastValidTouchRef.current = {\n clientX: coordinates.clientX,\n clientY: coordinates.clientY,\n };\n } else if (event.type === 'touchend' && touchStartRef.current) {\n coordinates = {\n clientX: touchStartRef.current.x,\n clientY: touchStartRef.current.y,\n };\n } else if (lastValidTouchRef.current) {\n coordinates = lastValidTouchRef.current;\n } else {\n return;\n }\n } else if (event instanceof MouseEvent) {\n coordinates = event;\n } else {\n return;\n }\n\n const relativeX =\n ((coordinates.clientX - zoomer.left) / zoomer.width) * 100;\n const relativeY =\n ((coordinates.clientY - zoomer.top) / zoomer.height) * 100;\n\n const x = ((50 - relativeX) * (scale - 1)) / scale;\n const y = ((50 - relativeY) * (scale - 1)) / scale;\n\n setPosition({\n x: Math.max(-overlap, Math.min(x, overlap)) || 0,\n y: Math.max(-overlap, Math.min(y, overlap)) || 0,\n });\n };\n\n if (typeof process !== 'undefined' && process.env?.NODE_ENV === 'test') {\n updatePositionLogic();\n } else {\n if (animationFrameRef.current) {\n cancelAnimationFrame(animationFrameRef.current);\n }\n animationFrameRef.current = requestAnimationFrame(updatePositionLogic);\n }\n },\n [scale]\n );\n\n useEffect(() => {\n cachedBoundsRef.current = null;\n }, [zoomed]);\n\n const startDrag = (event: TouchEvent) => {\n if (!zoomed || event.type !== 'touchstart') return;\n setDragStart({ x: event.touches[0].clientX, y: event.touches[0].clientY });\n setDragStartPosition({ x: position.x, y: position.y });\n setDrag(true);\n };\n\n const dragMove = (event: TouchEvent) => {\n if (!drag || event.type !== 'touchmove') return;\n const zoomer = (\n event.currentTarget as HTMLElement\n )?.getBoundingClientRect();\n const overlap = (100 - 100 / scale) / 2;\n const movedX = event.touches[0].clientX - dragStart.x;\n const movedY = event.touches[0].clientY - dragStart.y;\n const movedXPercent = (movedX * 100) / (zoomer.width * scale);\n const movedYPercent = (movedY * 100) / (zoomer.height * scale);\n const x = dragStartPosition.x + movedXPercent;\n const y = dragStartPosition.y + movedYPercent;\n setPosition({\n x: Math.max(-overlap, Math.min(x, overlap)) || 0,\n y: Math.max(-overlap, Math.min(y, overlap)) || 0,\n });\n event.preventDefault();\n };\n\n const handleTouchStart = (event: TouchEvent) => {\n if (closeButton) {\n touchStartRef.current = {\n x: event.touches[0].clientX,\n y: event.touches[0].clientY,\n time: Date.now(),\n };\n\n lastValidTouchRef.current = {\n clientX: event.touches[0].clientX,\n clientY: event.touches[0].clientY,\n };\n\n isSwipingRef.current = false;\n\n if (zoomed) {\n startDrag(event);\n }\n } else {\n if (drag) return;\n\n !zoomed && updatePosition(event);\n\n setZoomed(!zoomed);\n\n event.preventDefault();\n }\n };\n\n const handleTouchMove = (event: TouchEvent) => {\n if (event.touches.length === 0) return;\n\n lastValidTouchRef.current = {\n clientX: event.touches[0].clientX,\n clientY: event.touches[0].clientY,\n };\n\n if (closeButton) {\n if (!touchStartRef.current) return;\n\n if (drag) {\n dragMove(event);\n return;\n }\n\n const touchX = event.touches[0].clientX;\n const touchY = event.touches[0].clientY;\n const deltaX = Math.abs(touchX - touchStartRef.current.x);\n const deltaY = Math.abs(touchY - touchStartRef.current.y);\n\n if (deltaX > 10 || deltaY > 10) {\n isSwipingRef.current = true;\n }\n }\n\n if (zoomed) {\n updatePosition(event);\n }\n };\n\n const handleTouchEnd = (event: TouchEvent) => {\n if (closeButton) {\n if (!touchStartRef.current) return;\n\n const tapDuration = Date.now() - touchStartRef.current.time;\n\n if (!isSwipingRef.current && tapDuration < 300 && !drag) {\n setZoomed(true);\n updatePosition(event);\n event.preventDefault();\n }\n\n setDrag(false);\n touchStartRef.current = null;\n } else {\n setZoomed(false);\n }\n };\n\n const handleClick = (event: MouseEvent) => {\n if ('touches' in event) return;\n\n if (drag) return;\n\n if (zoomed) {\n !closeButton && setZoomed(false);\n } else {\n setZoomed(true);\n updatePosition(event);\n }\n event.preventDefault();\n };\n\n const handleMove = (event: MouseEvent) => {\n if ('touches' in event) return;\n\n if (zoomed) {\n updatePosition(event);\n }\n };\n\n const handleLeave = (event: MouseEvent) => {\n if ('touches' in event) return;\n\n if (closeButton) {\n setDrag(false);\n return;\n }\n setZoomed(false);\n };\n\n const closeButtonClick = (event: MouseEvent | TouchEvent) => {\n setZoomed(false);\n event.stopPropagation();\n };\n\n const transformStyle = zoomed\n ? `scale(${scale}) translateX(${position.x}%) translateY(${position.y}%)`\n : 'none';\n\n const CloseLabel = useText('PDP.Zoom.Close.label').label;\n const child = Children.only(children) as any;\n\n useEffect(() => {\n const handleGalleryChange = () => {\n if (zoomed) {\n setZoomed(false);\n setPosition({ x: 0, y: 0 });\n setDrag(false);\n }\n };\n\n const gallery = document.querySelector('#gallery');\n if (gallery) {\n gallery.addEventListener('click', handleGalleryChange);\n return () => gallery.removeEventListener('click', handleGalleryChange);\n }\n }, [zoomed]);\n\n const ImageClone = cloneElement(child, {\n ...child.props,\n draggable: false,\n style: {\n ...child.props?.style,\n '--transform': transformStyle,\n },\n });\n\n useEffect(() => {\n const className = zoomed\n ? `pdp-zoom ${closeButton ? 'pdp-zoom--no-effects' : 'pdp-zoom--zoomed'}`\n : 'pdp-zoom';\n setFigureClassName(className);\n }, [zoomed, closeButton]);\n\n useEffect(() => {\n if (lastTransformRef.current === transformStyle) return;\n lastTransformRef.current = transformStyle;\n\n const updateTransforms = () => {\n if (!containerRef.current) return;\n\n const images = containerRef.current.querySelectorAll('img');\n images.forEach((img) => {\n if (zoomed && transformStyle !== 'none') {\n img.style.setProperty('transform', transformStyle, 'important');\n } else {\n img.style.removeProperty('transform');\n }\n });\n };\n\n requestAnimationFrame(updateTransforms);\n }, [transformStyle, zoomed]);\n\n useEffect(() => {\n return () => {\n if (animationFrameRef.current) {\n cancelAnimationFrame(animationFrameRef.current);\n }\n };\n }, []);\n\n return (\n <figure\n ref={containerRef}\n className={figureClassName}\n onClick={handleClick}\n onMouseMove={handleMove}\n onMouseLeave={handleLeave}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n >\n {ImageClone}\n {closeButton && zoomed && (\n <Button\n aria-label={CloseLabel}\n variant=\"tertiary\"\n className=\"pdp-zoom__close-button\"\n icon={<CloseSVG />}\n onClick={closeButtonClick}\n />\n )}\n </figure>\n );\n};\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2024 Adobe\n * All Rights Reserved.\n * __________________\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n */\n\nimport { FunctionComponent, VNode } from 'preact';\nimport { HTMLAttributes } from 'preact/compat';\nimport { classes, VComponent } from '@adobe-commerce/elsie/lib';\nimport '@/pdp/components/Header/Header.css';\n\nexport interface HeaderProps\n extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n title: VNode;\n sku: VNode;\n hideSku?: boolean;\n /** When provided, displayed as variant name (e.g. when all options are selected on a configurable product) */\n variantName?: VNode;\n /** When provided, displayed as variant SKU (e.g. when all options are selected on a configurable product) */\n variantSku?: VNode;\n}\n\nexport const Header: FunctionComponent<HeaderProps> = ({\n className,\n title,\n sku,\n hideSku = false,\n variantName,\n variantSku,\n children,\n ...props\n}) => {\n return (\n <div {...props} className={classes(['pdp-header', className])}>\n <h1 className=\"pdp-header__title\">\n <VComponent node={title} />\n </h1>\n {!hideSku && (\n <div className=\"pdp-header__sku\">\n <VComponent node={sku} />\n </div>\n )}\n {(variantName || variantSku) && (\n <div className=\"pdp-header__variant\">\n {variantName && (\n <span className=\"pdp-header__variant-name\">\n <VComponent node={variantName} />\n </span>\n )}\n {variantName && variantSku && (\n <span className=\"pdp-header__variant-separator\"> – </span>\n )}\n {variantSku && (\n <span className=\"pdp-header__variant-sku\">\n <VComponent node={variantSku} />\n </span>\n )}\n </div>\n )}\n </div>\n );\n};\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2024 Adobe\n * All Rights Reserved.\n * __________________\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n */\nimport { FunctionComponent, VNode } from 'preact';\n\nimport { HTMLAttributes } from 'preact/compat';\nimport { classes, VComponent } from '@adobe-commerce/elsie/lib';\nimport '@/pdp/components/Price/Price.css';\nimport { useText } from '@adobe-commerce/elsie/i18n';\n\nexport interface PriceProps extends HTMLAttributes<HTMLDivElement> {\n price?: VNode;\n specialPrice?: VNode;\n tiers?: VNode;\n}\n\nexport const Price: FunctionComponent<PriceProps> = ({\n className,\n price,\n specialPrice,\n tiers,\n children,\n ...props\n}) => {\n const RegularPriceLabel = useText('PDP.Product.RegularPrice.label').label;\n const SpecialPriceLabel = useText('PDP.Product.SpecialPrice.label').label;\n const TierPriceLabel = useText('PDP.Product.TierPrice.label').label;\n\n return (\n <div {...props} className={classes(['pdp-price', className])}>\n {specialPrice && (\n <VComponent\n node={specialPrice}\n className={classes([\n 'pdp-price__amount-special',\n 'pdp-price__amount',\n ])}\n aria-label={SpecialPriceLabel}\n role=\"text\"\n />\n )}\n {price && (\n <VComponent\n node={price}\n className={classes([\n 'pdp-price__amount-regular',\n 'pdp-price__amount--grey',\n ])}\n aria-label={RegularPriceLabel}\n role=\"text\"\n />\n )}\n {tiers && (\n <VComponent\n node={tiers}\n className={classes(['pdp-price__tiers'])}\n aria-label={TierPriceLabel}\n role=\"text\"\n />\n )}\n </div>\n );\n};\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2023 Adobe\n * All Rights Reserved.\n * __________________\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n */\n\nimport { HTMLAttributes } from 'preact/compat';\nimport '@/pdp/components/PriceTiers/PriceTiers.css';\nimport { FunctionalComponent } from 'preact';\nimport { Price } from '@adobe-commerce/elsie/components';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { Tier } from '@/pdp/data/models';\n\nexport interface PriceTiersProps extends HTMLAttributes<HTMLDivElement> {\n locale?: string;\n tiers: Tier[];\n regularPrice?: number; // Base price to calculate savings percentage\n}\n\nexport const PriceTiers: FunctionalComponent<PriceTiersProps> = ({\n locale,\n tiers,\n regularPrice,\n ...props\n}) => {\n const TierPricingLabel = useText('PDP.Product.TierPricing.label').label;\n\n if (!tiers || tiers.length === 0) {\n return null;\n }\n\n return (\n <div className=\"pdp-price-tiers\" {...props}>\n {tiers.map((tier, index) => {\n const tierPrice = tier?.tier?.amount ?? 0;\n const quantity = tier?.quantity ?? 0;\n const currency = tier?.tier?.currency ?? '';\n\n let savingsPercent = 0;\n if (regularPrice && tierPrice && tierPrice < regularPrice) {\n savingsPercent = Math.round(\n ((regularPrice - tierPrice) / regularPrice) * 100\n );\n }\n\n const textBeforePrice = TierPricingLabel.replace(\n '{quantity}',\n quantity.toString()\n ).split('{price}')[0];\n\n const textAfterPrice = TierPricingLabel.replace(\n '{quantity}',\n quantity.toString()\n )\n .split('{price}')[1]\n .replace(\n '{percent}',\n savingsPercent > 0 ? savingsPercent.toString() : '0'\n );\n\n return (\n <div key={index} className=\"pdp-price-tiers__tier\">\n <span className=\"pdp-price-tiers__text\">\n {textBeforePrice}\n <Price\n amount={tierPrice}\n currency={currency}\n locale={locale}\n className=\"pdp-price-tiers__price\"\n />\n {textAfterPrice}\n </span>\n </div>\n );\n })}\n </div>\n );\n};\n","import { FunctionComponent } from 'preact';\nimport { useState, useEffect, useMemo, useCallback } from 'preact/hooks';\nimport { HTMLAttributes } from 'preact/compat';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport {\n Field,\n Input,\n TextArea,\n Picker,\n PickerOption,\n} from '@adobe-commerce/elsie/components';\nimport { classes } from '@adobe-commerce/elsie/lib';\nimport { Option, OptionField } from '@/pdp/data/models/values-model';\nimport './GiftCardOptions.css';\n\nenum ComponentType {\n INPUT = 'input',\n TEXTAREA = 'textarea',\n PICKER = 'picker',\n}\n\nexport interface GiftCardOptionsProps extends HTMLAttributes<HTMLDivElement> {\n options: Option[];\n currency?: string;\n optionValues: OptionField[];\n onOptionChange: (uid: string, value: string) => void;\n onValidationChange: (valid: boolean) => void;\n}\n\n// Utility functions\nconst getInputType = (validationType: string): string => {\n switch (validationType) {\n case 'number':\n return 'number';\n case 'email':\n return 'email';\n default:\n return 'text';\n }\n};\n\nconst getComponentType = (option: Option): ComponentType => {\n if (option.name === 'giftcard/giftcard_message') {\n return ComponentType.TEXTAREA;\n }\n\n if (option.name === 'giftcard/giftcard_amount') {\n return ComponentType.PICKER;\n }\n\n return ComponentType.INPUT;\n};\n\nconst mapToPickerOptions = (\n values: (string | number)[],\n hasCustomAmountField: boolean,\n chooseAmountText: string,\n otherAmountText: string\n): PickerOption[] => {\n const options: PickerOption[] = [\n {\n text: chooseAmountText,\n value: '0',\n disabled: false,\n },\n ...values.map((value) => ({\n text: value.toString(),\n value: value.toString(),\n disabled: false,\n })),\n ...(hasCustomAmountField\n ? [\n {\n text: otherAmountText,\n value: 'other',\n disabled: false,\n },\n ]\n : []),\n ];\n return options;\n};\n\nconst validate = (\n option: Option,\n value: string,\n errorMessages: {\n RequiredFieldError: string;\n NumberError: string;\n MinError: string;\n MaxError: string;\n MinLengthError: string;\n MaxLengthError: string;\n EmailError: string;\n InvalidValueError: string;\n }\n) => {\n const { validationRule } = option;\n\n if (option.name === 'giftcard/giftcard_amount') {\n if (\n validationRule.required &&\n (value === '0' || !value || value.trim() === '')\n ) {\n return errorMessages.RequiredFieldError;\n }\n if (value === '0') {\n return errorMessages.RequiredFieldError;\n }\n if (value === 'other') {\n return '';\n }\n } else if (validationRule.required && (!value || value.trim() === '')) {\n return errorMessages.RequiredFieldError;\n }\n\n if (!value || value.trim() === '') {\n return '';\n }\n\n switch (validationRule.type) {\n case 'email': {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (!emailRegex.test(value)) {\n return errorMessages.EmailError;\n }\n break;\n }\n\n case 'number': {\n const num = Number(value);\n if (isNaN(num)) {\n return errorMessages.NumberError;\n }\n\n // Check min value\n if (validationRule.min !== undefined && num < validationRule.min) {\n return errorMessages.MinError.replace(\n '{min}',\n validationRule.min.toString()\n );\n }\n\n // Check max value\n if (validationRule.max !== undefined && num > validationRule.max) {\n return errorMessages.MaxError.replace(\n '{max}',\n validationRule.max.toString()\n );\n }\n\n // Check allowed values\n if (validationRule.values) {\n const isValidValue = validationRule.values.some((val) =>\n typeof val === 'number' ? val === num : val === value\n );\n if (!isValidValue) {\n return errorMessages.InvalidValueError.replace(\n '{values}',\n validationRule.values.join(', ')\n );\n }\n }\n break;\n }\n\n case 'string': {\n const length = value.length;\n\n // Check min length\n if (\n validationRule.minLength !== undefined &&\n length < validationRule.minLength\n ) {\n return errorMessages.MinLengthError.replace(\n '{min_length}',\n validationRule.minLength.toString()\n );\n }\n\n // Check max length\n if (\n validationRule.maxLength !== undefined &&\n length > validationRule.maxLength\n ) {\n return errorMessages.MaxLengthError.replace(\n '{max_length}',\n validationRule.maxLength.toString()\n );\n }\n break;\n }\n }\n\n return '';\n};\n\nexport const GiftCardOptions: FunctionComponent<GiftCardOptionsProps> = ({\n options,\n currency,\n optionValues,\n onOptionChange,\n onValidationChange,\n}) => {\n const ChooseAmount = useText(\n 'PDP.Product.GiftCardOptions.ChooseAmount.label'\n ).label;\n const OtherAmount = useText(\n 'PDP.Product.GiftCardOptions.OtherAmount.label'\n ).label;\n const RequiredFieldError = useText(\n 'PDP.Product.GiftCardOptions.RequiredFieldError.label'\n ).label;\n const NumberError = useText(\n 'PDP.Product.GiftCardOptions.NumberError.label'\n ).label;\n const MinError = useText('PDP.Product.GiftCardOptions.MinError.label').label;\n const MaxError = useText('PDP.Product.GiftCardOptions.MaxError.label').label;\n const MinLengthError = useText(\n 'PDP.Product.GiftCardOptions.MinLengthError.label'\n ).label;\n const MaxLengthError = useText(\n 'PDP.Product.GiftCardOptions.MaxLengthError.label'\n ).label;\n const EmailError = useText(\n 'PDP.Product.GiftCardOptions.EmailError.label'\n ).label;\n const InvalidValueError = useText(\n 'PDP.Product.GiftCardOptions.InvalidValueError.label'\n ).label;\n\n const [errors, setErrors] = useState<Record<string, string>>({});\n const [showCustomAmount, setShowCustomAmount] = useState(false);\n\n // Helper function to find option by name\n const findOptionByName = useCallback(\n (name: string): Option | undefined => {\n return options.find((option) => option.name === name);\n },\n [options]\n );\n\n // Memoize error messages to avoid recreating them on every render\n const errorMessages = useMemo(\n () => ({\n RequiredFieldError,\n NumberError,\n MinError,\n MaxError,\n MinLengthError,\n MaxLengthError,\n EmailError,\n InvalidValueError,\n }),\n [\n RequiredFieldError,\n NumberError,\n MinError,\n MaxError,\n MinLengthError,\n MaxLengthError,\n EmailError,\n InvalidValueError,\n ]\n );\n\n // Run initial validation only when options or optionValues change\n useEffect(() => {\n const valid = options.every((option) => {\n // Skip validation for custom gift card amount when it's not shown\n if (\n option.name === 'giftcard/custom_giftcard_amount' &&\n !showCustomAmount\n ) {\n return true;\n }\n\n const field = optionValues.find((f) => f.id === option.uid);\n const value = field?.value || '';\n return validate(option, value, errorMessages) === '';\n });\n\n onValidationChange(valid);\n }, [\n options,\n optionValues,\n onValidationChange,\n errorMessages,\n showCustomAmount,\n ]);\n\n useEffect(() => {\n const giftCardAmountOption = findOptionByName('giftcard/giftcard_amount');\n const customAmountOption = findOptionByName(\n 'giftcard/custom_giftcard_amount'\n );\n\n const giftCardAmountField = optionValues.find(\n (f) => f.id === giftCardAmountOption?.uid\n );\n\n const selectedValue = giftCardAmountField?.value || '';\n const wasShowingCustomAmount = showCustomAmount;\n\n // If there's no gift card amount option, always show custom amount\n // Otherwise, show custom amount only when \"other\" is selected\n const willShowCustomAmount = giftCardAmountOption\n ? selectedValue === 'other'\n : !!customAmountOption;\n\n setShowCustomAmount(willShowCustomAmount);\n\n // Reset custom amount value when switching away from \"other\"\n if (wasShowingCustomAmount && !willShowCustomAmount && customAmountOption) {\n onOptionChange(customAmountOption.uid, '');\n }\n }, [optionValues, findOptionByName, showCustomAmount, onOptionChange]);\n\n const handleChange = (option: Option, value: string) => {\n const error = validate(option, value, errorMessages);\n setErrors((prev: Record<string, string>) => ({\n ...prev,\n [option.uid]: error,\n }));\n\n onOptionChange(option.uid, value);\n };\n\n const handleBlur = (option: Option, value: string) => {\n const error = validate(option, value, errorMessages);\n setErrors((prev: Record<string, string>) => ({\n ...prev,\n [option.uid]: error,\n }));\n };\n\n const handlePickerSelect = (option: Option, event: any) => {\n const selectedValue = event.target.value;\n handleChange(option, selectedValue);\n };\n\n const renderField = (option: Option) => {\n const field = optionValues.find((f) => f.id === option.uid);\n const value = field?.value;\n const error = errors[option.uid];\n const componentType = getComponentType(option);\n const hasCustomAmountField = !!findOptionByName(\n 'giftcard/custom_giftcard_amount'\n );\n\n // Add currency to custom gift card amount label\n let label = option.label;\n if (option.name === 'giftcard/custom_giftcard_amount' && currency) {\n label = `${option.label} ${currency}`;\n }\n\n return (\n <Field\n key={option.uid}\n label={label}\n className={classes([\n 'pdp-gift-card-options__option-field',\n componentType === ComponentType.TEXTAREA &&\n 'pdp-gift-card-options__option-field--full-width',\n ])}\n error={error}\n >\n {(() => {\n if (componentType === ComponentType.TEXTAREA) {\n return (\n <TextArea\n value={value}\n label={option.label}\n onChange={(e: any) =>\n handleChange(option, (e.target as HTMLTextAreaElement).value)\n }\n onBlur={(e: any) =>\n handleBlur(option, (e.target as HTMLTextAreaElement).value)\n }\n aria-invalid={!!error}\n />\n );\n }\n\n if (componentType === ComponentType.PICKER) {\n return (\n <Picker\n aria-label={option.label}\n label={option.label}\n handleSelect={(event) => handlePickerSelect(option, event)}\n options={mapToPickerOptions(\n option.validationRule.values || [],\n hasCustomAmountField,\n ChooseAmount,\n OtherAmount\n )}\n value={value}\n aria-invalid={!!error}\n />\n );\n }\n\n return (\n <Input\n type={getInputType(option.validationRule.type)}\n value={value}\n onChange={(e) =>\n handleChange(option, (e.target as HTMLInputElement).value)\n }\n onBlur={(e) =>\n handleBlur(option, (e.target as HTMLInputElement).value)\n }\n aria-invalid={!!error}\n />\n );\n })()}\n </Field>\n );\n };\n\n return (\n <div className=\"pdp-gift-card-options__grid\">\n {/* Row 1: Gift card amount and custom amount */}\n <div className=\"pdp-gift-card-options__row\">\n {findOptionByName('giftcard/giftcard_amount') &&\n renderField(findOptionByName('giftcard/giftcard_amount')!)}\n {findOptionByName('giftcard/custom_giftcard_amount') &&\n showCustomAmount &&\n renderField(findOptionByName('giftcard/custom_giftcard_amount')!)}\n </div>\n\n {/* Row 2: Sender name and email */}\n <div className=\"pdp-gift-card-options__row\">\n {findOptionByName('giftcard/giftcard_sender_name') &&\n renderField(findOptionByName('giftcard/giftcard_sender_name')!)}\n {findOptionByName('giftcard/giftcard_sender_email') &&\n renderField(findOptionByName('giftcard/giftcard_sender_email')!)}\n </div>\n\n {/* Row 3: Recipient name and email */}\n <div className=\"pdp-gift-card-options__row\">\n {findOptionByName('giftcard/giftcard_recipient_name') &&\n renderField(findOptionByName('giftcard/giftcard_recipient_name')!)}\n {findOptionByName('giftcard/giftcard_recipient_email') &&\n renderField(findOptionByName('giftcard/giftcard_recipient_email')!)}\n </div>\n\n {/* Row 4: Gift card message */}\n <div className=\"pdp-gift-card-options__row\">\n {findOptionByName('giftcard/giftcard_message') &&\n renderField(findOptionByName('giftcard/giftcard_message')!)}\n </div>\n </div>\n );\n};\n","/**\n * ADOBE CONFIDENTIAL\n * __________________\n * Copyright 2023 Adobe\n * All Rights Reserved.\n * __________________\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe and its suppliers, if any. The intellectual\n * and technical concepts contained herein are proprietary to Adobe\n * and its suppliers and are protected by all applicable intellectual\n * property laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe.\n */\n\nimport { FunctionComponent } from 'preact';\nimport { HTMLAttributes, useState, useCallback } from 'preact/compat';\nimport { classes } from '@adobe-commerce/elsie/lib';\nimport { useText } from '@adobe-commerce/elsie/i18n';\nimport { Price } from '@adobe-commerce/elsie/components';\n\nimport '@/pdp/components/DownloadableOptions/DownloadableOptions.css';\n\nexport type DownloadableLink = {\n uid: string;\n price: number;\n sample_url: string | null;\n label: string;\n number_of_downloads: number;\n};\n\nexport type DownloadableSample = {\n uid: string;\n label: string;\n url: string;\n};\n\nexport type DownloadableValue = {\n links: DownloadableLink[];\n samples: DownloadableSample[];\n purchaseSeparately: boolean;\n};\n\nexport interface DownloadableOptionsProps\n extends Omit<HTMLAttributes<HTMLDivElement>, 'value'> {\n label: string;\n value: DownloadableValue;\n onLinkChange?: (uid: string, selected: boolean) => void;\n currency?: string;\n locale?: string;\n}\n\nexport const DownloadableOptions: FunctionComponent<\n DownloadableOptionsProps\n> = ({ label, value, onLinkChange, currency, locale, className, ...props }) => {\n const SampleLabel = useText('PDP.DownloadableOptions.Sample.label').label;\n const ViewSampleLabel = useText('PDP.DownloadableOptions.ViewSample.label');\n\n const { links, samples, purchaseSeparately } = value;\n\n const initialSelected = purchaseSeparately\n ? new Set<string>()\n : new Set(links.map((link) => link.uid));\n\n const [selected, setSelected] = useState<Set<string>>(initialSelected);\n\n const handleToggle = useCallback(\n (uid: string, isSelected: boolean, isDisabled: boolean) => {\n if (!purchaseSeparately || isDisabled) {\n return;\n }\n\n setSelected((prev) => {\n const next = new Set(prev);\n if (isSelected) {\n next.add(uid);\n } else {\n next.delete(uid);\n }\n return next;\n });\n onLinkChange?.(uid, isSelected);\n },\n [onLinkChange, purchaseSeparately]\n );\n\n const renderLink = (link: DownloadableLink) => {\n const isSelected = purchaseSeparately && selected.has(link.uid);\n\n return (\n <div\n key={link.uid}\n className={`pdp-downloadable-options__item ${\n isSelected ? 'pdp-downloadable-options__item--selected' : ''\n } ${\n !purchaseSeparately ? 'pdp-downloadable-options__item--disabled' : ''\n }`}\n >\n <button\n type=\"button\"\n className=\"pdp-downloadable-options__clickable\"\n aria-pressed={isSelected}\n disabled={!purchaseSeparately}\n onClick={() =>\n purchaseSeparately &&\n handleToggle(link.uid, !isSelected, !purchaseSeparately)\n }\n onKeyDown={(e) => {\n if (purchaseSeparately && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault();\n handleToggle(link.uid, !isSelected, !purchaseSeparately);\n }\n }}\n >\n <div className=\"pdp-downloadable-options__content\">\n <div className=\"pdp-downloadable-options__header\">\n <span className=\"pdp-downloadable-options__title\">\n {link.label}\n </span>\n <Price\n amount={link.price}\n currency={currency}\n locale={locale}\n className=\"pdp-downloadable-options__price\"\n />\n </div>\n </div>\n </button>\n {link.sample_url && (\n <a\n href={link.sample_url}\n className=\"pdp-downloadable-options__sample-button\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label={ViewSampleLabel.label.replace('{label}', link.label)}\n >\n {SampleLabel}\n </a>\n )}\n </div>\n );\n };\n\n const renderSample = (sample: DownloadableSample) => {\n return (\n <div\n key={sample.uid}\n className=\"pdp-downloadable-options__item pdp-downloadable-options__item--sample\"\n >\n <button\n type=\"button\"\n className=\"pdp-downloadable-options__clickable\"\n aria-pressed={false}\n disabled={true}\n >\n <div className=\"pdp-downloadable-options__content\">\n <div className=\"pdp-downloadable-options__header\">\n <span className=\"pdp-downloadable-options__title\">\n {sample.label}\n </span>\n </div>\n </div>\n </button>\n <a\n href={sample.url}\n className=\"pdp-downloadable-options__sample-button\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label={`${SampleLabel} ${sample.label}`}\n >\n {SampleLabel}\n </a>\n </div>\n );\n };\n\n return (\n <div\n {...props}\n className={classes(['pdp-downloadable-options', className])}\n data-slot-key=\"product-downloadable-options\"\n >\n <div className=\"pdp-downloadable-options__field\">\n <div className=\"pdp-downloadable-options__field__label\">{label}</div>\n\n <div className=\"pdp-downloadable-options__list\">\n {links.map((link) => renderLink(link))}\n {samples.map((sample) => renderSample(sample))}\n </div>\n </div>\n </div>\n );\n};\n"],"names":["SvgChevronDown","props","React","SvgClose","PEAK_WIDTH","THUMB_GAP","ICON_SIZE","GapSize","Carousel","show","scrollbar","peak","arrows","controls","arrowsOnMainImage","loop","gap","direction","width","height","defaultIndex","className","children","thumbnails","isZoomed","Label","useText","SlideLabel","PreviousLabel","NextLabel","ControlsLabel","ControlsBtnLabel","perPage","setPerPage","useState","getPerPageFromBreakpoint","length","Children","peakWidth","gapWidth","rest","current","setCurrent","isRTL","thumbnailsRefs","useRef","thumbWidth","setThumbWidth","thumbHeight","setThumbHeight","thumbnailSlides","useMemo","slides","returnValue","acc","child","i","wrapperRef","thumbnailsWrapperRef","thumbnailControls","useEffect","wrapper","handleResize","debounce","newPerPage","observer","handleThumbnailsScroll","useCallback","nextSlideIndex","nextItem","thumbnailRef","oneItemWidth","oneItemHeight","thumbnailsWrapper","isRow","isColumn","offset","oneItemSize","visibleThumbnails","centerOffset","targetScrollPosition","handleScrollTo","smooth","reset","realWidth","element","dataIndex","futureIndex","scrollWidth","diff","handleGoToPrev","handleGoToNext","lastSlideIndex","handleKeyDown","event","useLayoutEffect","handleOnScroll","dividing","totalWidth","scrollOffset","getArrow","forThumbnails","callback","jsx","Button","classes","Icon","ChevronDown","prevArrow","nextArrow","prevArrowMainImage","nextArrowMainImage","jsxs","page","index","orphan","Fragment","_","key","buttonsLength","active","el","breakpoints","small","medium","large","matchingBreakpoint","breakpoint","Product","title","breadcrumbs","galleryContent","infoContent","productContent","sku","outOfStock","shortDescription","description","attributes","images","options","giftCardOptions","downloadableOptions","price","specialPrice","quantity","actions","carouselConfig","zoomType","closeButton","RegularPriceLabel","SpecialPriceLabel","OutOfStockLabel","ImagesLabel","zoom","setZoom","galleryImages","image","alt","_a","Zoom","VComponent","localThumbnailsImages","_b","_c","_d","GalleryGrid","_e","_f","_g","_h","_i","Overlay","style","count","PriceRange","amount","currency","locale","variant","sale","minimumAmount","maximumAmount","Price","centered","onClose","CloseLabel","overlayRef","handleOnClose","input","scrollingElement","defaultOverflowValue","CloseSVG","supportedTypes","mapToPickerOptions","items","item","isBundleOptionGroup","typename","hasBundleQuantityControl","option","optionUIDsToSelection","optionUIDs","accum","selectedItems","getSingleSelectedValue","entry","Swatches","hideSelectedValue","disablePreselections","selectedUIDs","onValues","onErrors","bundleOptionQuantities","onBundleOptionQuantityChange","defaultOptions","selectionsToUpdate","imageSwatchNode","RequiredLabel","ChooseOptionLabel","BundleOptionQuantityLabel","selections","setSelections","picked","defaultSelection","selected","selection","prev","next","selectionToUpdate","selectedItem","errors","satisfied","handleOnSelection","optionGroupId","label","itemUid","handleMultiToggle","itemId","checked","groupItems","prevEntry","prevValues","nextValues","v","labelById","nextLabel","uid","handlePickerSelect","optionId","renderBundleOptionQuantity","defaultQuantity","quantityValue","ariaLabel","Incrementer","value","renderOptionControl","id","required","type","multiple","uniqueId","selectedIds","Checkbox","e","bundleOptions","Picker","common","swatch","TextSwatch","ImageSwatch","ColorSwatch","scale","zoomed","setZoomed","figureClassName","setFigureClassName","drag","setDrag","dragStart","setDragStart","dragStartPosition","setDragStartPosition","position","setPosition","containerRef","cachedBoundsRef","animationFrameRef","lastTransformRef","touchStartRef","isSwipingRef","lastValidTouchRef","updatePosition","updatePositionLogic","zoomer","overlap","coordinates","relativeX","relativeY","x","y","startDrag","dragMove","movedX","movedY","movedXPercent","movedYPercent","handleTouchStart","handleTouchMove","touchX","touchY","deltaX","deltaY","handleTouchEnd","tapDuration","handleClick","handleMove","handleLeave","closeButtonClick","transformStyle","handleGalleryChange","gallery","ImageClone","cloneElement","img","Header","hideSku","variantName","variantSku","tiers","TierPriceLabel","PriceTiers","regularPrice","TierPricingLabel","tier","tierPrice","savingsPercent","textBeforePrice","textAfterPrice","getInputType","validationType","getComponentType","values","hasCustomAmountField","chooseAmountText","otherAmountText","validate","errorMessages","validationRule","num","val","GiftCardOptions","optionValues","onOptionChange","onValidationChange","ChooseAmount","OtherAmount","RequiredFieldError","NumberError","MinError","MaxError","MinLengthError","MaxLengthError","EmailError","InvalidValueError","setErrors","showCustomAmount","setShowCustomAmount","findOptionByName","name","valid","field","f","giftCardAmountOption","customAmountOption","giftCardAmountField","selectedValue","wasShowingCustomAmount","willShowCustomAmount","handleChange","error","handleBlur","renderField","componentType","Field","TextArea","Input","DownloadableOptions","onLinkChange","SampleLabel","ViewSampleLabel","links","samples","purchaseSeparately","initialSelected","link","setSelected","handleToggle","isSelected","isDisabled","renderLink","renderSample","sample"],"mappings":"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","x_google_ignoreList":[0,1]}
|