{"version":3,"file":"564.min.js?t=1743173738202","mappings":"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","sources":["webpack://@hero-digital/masonite/./src/components/foundation/Image/Image.template.js","webpack://@hero-digital/masonite/./src/components/modules/ColorPicker/ColorPicker.js","webpack://@hero-digital/masonite/./src/components/modules/ColorPicker/ColorPicker.template.js","webpack://@hero-digital/masonite/./src/components/modules/PlayIcon/PlayIcon.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductInfo/ProductInfo.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductInfo/ProductInfo.template.js","webpack://@hero-digital/masonite/./src/components/modules/Tabs/Tabs.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductOptionGroup/ProductOptionGroup.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductOptionCategory/ProductOptionCategory.template.js","webpack://@hero-digital/masonite/./src/components/modules/Modal/Modal.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductOptionsCustomColor/ProductOptionCustomColor.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductOptionsCustomColor/ProductOptionsCustomColor.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductOptionCategory/ProductOptionCategory.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductOptionGroup/ProductOptionGroup.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductOptionFilters/ProductOptionFilters.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductOptionFilters/ProductOptionFilters.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductOptions/ProductOptions.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductOptions/ProductOptions.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductTools/components/ProductShare/ProductShare.template.js","webpack://@hero-digital/masonite/./src/js/utilities/scriptLoader.js","webpack://@hero-digital/masonite/./src/components/modules/ProductTools/components/ProductShare/ProductShare.js","webpack://@hero-digital/masonite/./src/components/modules/ProductTools/ProductTools.js","webpack://@hero-digital/masonite/./src/components/modules/ProductTools/ProductTools.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductMediaThumbnails/ProductMediaThumbnails.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductMediaThumbnails/ProductMediaThumbnails.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductMediaImage/ProductMediaImage.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductMediaImage/ProductMediaImage.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductMediaVideo/ProductMediaVideo.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductMediaVideo/ProductMediaVideo.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductMediaVisualizer/ProductMediaVisualizer.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductMediaVisualizer/ProductMediaVisualizer.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductMediaGallery/ProductMediaGallery.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductMediaGallery/ProductMediaGallery.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductFeatures/ProductFeatures.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductDetails/ProductDetails.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductSpecifications/ProductSpecifications.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductMeasurement/ProductMeasurement.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductDocuments/ProductDocuments.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductDetails/ProductDetails.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductRelatedContent/ProductRelatedContent.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/components/ProductRelatedContent/ProductRelatedContent.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/models/ProductInformationModel/ProductInformationModel.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/services/ProductInformationRouter/ProductInformationRouter.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/ProductInformation.js","webpack://@hero-digital/masonite/./src/components/modules/ProductInformation/ProductInformation.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductTools/components/Notification/Notification.js","webpack://@hero-digital/masonite/./src/components/modules/ProductTools/components/Notification/Notification.template.js","webpack://@hero-digital/masonite/./src/components/modules/ProductTools/components/ProductSave/ProductSave.js","webpack://@hero-digital/masonite/./src/components/modules/ProductTools/components/ProductSave/ProductSave.template.js","webpack://@hero-digital/masonite/./src/components/modules/Tabs/index.js","webpack://@hero-digital/masonite/./src/components/modules/VideoPlayer/VideoPlayer.js","webpack://@hero-digital/masonite/./src/components/modules/VideoPlayer/VideoPlayer.template.js"],"sourcesContent":["import classNames from 'utilities/classnames'\n\n/**\n *\n * @param {Object} args Template arguments\n * @param {String} args.addClassName Additional class name\n * @param {String} args.altText Image alt text\n * @param {String} args.defaultAspectRatio default aspect ratio\n * @param {String} args.defaultSrc Desktop src\n * @param {String} args.loading Image loading style\n * @param {String} args.mobileSrc Mobile srcset\n * @param {String} args.mobileAspectRatio mobile view aspect ratio\n * @returns\n */\nconst ImageTemplate = ({\n addClassName,\n altText,\n defaultAspectRatio,\n defaultSrc,\n loading = 'lazy',\n mobileAspectRatio,\n mobileSrc\n}) => `\n \n ${\n mobileSrc\n ? ``\n : ''\n }\n \n \n`\n\nexport default ImageTemplate\n","import { insert } from 'utilities/renderer'\nimport { noop } from 'utilities/utilities'\nimport iro from '@jaames/iro'\nimport Services from 'services'\nimport template from './ColorPicker.template.js'\n\n/**\n * ColorPicker component responsible for rendering a color picker\n * and providing a callback for when the color changes\n * @param {HTMLElement} element - the element to render the component in\n * @param {Object} options - the options for the component\n * @param {number} options.height - the height of the color picker\n * @param {string} options.initialColor - the initial color for the color picker\n * @param {Function} options.onChange - the callback for when the color changes\n * @param {string} options.theme - the theme for the color picker\n */\nexport default class ColorPicker {\n static SELECTORS = {\n WHEEL: '[data-cmp-hook=\"color-picker-wheel\"]',\n INPUT_HEX: '[data-cmp-hook=\"color-input-hex\"]',\n INPUT_RGB: '[data-cmp-hook=\"color-input-rgb\"]'\n }\n\n constructor(\n element,\n { height = 242, onChange = noop, initialColor = '', theme = 'light' } = {}\n ) {\n this.element = element\n this.onChange = onChange\n this.services = Services.getInstance()\n this.initialColor = initialColor\n this.height = height\n this.theme = theme\n this.resizeService = this.services.ResizeService\n this.init()\n }\n\n /**\n * Initialize the component\n */\n init() {\n this.template = template({\n theme: this.theme\n })({\n getNode: true\n })\n this.cacheDom()\n this.createWheel()\n this.attachEvents()\n this.render()\n this.setPickerWidth()\n }\n\n /**\n * Cache the DOM elements\n */\n cacheDom() {\n this.wheelEl = this.template.querySelector(ColorPicker.SELECTORS.WHEEL)\n this.inputHex = this.template.querySelector(ColorPicker.SELECTORS.INPUT_HEX)\n this.inputsRgb = this.template.querySelectorAll(\n ColorPicker.SELECTORS.INPUT_RGB\n )\n }\n\n /**\n * Attach the events\n */\n attachEvents() {\n this.inputHex.addEventListener('change', this.onHexChange)\n this.inputsRgb.forEach((input) => {\n input.addEventListener('change', this.onRgbChange)\n })\n this.wheel.on(['color:init', 'color:change'], this.onWheelChange)\n this.resizeService.addCallback(this.setPickerWidth)\n }\n\n /**\n * Detach the events\n */\n detachEvents() {\n this.inputHex.removeEventListener('change', this.onHexChange)\n this.inputsRgb.forEach((input) => {\n input.removeEventListener('change', this.onRgbChange)\n })\n this.wheel.off(['color:init', 'color:change'], this.onWheelChange)\n this.resizeService.removeCallback(this.setPickerWidth)\n }\n\n /**\n * Destroy the component\n */\n destroy() {\n this.detachEvents()\n }\n\n /**\n * Create the color wheel picker\n */\n createWheel() {\n this.wheel = new iro.ColorPicker(this.wheelEl, {\n display: 'block',\n width: 200,\n boxHeight: this.height,\n color: this.initialColor,\n layout: [\n {\n component: iro.ui.Box\n },\n {\n component: iro.ui.Slider,\n options: {\n id: 'hue-slider',\n sliderType: 'hue',\n sliderSize: 12\n }\n }\n ]\n })\n }\n\n /**\n * Set the hex input value\n */\n setHexInput(hex) {\n this.inputHex.value = hex\n }\n\n /**\n * Set the rbg input values\n */\n setRgbInputs(rgb) {\n this.inputsRgb.forEach((input) => {\n if (rgb[input.dataset.color]) {\n input.value = rgb[input.dataset.color]\n }\n })\n }\n\n /**\n * Set the width of the color picker to the width of the parent element\n */\n setPickerWidth = () => {\n const width = this.wheelEl.offsetWidth\n this.wheel.resize(width)\n }\n\n /**\n * Callback for when the color wheel changes to set the inputs and apply the onChange callback\n * @param {Object} color - the color object\n */\n onWheelChange = (color) => {\n const hex = color.hexString\n const rgb = color.rgb\n\n this.setHexInput(hex)\n this.setRgbInputs(rgb)\n this.onChange(hex)\n }\n\n /**\n * Callback for when the hex input changes to set hex to the color wheel and apply the onChange callback\n * @param {Event} event - input change event\n */\n onHexChange = (event) => {\n try {\n this.wheel.color.set(event.currentTarget.value)\n } catch (e) {\n this.setHexInput(this.wheel.color.hexString)\n }\n\n // fallback to previous color if the active color doesn't match the input color\n // this is to prevent the color from changing if the input is invalid\n if (this.wheel.color.hexString !== this.inputHex.value) {\n this.setHexInput(this.wheel.color.hexString)\n }\n\n this.onChange(this.wheel.color.hexString)\n }\n\n /**\n * Callback for when a rgb input changes to set rgb values to the color wheel and apply the onChange callback\n * @param {Event} event - input change event\n */\n onRgbChange = (event) => {\n const colorType = event.currentTarget.dataset.color\n try {\n const rgb = {}\n this.inputsRgb.forEach((input) => {\n rgb[input.dataset.color] = input.value\n })\n\n this.wheel.color.set(`rgb(${rgb.r}, ${rgb.g}, ${rgb.b}`)\n } catch (e) {\n this.setRgbInputs(this.wheel.color.rgb)\n }\n\n // fallback to previous color if the active color doesn't match the input color\n // this is to prevent the color from changing if the input is invalid\n if (\n this.wheel.color.rgb[colorType].toString() !== event.currentTarget.value\n ) {\n this.setRgbInputs(this.wheel.color.rgb)\n }\n\n this.onChange(this.wheel.color.hexString)\n }\n\n /**\n * Render the component\n */\n render() {\n insert(this.template, this.element)\n }\n}\n","import html from 'utilities/html'\nimport inputTemplate from 'foundation/Input/Input.template'\n\n/**\n * Template for the color picker component\n * @param {Object} args\n * @param {string} args.theme - The theme of the color picker\n * @returns {Function} - The template function\n */\nexport default ({ theme = 'light' }) => html`\n
\n
\n
\n \n ${inputTemplate({\n addClassName:\n 'mod-color-picker__input-group mod-color-picker__input-group--hex',\n accessibilityLabel: 'Hex',\n dataAttributes: [\n 'data-cmp-hook=\"color-input-hex\"',\n 'data-color=\"hex\"'\n ],\n id: 'hex',\n label: 'Hex',\n name: 'hex',\n theme\n })}\n \n \n ${inputTemplate({\n addClassName:\n 'mod-color-picker__input-group mod-color-picker__input-group--rgb',\n accessibilityLabel: 'R',\n dataAttributes: ['data-cmp-hook=\"color-input-rgb\"', 'data-color=\"r\"'],\n id: 'rgb-r',\n label: 'R',\n name: 'rgb-r',\n theme\n })}\n ${inputTemplate({\n addClassName:\n 'mod-color-picker__input-group mod-color-picker__input-group--rgb',\n accessibilityLabel: 'G',\n dataAttributes: ['data-cmp-hook=\"color-input-rgb\"', 'data-color=\"g\"'],\n id: 'rgb-g',\n label: 'G',\n name: 'rgb-g',\n theme\n })}\n ${inputTemplate({\n addClassName:\n 'mod-color-picker__input-group mod-color-picker__input-group--rgb',\n accessibilityLabel: 'B',\n dataAttributes: ['data-cmp-hook=\"color-input-rgb\"', 'data-color=\"b\"'],\n id: 'rgb-b',\n label: 'B',\n name: 'rgb-b',\n theme\n })}\n \n \n \n \n`\n","import Icon from 'foundation/Icon/Icon.template.js'\nimport classNames from 'utilities/classnames'\n\n/**\n * Play Icon Positions\n */\nexport const POSITIONS = {\n BOTTOM_LEFT: 'bottom-left',\n BOTTOM_RIGHT: 'bottom-right',\n CENTER: 'center',\n TOP_LEFT: 'top-left',\n TOP_RIGHT: 'top-right'\n}\n\n/**\n * Play Icon Sizes\n */\nexport const SIZES = {\n LARGE: 'large',\n SMALL: 'small'\n}\n\n/**\n * Render Video Play Icon template\n * @param {String} addClassName Additional class name to component\n * @param {Object} a11y Accessibility labels\n * @param {String} a11y.buttonLabel Accessibility label for button\n * @param {String} a11y.playLabel Accessibility label for play icon\n * @param {String} a11y.pauseLabel Accessibility label for pause icon\n * @param {Array} dataAttributes Data attributes to add to component\n * @param {String} id ID to add to component\n * @param {Boolean} isButton If true, component will render as a button\n * @param {Boolean} isInline If true, component will render inline vs the full contents of the parent\n * @param {String} position Position of play icon\n * @param {String} size Size of play icon (small or large)\n */\nconst PlayIcon = ({\n addClassName,\n a11y: { buttonLabel = '', playLabel = 'Play', pauseLabel = 'Pause' } = {},\n dataAttributes,\n id,\n isButton,\n isInline,\n position,\n size,\n isBlackAndWhite = false\n} = {}) => {\n const tag = isButton ? 'button' : 'div'\n\n return /* HTML */ `\n <${tag}\n class=\"${classNames(\n 'mod-play-icon',\n addClassName,\n isBlackAndWhite && `mod-play-icon--black-white`,\n isInline && `mod-play-icon--inline`,\n position && `mod-play-icon--position`,\n position && `mod-play-icon--position-${position}`,\n size && `mod-play-icon--size-${size}`\n )}\"\n ${id ? `id=\"${id}\"` : ''}\n ${buttonLabel ? `aria-label=\"${buttonLabel}\"` : ''}\n ${dataAttributes ? dataAttributes.join(' ') : ''}\n data-is-paused=\"true\"\n >\n
\n
\n ${Icon({\n icon: 'play'\n })}\n
\n
\n ${Icon({\n icon: 'pause'\n })}\n
\n
\n \n`\n}\n\nexport default PlayIcon\n","import { insert } from 'utilities/renderer'\nimport template from './ProductInfo.template'\n\nexport default class ProductInfo {\n\tconstructor(element, { collection, glassAvailable, benefits, cta, constructionEyebrow, featuredInEyebrow, comingSoonEyebrow } = {}) {\n\t\tthis.element = element\n\t\tthis.collection = collection\n\t\tthis.glassAvailable = glassAvailable\n\t\tthis.benefits = benefits\n\t\tthis.cta = cta\n\t\tthis.constructionEyebrow = constructionEyebrow\n\t\tthis.featuredInEyebrow = featuredInEyebrow\n\t\tthis.comingSoonEyebrow = comingSoonEyebrow\n\t\tthis.init()\n\t}\n\n\tinit() {\n\t\tthis.template = template({\n\t\t\tcollection: this.collection,\n\t\t\tglassAvailable: this.glassAvailable,\n\t\t\tbenefits: this.benefits,\n\t\t\tcta: this.cta,\n\t\t\tconstructionEyebrow: this.constructionEyebrow,\n\t\t\tfeaturedInEyebrow: this.featuredInEyebrow,\n\t\t\tcomingSoonEyebrow: this.comingSoonEyebrow\n\t\t})({\n\t\t\tgetNode: true\n\t\t})\n\t\tthis.render()\n\t}\n\n\trender() {\n\t\tinsert(this.template, this.element)\n\t}\n}\n","import html from 'utilities/html'\nimport textTemplate, {\n\tTYPES as TEXT_TYPES\n} from 'foundation/Text/Text.template'\nimport linkTemplate from 'foundation/Link/Link.template'\nimport titleTemplate, {\n\tTYPES as TITLE_TYPES\n} from 'foundation/Title/Title.template'\n\n/**\n * Template for the Product Information component\n * @param {Object} args\n * @param {string} args.collection - The name of the collection\n * @param {Object} args.glassAvailable - The glass available object\n * @param {Array} args.benefits - The benefits of the collection\n * @param {Object} args.cta - The CTA of the collection\n * @param {string} args.cta.label - The label of the CTA\n * @param {string} args.cta.url - The url of the CTA\n * @param {string} args.cta.target - The target of the CTA\n * @returns {Function} - The template function\n */\nconst template = ({\n\tcollection = '',\n\tglassAvailable = null,\n\tbenefits = '',\n\tcta = {},\n\tconstructionEyebrow = '',\n\tfeaturedInEyebrow = null,\n\tcomingSoonEyebrow = null\n} = {}) => html`\n
\n
\n ${titleTemplate({\n\ttext: collection,\n\theadingElement: 'h1',\n\theadingType: TITLE_TYPES.H4\n})}\n
\n\n ${glassAvailable !== null\n\t\t? /* html */ `\n \n ${textTemplate({\n\t\t\ttext: glassAvailable.label,\n\t\t\ttextElement: 'span',\n\t\t\ttextType: TEXT_TYPES.BODY_XSM\n\t\t})}\n
\n `\n\t\t: ''}\n\n\t\t${featuredInEyebrow !== null\n\t\t? /* html */ `\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t${textTemplate({\n\t\t\ttext: featuredInEyebrow,\n\t\t\ttextElement: 'span',\n\t\t\ttextType: TEXT_TYPES.BODY_XSM\n\t\t})}\n\t\t\t\t\t\t\n\t\t\t\t\t`\n\t\t: ''}\n\n\t\t${comingSoonEyebrow !== null\n\t\t? /* html */ `\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t${textTemplate({\n\t\t\ttext: comingSoonEyebrow,\n\t\t\ttextElement: 'span',\n\t\t\ttextType: TEXT_TYPES.BODY_XSM\n\t\t})}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t`\n\t\t: ''}\n\n\t\t\n ${textTemplate({\n\t\t\ttext: constructionEyebrow,\n\t\t\ttextElement: 'span',\n\t\t\ttextType: TEXT_TYPES.BODY_XSM\n\t\t})}\n\t\t\n\n
    \n ${Array.isArray(benefits)\n\t\t? benefits\n\t\t\t.map((benefit) =>\n\t\t\t\thtml`\n
  • \n ${textTemplate({\n\t\t\t\t\ttext: benefit,\n\t\t\t\t\ttextElement: 'span'\n\t\t\t\t})}\n
  • \n `()\n\t\t\t)\n\t\t\t.join('')\n\t\t: ''}\n
\n
\n ${linkTemplate({\n\t\t\taccessibilityLabel: cta?.text,\n\t\t\thref: cta?.url,\n\t\t\ttarget: cta?.target,\n\t\t\tlabel: cta?.text,\n\t\t\tlinkStyle: 'link-style-primary',\n\t\t\tlinkButtonStyle: 'link-style-primary',\n\t\t\tlinkTextStyle: 'link-style-primary',\n\t\t\tlinkSize: 'link-large',\n\t\t\tshowAsButtonLink: false,\n\t\t\tstartIcon: 'map-pin',\n\t\t\tanalytics: {\n\t\t\t\tevent: 'cta_link',\n\t\t\t\tcta_text: cta?.text,\n\t\t\t\tcta_title: collection\n\t\t\t}\n\t\t})}\n
\n \n`\n\nexport default template\n","// import html from 'utilities/html'\nimport classNames from 'utilities/classnames'\n\n/**\n * Single Tab Template\n * @param {Object} tab - Tab details\n * @param {String} id - Unique identifier for the tab\n * @param {String} accessibilityLabel - Accessibility label for the tab\n * @param {String} title - Title of the tab\n * @param {String} theme - Theme class for the tab\n * @param {Boolean} disabled - Whether the tab is disabled\n * @param {Boolean} isActive - Whether the tab is active\n */\nconst Tab = ({\n\tid,\n\taccessibilityLabel,\n\ttitle,\n\ttheme,\n\tdisabled,\n\tisActive\n}) => `\n \n
\n \n ${title}\n \n
\n \n`\n\n/**\n * Display the tabs\n * @param {String} id - ID of the tabs component\n * @param {Array} tabs - Array of tab objects\n * @param {String} theme - Theme class\n * @returns {String} - HTML string for tabs\n */\nconst displayTabs = (id, tabs, theme) => (\n\ttabs\n\t\t? tabs.map((tab, index) => Tab({\n\t\t\tid: `${id}-tab-${tab.id || index}`,\n\t\t\taccessibilityLabel: tab.title || '',\n\t\t\ttitle: tab.title || '',\n\t\t\ttheme,\n\t\t\tdisabled: tab.disabled || false,\n\t\t\tisActive: tab.isActive || false\n\t\t})).join('')\n\t\t: ''\n)\n\n/**\n * Display the content\n * @param {String} id - ID of the tabs component\n * @param {Array} tabs - Array of tab objects\n * @param {String} theme - Theme class\n * @returns {String} - HTML string for tab contents\n */\nconst displayContent = (id, tabs, theme) => `\n
\n ${tabs\n\t? tabs.map((tab, index) => `\n
\n ${tab.content || ''}\n
\n `).join('')\n\t: ''}\n
\n`\n\n/**\n * Display the select dropdown\n * @param {Array} tabs - Array of tab objects\n * @param {String} id - ID of the tabs component\n * @returns {String} - HTML string for the dropdown select\n */\nconst displaySelect = (tabs, id) => `\n
\n \n ${tabs.find(tab => tab.isActive)?.title || 'Select a tab'}\n \n\n \n ${tabs.map((tab, index) => `\n
  • \n \n \n ${tab.title}\n \n \n
  • \n `).join('')}\n \n
    \n`\n\n/**\n * Tabs Template\n * @param {Object} args - Template arguments\n * @param {String} args.alignment - Alignment class for the tabs\n * @param {String} args.id - ID of the tabs component\n * @param {String} args.moduleSpacing - Spacing class for the module\n * @param {Array} args.tabs - Array of tab objects\n * @param {String} args.theme - Theme class\n * @returns {String} - Complete HTML for the Tabs component\n */\nconst TabsTemplate = ({\n\taddClassName,\n\tid,\n\talignment,\n\tfullWidth = false,\n\tmoduleSpacing,\n\ttabs,\n\ttheme = 'theme-light'\n}) => `\n \n \n ${displaySelect(tabs, id)}\n\n \n
    \n
    \n
    \n ${displayTabs(id, tabs, theme)}\n \n
    \n ${displayContent(id, tabs, theme)}\n
    \n
    \n \n`\n\nexport default TabsTemplate\n","import html from 'utilities/html'\nimport classNames from 'utilities/classnames'\nimport imageTemplate from 'foundation/Image/Image.template'\nimport linkTemplate from 'foundation/Link/Link.template'\nimport textTemplate, {\n TYPES as TEXT_TYPES\n} from 'foundation/Text/Text.template'\nimport iconTemplate from 'foundation/Icon/Icon.template'\nimport tabsTemplate from '../../../Tabs/Tabs.template'\nimport { Default as buttonTemplate } from 'foundation/Button/Button.stories'\n\n/**\n * Utility function to get the custom color from the option value\n */\nfunction getCustomColor(option) {\n const customColorPrefix = 'custom-color-'\n const isCustomColor = option?.value.includes(customColorPrefix)\n const customColor = isCustomColor\n ? option.value.split(customColorPrefix)[1]\n : ''\n return customColor\n}\n\n/**\n * Template for the option image\n * @param {Object} args\n * @param {Object} args.option - The option object\n * @param {Object} args.selectedOption - The selected option object\n * @param {Boolean} args.displayDarkImage - Whether to display the dark image\n */\nconst activeOptionImageTemplate = ({\n option,\n selectedOption,\n displayDarkImage\n} = {}) => {\n const customColor = getCustomColor(selectedOption)\n\n if (customColor) {\n return html``\n }\n\n return selectedOption?.imageDark && displayDarkImage\n ? html` ${imageTemplate({\n addClassName:\n 'mod-product-option-group__active-image mod-product-option-group__active-image--light',\n defaultAspectRatio: '1/1',\n mobileAspectRatio: '1/1',\n defaultSrc: selectedOption?.image,\n mobileSrc: selectedOption?.image,\n altText: selectedOption?.label,\n loading: 'eager'\n })}\n ${imageTemplate({\n addClassName:\n 'mod-product-option-group__active-image mod-product-option-group__active-image--dark',\n defaultAspectRatio: '1/1',\n mobileAspectRatio: '1/1',\n defaultSrc: selectedOption?.imageDark,\n mobileSrc: selectedOption?.imageDark,\n altText: selectedOption?.label,\n loading: 'eager'\n })}`\n : html` ${imageTemplate({\n addClassName: 'mod-product-option-group__active-image',\n defaultAspectRatio: '1/1',\n mobileAspectRatio: '1/1',\n defaultSrc: selectedOption?.image,\n mobileSrc: selectedOption?.image,\n altText: selectedOption?.label,\n loading: 'eager'\n })}`\n}\n\n/**\n * Template for a single product option category. This is the element that each option input will be rendered into.\n * @param {*} category\n * @returns\n */\nconst categoryTemplate = ({ category = {} }) => html`\n
    \n
    \n
    \n`\n\n/**\n * Template for the product option tabs\n * @param {Array} categories - The categories of the product option group\n * @returns\n */\nconst categoryTabsTemplate = ({ breakpoint, categories = [], groupValue }) =>\n html`\n
    \n ${tabsTemplate({\n addClassName: 'mod-product-option-group__tabs',\n disableTabsScrollIntoView: true,\n id: `product-option-tabs-${groupValue}`,\n tabs: categories.map((category) => ({\n title: category.label,\n content: categoryTemplate({\n breakpoint,\n category\n })()\n })),\n theme: breakpoint.MEDIUM_LARGE ? 'theme-light' : 'theme-dark'\n })}\n
    \n `\n\nexport const rangeTemplate = ({\n rangeLabel,\n rangeMax,\n rangeMin,\n rangeValue\n} = {}) => html`\n
    \n
    \n ${textTemplate({\n textType: TEXT_TYPES.CAPTION,\n text: `${rangeLabel}:`\n })}\n
    \n
    \n ${Array.from({ length: rangeMax - rangeMin + 1 }, (_, i) => i + 1)\n .map((_, i) =>\n html`\n \n `()\n )\n .join('')}\n
    \n
    \n ${textTemplate({\n textType: TEXT_TYPES.CAPTION,\n text: `${rangeValue}/${rangeMax}`\n })}\n
    \n
    \n`\n\nconst optionInfoTemplate = ({ option, selectedOption } = {}) => {\n const isColor = option.type === 'color'\n const customColor = getCustomColor(selectedOption)\n\n return html`\n
    \n \n ${activeOptionImageTemplate({ option, selectedOption })()}\n
    \n
    \n ${textTemplate({\n textType: TEXT_TYPES.CALLOUT,\n text: selectedOption?.label || ''\n })}\n
    \n \n `\n}\n\n/**\n *\n * @param {args} {Object}\n * @param {args.option} {Object} - The option object\n * @param {args.selectedOption} {Object} - The selected option object\n * @param {args.isToggleButton} {Boolean} - Whether the option is a toggle button\n * @returns\n */\nexport const optionDetailsTemplate = ({\n option,\n option: { label, tooltip, rangeLabel, rangeMax, rangeMin },\n selectedOption,\n isToggleButton\n} = {}) => {\n const isColor = option.type === 'color'\n const customColor = getCustomColor(selectedOption)\n\n return html`\n \n \n ${activeOptionImageTemplate({\n option,\n selectedOption,\n displayDarkImage: isToggleButton\n })()}\n \n
    \n
    \n ${textTemplate({\n textType: TEXT_TYPES.CTA_LG,\n text: label\n })}\n
    \n ${tooltip !== ''\n ? /* HTML */ `\n
    \n \n \n ${tooltip}\n ${iconTemplate({\n addClassName: 'cmp-tooltip__svg',\n icon: 'info'\n })}\n
    \n \n ${textTemplate({\n text: tooltip,\n textElement: 'p',\n textType: TEXT_TYPES.BODY_SM,\n addClassName: 'cmp-tooltip__text'\n })}\n
    \n \n \n `\n : ''}\n
    \n ${textTemplate({\n textType: TEXT_TYPES.CALLOUT,\n text: selectedOption?.label || ''\n })}\n
    \n ${rangeLabel\n ? rangeTemplate({\n rangeLabel,\n rangeMax,\n rangeMin,\n rangeValue: selectedOption?.range || ''\n })()\n : ''}\n \n \n `\n}\n\nexport const toggleButtonTemplate = ({\n option,\n selectedOption,\n breakpoint\n}) => html`\n
    \n ${breakpoint?.MEDIUM_LARGE\n ? optionDetailsTemplate({ option, selectedOption })()\n : optionInfoTemplate({ option, selectedOption })()}\n
    \n`\n\n/**\n * Template for the more details link\n * @param {Object} args\n * @param {Object} args.moreDetails\n * @param {string} args.moreDetails.detailsId - The id of the details element\n * @param {string} args.moreDetails.label - The label for the more details link\n * @returns\n */\nconst moreDetailsTemplate = ({ moreDetails } = {}) => html`\n
    \n ${linkTemplate({\n linkStyle: 'link-style-text',\n dataAttributes: ['data-cmp-hook=\"product-option-group-more-details\"'],\n href: `#product-details-categories-tab-${moreDetails.detailsId}`,\n label: moreDetails.label,\n linkSize: 'link-large',\n showAsButtonLink: false,\n showAsTextLink: true\n })}\n
    \n`\n\n/**\n *\n * @param {Object} productOptionGroup\n * @param {string} productOptionGroup.label - The label for the product option group\n * @param {string} productOptionGroup.rangeLabel - The label for the range of the product option group\n * @param {string} productOptionGroup.rangeMax - The maximum value for the range of the product option group\n * @param {string} productOptionGroup.rangeMin - The minimum value for the range of the product option group\n * @param {string} productOptionGroup.type - The type of the product option group\n * @param {string} productOptionGroup.value - The value of the product option group\n * @param {Array} productOptionGroup.categories - The categories of the product option group\n * @returns\n */\nconst template = ({\n hasSingleOption,\n option,\n option: {\n label = '',\n tooltip = '',\n rangeLabel = '',\n rangeMax = '',\n rangeMin = '',\n type = '',\n value = '',\n categories = []\n } = {},\n optionTools: { select, cancel } = {},\n selectedOption,\n breakpoint\n} = {}) => html`\n
    \n
    \n ${textTemplate({\n textType: TEXT_TYPES.CALLOUT,\n text: label\n })}\n
    \n\n \n
    \n\n ${hasSingleOption\n ? ''\n : /* HTML */ `\n ${iconTemplate({\n icon: 'chevron-down',\n addClassName:\n 'mod-product-option-group__toggle-button-indicator-icon'\n })}\n `}\n \n \n
    \n
    \n ${optionDetailsTemplate({\n option,\n selectedOption,\n isToggleButton: true\n })()}\n
    \n ${Array.isArray(categories) && categories.length > 1\n ? categoryTabsTemplate({\n breakpoint,\n categories,\n groupValue: value,\n option,\n selectedOption\n })()\n : ''}\n ${Array.isArray(categories) && categories.length === 1\n ? categoryTemplate({\n breakpoint,\n category: categories[0],\n option,\n selectedOption\n })()\n : ''}\n ${option.moreDetails\n ? moreDetailsTemplate({ moreDetails: option.moreDetails })()\n : ''}\n
    \n ${buttonTemplate({\n buttonSize: 'button-large',\n buttonStyle: 'button-style-primary-reversed',\n dataAttributes: ['data-cmp-hook=\"product-option-group-submit\"'],\n label: select?.label || '',\n accessibilityLabel: select?.accessibilityLabel || ''\n })}\n ${buttonTemplate({\n buttonSize: 'button-large',\n buttonStyle: 'button-style-tertiary-reversed',\n dataAttributes: ['data-cmp-hook=\"product-option-group-cancel\"'],\n label: cancel?.label || '',\n accessibilityLabel: cancel?.accessibilityLabel || ''\n })}\n
    \n
    \n \n \n`\n\nexport default template\n","import html from 'utilities/html'\nimport classNames from 'utilities/classnames'\nimport textTemplate, {\n TYPES as TEXT_TYPES\n} from 'foundation/Text/Text.template'\nimport imageTemplate from 'foundation/Image/Image.template'\nimport iconTemplate from 'foundation/Icon/Icon.template'\n\n/**\n * Tile option input template\n * @param {Object} args\n * @param {Object} args.option - The option object\n * @param {String} args.optionId - The id of the option\n * @param {String} args.categoryValue - The value of the category\n * @param {String} args.groupValue - The value of the group\n * @param {String} args.groupType - The type of the group\n * @param {String} args.groupType - The type of the group\n * @returns {Function} - html template function\n */\nconst tileOptionTemplate = ({\n option,\n optionId,\n categoryValue,\n groupValue,\n groupType\n}) => html`\n \n \n \n \n`\n\n/**\n * Custom Color option input template\n * @param {Object} args\n * @param {Object} args.option - The option object\n * @param {String} args.optionId - The id of the option\n * @param {String} args.categoryValue - The value of the category\n * @param {String} args.groupValue - The value of the group\n * @param {String} args.groupType - The type of the group\n * @returns {Function} - html template function\n */\nconst customColorTemplate = ({\n option,\n optionId,\n categoryValue,\n groupValue,\n groupType\n}) => html`\n
    \n \n \n \n ${imageTemplate({\n addClassName: 'mod-product-option-category__image',\n defaultAspectRatio: '1/1',\n mobileAspectRatio: '1/1',\n defaultSrc: option.image,\n mobileSrc: option.image,\n altText: option.label\n})}\n \n
    \n
    \n \n`\n\n/**\n * Text option input template\n * @param {Object} args\n * @param {Object} args.option - The option object\n * @param {String} args.optionId - The id of the option\n * @param {String} args.categoryValue - The value of the category\n * @param {String} args.groupValue - The value of the group\n * @param {String} args.groupType - The type of the group\n * @param {String} args.groupType - The type of the group\n * @returns {Function} - html template function\n */\nconst textOptionTemplate = ({\n option,\n optionId,\n categoryValue,\n groupValue,\n groupType\n}) => html`\n \n \n \n \n`\n/**\n * Tile Text option input template\n * Note: this template is unique in that is displays the value of the option instead of the label\n * @param {Object} args\n * @param {Object} args.option - The option object\n * @param {String} args.optionId - The id of the option\n * @param {String} args.categoryValue - The value of the category\n * @param {String} args.groupValue - The value of the group\n * @param {String} args.groupType - The type of the group\n * @param {String} args.groupType - The type of the group\n * @returns {Function} - html template function\n */\nconst tileTextOptionTemplate = ({\n option,\n optionId,\n categoryValue,\n groupValue,\n groupType\n}) => html`\n \n \n \n \n`\n\n/**\n * Template for rendering a single option\n * @param {Object} option\n * @returns\n */\nconst categoryOptionTemplate = ({\n option = {},\n categoryValue = '',\n groupValue = '',\n groupType = ''\n}) => {\n const optionId = `${groupValue}-${categoryValue}-${option.value}`\n\n if (groupType === 'color' && categoryValue === 'Custom') {\n return customColorTemplate({\n option,\n optionId,\n categoryValue,\n groupValue,\n groupType\n })\n } else if (groupType === 'color' || groupType === 'tile') {\n return tileOptionTemplate({\n option,\n optionId,\n categoryValue,\n groupValue,\n groupType\n })\n } else if (groupType === 'tileText') {\n return tileTextOptionTemplate({\n option,\n optionId,\n categoryValue,\n groupValue,\n groupType\n })\n } else if (groupType === 'text') {\n return textOptionTemplate({\n option,\n optionId,\n categoryValue,\n groupValue,\n groupType\n })\n }\n\n return html``\n}\n\nconst viewMoreButton = ({ isLargeBreakpoint, optionsWrapperId }) => html`\n \n \n \n ${iconTemplate({\n icon: 'chevron-down',\n addClassName: 'mod-product-option-category__view-more-svg'\n})}\n \n \n`\n\nconst viewMoreTemplate = ({ optionsWrapperId }) => html`\n
    \n ${viewMoreButton({ isLargeBreakpoint: true, optionsWrapperId })()}\n ${viewMoreButton({ isLargeBreakpoint: false, optionsWrapperId })()}\n
    \n`\n\nconst noteTemplate = ({ note }) => html`\n
    \n ${textTemplate({\n text: note,\n textType: TEXT_TYPES.CALLOUT,\n textElement: 'p'\n})}\n
    \n`\n\n/**\n * ProductOptionCategory template responsible for rendering a category of options\n * @param {Object} args\n * @param {Object} args.category - Option category object\n * @param {String} args.groupValue - the value of the group\n * @param {String} args.groupType - the type of the group\n * @param {Number} args.maxOptions - the maximum number of options to show before collapsing\n * @returns {Function} - html template function\n */\nconst template = ({ category, groupValue, groupType, maxOptions }) => {\n const optionModifiers = {\n tile: 'mod-product-option-category--tile',\n tileText: 'mod-product-option-category--tile-text',\n color: 'mod-product-option-category--tile-color',\n text: 'mod-product-option-category--text'\n }\n const hasOptions =\n Array.isArray(category.options) && category.options.length > 0\n const optionsWrapperId = `${groupValue}-${category.value}-category-options`\n\n return html`\n \n
    \n \n ${textTemplate({\n text: category.helperLabel || category.labelAccessibility,\n textType: TEXT_TYPES.BODY_SM\n })}\n \n \n ${hasOptions\n ? category.options\n .map((option, index) =>\n categoryOptionTemplate({\n option,\n categoryValue: category.value,\n groupValue,\n groupType\n })()\n )\n .join('')\n : ''}\n \n
    \n ${category.note ? noteTemplate({ note: category.note })() : ''}\n ${hasOptions && category.options.length > maxOptions\n ? viewMoreTemplate({\n optionsWrapperId\n })()\n : ''}\n \n `\n}\nexport default template\n","import classNames from 'utilities/classnames'\n\n/**\n * @param {Object} icon SVG icon to display\n * @returns\n */\nconst displayCloseIcon = (icon) =>\n icon\n ? `\n \n \n \n `\n : ''\n\n/**\n * Render Modal template\n * @param {Object} options Component options\n * @param {String} options.id Component ID\n * @param {Boolean} options.defaultOpen Whether the modal is open by default\n * @param {String} options.children Content to be rendered within the modal\n * @param {String} options.closeButtonAriaLabel Aria label for the close button\n * @param {String} options.closeButtonClass CSS class for the close button\n * @param {String} options.fullScreen CSS class for the modal to go full screen\n * @param {String} options.hasHeader CSS class to add a header to the modal\n * @param {String} options.modalClass CSS class for the modal\n * @param {String} options.transition CSS class for the modal transition\n * @param {String} options.headerTitle Header title text\n */\nconst ModalOverlayTemplate = ({\n id,\n defaultOpen = false,\n children = '',\n closeButtonAriaLabel = '',\n closeButtonClass = '',\n fullScreen = false,\n hasHeader = false,\n modalClass = '',\n transition = 'fade',\n headerTitle = ''\n}) => /* HTML */ `\n \n
    \n \n ${displayCloseIcon('close-x')}\n \n ${hasHeader\n ? `

    ${headerTitle}

    `\n : ''}\n ${children}\n
    \n \n`\n\nexport default ModalOverlayTemplate\n","import html from 'utilities/html'\nimport classNames from 'utilities/classnames'\nimport modalTemplate from 'modules/Modal/Modal.template'\nimport textTemplate, {\n TYPES as TEXT_TYPES\n} from 'foundation/Text/Text.template'\nimport titleTemplate, {\n TYPES as TITLE_TYPES\n} from 'foundation/Title/Title.template'\nimport { Default as buttonTemplate } from 'foundation/Button/Button.stories'\n\n/**\n * Template for the ProductOptionCustomColor select and cancel buttons for mobile breakpoints\n * @param {Object} arg\n * @param {Object} args.optionTools - The option tools object with the select and cancel labels\n * @returns {Function} - The template function\n */\nconst mobileButtons = ({ optionTools = {} }) => html`\n
    \n ${buttonTemplate({\n addClassName: 'mod-product-option-custom-color__button',\n buttonSize: 'button-large',\n buttonStyle: 'button-style-primary-reversed',\n dataAttributes: ['data-cmp-hook=\"color-picker-select-button\"'],\n label: optionTools.select?.label || '',\n accessibilityLabel: optionTools.select?.accessibilityLabel || ''\n })}\n ${buttonTemplate({\n addClassName: 'mod-product-option-custom-color__button',\n buttonSize: 'button-large',\n buttonStyle: 'button-style-tertiary-reversed',\n dataAttributes: ['data-cmp-hook=\"color-picker-cancel-button\"'],\n label: optionTools.cancel?.label || '',\n accessibilityLabel: optionTools.cancel?.accessibilityLabel || ''\n })}\n
    \n`\n\n/**\n * Template for the ProductOptionCustomColor select and cancel buttons for desktop breakpoints\n * @param {Object} arg\n * @param {Object} args.optionTools - The option tools object with the select and cancel labels\n * @returns {Function} - The template function\n */\nconst desktopButtons = ({ optionTools = {} }) => html`\n
    \n ${buttonTemplate({\n addClassName: 'mod-product-option-custom-color__button',\n buttonSize: 'button-large',\n buttonStyle: 'button-style-tertiary',\n dataAttributes: ['data-cmp-hook=\"color-picker-cancel-button\"'],\n label: optionTools.cancel?.label || '',\n accessibilityLabel: optionTools?.accessibilityLabel || ''\n })}\n ${buttonTemplate({\n addClassName: 'mod-product-option-custom-color__button',\n buttonSize: 'button-large',\n buttonStyle: 'button-style-primary',\n dataAttributes: ['data-cmp-hook=\"color-picker-select-button\"'],\n label: optionTools.select?.label || '',\n accessibilityLabel: optionTools.select?.accessibilityLabel || ''\n })}\n
    \n`\n\n/**\n * Template for the ProductOptionCustomColor content\n * @param {Object} args\n * @param {Object} args.content - The content object for the component\n * @param {Object} args.content.title - The title to display\n * @param {Object} args.content.description - The description to display\n * @param {Object} args.content.optionTools - The option tools object with the select and cancel labels\n * @param {Boolean} args.isMediumLarge - Whether the breakpoint is medium-large\n * @returns {Function} - The template function\n */\nconst modalContent = ({\n content: { title, description, optionTools } = {},\n isMediumLarge\n}) => html`\n
    \n ${titleTemplate({\n addClassName: 'mod-product-option-custom-color__title',\n headingType: TITLE_TYPES.H4,\n text: title || '',\n headingElement: 'h2'\n })}\n ${textTemplate({\n addClassName: 'mod-product-option-custom-color__description',\n textType: TEXT_TYPES.BODY_MEDIUM,\n text: description || ''\n })}\n
    \n ${isMediumLarge\n ? desktopButtons({ optionTools })()\n : mobileButtons({ optionTools })()}\n \n`\n\n/**\n * Template for the ProductOptionCustomColor component\n * @param {Object} args\n * @param {Object} args.content - The content object for the component\n * @param {Object} args.content.title - The title to display\n * @param {Object} args.content.description - The description to display\n * @param {Object} args.content.optionTools - The option tools object with the select and cancel labels\n * @param {Boolean} args.isMediumLarge - Whether the breakpoint is medium-large\n * @returns {Function} - The template function\n */\nconst template = ({\n content,\n content: { title, description, optionTools } = {},\n isMediumLarge\n}) => html`\n \n ${modalTemplate({\n closeButtonAriaLabel: optionTools.cancelAccessibility,\n headerTitle: title || '',\n id: 'custom-color-modal',\n modalClass: 'mod-product-option-custom-color__modal',\n children: modalContent({ content, isMediumLarge })()\n })}\n \n`\n\nexport default template\n","import { insert } from 'utilities/renderer'\nimport { noop } from 'utilities/utilities'\nimport Services from 'services'\nimport ColorPicker from 'modules/ColorPicker/ColorPicker'\nimport template from './ProductOptionCustomColor.template'\nimport Modal from 'modules/Modal/Modal'\n\n/**\n * ProductOptionCustomColor component responsible for rendering a custom color picker in a modal\n * @param {HTMLElement} element - the element to render the component in\n * @param {Object} options - the options for the component\n * @param {Object} options.content - the content for the component\n * @param {string} options.content.title - the title for the color picker modal\n * @param {string} options.content.description - the description for the color picker modal\n * @param {Object} options.content.optionTools - the option tools for the color picker modal (e.g. \"Select\" and \"Cancel\" buttons)\n * @param {string} options.initialColor - the initial color for the color picker\n * @param {Function} options.onSelect - the callback for when the color changes\n * @param {Function} options.onCancel - the callback for when the color picker is cancelled\n */\nexport default class ProductOptionCustomColor {\n static SELECTORS = {\n BUTTON_CANCEL: '[data-cmp-hook=\"color-picker-cancel-button\"]',\n BUTTON_SELECT: '[data-cmp-hook=\"color-picker-select-button\"]',\n COLOR_PICKER_BUTTON: '[data-cmp-hook=\"color-picker-button\"]',\n COLOR_PICKER: '[data-cmp-hook=\"color-picker\"]',\n MODAL: '[data-cmp-is=\"modal\"]'\n }\n\n constructor(\n element,\n { content = {}, initialColor = null, onSelect = noop, onCancel } = {}\n ) {\n this.element = element\n this.services = Services.getInstance()\n this.EventEmitterService = this.services.EventEmitterService\n this.mediaQuery = this.services.BreakpointListener.queryMatch\n this.content = content\n this.onSelect = onSelect\n this.onCancel = onCancel\n this.color = initialColor\n this.pendingColor = initialColor\n this.init()\n }\n\n /**\n * Initializes the component\n */\n init() {\n if (this.template) {\n this.detachEvents()\n }\n\n this.template = template({\n content: this.content,\n isMediumLarge: this.mediaQuery.MEDIUM_LARGE\n })({\n getNode: true\n })\n\n this.cacheDom()\n this.attachEvents()\n this.render()\n }\n\n /**\n * Cache the DOM elements\n */\n cacheDom() {\n this.colorPickerButtonEl = this.template.querySelector(\n ProductOptionCustomColor.SELECTORS.COLOR_PICKER_BUTTON\n )\n\n this.colorPickerEl = this.template.querySelector(\n ProductOptionCustomColor.SELECTORS.COLOR_PICKER\n )\n\n this.modalEl = this.template.querySelector(\n ProductOptionCustomColor.SELECTORS.MODAL\n )\n\n this.buttonSelect = this.template.querySelector(\n ProductOptionCustomColor.SELECTORS.BUTTON_SELECT\n )\n\n this.buttonCancel = this.template.querySelector(\n ProductOptionCustomColor.SELECTORS.BUTTON_CANCEL\n )\n }\n\n /**\n * Attach the events\n */\n attachEvents() {\n this.EventEmitterService.on(Modal.EVENTS.CLOSE_MODAL, this.onModalClose)\n\n this.buttonSelect.addEventListener('click', this.onSelectHandler)\n this.buttonCancel.addEventListener('click', this.onCancelHandler)\n\n this.services.BreakpointListener.addListener(this.onBreakpointChange)\n }\n\n /**\n * Detach the events\n */\n detachEvents() {\n this.services.BreakpointListener.removeListener(this.onBreakpointChange)\n }\n\n /**\n * Destroy the component\n */\n destroy() {\n this.detachEvents()\n }\n\n /**\n * Store the active color picker color\n * @param {string} color - hex color value\n */\n setColor = (color) => {\n this.pendingColor = color\n }\n\n /**\n * Open the color picker modal and initialize the color picker\n */\n openColorPicker = () => {\n this.modal = new Modal(this.modalEl)\n\n // fix for a race condition with the keydown event + Enter key\n // forcing the modal to close when opened\n requestAnimationFrame(() => {\n this.modal.open()\n })\n\n // Large breakpoints, show ColorPicker in a modal\n this.colorPicker = new ColorPicker(this.colorPickerEl, {\n theme: this.mediaQuery.MEDIUM_LARGE ? 'light' : 'dark',\n onChange: this.setColor,\n initialColor: this.color\n })\n }\n\n /**\n * Callback for when a modal is closed to destroy the modal and color picker\n * @param {string} modalId - The id of the modal that was closed\n */\n onModalClose = (modalId) => {\n if (modalId === this.modalEl.id) {\n this.modal?.destroy()\n this.colorPicker?.destroy()\n }\n }\n\n /**\n * Callback for when the color picker select button is clicked to update the color and trigger the onSelect callback\n */\n onSelectHandler = () => {\n this.color = this.pendingColor\n this.onSelect(this.pendingColor)\n this.modal.close()\n }\n\n /**\n * Callback for when the color picker cancel button is clicked to reset the color and trigger the onCancel callback\n */\n onCancelHandler = () => {\n this.pendingColor = this.color\n\n if (this.modal) {\n this.modal.close()\n }\n }\n\n /**\n * Callback for when the breakpoint changes to re-render the component and close the modal\n * @param {Object} breakpoint - the mediaQuery breakpoint object\n */\n onBreakpointChange = (breakpoint) => {\n const hasChanged = breakpoint.MEDIUM_LARGE !== this.mediaQuery.MEDIUM_LARGE\n\n this.mediaQuery = breakpoint\n\n if (hasChanged) {\n this.onCancelHandler()\n this.init()\n }\n }\n\n /**\n * Render the component\n */\n render() {\n insert(this.template, this.element)\n }\n}\n","import { insert } from 'utilities/renderer'\nimport template from './ProductOptionCategory.template'\nimport ProductOptionCustomColor from '../ProductOptionsCustomColor/ProductOptionsCustomColor'\n\n/**\n * ProductOptionCategory component responsible for rendering a category of options\n * @param {HTMLElement} element - the element to render the component in\n * @param {Object} options - the options for the component\n * @param {String} options.groupValue - the value of the group\n * @param {Object} options.category - the category object\n * @param {Object} options.optionTools - the option tools object\n */\nexport default class ProductOptionCategory {\n /**\n * Selectors used by the component\n */\n static SELECTORS = {\n INPUT: '[data-cmp-hook=\"product-option-input\"]',\n OPTIONS: '[data-cmp-hook=\"product-option-category-options\"]',\n OPTION: '[data-cmp-hook=\"product-option\"]',\n OPTION_CUSTOM_COLOR_INPUT: '[data-custom-input=\"custom-color\"]',\n OPTION_CUSTOM_COLOR_LABEL: '[data-custom-label=\"custom-color\"]',\n CUSTOM_COLOR: '[data-cmp-hook=\"product-option-custom-color\"]',\n VIEW_MORE: '[data-cmp-hook=\"product-options-view-more\"]',\n VIEW_MORE_LABEL: '[data-cmp-hook=\"product-options-view-more-label\"]'\n }\n\n /**\n * Classes used by the component\n */\n static CLASSES = {\n OPTION_HIDE: 'mod-product-option-category__option--hide',\n VIEW_MORE_EXPANDED:\n 'mod-product-option-category__view-more-button--expanded'\n }\n\n /**\n * The maximum number of options to show before collapsing\n */\n static MAX_OPTIONS = {\n tile: 10,\n color: 12,\n text: 6\n }\n\n constructor(\n element,\n { groupValue, groupType, category = {}, optionTools = {} } = {}\n ) {\n this.element = element\n this.groupValue = groupValue\n this.groupType = groupType\n this.category = category\n this.optionTools = optionTools\n this.maxOptions = ProductOptionCategory.MAX_OPTIONS[this.groupType]\n this.isExpanded = false\n\n this.init()\n }\n\n /**\n * Initialize the component\n */\n init() {\n this.template = template({\n category: this.category,\n groupValue: this.groupValue,\n groupType: this.groupType,\n maxOptions: this.maxOptions,\n optionTools: this.optionTools\n })({\n getNode: true\n })\n\n this.cacheDom()\n this.createCustomColor()\n this.attachEvents()\n this.checkViewMore()\n this.render()\n }\n\n /**\n * Cache DOM elements\n */\n cacheDom() {\n this.optionsEl = this.template.querySelector(\n ProductOptionCategory.SELECTORS.OPTIONS\n )\n\n this.optionEls = this.template.querySelectorAll(\n ProductOptionCategory.SELECTORS.OPTION\n )\n\n this.optionCustomColorInput = this.template.querySelector(\n ProductOptionCategory.SELECTORS.OPTION_CUSTOM_COLOR_INPUT\n )\n\n this.optionCustomColorLabel = this.template.querySelector(\n ProductOptionCategory.SELECTORS.OPTION_CUSTOM_COLOR_LABEL\n )\n\n this.customColorEl = this.template.querySelector(\n ProductOptionCategory.SELECTORS.CUSTOM_COLOR\n )\n\n this.viewMoreButtonEls = this.template.querySelectorAll(\n ProductOptionCategory.SELECTORS.VIEW_MORE\n )\n\n this.viewMoreLabelEls = this.template.querySelectorAll(\n ProductOptionCategory.SELECTORS.VIEW_MORE_LABEL\n )\n }\n\n /**\n * Attach events\n */\n attachEvents() {\n if (this.viewMoreButtonEls.length > 0) {\n this.viewMoreButtonEls.forEach((viewMoreButtonEl) => {\n viewMoreButtonEl.addEventListener('click', this.toggleViewMore)\n })\n }\n\n if (this.optionCustomColorLabel && this.optionCustomColorInput) {\n this.optionCustomColorInput.addEventListener(\n 'click',\n this.onCustomColorInputSelect\n )\n\n this.optionCustomColorInput.addEventListener(\n 'keydown',\n this.onCustomColorInputSelect\n )\n }\n }\n\n /**\n * Detach events\n */\n detachEvents() {\n if (this.viewMoreButtonEls.length > 0) {\n this.viewMoreButtonEls.forEach((viewMoreButtonEl) => {\n viewMoreButtonEl.removeEventListener('click', this.toggleViewMore)\n })\n }\n\n if (this.optionCustomColorLabel && this.optionCustomColorInput) {\n this.optionCustomColorInput.removeEventListener(\n 'click',\n this.onCustomColorInputSelect\n )\n\n this.optionCustomColorInput.removeEventListener(\n 'keydown',\n this.onCustomColorInputSelect\n )\n }\n }\n\n /**\n * Destroy the component\n */\n destroy() {\n this.detachEvents()\n }\n\n /**\n * Create the custom color picker\n */\n createCustomColor() {\n if (this.customColorEl) {\n const colorPrefix = 'custom-color-'\n const customColorOption = this.category.options.find(\n (option) => option.value.indexOf(colorPrefix) > -1\n )\n const initialColor = customColorOption\n ? `#${customColorOption.value.split(colorPrefix)[1]}`\n : null\n\n this.productOptionCustomColor = new ProductOptionCustomColor(\n this.customColorEl,\n {\n initialColor,\n content: {\n title: this.category.helperLabel,\n description: this.category.helperText,\n optionTools: this.optionTools\n },\n onSelect: this.onCustomColorSelect\n }\n )\n }\n }\n\n /**\n * Callback for when the custom color input is selected (e.g. click or enter) to open the color picker\n * @param {Event} e - the event object\n */\n onCustomColorInputSelect = (e) => {\n if (\n (e.type === 'keydown' && (e.key === 'Enter' || e.key === ' ')) ||\n e.type === 'click'\n ) {\n e.stopImmediatePropagation()\n this.productOptionCustomColor.openColorPicker()\n }\n }\n\n /**\n * Callback for when a custom color is selected to update the custom color input as selected and trigger a change event\n * @param {string} color - the color hex that was selected\n */\n onCustomColorSelect = (color) => {\n this.optionCustomColorInput.value = `custom-color-${color.replace('#', '')}`\n\n this.optionCustomColorInput.checked = true\n this.optionCustomColorInput.dispatchEvent(new Event('change'))\n }\n\n /**\n * Check if the view more button should be expanded, collapsed, or hidden\n */\n checkViewMore() {\n const selectedOptionIdx = Array.isArray(this.category.options)\n ? this.category.options.findIndex((option) => {\n return option.isSelected\n })\n : -1\n\n if (selectedOptionIdx && selectedOptionIdx + 1 > this.maxOptions) {\n this.expandViewMore()\n } else {\n this.collapseViewMore()\n }\n }\n\n /**\n * Expand the view more button to show all options\n */\n expandViewMore() {\n this.isExpanded = true\n\n this.optionEls.forEach((optionEl) => {\n optionEl.classList.remove(ProductOptionCategory.CLASSES.OPTION_HIDE)\n optionEl.setAttribute('aria-hidden', false)\n optionEl.removeAttribute('tabindex')\n })\n\n this.viewMoreButtonEls.forEach((viewMoreButtonEl) => {\n viewMoreButtonEl.classList.add(\n ProductOptionCategory.CLASSES.VIEW_MORE_EXPANDED\n )\n\n viewMoreButtonEl.setAttribute('aria-expanded', true)\n\n viewMoreButtonEl.setAttribute(\n 'aria-label',\n this.optionTools.seeLessAccessibility\n )\n })\n\n this.viewMoreLabelEls.forEach((viewMoreLabelEl) => {\n viewMoreLabelEl.innerHTML = this.optionTools.seeLess\n })\n }\n\n /**\n * Collapse the view more button to hide options\n */\n collapseViewMore() {\n this.isExpanded = false\n\n this.optionEls.forEach((optionEl, index) => {\n if (index + 1 > this.maxOptions) {\n optionEl.classList.add(ProductOptionCategory.CLASSES.OPTION_HIDE)\n optionEl.setAttribute('aria-hidden', true)\n optionEl.setAttribute('tabindex', -1)\n }\n })\n\n this.viewMoreButtonEls.forEach((viewMoreButtonEl) => {\n viewMoreButtonEl.classList.remove(\n ProductOptionCategory.CLASSES.VIEW_MORE_EXPANDED\n )\n viewMoreButtonEl.setAttribute('aria-expanded', false)\n\n viewMoreButtonEl.setAttribute(\n 'aria-label',\n this.optionTools.seeAllAccessibility\n )\n })\n\n this.viewMoreLabelEls.forEach((viewMoreLabelEl) => {\n viewMoreLabelEl.innerHTML = this.optionTools.seeAll\n })\n }\n\n /**\n * Toggle the view more button to show or hide options\n */\n toggleViewMore = () => {\n if (this.isExpanded) {\n this.collapseViewMore()\n } else {\n this.expandViewMore()\n }\n }\n\n render() {\n insert(this.template, this.element)\n }\n}\n","import { insert } from 'utilities/renderer'\nimport {\n noop,\n actionOnClickOutside,\n limitKeyboardAccessibility\n} from 'utilities/utilities'\nimport template, {\n toggleButtonTemplate,\n optionDetailsTemplate\n} from './ProductOptionGroup.template'\nimport ProductOptionCategory from '../ProductOptionCategory/ProductOptionCategory'\nimport Services from 'services'\nimport Tabs from 'modules/Tabs'\nimport Analytics from 'services/Analytics/Analytics'\nimport tippy from 'tippy.js'\n\n/**\n * ProductOptionGroup component responsible for rendering a single product option group, eg. Glass, Color, Size, etc.\n * @param {HTMLElement} element - the root element for this component\n * @param {Object} option - the product option group object\n * @param {Object} optionTools - the product option tools object\n * @param {Function} onProductSelect - callback function for when a product option is selected\n * @param {Function} onProductSubmit - callback function for when the product option group is submitted\n * @param {Function} onProductCancel - callback function for when the product option group is cancelled\n */\nexport default class ProductOptionGroup {\n static SELECTORS = {\n TABS: '[data-cmp-is=\"tabs\"]',\n INPUT: '[data-cmp-hook=\"product-option-input\"]',\n DRAWER: '[data-cmp-hook=\"product-option-group-drawer\"]',\n TOGGLE: '[data-cmp-hook=\"product-option-group-toggle\"]',\n TOGGLE_CONTENT: '[data-cmp-hook=\"product-option-group-toggle-content\"]',\n DETAILS: '[data-cmp-hook=\"product-option-details\"]',\n SUBMIT_BUTTON: '[data-cmp-hook=\"product-option-group-submit\"]',\n CANCEL_BUTTON: '[data-cmp-hook=\"product-option-group-cancel\"]',\n MORE_DETAILS: '[data-cmp-hook=\"product-option-group-more-details\"]',\n TOOLTIP_TOGGLE_BUTTON: '[data-cmp-hook=\"tooltip-toggle-button\"]',\n TOOLTIP_DRAWER_INFO: '[data-cmp-hook=\"tooltip-drawer-info\"]',\n }\n\n static CLASSES = {\n ACTIVE_GROUP: 'mod-product-option-group--active',\n DISABLED_GROUP: 'mod-product-option-group--disabled',\n THEME_LIGHT: 'theme-light',\n THEME_DARK: 'theme-dark'\n }\n\n constructor(\n element,\n {\n option = {},\n optionTools = {},\n onProductSelect = noop,\n onProductSubmit = noop,\n onProductCancel = noop\n } = {}\n ) {\n this.element = element\n this.option = option\n this.optionTools = optionTools\n this.categories = {}\n this.tabs = null // reference to tabs component\n this.tooltipsToggleButtons = []\n this.onProductSelect = onProductSelect\n this.onProductSubmit = onProductSubmit\n this.onProductCancel = onProductCancel\n this.isDrawerOpen = false\n this.services = Services.getInstance()\n this.eventEmitterService = this.services.EventEmitterService\n this.mediaQuery = this.services.BreakpointListener.queryMatch\n this.analyticsService = Analytics.getInstance()\n this.init()\n }\n\n /**\n * Initialize the component and create all of the product option categories\n */\n init() {\n const hasSingleOption =\n this.option?.categories?.reduce(\n (acc, category) => acc.concat(category.options),\n []\n ).length === 1\n\n this.template = template({\n hasSingleOption,\n option: this.option,\n optionTools: this.optionTools,\n selectedOption: this.getSelectedOption(),\n breakpoint: this.mediaQuery\n })({\n getNode: true\n })\n\n this.createCategories()\n this.cacheDom()\n this.attachEvents()\n this.createToggleButton()\n this.createDrawerTooltips()\n this.createTabs()\n this.setTheme()\n this.setDisabledDrawer()\n this.render()\n }\n\n /**\n * Cache all DOM elements\n */\n cacheDom() {\n this.tabsEl = this.template.querySelector(ProductOptionGroup.SELECTORS.TABS)\n\n this.optionInputs = Array.from(\n this.template.querySelectorAll(ProductOptionCategory.SELECTORS.INPUT)\n )\n\n this.optionDrawer = this.template.querySelector(\n ProductOptionGroup.SELECTORS.DRAWER\n )\n\n this.optionToggleButton = this.template.querySelector(\n ProductOptionGroup.SELECTORS.TOGGLE\n )\n\n this.optionToggleButtonContent = this.template.querySelector(\n ProductOptionGroup.SELECTORS.TOGGLE_CONTENT\n )\n\n this.submitButton = this.template.querySelector(\n ProductOptionGroup.SELECTORS.SUBMIT_BUTTON\n )\n\n this.cancelButton = this.template.querySelector(\n ProductOptionGroup.SELECTORS.CANCEL_BUTTON\n )\n\n this.moreDetails = this.template.querySelector(\n ProductOptionGroup.SELECTORS.MORE_DETAILS\n )\n }\n\n /**\n * Attach all events\n */\n attachEvents() {\n this.optionInputs.forEach((input) => {\n input.addEventListener('change', this.onProductSelectHandler)\n })\n\n this.optionToggleButton.addEventListener('focus', this.onToggleFocus)\n this.optionToggleButton.addEventListener('keydown', this.onToggleKeydown)\n this.optionToggleButton.addEventListener('click', this.toggleDrawer)\n this.submitButton.addEventListener('click', this.onSubmit)\n this.cancelButton.addEventListener('click', this.onCancel)\n this.services.BreakpointListener.addListener(this.onBreakpointChange)\n\n if (this.moreDetails) {\n this.moreDetails.addEventListener('click', this.onMoreDetails)\n }\n }\n\n /**\n * Detach all events\n */\n detachEvents() {\n this.optionInputs.forEach((input) => {\n input.removeEventListener('change', this.onProductSelectHandler)\n })\n\n if (this.moreDetails) {\n this.moreDetails.removeEventListener('click', this.onMoreDetails)\n }\n }\n\n /**\n * Destroy the component\n */\n destroy() {\n if (this.tabs) {\n this.tabs.destroy()\n }\n\n this.detachEvents()\n }\n\n /**\n * Callback for when the breakpoint changes to close the drawer if it's open and the breakpoint changes between LARGE and SMALL/MEDIUM\n * @param {Object} breakpoint - The breakpoint object\n */\n onBreakpointChange = (breakpoint) => {\n const hasChanged = breakpoint.MEDIUM_LARGE !== this.mediaQuery.MEDIUM_LARGE\n\n this.mediaQuery = breakpoint\n\n if (hasChanged) {\n this.closeDrawer()\n this.createToggleButton()\n this.setTheme()\n }\n }\n\n /**\n * Event handler for when a product option is selected to invoke the\n * onProductSelect callback with selected product option data\n * @param {Event} event - Change event object\n */\n onProductSelectHandler = (event) => {\n const { target } = event\n const { dataset, value, checked } = target\n\n if (typeof this.onProductSelect === 'function') {\n this.onProductSelect({\n groupValue: dataset.group,\n categoryValue: dataset.category,\n optionValue: value,\n isSelected: checked\n })\n }\n }\n\n /**\n * Event handler for when the submit button is clicked to invoke the\n * onProductSubmit callback and close the drawer\n */\n onSubmit = () => {\n this.onProductSubmit()\n this.closeDrawer()\n }\n\n /**\n * Event handler for when the cancel button is clicked to invoke the\n * onProductCancel callback and close the drawer\n */\n onCancel = () => {\n this.onProductCancel()\n this.closeDrawer()\n }\n\n /**\n * Event handler for when the more details button is clicked to switch to the details tab\n * @param {*} event\n */\n onMoreDetails = (event) => {\n event.preventDefault()\n\n const detailsId = this.option?.moreDetails?.detailsId\n\n if (detailsId) {\n if (!this.mediaQuery.MEDIUM_LARGE) {\n // close the drawer if it's open on mobile/tablet\n this.onCancel()\n }\n this.eventEmitterService.emit(Tabs.EVENTS.SWITCH_TAB, {\n tabsId: 'product-details-categories',\n tabId: `product-details-categories-tab-${detailsId}`\n })\n }\n\n\t\tsetTimeout(() => {\n\t\t\tconst tabNav = document.getElementById(`product-details-categories`);\n\t\t\tif(tabNav) {\n\t\t\t\ttabNav.scrollIntoView({\n\t\t\t\t\tbehavior: \"smooth\"\n\t\t\t\t});\n\t\t\t}\n\t\t}, 500)\n }\n\n /**\n * Create the toggle button for the product option group to set the\n * text of the button based on the breakpoint and selected option\n */\n createToggleButton() {\n const toggleButton = toggleButtonTemplate({\n option: this.option,\n selectedOption: this.getSelectedOption(),\n breakpoint: this.mediaQuery\n })({ getNode: true })\n\n insert(toggleButton, this.optionToggleButtonContent)\n this.createTooltipToggleButtons()\n }\n\n /**\n * Create all of the product option categories\n */\n createCategories() {\n const { categories } = this.option\n\n if (categories) {\n categories.forEach((category) => {\n const categoryEl = this.template.querySelector(\n `[data-cpm-hook=\"product-option-category-${category.value}\"]`\n )\n const el = document.createElement('div')\n\n if (categoryEl) {\n categoryEl.appendChild(el)\n }\n\n this.categories[category.value] = new ProductOptionCategory(el, {\n groupValue: this.option.value,\n groupType: this.option.type,\n category,\n optionTools: this.optionTools\n })\n })\n }\n }\n\n /**\n * Create the tabs for the product option group if there are more than one category\n */\n createTabs() {\n const { categories } = this.option\n if (this.tabsEl && categories.length > 1) {\n this.tabs = new Tabs(this.tabsEl)\n }\n }\n\n /**\n * Create the tooltips for the product option group toggle button\n */\n createTooltipToggleButtons() {\n if (this.tooltipsToggleButtons.length > 0) {\n this.tooltipsToggleButtons.forEach((tooltip) => {\n tooltip.destroy()\n })\n }\n\n this.tooltipsToggleButtons = []\n\n this.tooltipToggleButtonsEls = this.template.querySelectorAll(\n ProductOptionGroup.SELECTORS.TOOLTIP_TOGGLE_BUTTON\n )\n\n this.tooltipToggleButtonsEls.forEach((tooltipEl, i) => {\n const tooltipContent = tooltipEl.querySelector('.js-tooltip-content')\n const tooltip = this.createTooltip(tooltipEl, tooltipContent)\n this.tooltipsToggleButtons.push(tooltip)\n\n })\n }\n\n /**\n * Create the tooltips for the product option group drawer info\n */\n createDrawerTooltips() {\n this.tooltipsDrawers = []\n\n this.tooltipDrawerEls = this.template.querySelectorAll(\n ProductOptionGroup.SELECTORS.TOOLTIP_DRAWER_INFO\n )\n\n this.tooltipDrawerEls.forEach((tooltipEl, i) => {\n const tooltipContent = tooltipEl.querySelector('.js-tooltip-content')\n const tooltip = this.createTooltip(tooltipEl, tooltipContent)\n\n this.tooltipsDrawers.push(tooltip)\n })\n }\n\n /**\n * Create an instance of tippy for the tooltip\n * @param {Element} tooltipEl - The tooltip element\n * @param {Element} tooltipContent - The tooltip content element\n * @returns\n */\n createTooltip(tooltipEl, tooltipContent) {\n return tippy(tooltipEl, {\n allowHTML: true,\n content: tooltipContent,\n animateFill: true,\n interactive: true,\n placement: 'auto',\n trigger: 'click',\n flipOnUpdate: true,\n onTrigger: (instance, e) => {\n e.stopImmediatePropagation()\n },\n onUntrigger: (instance, e) => {\n e.stopImmediatePropagation()\n }\n })\n\n\n }\n\n /**\n * Get the index of the selected category\n * @returns {Number} - The index of the selected category\n */\n getSelectedCategoryIndex = () => {\n return this.option.categories.findIndex((category) => {\n return category.options.find((option) => option.isSelected)\n })\n }\n\n /**\n * Get the selected option for this product option group\n * @returns {Object} - The selected option for this product option group\n */\n getSelectedOption = () => {\n return this.option.categories\n .reduce((acc, category) => acc.concat(category.options), [])\n .find((option) => option?.isSelected)\n }\n\n /**\n * Get all of the options for this product option group\n * @returns {Array} - All of the options for this product option group\n */\n getAllOptions = () => {\n return this.option.categories.reduce((acc, category) => {\n return acc.concat(category.options)\n }, [])\n }\n\n /**\n * Set the theme based on the breakpoint\n */\n setTheme() {\n this.optionDrawer.classList.remove(\n this.mediaQuery.MEDIUM_LARGE\n ? ProductOptionGroup.CLASSES.THEME_DARK\n : ProductOptionGroup.CLASSES.THEME_LIGHT\n )\n this.optionDrawer.classList.add(\n this.mediaQuery.MEDIUM_LARGE\n ? ProductOptionGroup.CLASSES.THEME_LIGHT\n : ProductOptionGroup.CLASSES.THEME_DARK\n )\n\n if (this.tabs) {\n this.tabs.setTheme(\n this.mediaQuery.MEDIUM_LARGE ? Tabs.THEMES.LIGHT : Tabs.THEMES.DARK\n )\n }\n }\n\n /**\n * Set the active tab based on the selected option\n */\n setActiveTab = () => {\n const activeCatIdx = this.getSelectedCategoryIndex()\n const activeTabId = this.tabs\n ? Object.keys(this.tabs.tabIds)[activeCatIdx]\n : null\n\n if (activeTabId) {\n this.tabs.switchTab(activeTabId)\n }\n }\n\n /**\n * Set the selected options for this product option group based on the options passed in\n * @param {Object} options - Object containing the selected options for this product option group\n * @param {Array} options.categories - Array of categories containing the selected options for each category\n * @param {String} options.categories[].value - Value of the category\n * @param {Array} options.categories[].options - Array of options for the category\n * @param {String} options.categories[].options[].value - Value of the option\n * @param {Boolean} options.categories[].options[].isSelected - Whether or not the option is selected\n */\n setSelectedOptions = (options, optionsApplied) => {\n const prevSelectedOption = this.getSelectedOption()\n const hasDisabledChanged = this.option?.isDisabled !== options?.isDisabled\n this.option = options\n const selectedOption = this.getSelectedOption()\n const allOptions = this.getAllOptions()\n const hasOptionChanged =\n prevSelectedOption?.value !== selectedOption?.value || optionsApplied\n const customColorIdx = (val) => val.includes('custom-color')\n\n if (hasDisabledChanged) {\n this.setDisabledDrawer()\n }\n\n if (hasOptionChanged) {\n this.optionInputs.forEach((input) => {\n const { value, checked } = input\n const option = allOptions.find(\n (option) =>\n (customColorIdx(option.value) && customColorIdx(value)) ||\n option.value === value\n )\n\n if (!!option?.isSelected !== checked) {\n input.checked = option.isSelected\n }\n\n if (option?.isDisabled) {\n input.setAttribute('disabled', true)\n } else {\n input.removeAttribute('disabled')\n }\n\n })\n\n if (optionsApplied) {\n this.createToggleButton()\n }\n this.setOptionDetails()\n }\n\n }\n\n /**\n * Set the option details based on the selected option\n */\n setOptionDetails = () => {\n const optionDetails = this.template.querySelectorAll(\n ProductOptionGroup.SELECTORS.DETAILS\n )\n const selectedOption = this.getSelectedOption()\n const updatedOptionDetails = optionDetailsTemplate({\n option: this.option,\n selectedOption\n })({ getNode: true })\n\n optionDetails.forEach((optionDetail) => {\n optionDetail.replaceWith(updatedOptionDetails.cloneNode(true));\n });\n\n\t this.createTooltipToggleButtons()\n }\n\n /**\n * When the toggle button is focused, scroll it into view\n */\n onToggleFocus = (event) => {\n if (!this.mediaQuery.MEDIUM_LARGE) {\n // scroll the button into view after the drawer is open\n // this solves an where the scoll is prevent by the drawer animating in\n requestAnimationFrame(() => {\n this.optionToggleButton.scrollIntoView({\n behavior: 'smooth',\n inline: 'nearest',\n block: 'nearest'\n })\n })\n }\n }\n\n /**\n * Callback to close the drawer when the user selects the escape key when the button is focused\n * @param {Event} event\n */\n onToggleKeydown = (event) => {\n if (\n (event.key === 'Escape' || event.eyCode === 27) &&\n !this.mediaQuery.MEDIUM_LARGE\n ) {\n this.closeDrawer()\n }\n }\n\n /**\n * Toggles the drawer open and close. If the drawer is open,\n * it calls closeDrawer. Otherwise, it calls openDrawer.\n * @param {Event} event - The click event that triggers the toggle\n */\n toggleDrawer = (event) => {\n event.stopImmediatePropagation()\n\n if (this.isDrawerOpen) {\n this.closeDrawer()\n } else {\n this.openDrawer()\n }\n }\n\n /**\n * Open the drawer for this product option group, wire up the events\n * for closing the drawer, set focus trap, and set the active tab\n */\n openDrawer = () => {\n this.isDrawerOpen = true\n\n this.optionToggleButton.setAttribute('aria-expanded', true)\n this.template.classList.add(ProductOptionGroup.CLASSES.ACTIVE_GROUP)\n\n if (!this.mediaQuery.MEDIUM_LARGE) {\n actionOnClickOutside(this.optionDrawer, this.onCancel)\n limitKeyboardAccessibility(this.optionDrawer, this.onCancel)\n }\n\n if (this.tabs) {\n this.setActiveTab()\n }\n\n this.trackDrawer()\n }\n\n /**\n * Close the drawer for this product option group and remove focus from the drawer\n */\n closeDrawer = () => {\n this.isDrawerOpen = false\n\n this.optionToggleButton.setAttribute('aria-expanded', false)\n this.optionToggleButton.focus()\n this.template.classList.remove(ProductOptionGroup.CLASSES.ACTIVE_GROUP)\n\n if (typeof this.optionDrawer.clearListener === 'function') {\n this.optionDrawer.clearListener()\n }\n\n if (typeof this.optionDrawer.clearKeyHandler === 'function') {\n this.optionDrawer.clearKeyHandler()\n }\n\n this.trackDrawer()\n }\n\n /**\n * Set the disabled state of the drawer based on the option.isDisabled property\n */\n setDisabledDrawer = () => {\n const action = this.option?.isDisabled ? 'add' : 'remove'\n this.template.classList[action](ProductOptionGroup.CLASSES.DISABLED_GROUP)\n }\n\n /**\n * Track the drawer open/close event\n */\n trackDrawer = () => {\n this.analyticsService.trackInteraction('product_option_drawer', {\n state: this.isDrawerOpen ? 'open' : 'close',\n option: this.option?.label?.toLowerCase()\n })\n }\n\n render() {\n insert(this.template, this.element)\n }\n}\n","import {\n noop\n} from 'utilities/utilities'\n\nimport template from './ProductOptionFilters.template'\n\n/**\n * ProductOptionFilters component responsible for rendering filters to filter product options\n * @param {HTMLElement} element - the root element for this component\n * @param {Object} filters - the product filters group object\n * @param {Function} onFilterSelect - callback function for when a filter option is selected\n *\n */\nexport default class ProductOptionFilters {\n static SELECTORS = {\n OPTION: '[data-cmp-hook=\"checkbox-filter-input\"]'\n }\n\n constructor(element, { filters = {}, onFilterSelect = noop }) {\n this.element = element\n this.filters = filters\n this.onFilterSelect = onFilterSelect\n\n this.init()\n }\n\n init() {\n this.template = template({\n filters: this.filters\n })({\n getNode: true\n })\n\n this.cacheDom()\n this.attachEvents()\n this.render()\n }\n\n /**\n * Cache DOM elements\n */\n cacheDom() {\n this.optionEls = this.template.querySelectorAll(\n ProductOptionFilters.SELECTORS.OPTION\n )\n }\n\n /**\n * Attach events to the component\n */\n attachEvents() {\n this.optionEls.forEach((optionEl) => {\n optionEl.addEventListener('change', this.onFilterSelectHandler)\n })\n }\n\n /**\n * Detach events from the component\n */\n detachEvents() {\n this.optionEls.forEach((optionEl) => {\n optionEl.removeEventListener('change', this.onFilterSelectHandler)\n })\n }\n\n /**\n * Event handler for when a filter option is selected to invoke the\n * onFilterSelect callback with selected filter option data\n * @param {Event} event - Change event object\n */\n onFilterSelectHandler = (event) => {\n const { target } = event\n const { dataset, value, checked } = target\n\n if (typeof this.onFilterSelect === 'function') {\n this.onFilterSelect({\n filterId: dataset?.filterId,\n optionValue: value,\n isSelected: checked\n })\n }\n }\n\n /**\n * Render the component\n */\n render() {\n this.element.appendChild(this.template)\n }\n\n}\n","import html from 'utilities/html'\n\n/**\n * Template for the checkbox item\n * @param {Object} param\n * @param {Object} param.filter - The filter object\n * @returns\n */\nconst checkboxItemTemplate = ({ filter }) => {\n return html`\n
    \n \n \n
    \n `()\n}\n\n/**\n * Template for the ProductOptionFilters component that renders a groupd of filters\n * @param {Object} param\n * @param {Object} param.option - The option group object to display\n */\nconst template = ({ filters }) => {\n return html`\n
    \n \n \n ${filters.label}\n \n ${filters?.filterOptions.map((filter) => {\n switch (filter.type) {\n case 'checkbox':\n return checkboxItemTemplate({ filter })\n default:\n return ''\n }\n })}\n \n
    \n`}\n\nexport default template\n","import { insert } from 'utilities/renderer'\nimport template from './ProductOptions.template'\nimport ProductOptionGroup from '../ProductOptionGroup/ProductOptionGroup'\nimport ProductOptionFilters from '../ProductOptionFilters/ProductOptionFilters'\nimport Services from 'services'\n\n/**\n * ProductOptions component responsible for rendering all of the product options for a product,eg. Glass, Color, Size, etc.\n * @param {HTMLElement} element - the element to render the component in\n * @param {Object} options - the options for the component\n * @param {Array} options.options - the options for the product\n * @param {Object} options.productModel - the product model\n */\nexport default class ProductOptions {\n static SELECTORS = {\n PRODUCT_OPTION_FILTERS: '[data-cmp-hook=\"product-option-filters\"]',\n PRODUCT_OPTION_WRAPPER: '[data-cmp-hook=\"product-option-wrapper\"]',\n PRODUCT_OPTION_MESSAGE: '.mod-product-options__message',\n PRODUCT_OPTION_MESSAGE_ICON: '.mod-product-options__message-icon',\n PRODUCT_OPTION_MESSAGE_TEXT: '.mod-product-options__message-text'\n }\n\n static CLASSES = {\n OPTION: 'mod-product-options__item',\n FILTER_OPTION: 'mod-product-options__filter-item',\n MESSAGE_ACTIVE: 'mod-product-options__message--active'\n }\n\n constructor(element, { filters = {}, options = [], productModel } = {}) {\n this.element = element\n this.productOptions = {}\n this.productModel = productModel\n this.options = options\n this.filters = filters\n this.services = Services.getInstance()\n this.init()\n }\n\n init() {\n this.template = template()({\n getNode: true\n })\n\n this.cacheDom()\n this.createProductOptions()\n this.createOptionFilters()\n this.attachEvents()\n this.render()\n }\n\n /**\n * Cache the DOM elements for the ProductOptions component.\n */\n cacheDom() {\n this.productOptionFilterItemsEl = this.template.querySelector(\n ProductOptions.SELECTORS.PRODUCT_OPTION_FILTERS\n )\n\n this.productOptionWrapperEl = this.template.querySelector(\n ProductOptions.SELECTORS.PRODUCT_OPTION_WRAPPER\n )\n\n this.productOptionMessageTextEl = this.template.querySelector(\n ProductOptions.SELECTORS.PRODUCT_OPTION_MESSAGE_TEXT\n )\n\n this.productOptionMessageEl = this.template.querySelector(\n ProductOptions.SELECTORS.PRODUCT_OPTION_MESSAGE\n )\n }\n\n /**\n * Attach events to the ProductOptions component.\n */\n attachEvents() {\n this.productModel.addEventListener(this.onModelUpdate)\n }\n\n /**\n * Detach events from the ProductOptions component.\n */\n detachEvents() {\n this.productModel.removeEventListener(this.onModelUpdate)\n }\n\n /**\n * Destroy ProductOptions component.\n */\n destroy() {\n this.detachEvents()\n }\n\n /**\n * Create all of the product option filters\n */\n createOptionFilters() {\n const { context: { filters = {} } = {} } =\n this.productModel.getState()\n\n if (filters?.filterOptions?.length > 0) {\n const el = document.createElement('div')\n\n this.productOptionFilterItemsEl.appendChild(el)\n el.classList.add(ProductOptions.CLASSES.FILTER_OPTION)\n this.productFilterOptions = new ProductOptionFilters(el, {\n filters,\n onFilterSelect: this.onFilterSelect\n })\n }\n }\n\n /**\n * Create all of the product options\n */\n createProductOptions() {\n const { context: { pendingOptions = [], optionTools } = {} } =\n this.productModel.getState()\n\n pendingOptions.forEach((option) => {\n const el = document.createElement('div')\n\n this.productOptionWrapperEl.appendChild(el)\n el.classList.add(ProductOptions.CLASSES.OPTION)\n this.productOptions[option.value] = new ProductOptionGroup(el, {\n option,\n optionTools,\n onProductSelect: this.onProductSelect,\n onProductSubmit: this.onProductSubmit,\n onProductCancel: this.onProductCancel\n })\n })\n }\n\n /**\n * Set the product option message based on if the product options have been modified\n */\n setProductOptionMessage() {\n const { context: { hasModifiedSelectedOption, optionMessages } } = this.productModel.getState()\n const message = hasModifiedSelectedOption && optionMessages?.modifiedOption ? optionMessages.modifiedOption : ''\n\n if (hasModifiedSelectedOption) {\n this.productOptionMessageEl.classList.add(ProductOptions.CLASSES.MESSAGE_ACTIVE)\n } else {\n this.productOptionMessageEl.classList.remove(ProductOptions.CLASSES.MESSAGE_ACTIVE)\n }\n\n this.productOptionMessageTextEl.innerHTML = message\n }\n\n /**\n * Event handler for when a product option filter is selected\n * @param {Object} event\n * @param {String} event.filterId - The id of the filter\n * @param {String} event.optionValue - The value of the filter option\n * @param {Boolean} event.isSelected - Whether or not the filter option is selected\n */\n onFilterSelect = (event) => {\n const { filterId, optionValue, isSelected } = event\n\n this.productModel.setFilter({\n filter: {\n filterId,\n optionValue,\n isSelected\n }\n })\n }\n\n /**\n * Event handler for when a product option is selected\n * @param {Object} event\n * @param {String} event.groupValue - The value of the product option group\n * @param {String} event.categoryValue - The value of the product option category\n * @param {String} event.optionValue - The value of the product option\n * @param {Boolean} event.isSelected - Whether or not the product option is selected\n */\n onProductSelect = (event) => {\n const { groupValue, categoryValue, optionValue, isSelected } = event\n const autoApply =\n this.services.BreakpointListener.getCurrentBreakpoint().MEDIUM_LARGE\n\n // Note: this is where we would update the product model if the product options changed\n this.productModel.setOption(\n {\n groupValue,\n categoryValue,\n optionValue,\n isSelected\n },\n autoApply\n )\n }\n\n /**\n * Event handler for when a product option selection is submitted to\n * apply the product options to the product model\n */\n onProductSubmit = () => {\n this.productModel.applyOptions()\n }\n\n /**\n * Event handler for when a product option selection is cancelled to\n * reset the product model to the last applied state\n */\n onProductCancel = () => {\n this.productModel.cancelOptions()\n }\n\n /**\n * Event handler for when the product model is updated\n * @param {Object} state - The state object from XState\n * @param {Object} event - The event object from XState\n */\n onModelUpdate = (state, event) => {\n if (\n event.type === 'UPDATE_OPTIONS' ||\n event.type === 'APPLY_OPTIONS' ||\n event.type === 'CANCEL_OPTIONS'\n ) {\n const { context: { pendingOptions = [] } = {} } = state\n const autoApply = event?.data?.autoApply || event.type === 'APPLY_OPTIONS'\n\n Object.keys(this.productOptions).forEach((key) => {\n const optionGroup = pendingOptions.find(\n (option) => option.value === key\n )\n\n this.productOptions[key].setSelectedOptions(optionGroup, autoApply)\n })\n\n\n }\n\n if (event.type === 'APPLY_OPTIONS' || (event.type === 'UPDATE_OPTIONS' && event?.data?.autoApply)) {\n this.setProductOptionMessage()\n }\n }\n\n /**\n * Render the ProductOptions component in the DOM.\n */\n render() {\n insert(this.template, this.element)\n }\n}\n","import html from 'utilities/html'\nimport textTemplate, { TYPES as TEXT_TYPES } from 'foundation/Text/Text.template'\nimport iconTemplate from 'foundation/Icon/Icon.template'\n\nconst template = () =>\n html`\n
    \n
    \n ${iconTemplate({\n icon: 'alert-circle', addClassName: 'mod-product-options__message-icon'\n })}\n ${textTemplate({\n addClassName: 'mod-product-options__message-text',\n tag: 'p',\n text: '',\n textType: TEXT_TYPES.CALLOUT\n })}\n
    \n
    \n \n \n `\n\nexport default template\n","import html from 'utilities/html'\nimport Icon from 'foundation/Icon/Icon.template'\n\nconst template = ({ product, share, pinterest, copy, copySuccess } = {}) =>\n html`\n
    \n
    \n \n ${Icon({\n addClassName: 'mod-product-share__tooltip-icon',\n icon: 'share'\n })}\n ${share.label}\n \n \n
      \n
    • \n \n ${Icon({\n addClassName:\n 'mod-product-share__item-icon mod-product-share__item-icon--pinterest',\n icon: 'social-pinterest'\n })}\n ${pinterest.label}\n \n
    • \n
    • \n \n ${Icon({\n addClassName: 'mod-product-share__item-icon',\n icon: 'link'\n })}\n ${copy.label}\n \n \n ${Icon({\n addClassName:\n 'mod-product-share__item-icon mod-product-share__item-icon--success',\n icon: 'check-circle'\n })}\n \n ${copySuccess.label}\n \n
    \n \n \n
    \n \n \n `\n\nexport default template\n","/*\n * Load Dependency: Load a dependency script and call a callback when it's loaded\n * @param {string} urlPath\n * @param {function} onComplete\n */\nconst scripts = []\n\nexport function loadDependency(urlPath, onComplete) {\n if (scripts.includes(urlPath)) {\n onComplete(true)\n return\n }\n\n const headElm = document.querySelector('head')\n const script = document.createElement('script')\n script.src = urlPath\n script.defer = true\n\n script.onload = function onDependencyLoad() {\n onComplete(true)\n scripts.push(urlPath)\n }\n script.onerror = function onDependencyError() {\n onComplete(false)\n }\n\n headElm.appendChild(script)\n}\n","import { insert } from 'utilities/renderer'\nimport template from './ProductShare.template'\nimport tippy from 'tippy.js'\nimport { loadDependency } from 'utilities/scriptLoader'\nimport Analytics from 'services/Analytics/Analytics'\n\n/**\n * ProductShare component responsible for sharing a product\n * Note: sub-components should be created for each share method (e.g. copy link, pinterest, etc.)\n */\nexport default class ProductShare {\n static SELECTORS = {\n shareTooltip: '[data-cmp-hook=\"share-tooltip\"]',\n shareCopy: '[data-cmp-hook=\"share-copy\"]',\n sharePinterest: '[data-cmp-hook=\"share-pinterest\"]',\n successMessage: '[data-cmp-hook=\"share-success-message\"]'\n }\n\n /**\n *\n * @param {*} element\n * @param {Object} props\n * @param {Object} props.product\n * @param {Object} props.product.sku - Product sku\n * @param {Object} props.product.collection - Product collection name\n * @param {Object} props.product.media - Product media\n * @param {Object} props.product.media.src - Product media url\n * @param {Object} props.product.media.alt - Product media alt\n * @param {Object} props.product.url - Product url\n * @param {Object} props.content - Product tools content\n * @param {Object} props.content.share - Product share content\n * @param {Object} props.content.pinterest - Product Pinterest content\n * @param {Object} props.content.copy - Product copy content\n * @param {Object} props.content.copySuccess - Product copy success content\n */\n constructor(element, { product = {}, content = {} } = {}) {\n this.element = element\n this.product = product\n this.content = content\n this.analyticsService = Analytics.getInstance()\n this.init()\n }\n\n init() {\n this.template = template({\n product: this.product,\n share: this.content.share,\n pinterest: this.content.pinterest,\n copy: this.content.copy,\n copySuccess: this.content.copySuccess\n })({\n getNode: true\n })\n this.cacheDom()\n this.attachEvents()\n this.createTooltip()\n this.loadPinterestScript()\n this.render()\n }\n\n /**\n * Cache the dom refs needed for the component\n */\n cacheDom() {\n this.shareTooltip = this.template.querySelectorAll(\n ProductShare.SELECTORS.shareTooltip\n )\n\n this.shareCopy = this.template.querySelector(\n ProductShare.SELECTORS.shareCopy\n )\n\n this.sharePinterest = this.template.querySelector(\n ProductShare.SELECTORS.sharePinterest\n )\n\n this.successMessage = this.template.querySelector(\n ProductShare.SELECTORS.successMessage\n )\n }\n\n /**\n * Attach the events needed for the component\n */\n attachEvents() {\n this.shareCopy.addEventListener('click', this.copyHandler)\n }\n\n /**\n * Detach the events needed for the component\n */\n detachEvents() {\n this.shareCopy.removeEventListener('click', this.copyHandler)\n\n if (this.isPinterestLoaded && window.PinUtils) {\n this.sharePinterest.removeEventListener('click', this.onPinterestClick)\n }\n }\n\n /**\n * Destroy the carousel instance and remove event listeners\n */\n destroy() {\n this.detachEvents()\n }\n\n /**\n * Copy URL from data-uri attribute for product\n * After copying link and showing a success message,\n * set a timeout to re-show the copy link\n */\n copyHandler = () => {\n const url = this.shareCopy.dataset.url\n\n navigator.clipboard.writeText(url).then(() => {\n if (this.successMessage.hasAttribute('hidden')) {\n this.showSuccessMessage()\n this.trackShare('copy')\n setTimeout(() => {\n this.showShareCopy()\n }, 5000)\n }\n })\n }\n\n /**\n * Show the copy link and hide the success message\n */\n showShareCopy() {\n this.shareCopy.removeAttribute('hidden')\n this.successMessage.setAttribute('hidden', '')\n }\n\n /**\n * Show the success message and hide the copy link\n */\n showSuccessMessage() {\n this.shareCopy.setAttribute('hidden', '')\n this.successMessage.removeAttribute('hidden')\n }\n\n /**\n * Create the tooltip to house the share options\n */\n createTooltip() {\n this.shareTooltip.forEach((tooltipEl, i) => {\n const tooltipContent = this.template.querySelector(\n '.js-tooltip-share-content'\n )\n\n tippy(tooltipEl, {\n allowHTML: true,\n content: tooltipContent,\n animateFill: true,\n interactive: true,\n placement: 'bottom',\n trigger: 'click'\n })\n })\n }\n\n /**\n * Load Pinterest script using the loadDependency utility\n */\n loadPinterestScript() {\n loadDependency(\n '//assets.pinterest.com/js/pinit_main.js',\n this.onPinterestLoaded\n )\n }\n\n /*\n * If the dependency is loaded and the window.PinUtils is available call onPinterestClick\n */\n onPinterestLoaded = (isLoaded) => {\n this.isPinterestLoaded = isLoaded\n\n if (this.isPinterestLoaded && window.PinUtils) {\n this.sharePinterest.addEventListener('click', this.onPinterestClick)\n }\n }\n\n /**\n * Call the PinUtils.pinOne method to share the product to Pinterest\n */\n onPinterestClick = (event) => {\n event.preventDefault()\n\n window.PinUtils.pinOne({\n url: this.product.url,\n media: this.product.media.src,\n description: this.product.collection\n })\n\n this.trackShare('pinterest')\n }\n\n /**\n * Track sharing clicks\n * @param {String} type - Sharing action type\n */\n trackShare = (type) => {\n this.analyticsService.trackInteraction('product_shares', {\n product_name: this.product.collection,\n product_share_type: type\n })\n }\n\n /**\n * Render the component\n */\n render() {\n insert(this.template, this.element)\n }\n}\n","import { insert } from 'utilities/renderer'\nimport template from './ProductTools.template'\nimport ProductSave from './components/ProductSave/ProductSave'\nimport ProductShare from './components/ProductShare/ProductShare'\n\n/**\n * ProductTools component responsible for rendering the ProductSave and ProductShare components\n */\nexport default class ProductTools {\n static SELECTORS = {\n PRODUCT_SAVE: '[data-cmp-hook=\"product-save\"]',\n PRODUCT_SHARE: '[data-cmp-hook=\"product-share\"]'\n }\n\n /**\n *\n * @param {Element} element - DOM element to render the component in\n * @param {Object} props\n * @param {Object} props.product\n * @param {Object} props.product.sku - Product sku\n * @param {Object} props.product.collection - Product collection name\n * @param {Object} props.product.media - Product media\n * @param {Object} props.product.media.src - Product media url\n * @param {Object} props.product.media.alt - Product media alt)\n * @param {Object} props.product.url - Product url\n * @param {Object} props.product.customOptions - Product options\n * @param {Object} props.content - Product tools content\n * @param {Object} props.content.save - Product save content\n * @param {Object} props.content.saved - Product saved content\n * @param {Object} props.content.savedSuccess - Product saved success content\n * @param {Object} props.content.share - Product share content\n * @param {Object} props.content.pinterest - Product pinterest content\n * @param {Object} props.content.copy - Product copy content\n * @param {Object} props.content.copySuccess - Product copu success content\n */\n constructor(element, { product = {}, content = {} } = {}) {\n this.element = element\n this.product = product\n this.content = content\n this.init()\n }\n\n init() {\n this.template = template({\n product: this.product\n })({\n getNode: true\n })\n\n this.cacheDom()\n this.createProductSave()\n this.createProductShare()\n this.render()\n }\n\n /**\n * Cache the DOM elements for the ProductSave component.\n */\n cacheDom() {\n this.productSaveEl = this.template.querySelector(\n ProductTools.SELECTORS.PRODUCT_SAVE\n )\n\n this.productShareEl = this.template.querySelector(\n ProductTools.SELECTORS.PRODUCT_SHARE\n )\n }\n\n /**\n * Create the ProductSave component\n */\n createProductSave() {\n this.productSave = new ProductSave(this.productSaveEl, {\n product: this.product,\n content: this.content,\n isButton: true,\n showCta: true\n })\n }\n\n /**\n * Create the ProductShare component\n */\n createProductShare() {\n this.productShare = new ProductShare(this.productShareEl, {\n product: this.product,\n content: {\n share: this.content.share,\n pinterest: this.content.pinterest,\n copy: this.content.copy,\n copySuccess: this.content.copySuccess\n }\n })\n }\n\n /**\n * Render the ProductTools component\n */\n render() {\n insert(this.template, this.element)\n }\n}\n","import html from 'utilities/html'\n\nconst template = () => html`
    \n
    \n
    \n
    `\n\nexport default template\n","import { insert } from 'utilities/renderer'\nimport template from './ProductMediaThumbnails.template'\n\n/**\n * Product Media Thumbnails responsible for rendering the thumbnails and handling the click event\n * @param {HTMLElement} element - DOM element to render the thumbnails\n * @param {Object} args\n * @param {Array} args.mediaGallery\n * @param {Function} args.onSelect - Callback function to be called when a thumbnail is selected with the index of the selected thumbnail\n */\nexport default class ProductMediaThumbnails {\n static SELECTORS = {\n THUMBAIL_BUTTON: '[data-cmp-hook=\"mod-product-media-thumbnail-button\"]'\n }\n\n static CLASSES = {\n THUMBNAIL_ACTIVE: 'mod-product-media-thumbnails__button--active'\n }\n\n constructor(element, { mediaGallery, onSelect } = {}) {\n this.element = element\n this.mediaGallery = mediaGallery\n this.onSelect = onSelect\n this.init()\n }\n\n init() {\n this.template = template({\n mediaGallery: this.mediaGallery\n })({\n getNode: true\n })\n\n this.cacheDom()\n this.attachEvents()\n this.render()\n }\n\n cacheDom() {\n this.thumbnailButtons = Array.from(\n this.template.querySelectorAll(\n ProductMediaThumbnails.SELECTORS.THUMBAIL_BUTTON\n )\n )\n }\n\n attachEvents() {\n this.thumbnailButtons.forEach((button, index) => {\n button.addEventListener('click', this.setActiveThumbnail)\n })\n }\n\n detachEvents() {\n this.thumbnailButtons.forEach((button, index) => {\n button.removeEventListener('click', this.setActiveThumbnail)\n })\n }\n\n /**\n * Set the active thumbnail and call the onSelect callback with the index of the selected thumbnail\n * @param {Event} event - Click event\n */\n setActiveThumbnail = (event) => {\n const { currentTarget } = event\n\n if (\n currentTarget.classList.contains(\n ProductMediaThumbnails.CLASSES.THUMBNAIL_ACTIVE\n )\n ) {\n return\n }\n\n this.thumbnailButtons.forEach((button, index) => {\n button.classList.remove(ProductMediaThumbnails.CLASSES.THUMBNAIL_ACTIVE)\n\n if (button === currentTarget) {\n button.classList.add(ProductMediaThumbnails.CLASSES.THUMBNAIL_ACTIVE)\n\n if (typeof this.onSelect === 'function') {\n this.onSelect(index)\n }\n }\n })\n }\n\n render() {\n insert(this.template, this.element)\n }\n}\n","import html from 'utilities/html'\nimport classNames from 'utilities/classnames'\nimport imageTemplate from 'foundation/Image/Image.template'\nimport playIconTemplate, {\n POSITIONS as PLAY_BUTTON_POSITIONS,\n SIZES as PLAY_BUTTON_SIZES\n} from 'modules/PlayIcon/PlayIcon.template'\n\n/**\n * Product Media Thumbnails Template\n * @param {Object} args\n * @param {Array} args.mediaGallery\n * @param {String} args.mediaGallery[].alt - Alt text for the image\n * @param {String} args.mediaGallery[].poster - Poster image for the video\n * @param {String} args.mediaGallery[].src - Image or video src\n * @param {String} args.mediaGallery[].type - Media type (expected: 'image' or 'video')\n * @returns\n */\nconst template = ({ mediaGallery }) => html`\n
    \n
      \n ${mediaGallery\n .map((mediaItem, index) =>\n html`
    • \n \n ${mediaItem.type === 'video'\n ? playIconTemplate({\n addClassName: 'mod-product-media-thumbnails__play-icon',\n position: PLAY_BUTTON_POSITIONS.CENTER,\n size: PLAY_BUTTON_SIZES.SMALL\n })\n : ''}\n ${imageTemplate({\n addClassName: 'mod-product-media-thumbnails__image',\n defaultSrc:\n mediaItem.type === 'video' ? mediaItem.poster : mediaItem.src,\n mobileSrc:\n mediaItem.type === 'video' ? mediaItem.poster : mediaItem.src,\n altText: mediaItem.alt\n })}\n \n
    • `()\n )\n .join('')}\n
    \n
    \n`\n\nexport default template\n","import { insert } from 'utilities/renderer'\nimport template from './ProductMediaImage.template'\n\n/**\n * Product Media Image responsible for rendering a product image\n * @param {HTMLElement} element - DOM element to render the image to\n * @param {Object} args\n * @param {Object} args.media\n */\nexport default class ProductMediaImage {\n constructor(element, { media } = {}) {\n this.element = element\n this.media = media\n this.init()\n }\n\n init() {\n this.template = template({\n media: this.media\n })({\n getNode: true\n })\n\n this.render()\n }\n\n destroy() {\n this.template.remove()\n }\n\n render() {\n insert(this.template, this.element)\n }\n}\n","import html from 'utilities/html'\nimport classNames from 'utilities/classnames'\nimport imageTemplate from 'foundation/Image/Image.template'\n\n/**\n * Product Media Thumbnails Template\n * @param {Object} args\n * @param {Object} args.media\n * @param {String} args.media.alt - Alt text for the image\n * @param {String} args.media.poster - Poster image for the video\n * @param {String} args.media.src - Image or video src\n * @param {String} args.media.type - Media type (expected: 'image' or 'video')\n * @returns\n */\nconst template = ({ media }) => html`\n \n ${imageTemplate({\n addClassName: 'mod-product-media-image__asset',\n defaultSrc: media.src,\n mobileSrc: media.src,\n altText: media.alt,\n loading: 'eager'\n })}\n \n`\n\nexport default template\n","import { insert } from 'utilities/renderer'\nimport template from './ProductMediaVideo.template'\nimport VideoPlayer from 'modules/VideoPlayer/VideoPlayer'\n\n/**\n * Product Media Video component resonible for rendering video player\n */\nexport default class ProductMediaVideo {\n static SELECTORS = {\n VIDEO_PLAYER: '[data-cmp-is=\"video-player\"]'\n }\n\n constructor(element, { media }) {\n this.element = element\n this.media = media\n this.videoPlayer = null\n\n this.init()\n this.render()\n }\n\n init() {\n this.template = template({\n media: this.media\n })({\n getNode: true\n })\n\n const videoPlayerEl = this.template.querySelector(\n ProductMediaVideo.SELECTORS.VIDEO_PLAYER\n )\n\n this.videoPlayer = new VideoPlayer(videoPlayerEl, {\n ...this.media,\n id: 'product-media-video'\n })\n }\n\n destroy() {\n this.videoPlayer.destroy()\n }\n\n render() {\n insert(this.template, this.element)\n }\n}\n","import html from 'utilities/html'\nimport videoPlayerTemplate, {\n PLAY_BUTTON_POSITIONS\n} from 'modules/VideoPlayer/VideoPlayer.template'\n\n/**\n * Product Media Video Template\n * @param {Object} args\n * @param {Object} args.media\n * @param {String} args.media.alt - Alt text for the image\n * @param {String} args.media.poster - Poster image for the video\n * @param {String} args.media.src - Image or video src\n * @param {String} args.media.type - Media type (expected: 'image' or 'video')\n * @returns\n */\nconst template = ({ media }) => html`\n
    \n ${videoPlayerTemplate({\n hidePlayButtonAfterPlay: true,\n playButtonPosition: PLAY_BUTTON_POSITIONS.CENTER,\n playsInline: true,\n posterSrc: media.poster,\n showPlayButton: true,\n videoSrc: media.src\n })}\n
    \n`\n\nexport default template\n","import html from 'utilities/html'\nimport modalTemplate from 'modules/Modal/Modal.template'\n\n// eslint-disable-next-line no-unused-vars\n\nconst modalContent = (data) => html`\n
    \n ${data?.visualizer?.arModalMessage ? data?.visualizer?.arModalMessage : ''}\n
    \n \n
    \n
    \n`\n\n/**\n * Product Media Visualizer Template\n * @returns\n */\nconst template = (data) => html`
    \n ${modalTemplate({\n defaultOpen: false,\n hasHeader: false,\n id: 'custom-visualizer-modal',\n modalClass: 'mod-product-media-visualizer__modal',\n children: modalContent(data)()\n })}\n
    `\n\nexport default template\n","import { insert } from 'utilities/renderer'\nimport template from './ProductMediaVisualizer.template'\nimport Analytics from 'services/Analytics/Analytics'\nimport Services from 'services'\nimport Modal from '../../../Modal/Modal'\n\n/**\n * Product Media Visualizer responsible for rendering a ThreeKit visualizer player\n * and methods to set the door configuration and backplate scene\n * @param {HTMLElement} element - DOM element to render the image to\n * @param {Object} args\n * @param {Object} args.productModel - Product model\n */\nexport default class ProductMediaVisualizer {\n static CLASSES = {\n HIDE: 'mod-product-media-visualizer--hidden',\n VISUALIZER_BUTTON: 'mod-product-media-visualizer__ar-button'\n }\n\n static SELECTORS = {\n MODAL: '[data-cmp-is=\"modal\"]'\n }\n\n constructor (element, { productModel } = {}) {\n this.element = element\n this.productModel = productModel\n this.initialData = this.getInitialData()\n this.hasDependency = false\n this.focusableElements = []\n this.services = Services.getInstance()\n this.EventEmitterService = this.services.EventEmitterService\n this.analyticsService = Analytics.getInstance()\n\n this.loadDependency().then(() => {\n this.init()\n })\n }\n\n /**\n * Initialize the component by creating the template, attaching events and rendering the component\n */\n init () {\n this.template = template(this.initialData)({\n getNode: true\n })\n\n this.cacheDom()\n this.createPlayer()\n this.attachEvents()\n this.render()\n this.setupButtonClone()\n }\n\n isMobileDevice () {\n const userAgent = navigator.userAgent || window.opera\n\n // Regular expressions to match common mobile and tablet devices\n const phonePattern = /Mobi|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Windows Phone/i\n const tabletPattern = /Tablet|iPad|PlayBook|Silk|Kindle|KFTT|KFOT|KFJWI|KFJWA|KFOT/i\n\n return phonePattern.test(userAgent) || tabletPattern.test(userAgent)\n }\n\n setupButtonClone () {\n const checkForButton = () => {\n const arButton = this.template.querySelector('button[data-id=\"arButton\"]')\n\n if (arButton) {\n let newButton = this.template.querySelector('button[data-id=\"arButtonClone\"]')\n\n // Only create and insert the newButton if it doesn't already exist\n if (!newButton) {\n newButton = arButton.cloneNode(true)\n newButton.setAttribute('data-id', 'arButtonClone') // Add an ID to the newButton\n if (this.isMobileDevice()) {\n newButton.addEventListener('click', () => {\n this.setupModal()\n })\n\n arButton.parentNode.insertBefore(newButton, arButton)\n arButton.style.display = 'none'\n }\n }\n } else {\n requestAnimationFrame(checkForButton)\n }\n }\n\n // Start checking for the button\n requestAnimationFrame(checkForButton)\n }\n\n addEventListeners () {\n const viewDoorButton = document.querySelector('.mod-product-media-visualizer__button')\n const arButton = this.template.querySelector('button[data-id=\"arButton\"]')\n\n if (viewDoorButton) {\n viewDoorButton.addEventListener('click', (e) => {\n if (this.isMobileDevice()) {\n e.preventDefault()\n arButton.click()\n this.onVisualizerButtonClick()\n this.onModalClose(this.modalEl.id)\n }\n })\n }\n }\n\n cacheDom () {\n this.modalEl = this.template.querySelector(\n ProductMediaVisualizer.SELECTORS.MODAL\n )\n }\n\n getInitialData () {\n if (!window.masonite?.pip) {\n console.error(\n 'No initial data was found for the ProductInformation component. Please add the data to the window.masonite.pip object.'\n )\n return {}\n }\n\n return typeof window.masonite.pip === 'string'\n ? JSON.parse(window.masonite.pip)\n : window.masonite.pip\n }\n\n onModalClose = (modalId) => {\n if (modalId === this.modalEl.id) {\n this.modal?.destroy()\n }\n\n if (document.body.classList.contains('no-scroll')) {\n document.body.classList.remove('no-scroll')\n }\n }\n\n onModalOpen = (modalId) => {\n if (modalId === this.modalEl.id) {\n this.addEventListeners()\n }\n }\n\n /**\n * Attach events to the component.\n */\n attachEvents () {\n this.EventEmitterService.on(Modal.EVENTS.CLOSE_MODAL, this.onModalClose)\n this.productModel.addEventListener(this.onModelUpdate)\n }\n\n /**\n * Detach events from the component.\n */\n detachEvents () {\n this.productModel.removeEventListener(this.onModelUpdate)\n }\n\n /**\n * Attach the visualizer button events\n */\n attachVisualizerButtonEvents = () => {\n this.visualizerButton = this.template.querySelector(\n `.${ProductMediaVisualizer.CLASSES.VISUALIZER_BUTTON}`\n )\n\n if (this.visualizerButton) {\n this.visualizerButton.addEventListener(\n 'click',\n this.onVisualizerButtonClick\n )\n\n if (this.productModel.getState().context.showARModal) {\n if (this.isMobileDevice() === true) {\n this.setupModal()\n }\n }\n }\n }\n\n setupModal () {\n this.modal = new Modal(this.modalEl)\n this.modal.open()\n this.EventEmitterService.on(Modal.EVENTS.OPEN_MODAL, this.onModalOpen)\n }\n\n /**\n * Detach the visualizer button events\n */\n detachVisualizerButtonEvents = () => {\n if (this.visualizerButton) {\n this.visualizerButton.removeEventListener(\n 'click',\n this.onVisualizerButtonClick\n )\n }\n }\n\n /**\n * Destroy the component\n */\n destroy () {\n this.detachEvents()\n this.detachVisualizerButtonEvents()\n this.template.remove()\n }\n\n /**\n * Load the ThreeKit dependency and resolve when loaded\n * @returns {Promise}\n */\n loadDependency () {\n return new Promise((resolve, reject) => {\n if (this.hasDependency) {\n resolve()\n } else {\n const visualizer = this.productModel.getState().context.visualizer\n const headElm = document.querySelector('head')\n const script = document.createElement('script')\n script.src = visualizer.library\n script.defer = true\n\n script.onload = function onDependencyLoad () {\n resolve()\n this.hasDependency = true\n }\n script.onerror = function onDependencyError () {\n reject(new Error('Failed to threekit load dependency'))\n this.hasDependency = false\n }\n\n headElm.appendChild(script)\n }\n })\n }\n\n /**\n * Create the ThreeKit player with the initial configuration\n *\n * Currently, the following doors can be tested (in the whitesweep scene only):\n * DR-SM-WIN-80\n * DR-SM-RIV-80\n * DR-SM-MEL-80\n * DR-SM-LOG-80\n * DR-SM-LIV-80\n * DR-SM-LNP-80\n * DR-SM-CHE-80\n * DR-SM-BER-80\n * DR-SM-6P-80\n * DR-SM-4P-80\n * DR-SM-2P-80\n * DR-SM-2PR-80\n * DR-TX-2PAT-80\n */\n createPlayer () {\n const { visualizer, isInterior } =\n this.productModel.getState().context || {}\n\n window\n .threekitPlayer({\n authToken: visualizer.authToken,\n el: this.template,\n customId: isInterior ? 'InteriorDoorTemplate' : 'ExteriorDoorTemplate', // \"InteriorDoorTemplate\" or \"ExteriorDoorTemplate\"\n display: 'image',\n initialConfiguration: this.getConfiguration(), // Catalog Code of door (salsify:id)\n // configurationId:'',// set when loading Favorites. Use this instead of initialConfiguration. Alternatively Favorites can also be loaded through URL paramater tkcsid\n cache: {\n maxAge: visualizer.cacheMaxAge, // milliseconds\n scope: visualizer.cacheScope // version\n }, // Best practice is to not use cached during development, but to enable at go live\n showConfigurator: false, // No need to show Threekit attributes\n showAR: true, // Show standard visualize button. see below for css\n showShare: false, // this is for standard button. see documentation on custom AR button\n classnames: {\n loading: 'loadingBar', // override css on player loading component\n mobile: 'mobilePlayer', // override css on player in moblie view\n share: { button: 'ShareButton', popup: 'SharePopup' }, // override css on share button and share popup\n ar: {\n button: ProductMediaVisualizer.CLASSES.VISUALIZER_BUTTON,\n popup: 'arPopup'\n }, // override css on Visualize button and Visualize popup\n fullscreen: 'mod-product-media-visualizer__fullscreen-button', // override css on fullscreen button\n help: 'helpButton' // override css on help button\n },\n showLoadingThumbnail: false, // not needed for 2D Player\n showLoadingProgress: false, // Will most likely not be needed for 2D Player. see https://community.threekit.com/hc/en-us/articles/4410044862107-2021-23-0-November-10-2021 for details\n // allowMobileVerticalOrbit // Not needed for 2D player\n // compression //Can be handled at Org level, no need to override\n publishStage: 'published' // prevents unpublished items/options from appearing on front end\n })\n .then(async (player) => {\n this.player = player\n\n // wait for the player to be rendered before setting the configuration\n await player.when('rendered')\n\n this.configurator = await player.getConfigurator() // This configurator will be used to set the door configuration\n this.stageConfigurator = await player.getStageConfigurator() // This configurator will be needed to set the Backplate Attribute\n\n // get a snapshot of the player when the player renders a new image\n this.player.on('rendered', this.getSnapshot)\n\n // give the player a second to render before attaching events to the Visualizer AR button\n setTimeout(this.attachVisualizerButtonEvents, 1000)\n })\n }\n\n /**\n * Convert a hex value to an RGB scale\n * @param {String} hexValue - The hex value to convert\n * @returns {Object} - The RGB scale\n * @example\n * convertHexToRgbScale('808080')\n * // returns { r: 0.5, g: 0.5, b: 0.5 }\n */\n convertHexToRgbScale (hexValue) {\n const r = parseInt(hexValue.substring(0, 2), 16) / 255\n const g = parseInt(hexValue.substring(2, 4), 16) / 255\n const b = parseInt(hexValue.substring(4, 6), 16) / 255\n\n return { r, g, b }\n }\n\n /**\n * Get the configuration values of the door for the visualizer configurator\n */\n getConfiguration () {\n const { sku } = this.productModel.getState().context || {}\n const options = this.productModel.getOptions()\n const disabledOptions = options.filter((option) => option.isDisabled)\n const optionParams = this.productModel.getOptionParams()\n\n const configuration = {\n Door: { customId: sku }\n }\n\n Object.keys(optionParams).forEach((key) => {\n const isDisabledOption = disabledOptions.some((option) => option.value === key)\n\n if (optionParams[key].includes('custom-color-')) {\n configuration.Color = { customId: 'CustomColor' }\n configuration.PaintColorPicker = this.convertHexToRgbScale(\n optionParams[key].replace('custom-color-', '')\n )\n } else if (!isDisabledOption) {\n configuration[key] = { customId: optionParams[key] }\n }\n })\n\n console.log('Visualizer configuration: ', configuration)\n\n return configuration\n }\n\n /**\n * Set the configuration values of the door to the visualizer configurator\n */\n async setConfiguration () {\n await this.configurator.setConfiguration(this.getConfiguration())\n }\n\n /**\n * Set the backplate scene\n * @param {String} sceneId - The scene id to set\n */\n async setScene (sceneId) {\n await this.stageConfigurator.setConfiguration({\n Backplate: { customId: sceneId }\n })\n }\n\n /**\n * Get the snapshot base64 image from the player and set it to the product model\n */\n getSnapshot = async () => {\n const savedScene = await this.player.snapshotAsync({\n mimeType: 'image/webp'\n })\n\n this.productModel.setVisualizerSnapshot(savedScene)\n }\n\n /**\n * Event handler for when the product model is updated to set the door configuration\n */\n onModelUpdate = (state, event) => {\n if (\n event.type === 'APPLY_OPTIONS' ||\n (event.type === 'UPDATE_OPTIONS' && event.data.autoApply)\n ) {\n this.setConfiguration()\n }\n }\n\n /**\n * Visually hide the visualizer and set the focusable elements to be hidden\n */\n hideVisualizer = () => {\n if (!this?.template) {\n return\n }\n\n const focusableElements = this.getFocusableElements()\n this.template.classList.add(ProductMediaVisualizer.CLASSES.HIDE)\n this.template.setAttribute('aria-hidden', true)\n\n focusableElements.forEach((el) => {\n el.setAttribute('tabIndex', -1)\n el.setAttribute('aria-hidden', true)\n el.setAttribute('hiddenTabIndex', true)\n })\n\n // set the scene to the default hero so that when changes are made\n // and saved, the default scene is shown\n this.setScene('hero')\n }\n\n /**\n * Visually show the visualizer and set the focusable elements to be visible\n */\n showVisualizer = () => {\n if (!this?.template) {\n return\n }\n\n const focusableElements = this.getFocusableElements()\n this.template.classList.remove(ProductMediaVisualizer.CLASSES.HIDE)\n this.template.removeAttribute('aria-hidden')\n\n focusableElements.forEach((el) => {\n if (el.hasAttribute('hiddenTabIndex')) {\n el.removeAttribute('tabIndex')\n el.removeAttribute('aria-hidden')\n }\n })\n }\n\n /**\n * Track the click event on the visualizer button\n */\n onVisualizerButtonClick = () => {\n this.analyticsService.trackInteraction('click_visualize')\n }\n\n /**\n * Get all focusable elements in the visualizer\n * @returns\n */\n getFocusableElements () {\n return this.template.querySelectorAll(\n 'a[href], button, input, textarea, select, details, [tabindex]'\n )\n }\n\n /**\n * Render the component\n */\n render () {\n insert(this.template, this.element)\n }\n}\n","import { insert, empty } from 'utilities/renderer'\nimport template from './ProductMediaGallery.template'\nimport ProductTools from 'modules/ProductTools'\nimport ProductMediaThumbnails from './../ProductMediaThumbnails/ProductMediaThumbnails'\nimport ProductMediaImage from './../ProductMediaImage/ProductMediaImage'\nimport ProductMediaVideo from './../ProductMediaVideo/ProductMediaVideo'\nimport ProductMediaVisualizer from './../ProductMediaVisualizer/ProductMediaVisualizer'\nimport Services from 'services'\nimport Analytics from 'services/Analytics/Analytics'\n\n/**\n * ProductMediaGallery component responsible for rendering the ProductMediaThumbnails, ProductMediaImage and ProductMediaVideo components\n */\nexport default class ProductMediaGallery {\n static SELECTORS = {\n THUMBNAILS: '[data-cmp-hook=\"product-media-thumbnails\"]',\n MEDIA: '[data-cmp-hook=\"product-media\"]',\n MEDIA_VISUALIZER: '[data-cmp-hook=\"product-media-visualizer\"]',\n MEDIA_WRAPPER: '[data-cmp-hook=\"product-media-wrapper\"]',\n TOOLS: '[data-cmp-hook=\"product-tools\"]',\n SLOT_1: '[data-cmp-hook=\"product-media-slot-1\"]',\n SLOT_2: '[data-cmp-hook=\"product-media-slot-2\"]'\n }\n\n /**\n *\n * @param {Element} element - DOM element to render the component in\n * @param {Object} props\n * @param {Object} props.productModel - Product model\n */\n constructor(element, { productModel } = {}) {\n this.element = element\n this.productModel = productModel\n this.services = Services.getInstance()\n this.analyticsService = Analytics.getInstance()\n this.mediaQuery = this.services.BreakpointListener.queryMatch\n this.init()\n }\n\n init() {\n const { context } = this.productModel.getState()\n const { mediaGallery } = context\n\n this.template = template()({\n getNode: true\n })\n\n this.cacheDom()\n this.createProductTools()\n this.createThumbnails(mediaGallery)\n this.createMediaPlayer(mediaGallery[0])\n this.attachEvents()\n this.setContentOrder()\n this.render()\n }\n\n /**\n * Cache the DOM elements for the ProductSave component.\n */\n cacheDom() {\n this.thumbnailsEl = this.template.querySelector(\n ProductMediaGallery.SELECTORS.THUMBNAILS\n )\n\n this.mediaEl = this.template.querySelector(\n ProductMediaGallery.SELECTORS.MEDIA\n )\n\n this.mediaVisualizerEl = this.template.querySelector(\n ProductMediaGallery.SELECTORS.MEDIA_VISUALIZER\n )\n\n this.productToolsEl = this.template.querySelector(\n ProductMediaGallery.SELECTORS.TOOLS\n )\n\n this.productMediaWrapperEl = this.template.querySelector(\n ProductMediaGallery.SELECTORS.MEDIA_WRAPPER\n )\n\n this.productMediaSlot1El = this.template.querySelector(\n ProductMediaGallery.SELECTORS.SLOT_1\n )\n\n this.productMediaSlot2El = this.template.querySelector(\n ProductMediaGallery.SELECTORS.SLOT_2\n )\n }\n\n /**\n * Attach events to the product media gallery component.\n */\n attachEvents() {\n this.services.BreakpointListener.addListener(this.onBreakpointChange)\n\n this.productModel.addEventListener(this.onModelUpdate)\n }\n\n /**\n * Create the thumbnails component\n */\n createThumbnails(mediaGallery) {\n this.productMediaThumbnails = new ProductMediaThumbnails(\n this.thumbnailsEl,\n {\n mediaGallery,\n onSelect: this.onThumbnailSelect\n }\n )\n }\n\n /**\n * Create the media player component based on the media type\n * @param {Object} media - Media object\n * @param {String} media.alt - Alt text for the image\n * @param {String} media.poster - Poster image for the video\n * @param {String} media.src - Image or video src\n * @param {String} media.type - Media type (expected: 'image' or 'video')\n *\n */\n createMediaPlayer(media) {\n const { context } = this.productModel.getState()\n const { isVisualizerEnabled } = context\n\n // clean up the media player by removing the current media\n // and hiding the visualizer if it is enabled\n empty(this.mediaEl)\n if (this.mediaVisualizer) {\n this.mediaVisualizer.hideVisualizer()\n }\n\n if (\n media.type === 'image' &&\n (!isVisualizerEnabled || !media.isVisualizer)\n ) {\n this.createMediaImage(media)\n } else if (\n media.type === 'image' &&\n isVisualizerEnabled &&\n media.isVisualizer\n ) {\n this.createMediaVisualizer(media)\n this.mediaVisualizer.showVisualizer()\n } else if (media.type === 'video') {\n this.createMediaVideo(media)\n }\n }\n\n /**\n * Create the media image component\n * @param {Object} media\n */\n createMediaImage(media) {\n if (this.mediaImage) {\n this.mediaImage.destroy()\n }\n\n this.mediaImage = new ProductMediaImage(this.mediaEl, { media })\n }\n\n /**\n * Create the media video component\n * @param {Object} media - Media object\n */\n createMediaVideo(media) {\n if (this.mediaVideo) {\n this.mediaVideo.destroy()\n }\n this.mediaVideo = new ProductMediaVideo(this.mediaEl, { media })\n }\n\n /**\n * Create the media video component\n * @param {Object} media - Media object\n */\n createMediaVisualizer(media) {\n if (this.mediaVisualizer) {\n this.mediaVisualizer.render()\n this.mediaVisualizer.setScene(media?.backplateScene)\n } else {\n this.mediaVisualizer = new ProductMediaVisualizer(\n this.mediaVisualizerEl,\n {\n productModel: this.productModel\n }\n )\n }\n }\n\n /**\n * Create the product tools component\n */\n createProductTools() {\n const { context } = this.productModel.getState()\n const customOptions = this.productModel.getOptionParams()\n const { collection, mediaGallery, sku, tools, visualizerSnapshot } = context\n\n this.productTools = new ProductTools(this.productToolsEl, {\n product: {\n sku,\n collection,\n media: {\n src: {\n defaultSrc: visualizerSnapshot || mediaGallery[0]?.src || ''\n }\n },\n url: window.location.href,\n customOptions\n },\n content: tools\n })\n }\n\n /**\n * Set the content order of the product media component based on the current breakpoint\n * to maintain the proper tab order as the layout reorders.\n */\n setContentOrder() {\n if (this.mediaQuery.MEDIUM) {\n this.productMediaSlot1El.appendChild(this.thumbnailsEl)\n this.productMediaSlot2El.appendChild(this.productMediaWrapperEl)\n } else {\n this.productMediaSlot1El.appendChild(this.productMediaWrapperEl)\n this.productMediaSlot2El.appendChild(this.thumbnailsEl)\n }\n }\n\n /**\n * Update the media query state and set the content order if the breakpoint has changed.\n * @param {*} breakpoint\n */\n onBreakpointChange = (breakpoint) => {\n const hasChanged = breakpoint.MEDIUM !== this.mediaQuery.MEDIUM\n\n this.mediaQuery = breakpoint\n\n if (hasChanged) {\n this.setContentOrder()\n }\n }\n\n /**\n * Handler for when a thumbail is selected\n * @param {*} index\n */\n onThumbnailSelect = (index) => {\n const { context } = this.productModel.getState()\n const { mediaGallery } = context\n\n this.createMediaPlayer(mediaGallery[index])\n this.trackThumbnailClick(mediaGallery[index])\n }\n\n /**\n * Track the thumbnail click\n * @param {Object} media - Media object\n */\n trackThumbnailClick = (media) => {\n if (media && media?.alt) {\n this.analyticsService.trackInteraction('product_gallery', {\n image_title: media?.alt\n })\n }\n }\n\n /**\n * Event handler for when the product model is updated\n * @param {Object} state - The state object from XState\n * @param {Object} event - The event object from XState\n */\n onModelUpdate = (_state, _event) => {\n this.createProductTools()\n }\n\n /**\n * Render the product media gallery component\n */\n render() {\n insert(this.template, this.element)\n }\n}\n","import html from 'utilities/html'\n\n/**\n * Product Media Gallery Template\n */\nconst template = () => html`\n
    \n \n \n \n
    \n \n \n \n \n \n \n \n`\n\nexport default template\n","import textTemplate, {\n TYPES as TEXT_TYPES,\n THEMES as TEXT_THEMES\n} from 'foundation/Text/Text.template'\n\n/**\n * Display features\n * @param {array} features The features to display\n */\nconst displayFeatures = (features) =>\n features && features.length\n ? `\n ${features\n .map(\n (feature) => `\n
  • \n ${textTemplate({\n addClassName: 'mod-product-feature__list-text',\n text: feature,\n textElement: 'p',\n textType: TEXT_TYPES.BODY_LG,\n theme: TEXT_THEMES.LIGHT\n })}\n
  • \n `\n )\n .join('')}\n `\n : ''\n\n/**\n * Display additional features\n * @param {array} features The additional features to display\n */\nconst displayAdditionalFeatures = (features) =>\n features && features.length\n ? `\n ${features\n .map(\n (feature) => `\n
  • \n \n \n \n ${textTemplate({\n addClassName: 'mod-product-feature__additional-element-text',\n text: feature,\n textElement: 'p',\n textType: TEXT_TYPES.BODY_MD,\n theme: TEXT_THEMES.LIGHT\n })}\n
  • \n `\n )\n .join('')}\n `\n : ''\n\nconst productFeaturesTemplate = ({\n description,\n features,\n additionalFeaturesLabel,\n additionalFeatures\n}) => {\n return `\n
    \n
    \n ${textTemplate({\n addClassName: 'mod-product-feature__description-text',\n text: description,\n textElement: 'p',\n textType: TEXT_TYPES.BODY_LG,\n theme: TEXT_THEMES.LIGHT\n })}\n
    \n
      \n ${displayFeatures(features)}\n
    \n
    \n ${\n additionalFeatures && additionalFeatures.length\n ? `\n
    \n ${textTemplate({\n addClassName: 'mod-product-feature__additional-text',\n text: `${additionalFeaturesLabel}:`,\n textElement: 'p',\n textType: TEXT_TYPES.BODY_MD_INLINE,\n theme: TEXT_THEMES.LIGHT\n })}\n
    \n
      \n ${displayAdditionalFeatures(additionalFeatures)}\n
    `\n : ''\n }\n
    \n
    \n `\n // return value\n}\n\nexport default productFeaturesTemplate\n","import html from 'utilities/html'\nimport tabsTemplate from '../../../Tabs/Tabs.template'\nimport productFeaturesTemplate from '../ProductFeatures/ProductFeatures.template'\nimport productSpecificationsTemplate from '../ProductSpecifications/ProductSpecifications.template'\nimport productMeasurementTemplate from '../ProductMeasurement/ProductMeasurement.template'\nimport productDocumentsTemplate from '../ProductDocuments/ProductDocuments.template'\n\n// Map of content templates for each category\nconst contentMap = {\n doorFeatures: productFeaturesTemplate, // Template for door features\n productSpecifications: productSpecificationsTemplate, // Template for product specifications\n measurements: productMeasurementTemplate, // Template for measurements\n technicalDocuments: productDocumentsTemplate // Template for technical documents\n}\n\n// Function to convert the JSON content into an array of product details\nconst generateProductDetails = (details) => {\n return Object.entries(details).map(([key, value]) => {\n const contentFunc = contentMap[key]\n const content = contentFunc ? contentFunc(value) : ''\n const { label } = value\n\n return {\n id: key,\n title: label,\n content\n }\n })\n}\n\nconst template = ({ details = {} }) => {\n const productDetails = generateProductDetails(details)\n\n return html`\n
    \n
    \n ${\n Array.isArray(productDetails) && productDetails.length > 1\n ? tabsTemplate({\n id: 'product-details-categories',\n fullWidth: true,\n tabs: productDetails\n })\n : ''\n }\n
    \n
    \n \n `\n}\nexport default template\n","import textTemplate, {\n TYPES as TEXT_TYPES\n} from 'foundation/Text/Text.template'\nimport Icon from 'foundation/Icon/Icon.template'\n\nconst productSpecificationsTemplate = ({ specs }) => {\n return `\n
    \n \n ${specs\n .map(\n ({ label, value, tooltip }) => `\n \n \n \n \n `\n )\n .join('')}\n
    \n
    \n ${textTemplate({\n text: label,\n textElement: 'p',\n textType: TEXT_TYPES.BODY_MD_INLINE,\n addClassName: 'mod-product-specs__label'\n })}\n ${\n tooltip && label !== ''\n ? `\n \n \n ${tooltip}\n ${Icon({\n addClassName: 'cmp-tooltip__svg',\n icon: 'info'\n })}\n \n \n ${textTemplate({\n text: tooltip,\n textElement: 'p',\n textType: TEXT_TYPES.BODY_SM,\n addClassName: 'cmp-tooltip__text'\n })}\n
    \n \n `\n : ''\n }\n \n
    \n ${textTemplate({\n text: value,\n textElement: 'p',\n textType: TEXT_TYPES.BODY_MD,\n addClassName: 'mod-product-specs__value'\n })}\n
    \n
    \n `\n}\n\nexport default productSpecificationsTemplate\n","import textTemplate, {\n TYPES as TEXT_TYPES,\n THEMES as TEXT_THEMES\n} from 'foundation/Text/Text.template'\nimport linkTemplate from 'foundation/Link/Link.template'\n\nconst productMeasurementTemplate = ({\n measurementText,\n measurementLink,\n measurementLinkText,\n widthLabel,\n heightLabel,\n widths,\n heights,\n available\n}) => {\n return /* HTML */ `\n
    \n ${measurementText && measurementText !== ''\n ? `\n
    \n ${textTemplate({\n addClassName: 'mod-product-measurement__description-text',\n text: measurementText,\n textElement: 'p',\n textType: TEXT_TYPES.BODY_LG\n })}\n ${\n measurementLink && measurementLink !== ''\n ? `\n
    \n ${linkTemplate({\n href: measurementLink,\n label: measurementLinkText,\n linkSize: 'link-small',\n linkStyle: 'link-style-text',\n showAsButtonLink: false,\n showAsTextLink: true\n })}\n
    `\n : ''\n }\n
    `\n : ''}\n
    \n ${textTemplate({\n addClassName: 'mod-product-measurement__legend-height-text',\n text: heightLabel,\n textElement: 'p',\n textType: TEXT_TYPES.EYEBROW,\n theme: TEXT_THEMES.LIGHT\n })}\n
    \n\n
    \n
    \n ${textTemplate({\n addClassName: 'mod-product-measurement__legend-width-text',\n text: widthLabel,\n textElement: 'p',\n textType: TEXT_TYPES.EYEBROW,\n theme: TEXT_THEMES.LIGHT\n })}\n
    \n
    \n \n \n \n \n ${heights\n .map(\n (height) =>\n ``\n )\n .join('')}\n \n \n\n \n ${widths\n .map(\n (width) => `\n \n \n ${heights\n .map((height) => {\n const cell = available.includes(\n `${width.replace(/\"/g, '')}-x-${height.replace(\n /\"/g,\n ''\n )}`\n )\n ? `
    \n
    \n
    \n `\n : `
    \n
    \n
    `\n return ``\n })\n .join('')}\n \n `\n )\n .join('')}\n \n
    \n ${textTemplate({\n text: height,\n textElement: 'p',\n textType: TEXT_TYPES.BODY_MD,\n theme: TEXT_THEMES.LIGHT\n })}\n
    \n ${textTemplate({\n text: width,\n textElement: 'p',\n textType: TEXT_TYPES.BODY_MD,\n theme: TEXT_THEMES.LIGHT\n })}\n ${cell}
    \n
    \n
    \n
    \n `\n}\n\nexport default productMeasurementTemplate\n","import linkTemplate from 'foundation/Link/Link.template'\n/**\n * Display additional documents\n * @param {array} documents The additional documents to display\n */\nconst displayDocumentsLinks = (documents) =>\n documents && documents.length\n ? `\n ${documents\n .map(\n ({ label, url }) => `\n
  • \n ${linkTemplate({\n accessibilityLabel: label,\n href: url,\n label,\n linkSize: 'link-large',\n linkStyle: 'link-style-text',\n showAsButtonLink: false,\n showAsTextLink: false,\n showAsDownloadLink: true,\n target: '_blank',\n analytics: {\n event: 'file_download',\n file_extension: 'pdf',\n file_name: label,\n click_url: url\n }\n })}\n
  • \n `\n )\n .join('')}\n `\n : ''\n\nconst productDocumentsTemplate = ({ documents }) => {\n return `\n
      \n ${displayDocumentsLinks(documents)}\n
    `\n}\n\nexport default productDocumentsTemplate\n","import { insert } from 'utilities/renderer'\nimport template from './ProductDetails.template'\nimport Tabs from 'modules/Tabs'\nimport tippy from 'tippy.js'\n\nexport default class ProductDetails {\n static SELECTORS = {\n TABS: '[data-cmp-hook=\"product-details-tabs\"]',\n TABS_CMP: '[data-cmp-is=\"tabs\"]',\n DOOR_FEATURES: '[data-cmp-hook=\"product-door-features\"]',\n PRODUCT_SPECIFICATIONS: '[data-cmp-hook=\"product-specifications\"]',\n MEASUREMENTS: '[data-cmp-hook=\"product-measurements\"]',\n TECHNICAL_DOCUMENTS: '[data-cmp-hook=\"product-technical-documents\"]',\n TOOLTIP: '[data-cmp-hook=\"tooltip\"]'\n }\n\n constructor(element, { details = {} } = {}) {\n this.tabs = null // reference to tabs component\n this.element = element\n this.details = details\n this.init()\n }\n\n init() {\n this.template = template({\n details: this.details\n })({\n getNode: true\n })\n this.cacheDom()\n this.render()\n this.createTabs()\n this.createTooltips()\n }\n\n cacheDom() {\n this.tabsEl = this.template.querySelector(ProductDetails.SELECTORS.TABS)\n this.doorFeaturesEl = this.template.querySelector(\n ProductDetails.SELECTORS.DOOR_FEATURES\n )\n this.productSpecificationsEl = this.template.querySelector(\n ProductDetails.SELECTORS.PRODUCT_SPECIFICATIONS\n )\n this.measurementsEl = this.template.querySelector(\n ProductDetails.SELECTORS.MEASUREMENTS\n )\n this.technicalDocumentsEl = this.template.querySelector(\n ProductDetails.SELECTORS.TECHNICAL_DOCUMENTS\n )\n this.tooltip = this.template.querySelectorAll(\n ProductDetails.SELECTORS.TOOLTIP\n )\n }\n\n /**\n * @todo Implement this method\n */\n createTabs() {\n const productDetailsCategories = Object.keys(this.details)\n const tabsCmpEl = this.tabsEl.querySelector(\n ProductDetails.SELECTORS.TABS_CMP\n )\n if (tabsCmpEl && productDetailsCategories.length > 1) {\n this.tabs = new Tabs(tabsCmpEl)\n }\n }\n\n createTooltips() {\n this.tooltip.forEach((tooltipEl, i) => {\n const tooltipContent = tooltipEl.querySelector('.js-tooltip-content')\n\n tippy(tooltipEl, {\n allowHTML: true,\n content: tooltipContent,\n animateFill: true,\n interactive: true,\n placement: 'auto',\n trigger: 'click'\n })\n })\n }\n\n /**\n * Destroy the component\n */\n destroy() {\n if (this.tabs) {\n this.tabs.destroy()\n }\n }\n\n render() {\n insert(this.template, this.element)\n }\n}\n","import { insert } from 'utilities/renderer'\nimport template from './ProductRelatedContent.template'\n\n/**\n * Component for the Product Related Articles Content\n */\nexport default class ProductRelatedContent {\n /**\n * @param {Element} element - The element to render the component in\n * @param {Object} props\n * @param {string} props.content - The content markup to display in the component\n */\n constructor(element, { content = '' } = {}) {\n this.element = element\n this.content = content\n this.init()\n }\n\n init() {\n this.template = template({\n id: this.id\n })({\n getNode: true\n })\n\n this.template.innerHTML = this.content\n this.render()\n }\n\n render() {\n insert(this.template, this.element)\n }\n}\n","import html from 'utilities/html'\n\nconst template = () =>\n html` `\n\nexport default template\n","import { createMachine, assign, interpret } from 'xstate'\n\n/**\n * ProductInformationModel responsible for managing the state of the ProductInformation module\n */\nexport default class ProductInformationModel {\n /**\n *\n * @param {Object} props\n * @param {Object} props.initialState - The initial state of the state machine\n * @param {Object} props.queryFilters - The url query param filters to parse\n * @param {Object} props.queryOptions - The url query param options to parse\n */\n constructor({ initialState, queryFilters = {}, queryOptions = {} }) {\n this.listeners = []\n this.initialState = this.parseInitialData({ initialState, queryFilters, queryOptions })\n\n console.log('initialState', this.initialState)\n\n this.machine = createMachine(\n {\n id: 'productInformation',\n initial: 'idle',\n context: {\n ...this.initialState,\n visualizerSnapshot: null,\n pendingOptions: [...this.initialState.options]\n },\n states: {\n idle: {\n on: {\n UPDATE_FILTERS: {\n actions: 'updateFilters'\n },\n UPDATE_OPTIONS: {\n actions: 'updateOptions'\n },\n APPLY_OPTIONS: {\n actions: 'applyOptions'\n },\n CANCEL_OPTIONS: {\n actions: 'cancelOptions'\n },\n SET_VISUALIZER_SNAPSHOT: {\n actions: 'setVisualizerSnapshot'\n }\n }\n }\n }\n },\n {\n actions: {\n updateFilters: assign((context, event) => ({\n ...context,\n filters: event.data.updatedFilters,\n })),\n updateOptions: assign((context, event) => ({\n ...context,\n hasModifiedSelectedOption: event.data.updatedOptions.meta.hasModifiedSelectedOption,\n options: event.data.autoApply\n ? event.data.updatedOptions.options\n : context.options,\n pendingOptions: event.data.updatedOptions.options\n })),\n applyOptions: assign((context, event) => ({\n ...context,\n options: [...context.pendingOptions]\n })),\n cancelOptions: assign((context, event) => ({\n ...context,\n pendingOptions: [...context.options]\n })),\n setVisualizerSnapshot: assign((context, event) => ({\n ...context,\n visualizerSnapshot: event.data.snapshot || null\n }))\n }\n }\n )\n\n this.machineService = interpret(this.machine).start()\n\n this.machineService.subscribe(this.onUpdate)\n }\n\n /**\n * Add a listener to the model to be called when the state changes\n * @param {Function} listener - Callback function to be called when the state changes\n */\n addEventListener(listener) {\n if (typeof listener === 'function') {\n this.listeners.push(listener)\n }\n }\n\n /**\n * Remove a listener from the callbacks\n * @param {Function} listener - Callback function to remove from the listeners\n */\n removeEventListener(listener) {\n this.listeners = this.listeners.filter((l) => l !== listener)\n }\n\n /**\n * Parse initial model data to set the initial state\n * @param {*} initialData - The initial data to parse\n * @param {*} queryOptions - The query options to parse\n * @returns {Object} - The parsed initial data\n */\n parseInitialData({ initialState, queryFilters, queryOptions }) {\n let filters = initialState?.filters || {}\n let options = initialState?.options || []\n\n // Set initial selected filters from query params\n if (Object.keys(queryFilters).length > 0) {\n filters = {\n ...filters,\n filterOptions: filters.filterOptions.map((filterOption) => {\n if (queryFilters[filterOption.id]) {\n switch (filterOption.type) {\n case 'checkbox':\n return {\n ...filterOption,\n option: {\n ...filterOption.option,\n isSelected: queryFilters[filterOption.id] === filterOption.option.value\n }\n }\n default:\n return filterOption\n }\n }\n\n return filterOption\n })\n }\n }\n\n\n // Set initial selected options from query params\n if (Object.keys(queryOptions).length > 0) {\n options = initialState.options.map((optionGroup, idx) => {\n if (queryOptions[optionGroup.value]) {\n return {\n ...optionGroup,\n categories: optionGroup.categories.map((category, idx) => {\n if (category.options) {\n return {\n ...category,\n options: category.options.map((option, idx) => {\n const customColorPrefix = 'custom-color-'\n const isCustomColorOption =\n option.value.includes(customColorPrefix)\n const isCustomColorQuery =\n queryOptions[optionGroup.value].includes(\n customColorPrefix\n )\n\n return {\n ...option,\n isSelected:\n (isCustomColorOption && isCustomColorQuery) ||\n queryOptions[optionGroup.value] === option.value,\n value:\n isCustomColorOption && isCustomColorQuery\n ? queryOptions[optionGroup.value]\n : option.value\n }\n })\n }\n }\n return category\n })\n }\n }\n\n return optionGroup\n }\n )\n }\n\n const parsedOptions = this.parseOptions({ filters, options })\n\n return {\n ...initialState,\n hasModifiedSelectedOption: parsedOptions.meta.hasModifiedSelectedOption,\n filters,\n options: parsedOptions.options,\n }\n }\n\n /**\n * Parses the options and applies business logic to select/deselect options and disable groups based on the association with other selected options and filters.\n *\n * @param {Object} param\n * @param {Object} param.filters - The filters to apply to the options\n * @param {Object} param.options - The options to parse\n * @returns {Object} - The parsed options and meta data related to the options\n */\n parseOptions({ filters, options }) {\n const controlledOptions = {}\n let hasModifiedSelectedOption = false\n // extract the selected options to compare against mustHaveOne options\n const selectedOptionValues = Object.values(this.parseSelectedOptions(options)).map((option) => option.value) || []\n\n // Create a map of controlledOptions for filters\n if (Array.isArray(filters?.filterOptions)) {\n filters?.filterOptions.forEach((filter) => {\n filter.controls.forEach((control) => {\n switch (filter.type) {\n case 'checkbox':\n controlledOptions[control] = filter?.option?.isSelected ? true : !!controlledOptions[control]\n break;\n default:\n break;\n }\n })\n })\n }\n\n const updatedOptions = options.map((optionGroup) => {\n // store a flag to determine if a selected option has been disabled\n let hasDisabledSelectedOption = false\n\n // update the option group with the isDisabled property based on the controlledOptions\n const updatedOptionGroup = {\n ...optionGroup,\n isDisabled: Object.prototype.hasOwnProperty.call(controlledOptions, optionGroup.value) ? !controlledOptions[optionGroup.value] : false,\n categories: optionGroup.categories.map((category) => {\n return {\n ...category,\n options: category.options.map((option) => {\n // if the option has a mustHaveOne property and it is not selected, disable the option\n if (Array.isArray(option.mustHaveOne) && option.mustHaveOne.length > 0) {\n const hasMustHave = option.mustHaveOne.some((mustHave) => selectedOptionValues.includes(mustHave))\n if (option.isSelected && !hasMustHave) {\n hasDisabledSelectedOption = true\n hasModifiedSelectedOption = true\n }\n\n return {\n ...option,\n isDisabled: !hasMustHave,\n isSelected: !hasMustHave ? false : option.isSelected\n }\n }\n\n return {\n ...option\n }\n })\n }\n })\n };\n\n // if a selected option has been disabled, select the first non-disabled option as selected\n if (hasDisabledSelectedOption) {\n let isDefaultSelected = false\n for (let i = 0; i < updatedOptionGroup.categories.length; i++) {\n if (isDefaultSelected) {\n break;\n }\n\n for (let j = 0; j < updatedOptionGroup.categories[i].options.length; j++) {\n if (!updatedOptionGroup.categories[i].options[j].isDisabled) {\n updatedOptionGroup.categories[i].options[j].isSelected = true\n isDefaultSelected = true\n break;\n }\n }\n }\n }\n\n return updatedOptionGroup\n })\n\n return {\n options: updatedOptions,\n meta: {\n hasModifiedSelectedOption: hasModifiedSelectedOption || false\n }\n }\n }\n\n\n /***\n * Callback function to be called when the state changes\n * @param {Object} state - The current state of the state machine\n */\n onUpdate = (state, event) => {\n this.listeners.forEach((listener) => listener(state, event))\n }\n\n /**\n * Event emitter to send events to the state machine\n * @param {Object} event - The event to send to the state machine\n * @param {string} event.type - The type of event to send to the state machine\n * @param {Object} event.data - The payload of the event to send to the state machine\n */\n send(event) {\n this.machineService.send(event)\n }\n\n /**\n * Set a filter selection state in filters context and send an event to the state machine with the updated filters and updated options based on the selected filters\n * @param {Object} param\n * @param {Object} param.filter - The filter to update\n */\n setFilter({ filter }) {\n const { filters, pendingOptions } = this.getState().context\n\n const updatedFilters = {\n ...filters,\n filterOptions: filters.filterOptions.map((filterOption) => {\n if (filterOption.id === filter.filterId) {\n return {\n ...filterOption,\n option: {\n ...filterOption.option,\n isSelected: filter.isSelected\n }\n }\n }\n return filterOption\n })\n }\n\n const updatedOptions = this.parseOptions({ filters: updatedFilters, options: pendingOptions })\n\n this.send({ type: 'UPDATE_FILTERS', data: { updatedFilters } })\n this.send({ type: 'UPDATE_OPTIONS', data: { updatedOptions, autoApply: true } })\n }\n\n /**\n * Set an option selection state in options context and send an event to the state machine with the updated options\n * @param {Object} option - The option to update\n */\n setOption(option, autoApply = false) {\n const { filters, pendingOptions } = this.getState().context\n const customColorIdx = (val) => val.indexOf('custom-color')\n\n\n let updatedOptions = pendingOptions.map((o, idx) => {\n if (o.value === option.groupValue) {\n return {\n ...o,\n categories: o.categories.map((c, idx) => {\n if (c.options) {\n return {\n ...c,\n options: c.options.map((o, idx) => {\n const isCustomColor =\n customColorIdx(o.value) > -1 &&\n customColorIdx(option.optionValue) > -1\n\n return {\n ...o,\n isSelected:\n o.value === option.optionValue || isCustomColor\n ? option.isSelected\n : false,\n value: isCustomColor ? option.optionValue : o.value\n }\n })\n }\n }\n\n return c\n })\n }\n }\n return o\n })\n\n updatedOptions = this.parseOptions({ filters, options: updatedOptions })\n\n this.send({ type: 'UPDATE_OPTIONS', data: { updatedOptions, autoApply } })\n }\n\n /**\n * Send an event to the state machine to apply the current pendingOptions\n */\n applyOptions() {\n this.send({\n type: 'APPLY_OPTIONS'\n })\n }\n\n /**\n * Send an event to the state machine to reset the current pendingOptions to the applied options\n */\n cancelOptions() {\n this.send({\n type: 'CANCEL_OPTIONS'\n })\n }\n\n /**\n * Get option parameters\n * @returns {Object} - The option parameters\n */\n getOptionParams() {\n const { options } = this.getState().context\n const params = {}\n\n options.forEach((optionGroup) => {\n optionGroup.categories.forEach((category) => {\n if (category.options) {\n category.options.forEach((option) => {\n if (option.isSelected) {\n params[optionGroup.value] = option.value\n }\n })\n }\n })\n })\n\n return params\n }\n\n /**\n * Parse the options and return a trimmed down object with only the selected options\n * @param {Object} options - The options to parse\n * @returns {Object} - The selected options\n */\n parseSelectedOptions(options) {\n const selectedOptions = {}\n\n options.forEach((optionGroup) => {\n optionGroup.categories.forEach((category) => {\n if (category.options) {\n category.options.forEach((option) => {\n if (option.isSelected) {\n selectedOptions[optionGroup.value] = option\n }\n })\n }\n })\n })\n\n return selectedOptions\n }\n\n /**\n * Get a trimmed down options object with only the selected options\n * @returns {Object} - The selected options\n */\n getSelectedOptions() {\n const { options } = this.getState().context\n return this.parseSelectedOptions(options)\n }\n\n /**\n * Get the options from the state machine context\n * @returns\n */\n getOptions() {\n const { options } = this.getState().context\n return options\n }\n\n /**\n * Set the visualizer snapshot image\n * @param {String} snapshot - The base64 encoded image string\n */\n setVisualizerSnapshot(snapshot) {\n this.machineService.send({\n type: 'SET_VISUALIZER_SNAPSHOT',\n data: { snapshot }\n })\n }\n\n /**\n * Get current state\n */\n getState = () => {\n const state = this.machineService.getSnapshot()\n const { value, context } = state\n return { value, context }\n }\n}\n","import History from 'services/History/History'\n\n/**\n * ProductInformationRouter responsible for managing the routing and history state of the product information page\n */\nexport default class ProductInformationRouter extends History {\n\n /**\n * Set the selected options in the url\n * @param {Array} options - The configured product options\n * @example [{ value: 'color', categories: [{ value: 'red', options: [{ value: 'red', isSelected: true }] }] }]\n * // Url = https://www.masonite.com/product-information?color=red\n */\n setOptions({ filters = {}, options = [] }) {\n const url = `${window.location.origin}${window.location.pathname}`\n const searchParams = new URLSearchParams(window.location.search)\n\n\n // Set the selected filters to the url\n if (Array.isArray(filters?.filterOptions)) {\n filters.filterOptions.forEach((filter) => {\n switch (filter.type) {\n case 'checkbox':\n if (filter.option.isSelected) {\n searchParams.set(filter.id, filter.option.value)\n } else if (searchParams.has(filter.id)) {\n searchParams.delete(filter.id)\n }\n break;\n default:\n break;\n }\n })\n }\n\n // Set the selected options to the url\n if (Array.isArray(options)) {\n options.forEach((option) => {\n const key = option.value\n const allOptions = option.categories.reduce((acc, category) => {\n return acc.concat(category.options)\n }, [])\n const selectedOption = allOptions.find((o) => o?.isSelected && !option.isDisabled)\n\n if (searchParams.has(key) && !selectedOption) {\n searchParams.delete(key)\n } else if (selectedOption) {\n searchParams.set(key, selectedOption.value)\n }\n })\n }\n\n this.replaceState(\n options,\n document.title,\n `${url}?${searchParams.toString()}`\n )\n }\n\n /**\n * Parse and return the valid options from the url\n * @param {Object} param\n * @param {Object} param.filters - The valid filters to parse from the url\n * @param {Object} param.options - The valid options to parse from the url\n * @returns {Object} - The valid options and filters parsed from the url\n * @example getOptions({ options: { categories: [{ value: 'color', options: [{ value: 'red' }] }] }})\n * // Url = https://www.masonite.com/product-information?color=red&invalidOption=blue\n * // { color: 'red' }\n * @example getOptions({ options: { categories: [{ value: 'color', options: [{ value: 'red' }] }, { value: 'size', options: [{ value: 'small' }] }] })\n * // Url = https://www.masonite.com/product-information?color=red&size=small\n * // { color: 'red', size: 'small' }\n *\n */\n getOptions({ filters, options }) {\n const searchParams = new URLSearchParams(window.location.search)\n\n const queryFilters = {}\n if (Array.isArray(filters?.filterOptions)) {\n filters.filterOptions.forEach((filter) => {\n switch (filter.type) {\n case 'checkbox':\n if (searchParams.has(filter.id)) {\n queryFilters[filter.id] = searchParams.get(filter.id)\n }\n break;\n default:\n break;\n }\n })\n }\n\n const queryOptions = {}\n if (Array.isArray(options)) {\n options.forEach((option) => {\n const key = option.value\n const allOptions = option.categories.reduce((acc, category) => {\n return acc.concat(category.options)\n }, [])\n\n const hasParam = searchParams.has(key)\n const customColorPrefix = 'custom-color-'\n let isValidOption = false\n\n if (hasParam && searchParams.get(key).includes(customColorPrefix)) {\n isValidOption =\n searchParams.get(key).split(customColorPrefix)[1].length === 6\n } else {\n isValidOption = allOptions.some((o) =>\n o?.value ? o.value === searchParams.get(key) : false\n )\n }\n\n if (hasParam && isValidOption) {\n queryOptions[key] = searchParams.get(key)\n }\n })\n }\n\n return { queryFilters, queryOptions }\n }\n}\n","import template from './ProductInformation.template'\nimport { insert } from 'utilities/renderer'\nimport ProductInfo from './components/ProductInfo/ProductInfo'\nimport ProductOptions from './components/ProductOptions/ProductOptions'\nimport ProductMediaGallery from './components/ProductMediaGallery/ProductMediaGallery'\nimport ProductDetails from './components/ProductDetails/ProductDetails'\nimport ProductRelatedContent from './components/ProductRelatedContent/ProductRelatedContent'\nimport ProductInformationModel from './models/ProductInformationModel/ProductInformationModel'\nimport ProductInformationRouter from './services/ProductInformationRouter/ProductInformationRouter'\nimport Services from 'services'\nimport Analytics from 'services/Analytics/Analytics'\n\nexport default class ProductInformation {\n\tstatic SELECTORS = {\n\t\tPRODUCT_INFO: '[data-cmp-hook=\"product-info\"]',\n\t\tPRODUCT_OPTIONS: '[data-cmp-hook=\"product-options\"]',\n\t\tPRODUCT_MEDIA_GALLERY: '[data-cmp-hook=\"product-media-gallery\"]',\n\t\tPRODUCT_DETAILS: '[data-cmp-hook=\"product-details\"]',\n\t\tPRODUCT_RELATED_CONTENT: '[data-cmp-hook=\"product-related-content\"]',\n\t\tPRODUCT_CONFIG_SLOT_1: '[data-cmp-hook=\"product-configuration-slot-1\"]',\n\t\tPRODUCT_CONFIG_SLOT_2: '[data-cmp-hook=\"product-configuration-slot-2\"]',\n\t\tPRODUCT_CONFIG_SLOT_3: '[data-cmp-hook=\"product-configuration-slot-3\"]',\n\t\tPRODUCT_CONFIG_SLOT_4: '[data-cmp-hook=\"product-configuration-slot-4\"]'\n\t}\n\n\tconstructor(element, { id = '' } = {}) {\n\t\tthis.element = element\n\t\tthis.id = id\n\t\tthis.initialData = this.getInitialData()\n\t\tthis.services = Services.getInstance()\n\t\tthis.mediaQuery = this.services.BreakpointListener.queryMatch\n\t\tthis.analyticsService = Analytics.getInstance()\n\t\tthis.init()\n\t}\n\n\t/**\n\t * Initialize the product information component.\n\t */\n\tinit() {\n\t\tthis.template = template({\n\t\t\tid: this.id\n\t\t})({\n\t\t\tgetNode: true\n\t\t})\n\n\t\tthis.cacheDom()\n\t\tthis.createProductInformationRouter()\n\t\tthis.createProductInformationModel()\n\t\tthis.createProductInfo()\n\t\tthis.createProductOptions()\n\t\tthis.createProductMediaGallery()\n\t\tthis.creatProductDetails()\n\t\tthis.createProductRelatedContent()\n\t\tthis.attachEvents()\n\t\tthis.setContentOrder()\n\t\tthis.render()\n\t}\n\n\t/**\n\t * Cache the DOM elements for the product information component.\n\t */\n\tcacheDom() {\n\t\tthis.productInfoEl = this.template.querySelector(\n\t\t\tProductInformation.SELECTORS.PRODUCT_INFO\n\t\t)\n\n\t\tthis.productOptionsEl = this.template.querySelector(\n\t\t\tProductInformation.SELECTORS.PRODUCT_OPTIONS\n\t\t)\n\n\t\tthis.productMediaGalleryEl = this.template.querySelector(\n\t\t\tProductInformation.SELECTORS.PRODUCT_MEDIA_GALLERY\n\t\t)\n\n\t\tthis.productDetailsEl = this.template.querySelector(\n\t\t\tProductInformation.SELECTORS.PRODUCT_DETAILS\n\t\t)\n\n\t\tthis.productRelatedContentEl = this.template.querySelector(\n\t\t\tProductInformation.SELECTORS.PRODUCT_RELATED_CONTENT\n\t\t)\n\n\t\tthis.productConfigSlot1El = this.template.querySelector(\n\t\t\tProductInformation.SELECTORS.PRODUCT_CONFIG_SLOT_1\n\t\t)\n\n\t\tthis.productConfigSlot2El = this.template.querySelector(\n\t\t\tProductInformation.SELECTORS.PRODUCT_CONFIG_SLOT_2\n\t\t)\n\n\t\tthis.productConfigSlot3El = this.template.querySelector(\n\t\t\tProductInformation.SELECTORS.PRODUCT_CONFIG_SLOT_3\n\t\t)\n\n\t\tthis.productConfigSlot4El = this.template.querySelector(\n\t\t\tProductInformation.SELECTORS.PRODUCT_CONFIG_SLOT_4\n\t\t)\n\t}\n\n\t/**\n\t * Attach the events to the product information component.\n\t */\n\tattachEvents() {\n\t\tthis.productInformationModel.addEventListener(this.onModelUpdate)\n\t\tthis.services.BreakpointListener.addListener(this.onBreakpointChange)\n\t}\n\n\t/**\n\t * Detach the events from the product information component.\n\t */\n\tdetachEvents() {\n\t\tthis.productInformationModel.removeEventListener(this.onModelUpdate)\n\t\tthis.services.BreakpointListener.renoveListener(this.onBreakpointChange)\n\t}\n\n\t/**\n\t * Destroy the product information component.\n\t */\n\tdestroy() {\n\t\tthis.detachEvents()\n\t}\n\n\t/**\n\t * Get the initial data for the product information component from the window object.\n\t * @returns\n\t */\n\tgetInitialData() {\n\t\tif (!window.masonite?.pip) {\n\t\t\tconsole.error(\n\t\t\t\t'No initial data was found for the ProductInformation component. Please add the data to the window.masonite.pip object.'\n\t\t\t)\n\t\t\treturn {}\n\t\t}\n\n\t\treturn typeof window.masonite.pip === 'string'\n\t\t\t? JSON.parse(window.masonite.pip)\n\t\t\t: window.masonite.pip\n\t}\n\n\t/**\n\t * Create the product information router.\n\t */\n\tcreateProductInformationRouter() {\n\t\tthis.productInformationRouter = new ProductInformationRouter()\n\t}\n\n\t/**\n\t * Create the product information model.\n\t */\n\tcreateProductInformationModel() {\n\t\tconst { queryFilters, queryOptions } = this.productInformationRouter.getOptions({\n\t\t\tfilters: this.initialData?.filters,\n\t\t\toptions: this.initialData?.options\n\t\t})\n\t\tthis.productInformationModel = new ProductInformationModel({\n\t\t\tinitialState: this.initialData,\n\t\t\tqueryFilters,\n\t\t\tqueryOptions\n\t\t})\n\t}\n\n\t/**\n\t * Create the product information component.\n\t */\n\tcreateProductInfo() {\n\t\tconst { context } = this.productInformationModel.getState()\n\n\t\tthis.productInfo = new ProductInfo(this.productInfoEl, {\n\t\t\tcollection: context.collection,\n\t\t\tglassAvailable: context.glassAvailable,\n\t\t\tbenefits: context.benefits,\n\t\t\tcta: context.wtbCta,\n\t\t\tconstructionEyebrow: context.constructionEyebrow,\n\t\t\tfeaturedInEyebrow: context.featuredInEyebrow,\n\t\t\tcomingSoonEyebrow: context.comingSoonEyebrow\n\t\t})\n\t}\n\n\t/**\n\t * Create the product options component.\n\t */\n\tcreateProductOptions() {\n\t\tthis.productOptions = new ProductOptions(this.productOptionsEl, {\n\t\t\tproductModel: this.productInformationModel\n\t\t})\n\t}\n\n\t/**\n\t * Create the product media gallery component.\n\t */\n\tcreateProductMediaGallery() {\n\t\tthis.productMediaGallery = new ProductMediaGallery(\n\t\t\tthis.productMediaGalleryEl,\n\t\t\t{\n\t\t\t\tproductModel: this.productInformationModel\n\t\t\t}\n\t\t)\n\t}\n\n\t/**\n\t * Create the product details component.\n\t */\n\tcreatProductDetails() {\n\t\tconst { context } = this.productInformationModel.getState()\n\n\t\tthis.productDetails = new ProductDetails(this.productDetailsEl, {\n\t\t\tdetails: context.details\n\t\t})\n\t}\n\n\t/**\n\t * Create the product related content component.\n\t */\n\tcreateProductRelatedContent() {\n\t\tconst { context } = this.productInformationModel.getState()\n\n\t\tthis.productRelatedContent = new ProductRelatedContent(\n\t\t\tthis.productRelatedContentEl,\n\t\t\t{\n\t\t\t\tcontent: context.relatedArticles\n\t\t\t}\n\t\t)\n\t}\n\n\t/**\n\t * Set the content order of the product information component based on the current breakpoint\n\t * to maintain the proper tab order as the layout reorders.\n\t */\n\tsetContentOrder() {\n\t\tif (this.mediaQuery.MEDIUM_LARGE) {\n\t\t\tthis.productConfigSlot1El.appendChild(this.productMediaGalleryEl)\n\t\t\tthis.productConfigSlot3El.appendChild(this.productInfoEl)\n\t\t\tthis.productConfigSlot4El.appendChild(this.productOptionsEl)\n\t\t} else {\n\t\t\tthis.productConfigSlot1El.appendChild(this.productMediaGalleryEl)\n\t\t\tthis.productConfigSlot4El.appendChild(this.productInfoEl)\n\t\t\tthis.productConfigSlot3El.appendChild(this.productOptionsEl)\n\t\t}\n\t}\n\n\t/**\n\t * Update the product information model when the options are updated.\n\t * @param {*} state\n\t * @param {*} event\n\t */\n\tonModelUpdate = (state, event) => {\n\t\tconst { context: { filters = {}, options = [] } = {} } = state\n\n\t\tif (\n\t\t\t(event.type === 'UPDATE_OPTIONS' && event.data.autoApply) ||\n\t\t\tevent.type === 'APPLY_OPTIONS'\n\t\t) {\n\t\t\tthis.productInformationRouter.setOptions({ filters, options })\n\t\t\tthis.trackOptions()\n\t\t}\n\t}\n\n\t/**\n\t * Update the media query state and set the content order if the breakpoint has changed.\n\t * @param {*} breakpoint\n\t */\n\tonBreakpointChange = (breakpoint) => {\n\t\tconst hasChanged =\n\t\t\tbreakpoint.SMALL !== this.mediaQuery.SMALL ||\n\t\t\tbreakpoint.MEDIUM !== this.mediaQuery.MEDIUM ||\n\t\t\tbreakpoint.MEDIUM_LARGE !== this.mediaQuery.MEDIUM_LARGE\n\n\t\tthis.mediaQuery = breakpoint\n\n\t\tif (hasChanged) {\n\t\t\tthis.setContentOrder()\n\t\t}\n\t}\n\n\t/**\n\t * Track the selected options in the analytics service.\n\t * The format of the parameters are as follows:\n\t * - product_info_selection: option name - option value | option name - option value | ...\n\t */\n\ttrackOptions = () => {\n\t\tconst selectedOptions = this.productInformationModel.getSelectedOptions()\n\n\t\tconst payload = Object.entries(selectedOptions)\n\t\t\t.map(\n\t\t\t\t([key, value]) =>\n\t\t\t\t\t`${key.toLowerCase()} - ${value?.label?.toLowerCase()}`\n\t\t\t)\n\t\t\t.join(' | ')\n\n\t\tthis.analyticsService.trackInteraction('product_info', {\n\t\t\tproduct_info_selection: payload\n\t\t})\n\t}\n\n\trender() {\n\t\tinsert(this.template, this.element)\n\t}\n}\n","import html from 'utilities/html'\n\nconst template = ({ id = '' } = {}) =>\n html`\n \n
    \n \n
    \n
    \n \n \n \n \n \n \n \n \n \n \n \n \n \n `\n\nexport default template\n","import { insert } from 'utilities/renderer'\nimport template from './Notification.template'\n\n/**\n * ProductSave component responsible for rendering a Save button\n * @param {HTMLElement} element - the element to render the component in\n * @param {Object} props - the options for the component\n * @param {String} props.text - the text to display in the notification\n * @param {Object} props.cta - the cta to display in the notification\n * @param {String} props.cta.text - the text to display in the cta\n * @param {String} props.cta.url - the url to navigate to when the cta is clicked\n * @param {Object} props.close - the close button to display in the notification\n * @param {String} props.close.text - the text to display in the close button\n * @param {Function} props.close.onClick - the function to call when the close button is clicked\n * @param {Boolean} props.showCta - whether or not to show the cta\n * @param {String} props.id - An id for the notification\n */\nexport default class Notification {\n static SELECTORS = {\n NOTIFICATION_BUTTON: '[data-cmp-hook=\"notification-button\"]',\n NOTIFICATION_CONTAINER: '[data-cmp-is=\"notification-container\"]'\n }\n\n static TIMERS = {\n NOTIFICATION: 10000\n }\n\n constructor(element, { text, cta = {}, close, showCta, id } = {}) {\n this.element = element\n this.text = text\n this.cta = cta\n this.close = close\n this.showCta = showCta\n this.id = id\n this.init()\n }\n\n init() {\n this.template = template({\n text: this.text,\n cta: this.cta,\n close: this.close,\n showCta: this.showCta,\n id: this.id\n })({\n getNode: true\n })\n\n this.cacheDom()\n this.attachEvents()\n this.initializeNotificationTimeout()\n this.render()\n }\n\n /**\n * Cache the DOM elements for the ProductSave component.\n */\n cacheDom() {\n this.closeButton = this.template.querySelector(\n Notification.SELECTORS.NOTIFICATION_BUTTON\n )\n }\n\n /**\n * Attach events to the Notification component.\n */\n attachEvents() {\n this.closeButton.addEventListener('click', this.handleClose)\n }\n\n /**\n * Remove events from the Notification component.\n */\n detachEvents() {\n this.closeButton.removeEventListener('click', this.handleClose)\n }\n\n /**\n * Destroy the Notification component.\n */\n destroy() {\n this.detachEvents()\n if (this.notificationTimeout) clearTimeout(this.notificationTimeout)\n }\n\n /**\n * Initialize the notification timeout.\n */\n initializeNotificationTimeout() {\n if (this.notificationTimeout) clearTimeout(this.notificationTimeout)\n this.notificationTimeout = setTimeout(() => {\n this.handleClose()\n }, Notification.TIMERS.NOTIFICATION)\n }\n\n /**\n * Handle the close event.\n */\n handleClose = () => {\n if (this.notificationTimeout) clearTimeout(this.notificationTimeout)\n\n this.template?.parentElement?.remove()\n }\n\n /**\n * Render the ProductTools component\n */\n render() {\n insert(this.template, this.element)\n }\n}\n","import html from 'utilities/html'\nimport textTemplate, {\n TYPES as TEXT_TYPES\n} from 'foundation/Text/Text.template'\nimport { Default as Link } from 'foundation/Link/Link.stories'\n\n/**\n * Display a popup notification\n * @param {Object} props\n * @param {string} props.text - The notification text\n * @param {Object} props.cta - The CTA properties\n * @param {string} props.cta.url - The CTA URL\n * @param {string} props.cta.text - The CTA text\n * @param {string} props.close - The close text\n * @param {boolean} props.showCta - Whether to show the CTA\n * @param {string} props.sku - The id of the notification\n * @returns {String} - The notification template\n */\nconst template = ({ text, cta = {}, close, showCta, id }) => html`\n \n
    \n
    \n \n ${textTemplate({\n text: text || '',\n textElement: 'p',\n textType: TEXT_TYPES.BODY_MD\n })}\n
    \n ${showCta\n ? Link({\n ...Link.args,\n accessibilityLabel: 'Go to Favorites',\n href: cta?.url || '#',\n label: cta?.text || 'Go to Favorites',\n linkStyle: 'mod-notification__cta link-style-primary',\n linkSize: 'link-small',\n showAsButtonLink: true,\n showAsListLink: false,\n showAsTextLink: false\n })\n : ''}\n
    \n\n \n \n \n \n ${close}\n \n \n \n`\n\nexport default template\n","import { insert } from 'utilities/renderer'\nimport { sortObjectKeys } from 'utilities/utilities'\nimport template from './ProductSave.template'\nimport Services from 'services'\nimport Notification from 'modules/ProductTools/components/Notification/Notification'\nimport Analytics from 'services/Analytics/Analytics'\n\n/**\n * ProductSave component responsible for rendering a Save button\n * @param {HTMLElement} element - the element to render the component in\n * @param {Object} props - the options for the component\n * @param {Boolean} props.isButton - whether the component should render as a button\n * @param {String} props.showCta - whether the component should show the CTA in the notification\n * @param {Object} props.product\n * @param {String} props.product.sku - Product sku\n * @param {String} props.product.collection - Product collection name\n * @param {Object} props.product.media - Product media\n * @param {String} props.product.media.src - Product media url\n * @param {String} props.product.media.alt - Product media alt\n * @param {String} props.product.url - Product url\n * @param {Object} props.product.customOptions - Product options\n * @param {Object} props.content - Product tools content\n * @param {Object} props.content.save - Product save content\n * @param {Object} props.content.saved - Product saved content\n * @param {Object} props.content.saveSuccess - Product saved success content\n * @param {Object} props.content.saveRemove - Product save remove content\n * @param {Object} props.content.saveError - Product save error content\n * @param {Object} props.content.share - Product share content\n * @param {Object} props.content.pinterest - Product pinterest content\n * @param {Object} props.content.copy - Product copy content\n * @param {Object} props.content.copySuccess - Product copy success content\n */\nexport default class ProductSave {\n static SELECTORS = {\n SAVE_BUTTON: '[data-cmp-hook=\"save-button\"]',\n SAVE_ICON: '[data-cmp-hook=\"save-icon\"]',\n STATUS: '[data-product-favorite-saved]',\n NOTIFICATION_CONTAINER: '[data-cmp-is=\"notification-container\"]'\n }\n\n static CLASSES = {\n BLANK_SAVED: 'mod-product-save__blank-style--saved',\n BUTTON_SAVED: 'mod-product-save__button-style--saved',\n ACTIVE: 'mod-product-save__notification--active',\n NOTIFICATION_CONTAINER: 'mod-notification__container',\n NOTIFICATION_ITEM: 'mod-notification__item'\n }\n\n static MESSAGES = {\n SAVED: 'was added to your Favorites',\n REMOVED: 'was removed from your Favorites',\n ERROR: 'We were unable to process your request, please try again later'\n }\n\n static EVENTS = {\n SAVE: 'saveFavorite',\n REMOVE: 'removeFavorite',\n DISMISS_NOTIFICATION: 'dismissNotificationFavorite'\n }\n\n static DATA_ATTRIBUTES = {\n NOTIFICATION: {\n ATTRIBUTE: 'data-cmp-is',\n VALUE: 'notification-container'\n }\n }\n\n constructor(element, { isButton, product, content, showCta } = {}) {\n this.element = element\n this.isFavorite = false\n this.product = product\n this.content = content\n this.isButton = isButton\n this.showCta = showCta\n this.services = Services.getInstance()\n this.analyticsService = Analytics.getInstance()\n\n this.EventEmitterService = this.services.EventEmitterService\n\n this.init()\n }\n\n init() {\n this.template = template({\n label: this.isFavorite\n ? this.content.saved?.label\n : this.content.save?.label,\n labelAccessibility: this.isFavorite\n ? this.content.saved?.labelAccessibility\n : this.content.save?.labelAccessibility,\n isFavorite: this.isFavorite,\n isButton: this.isButton\n })({\n getNode: true\n })\n\n this.cacheDom()\n this.attachEvents()\n this.initializeSavedState()\n this.createNotificationContainer()\n this.render()\n }\n\n /**\n * Cache the DOM elements for the ProductSave component.\n */\n cacheDom() {\n this.saveButton = this.template.querySelector(\n ProductSave.SELECTORS.SAVE_BUTTON\n )\n\n this.saveIcon = this.template.querySelector(ProductSave.SELECTORS.SAVE_ICON)\n\n this.saveLabel = this.template.querySelector(\n ProductSave.SELECTORS.SAVE_BUTTON\n ).lastElementChild\n }\n\n /**\n * Attach event listeners to the ProductSave component\n */\n attachEvents() {\n this.saveButton.addEventListener('click', this.handleClick)\n }\n\n /**\n * Detach the events from the ProductSave component\n */\n detachEvents() {\n this.saveButton.removeEventListener('click', this.handleClick)\n }\n\n /**\n * Destroy the ProductSave component.\n */\n destroy() {\n this.detachEvents()\n if (this.notification) this.notification.destroy()\n }\n\n /**\n * Initialize the component state\n */\n initializeSavedState() {\n // Get current favorites from local storage\n const doorFavorites = localStorage.getItem('doorFavorites')\n ? JSON.parse(localStorage.getItem('doorFavorites'))\n : []\n\n // Check if the current product is saved to favorites\n const productExists = doorFavorites.some(\n (product) =>\n product.sku === this.product.sku &&\n JSON.stringify(sortObjectKeys(product.customOptions || {})) ===\n JSON.stringify(sortObjectKeys(this.product.customOptions || {}))\n )\n\n // Update the state of the component\n this.isFavorite = productExists\n this.applyState(productExists)\n }\n\n /**\n * Handle the click event on the ProductSave component\n * @param {boolean} saved - If the current product is saved to favorites\n */\n applyState(saved) {\n if (saved) {\n this.saveIcon.src = '/dist/assets/icons/save-active.svg'\n this.saveButton.dataset.ProductSaveSaved = 'true'\n this.saveButton.setAttribute(\n 'aria-label',\n this.content.saved?.labelAccessibility\n )\n this.saveButton.classList.add(\n this.isButton\n ? ProductSave.CLASSES.BUTTON_SAVED\n : ProductSave.CLASSES.BLANK_SAVED\n )\n this.saveLabel.innerText = this.content.saved?.label\n } else {\n this.saveIcon.src = '/dist/assets/icons/save.svg'\n this.saveButton.dataset.ProductSaveSaved = 'false'\n this.saveButton.setAttribute(\n 'aria-label',\n this.content.save?.labelAccessibility\n )\n this.saveButton.classList.remove(\n this.isButton\n ? ProductSave.CLASSES.BUTTON_SAVED\n : ProductSave.CLASSES.BLANK_SAVED\n )\n this.saveLabel.innerText = this.content.save?.label\n }\n }\n\n /**\n * Create notification container\n */\n createNotificationContainer() {\n this.notificationContainer = document.querySelector(\n ProductSave.SELECTORS.NOTIFICATION_CONTAINER\n )\n\n if (!this.notificationContainer) {\n const notificationContainer = document.createElement('div')\n notificationContainer.setAttribute(\n ProductSave.DATA_ATTRIBUTES.NOTIFICATION.ATTRIBUTE,\n ProductSave.DATA_ATTRIBUTES.NOTIFICATION.VALUE\n )\n notificationContainer.classList.add(\n ProductSave.CLASSES.NOTIFICATION_CONTAINER\n )\n document.body.appendChild(notificationContainer)\n\n this.notificationContainer = document.querySelector(\n ProductSave.SELECTORS.NOTIFICATION_CONTAINER\n )\n }\n }\n\n /**\n * Create notification\n * @param {string} text - The notification text\n * @param {boolean} error - If the notification is an error\n */\n createNotification(text, error = false) {\n // Create a new notification\n this.notificationEl = document.createElement('div')\n this.notificationEl.classList.add(ProductSave.CLASSES.NOTIFICATION_ITEM)\n this.notification = new Notification(this.notificationEl, {\n text: error ? text : `${this.product.collection || 'This door'} ${text}`,\n cta: this.content.saveSuccess?.cta,\n close: this.content.saveSuccess?.close,\n showCta: this.showCta,\n id: this.product.sku\n })\n\n // Search for a previous notification that matches the current product\n const previousNotification = document.querySelector(\n `[data-notification-id=\"${this.product.sku}\"]`\n )\n\n // If a previous notification for this product exists, replace it\n if (previousNotification) {\n previousNotification.replaceWith(this.notificationEl)\n } else {\n // Otherwise, append the new notification to the container\n this.notificationContainer.appendChild(this.notificationEl)\n }\n }\n\n /**\n * Save the current product to favorites\n */\n handleSave() {\n const favoriteObject = this.product\n\n const doorFavorites = localStorage.getItem('doorFavorites')\n ? JSON.parse(localStorage.getItem('doorFavorites'))\n : []\n\n const productExists = doorFavorites.some(\n (product) =>\n product.sku === favoriteObject.sku &&\n JSON.stringify(sortObjectKeys(product.customOptions || {})) ===\n JSON.stringify(sortObjectKeys(favoriteObject.customOptions || {}))\n )\n\n if (!productExists) {\n doorFavorites.push(favoriteObject)\n localStorage.setItem('doorFavorites', JSON.stringify(doorFavorites))\n this.EventEmitterService.emit(ProductSave.EVENTS.SAVE, {\n product: this.product\n })\n }\n }\n\n /**\n * Remove the current product from favorites\n */\n handleRemove() {\n const doorFavorites = localStorage.getItem('doorFavorites')\n ? JSON.parse(localStorage.getItem('doorFavorites'))\n : []\n\n const productExists = doorFavorites.some(\n (product) =>\n product.sku === this.product.sku &&\n JSON.stringify(sortObjectKeys(product.customOptions || {})) ===\n JSON.stringify(sortObjectKeys(this.product.customOptions || {}))\n )\n\n if (productExists) {\n const filteredProducts = doorFavorites.filter(\n (product) =>\n product.sku !== this.product.sku ||\n JSON.stringify(sortObjectKeys(product.customOptions || {})) !==\n JSON.stringify(sortObjectKeys(this.product.customOptions || {}))\n )\n localStorage.setItem('doorFavorites', JSON.stringify(filteredProducts))\n this.EventEmitterService.emit(ProductSave.EVENTS.REMOVE, {\n product: this.product\n })\n }\n }\n\n /**\n * Handle clicking on the Save button\n * @param {event} event The click event\n */\n handleClick = (event) => {\n event.preventDefault()\n\n try {\n if (!this.isFavorite) {\n this.handleSave()\n this.isFavorite = true\n this.applyState(true)\n this.createNotification(\n this.content.saveSuccess?.message || ProductSave.MESSAGES.SAVED\n )\n this.trackSave(true)\n } else {\n this.handleRemove()\n this.isFavorite = false\n this.applyState(false)\n this.createNotification(\n this.content.saveRemove?.message || ProductSave.MESSAGES.REMOVED\n )\n this.trackSave(false)\n }\n } catch (error) {\n this.createNotification(\n this.content.saveError?.message || ProductSave.MESSAGES.ERROR,\n true\n )\n console.error(error)\n }\n }\n\n /**\n * Track the save action\n * @param {Boolean} isSave - Indicator for if the product is being added or removed\n */\n trackSave = (isSave) => {\n this.analyticsService.trackInteraction('product_favorite', {\n product_name: this.product.collection,\n product_favorite_type: isSave ? 'add' : 'remove'\n })\n }\n\n /**\n * Render the component to the dom\n */\n render() {\n insert(this.template, this.element)\n }\n}\n","import html from 'utilities/html'\nimport textTemplate, {\n TYPES as TEXT_TYPES\n} from 'foundation/Text/Text.template'\n\n/**\n * ProductSave Template\n * @param {object} props\n * @param {string} props.label - The label for the button\n * @param {string} props.labelAccessibility - The accessibility label for the button\n * @param {boolean} props.isFavorite - Whether the product is a favorite\n * @param {boolean} props.isButton - Whether the component should be a button\n * @returns\n */\nconst template = ({ label, labelAccessibility, isFavorite, isButton }) =>\n html`\n
    \n \n \n ${isButton\n ? textTemplate({\n addClassName: 'mod-product-save__label',\n text: label || 'Save',\n textElement: 'span',\n textType: TEXT_TYPES.BODY_SM,\n linesToDisplay: 1\n })\n : ''}\n \n
    \n `\n\nexport default template\n","import Tabs from './Tabs'\n\nexport default Tabs\n","import Services from 'services'\nimport playIcon, { POSITIONS } from 'modules/PlayIcon/PlayIcon.template'\nimport { fromTemplate } from 'utilities/renderer'\nimport Analytics from 'services/Analytics/Analytics'\nimport { debounce } from 'utilities/utilities'\n\n/**\n * Video Player component\n */\nexport default class VideoPlayer {\n static SELECTORS = {\n VIDEO: '[data-video-player=\"video-player\"]',\n PLAY_BUTTON: '[data-video-payer=\"play-button\"]'\n }\n\n static ATTRIBUTES = {\n PLAY_BUTTON_STATUS: 'data-is-paused',\n PLAY_BUTTON_LABEL: 'data-play-label',\n PAUSE_BUTTON_LABEL: 'data-pause-label',\n PLAY_BUTTON_POSITION: 'data-play-button-position',\n HIDE_PLAY_BUTTON_AFTER_PLAY: 'data-hide-button-after-play'\n }\n\n static EVENTS = {\n PLAY: 'videoPlay',\n PAUSE: 'videoPause',\n STOP: 'videoStop',\n PLAY_VIDEO: 'playVideo', // Remote instruction to play video\n PAUSE_VIDEO: 'pauseVideo' // Remote instruction to pause video\n }\n\n static CLASSES = {\n HIDDEN: 'mod-player__play-button--hidden'\n }\n\n constructor(element) {\n this.element = element\n this.services = Services.getInstance()\n this.analyticsService = Analytics.getInstance() // ref to analytics service\n this.videoProgressMarkers = new Map()\n this.EventEmitterService = this.services.EventEmitterService\n this.trackInteractionDebounce = debounce(this.trackInteraction, 200)\n this.hasStarted = false\n\n this.cacheDom()\n this.initPlayButton()\n this.attachEvents()\n }\n\n /**\n * Cache DOM elements\n */\n cacheDom() {\n this.videoEl = this.element.querySelector(VideoPlayer.SELECTORS.VIDEO)\n this.videoProgressMarkers.set(this.videoEl, [25, 50, 75, 100])\n\n this.playButtonEl = this.element.querySelector(\n VideoPlayer.SELECTORS.PLAY_BUTTON\n )\n\n this.hasControls = this.videoEl?.hasAttribute('controls')\n\n this.videoElId = this.videoEl?.id || null\n }\n\n /**\n * Add event listeners\n */\n attachEvents() {\n this.playButton?.addEventListener('click', this.togglePlay)\n\n this.videoEl.addEventListener('ended', this.handleVideoEnd)\n this.videoEl.addEventListener('play', this.trackInteractionDebounce)\n this.videoEl.addEventListener('seeking', this.trackInteractionDebounce)\n this.videoEl.addEventListener('timeupdate', this.trackInteractionDebounce)\n this.videoEl.addEventListener('pause', this.trackInteractionDebounce)\n this.videoEl.addEventListener('ended', this.trackInteraction)\n\n this.EventEmitterService.on(VideoPlayer.EVENTS.PLAY_VIDEO, this.remotePlay)\n this.EventEmitterService.on(\n VideoPlayer.EVENTS.PAUSE_VIDEO,\n this.remotePause\n )\n }\n\n /**\n * Remove event listeners\n */\n removeEvents() {\n this.playButton?.removeEventListener('click', this.togglePlay)\n\n this.videoEl.removeEventListener('ended', this.handleVideoEnd)\n\n this.videoEl.removeEventListener('play', this.trackInteractionDebounce)\n this.videoEl.removeEventListener(\n 'timeupdate',\n this.trackInteractionDebounce\n )\n this.videoEl.removeEventListener('pause', this.trackInteractionDebounce)\n this.videoEl.removeEventListener('ended', this.trackInteraction)\n\n this.EventEmitterService.off(VideoPlayer.EVENTS.PLAY_VIDEO, this.remotePlay)\n this.EventEmitterService.off(\n VideoPlayer.EVENTS.PAUSE_VIDEO,\n this.remotePause\n )\n }\n\n /**\n * Destroy the modal instance and remove event listeners\n */\n destroy() {\n this.removeEvents()\n }\n\n /**\n * Track interaction\n */\n trackInteraction = (event) => {\n const { target } = event\n const videoType = target.dataset?.type\n\n if (\n (videoType !== 'poster' && videoType !== 'modal') ||\n this.filterAnalyticsEvent\n )\n return\n\n switch (event.type) {\n case 'play':\n if (this.hasStarted) return\n\n this.hasStarted = true\n this.analyticsService.trackInteraction('video', {\n video_title: target.dataset?.title || undefined,\n video_status: 'start',\n video_view: 1,\n video_url: target.currentSrc,\n video_provider: 'widen'\n })\n break\n case 'timeupdate': {\n const progress = Math.floor(\n (target.currentTime / target.duration) * 100\n )\n let progressMarkers = this.videoProgressMarkers.get(target)\n\n for (let i = 0; i < progressMarkers.length; i++) {\n if (progress >= progressMarkers[i]) {\n this.analyticsService.trackInteraction('video', {\n video_title: target.dataset?.title || undefined,\n video_status: 'progress',\n video_percent: progressMarkers[i],\n video_url: target.currentSrc,\n video_provider: 'widen'\n })\n progressMarkers = progressMarkers.slice(i + 1)\n this.videoProgressMarkers.set(target, progressMarkers)\n break\n }\n }\n break\n }\n case 'pause': {\n /**\n * This is a workaround to stop the video player firing the pause event\n * along with the ended event when a file finishes playing.\n */\n const eventThreshold = Math.floor(target.duration) - 2 // Stop registering events 2 seconds before end of video\n if (target.currentTime >= eventThreshold) return\n\n this.analyticsService.trackInteraction('video', {\n video_title: target.dataset?.title || undefined,\n video_status: 'pause',\n video_url: target.currentSrc,\n video_provider: 'widen'\n })\n break\n }\n case 'ended':\n this.hasStarted = false\n\n this.analyticsService.trackInteraction('video', {\n video_title: target.dataset?.title || undefined,\n video_status: 'complete',\n video_percent: 100,\n video_url: target.currentSrc,\n video_provider: 'widen'\n })\n break\n default:\n break\n }\n }\n\n /**\n * Initialize and render the play button if there is an element to render it to\n */\n initPlayButton() {\n const hasPlayButton = !!this.playButton\n\n if (this.playButtonEl) {\n const playButtonPosition =\n this.playButtonEl.getAttribute(\n VideoPlayer.ATTRIBUTES.PLAY_BUTTON_POSITION\n ) || POSITIONS.BOTTOM_RIGHT\n\n if (!hasPlayButton) {\n this.playButton = fromTemplate(\n playIcon({\n isButton: true,\n isInline: true,\n position: playButtonPosition\n })\n )\n\n this.playButtonEl.appendChild(this.playButton)\n }\n\n this.playButton.setAttribute(\n VideoPlayer.ATTRIBUTES.PLAY_BUTTON_STATUS,\n !this.videoEl.autoplay\n )\n\n this.playButton.setAttribute(\n 'aria-label',\n this.element.getAttribute(\n this.videoEl.autoplay\n ? VideoPlayer.ATTRIBUTES.PAUSE_BUTTON_LABEL\n : VideoPlayer.ATTRIBUTES.PLAY_BUTTON_LABEL\n )\n )\n\n if (this.hasControls) {\n // hide the controls when the custom play button is enabled\n this.videoEl.removeAttribute('controls')\n }\n\n this.playButtonEl.classList.remove(VideoPlayer.CLASSES.HIDDEN)\n }\n }\n\n /**\n * Toggle Video\n */\n togglePlay = () => {\n if (this.videoEl.paused) {\n this.play()\n } else {\n this.pause()\n }\n }\n\n /**\n * Play Video and update button\n * @param {object} event - Event object\n * @param {boolean} event.forcePause - Force the video to play without checking if it is already playing\n */\n play = ({ forcePlay = false, triggerAnalyticsEvent = false } = {}) => {\n if (this.videoEl?.paused || forcePlay) {\n this.videoEl.play()\n this.EventEmitterService.emit(VideoPlayer.EVENTS.PLAY, {\n videoId: this.videoElId\n })\n\n if (triggerAnalyticsEvent) {\n this.videoEl.dispatchEvent(new Event('play'))\n }\n\n if (this.playButton) {\n this.playButton.setAttribute(\n VideoPlayer.ATTRIBUTES.PLAY_BUTTON_STATUS,\n false\n )\n this.playButton.setAttribute(\n 'aria-label',\n this.element.getAttribute(VideoPlayer.ATTRIBUTES.PAUSE_BUTTON_LABEL)\n )\n\n if (\n this.playButtonEl.getAttribute(\n VideoPlayer.ATTRIBUTES.HIDE_PLAY_BUTTON_AFTER_PLAY\n ) === 'true'\n ) {\n this.playButtonEl.classList.add(VideoPlayer.CLASSES.HIDDEN)\n }\n\n if (this.hasControls && !this.videoEl.getAttribute('controls')) {\n // reenable the controls when the custom play button is enabled and controls has been set\n this.videoEl.setAttribute('controls', '')\n }\n }\n }\n }\n\n /**\n * Stop Video\n */\n stop = ({ triggerAnalyticsEvent = false }) => {\n this.hasStarted = false\n this.videoEl.pause()\n this.EventEmitterService.emit(VideoPlayer.EVENTS.STOP, {\n videoId: this.videoElId\n })\n\n if (triggerAnalyticsEvent) {\n this.videoEl.dispatchEvent(new Event('pause'))\n // reset the video to the beginning after a pause event\n // setting a timeout give the debounce function time to clear so that\n // timeupdate event is not fired\n setTimeout(() => {\n this.videoEl.currentTime = 0\n }, 500)\n } else {\n this.videoEl.currentTime = 0\n }\n }\n\n /**\n * Pause Video and update play button\n * @param {object} event - Event object\n * @param {boolean} event.forcePause - Force the video to pause without checking if it is already paused\n */\n pause = ({ forcePause = false } = {}) => {\n if (!this.videoEl?.paused || forcePause) {\n this.videoEl.pause()\n this.EventEmitterService.emit(VideoPlayer.EVENTS.PAUSE, {\n videoId: this.videoElId\n })\n\n if (this.playButton) {\n this.playButton.setAttribute(\n VideoPlayer.ATTRIBUTES.PLAY_BUTTON_STATUS,\n true\n )\n\n this.playButton.setAttribute(\n 'aria-label',\n this.element.getAttribute(VideoPlayer.ATTRIBUTES.PLAY_BUTTON_LABEL)\n )\n }\n }\n }\n\n /**\n * Process a Remote play event\n * @param {object} event - Event object\n * @param {string} event.videoId - Video ID\n */\n remotePlay = (event) => {\n const { videoId } = event\n\n if (videoId === this.videoElId) {\n this.play({ forcePlay: true })\n }\n }\n\n /**\n * Process a Remote pause event\n * @param {object} event - Event object\n * @param {string} event.videoId - Video ID\n */\n remotePause = (event) => {\n const { videoId } = event\n\n if (videoId === this.videoElId) {\n this.pause({ forcePause: true })\n }\n }\n\n /**\n * When the video ends, emit a STOP event, reset the poster image and show play button\n */\n handleVideoEnd = () => {\n this.EventEmitterService.emit(VideoPlayer.EVENTS.STOP, {\n videoId: this.videoElId\n })\n this.initPlayButton()\n this.videoEl.load()\n }\n}\n","import classNames from 'utilities/classnames'\nimport { POSITIONS as PLAY_BUTTON_POSITIONS } from 'modules/PlayIcon/PlayIcon.template'\n\nexport { PLAY_BUTTON_POSITIONS }\n\n/**\n * Render Video Player component template\n * @param {Object} args\n * @param {Array} args.dataAttributes Additional data attributes\n * @param {Object} args.a11y\n * @param {String} args.a11y.playLabel Play button label\n * @param {String} args.a11y.pauseLabel Pause button label\n * @param {String} addClassName Additional class name\n * @param {Boolean} autoplay enable autoplay\n * @param {String} buttonClassName Button class name\n * @param {Boolean} hideControls hide controls\n * @param {Boolean} hidePlayButtonAfterPlay hide play button after video is played the first time\n * @param {String} id Component ID\n * @param {Boolean} muted mute video\n * @param {String} playButtonPosition play button position\n * @param {Boolean} playsInline play video inline\n * @param {String} posterSrc Video poster image\n * @param {Boolean} showPlayButton show play/pause button\n * @param {String} videoSrc Video source\n */\nconst VideoPlayerTemplate = ({\n a11y: { playLabel = 'Play', pauseLabel = 'Pause' } = {},\n addClassName = '',\n autoplay = false,\n buttonClassName = '',\n hideControls = false,\n hidePlayButtonAfterPlay = false,\n id = '',\n muted = false,\n playButtonPosition = PLAY_BUTTON_POSITIONS.BOTTOM_RIGHT,\n playsInline = false,\n posterSrc = '',\n showPlayButton = false,\n videoSrc,\n dataAttributes,\n videoCaptions\n}) => /* HTML */ `\n \n ${showPlayButton\n ? `
    `\n : ''}\n \n ${videoCaptions && videoCaptions.src\n ? `\n \n `\n : ''}\n Your browser does not support the video tag.\n \n \n`\n\nexport default VideoPlayerTemplate\n"],"names":["_ref","addClassName","altText","defaultAspectRatio","defaultSrc","loading","mobileAspectRatio","mobileSrc","classNames","ColorPicker","static","WHEEL","INPUT_HEX","INPUT_RGB","constructor","element","height","onChange","noop","initialColor","theme","arguments","length","undefined","this","services","Services","getInstance","resizeService","ResizeService","init","template","html","inputTemplate","accessibilityLabel","dataAttributes","id","label","name","getNode","cacheDom","createWheel","attachEvents","render","setPickerWidth","wheelEl","querySelector","SELECTORS","inputHex","inputsRgb","querySelectorAll","addEventListener","onHexChange","forEach","input","onRgbChange","wheel","on","onWheelChange","addCallback","detachEvents","removeEventListener","off","removeCallback","destroy","iro","display","width","boxHeight","color","layout","component","ui","Box","Slider","options","sliderType","sliderSize","setHexInput","hex","value","setRgbInputs","rgb","dataset","offsetWidth","resize","hexString","event","set","currentTarget","e","colorType","r","g","b","toString","insert","POSITIONS","BOTTOM_LEFT","BOTTOM_RIGHT","CENTER","TOP_LEFT","TOP_RIGHT","SIZES","LARGE","SMALL","a11y","buttonLabel","playLabel","pauseLabel","isButton","isInline","position","size","isBlackAndWhite","tag","join","Icon","icon","ProductInfo","collection","glassAvailable","benefits","cta","constructionEyebrow","featuredInEyebrow","comingSoonEyebrow","titleTemplate","text","headingElement","headingType","TITLE_TYPES","H4","ally","textTemplate","textElement","textType","TEXT_TYPES","BODY_XSM","Array","isArray","map","benefit","linkTemplate","href","url","target","linkStyle","linkButtonStyle","linkTextStyle","linkSize","showAsButtonLink","startIcon","analytics","cta_text","cta_title","_ref2","alignment","fullWidth","moduleSpacing","tabs","displaySelect","find","tab","isActive","title","index","displayTabs","disabled","Tab","displayContent","content","getCustomColor","option","customColorPrefix","isCustomColor","includes","split","activeOptionImageTemplate","selectedOption","displayDarkImage","imageDark","imageTemplate","image","categoryTemplate","category","optionDetailsTemplate","tooltip","rangeLabel","rangeMax","rangeMin","isToggleButton","isColor","type","customColor","CTA_LG","iconTemplate","BODY_SM","CALLOUT","rangeValue","CAPTION","from","_","i","rangeTemplate","range","viewMoreButton","_ref6","isLargeBreakpoint","optionsWrapperId","_ref9","groupValue","groupType","maxOptions","hasOptions","tile","tileText","helperLabel","labelAccessibility","_ref5","categoryValue","optionId","isDisabled","isSelected","customColorTemplate","tileOptionTemplate","_ref4","tileTextOptionTemplate","_ref3","textOptionTemplate","categoryOptionTemplate","note","_ref8","noteTemplate","_ref7","viewMoreTemplate","defaultOpen","children","closeButtonAriaLabel","closeButtonClass","fullScreen","hasHeader","modalClass","transition","headerTitle","modalContent","description","optionTools","isMediumLarge","BODY_MEDIUM","buttonTemplate","buttonSize","buttonStyle","cancel","select","desktopButtons","mobileButtons","ProductOptionCustomColor","BUTTON_CANCEL","BUTTON_SELECT","COLOR_PICKER_BUTTON","COLOR_PICKER","MODAL","onSelect","onCancel","EventEmitterService","mediaQuery","BreakpointListener","queryMatch","pendingColor","modalTemplate","cancelAccessibility","MEDIUM_LARGE","colorPickerButtonEl","colorPickerEl","modalEl","buttonSelect","buttonCancel","Modal","EVENTS","CLOSE_MODAL","onModalClose","onSelectHandler","onCancelHandler","addListener","onBreakpointChange","removeListener","setColor","openColorPicker","modal","requestAnimationFrame","open","colorPicker","modalId","close","breakpoint","hasChanged","ProductOptionCategory","INPUT","OPTIONS","OPTION","OPTION_CUSTOM_COLOR_INPUT","OPTION_CUSTOM_COLOR_LABEL","CUSTOM_COLOR","VIEW_MORE","VIEW_MORE_LABEL","OPTION_HIDE","VIEW_MORE_EXPANDED","MAX_OPTIONS","isExpanded","createCustomColor","checkViewMore","optionsEl","optionEls","optionCustomColorInput","optionCustomColorLabel","customColorEl","viewMoreButtonEls","viewMoreLabelEls","viewMoreButtonEl","toggleViewMore","onCustomColorInputSelect","colorPrefix","customColorOption","indexOf","productOptionCustomColor","helperText","onCustomColorSelect","key","stopImmediatePropagation","replace","checked","dispatchEvent","Event","selectedOptionIdx","findIndex","expandViewMore","collapseViewMore","optionEl","classList","remove","CLASSES","setAttribute","removeAttribute","add","seeLessAccessibility","viewMoreLabelEl","innerHTML","seeLess","seeAllAccessibility","seeAll","ProductOptionGroup","TABS","DRAWER","TOGGLE","TOGGLE_CONTENT","DETAILS","SUBMIT_BUTTON","CANCEL_BUTTON","MORE_DETAILS","TOOLTIP_TOGGLE_BUTTON","TOOLTIP_DRAWER_INFO","ACTIVE_GROUP","DISABLED_GROUP","THEME_LIGHT","THEME_DARK","onProductSelect","onProductSubmit","onProductCancel","categories","tooltipsToggleButtons","isDrawerOpen","eventEmitterService","analyticsService","Analytics","hasSingleOption","reduce","acc","concat","tabsTemplate","disableTabsScrollIntoView","categoryTabsTemplate","moreDetails","detailsId","showAsTextLink","moreDetailsTemplate","getSelectedOption","createCategories","createToggleButton","createDrawerTooltips","createTabs","setTheme","setDisabledDrawer","tabsEl","optionInputs","optionDrawer","optionToggleButton","optionToggleButtonContent","submitButton","cancelButton","onProductSelectHandler","onToggleFocus","onToggleKeydown","toggleDrawer","onSubmit","onMoreDetails","closeDrawer","group","optionValue","preventDefault","emit","Tabs","SWITCH_TAB","tabsId","tabId","setTimeout","tabNav","document","getElementById","scrollIntoView","behavior","toggleButton","optionInfoTemplate","toggleButtonTemplate","createTooltipToggleButtons","categoryEl","el","createElement","appendChild","tooltipToggleButtonsEls","tooltipEl","tooltipContent","createTooltip","push","tooltipsDrawers","tooltipDrawerEls","tippy","allowHTML","animateFill","interactive","placement","trigger","flipOnUpdate","onTrigger","instance","onUntrigger","getSelectedCategoryIndex","getAllOptions","THEMES","LIGHT","DARK","setActiveTab","activeCatIdx","activeTabId","Object","keys","tabIds","switchTab","setSelectedOptions","optionsApplied","prevSelectedOption","hasDisabledChanged","allOptions","hasOptionChanged","customColorIdx","val","setOptionDetails","optionDetails","updatedOptionDetails","optionDetail","replaceWith","cloneNode","inline","block","eyCode","openDrawer","actionOnClickOutside","limitKeyboardAccessibility","trackDrawer","focus","clearListener","clearKeyHandler","action","trackInteraction","state","toLowerCase","ProductOptionFilters","filters","onFilterSelect","filterOptions","filter","checkboxItemTemplate","onFilterSelectHandler","filterId","ProductOptions","PRODUCT_OPTION_FILTERS","PRODUCT_OPTION_WRAPPER","PRODUCT_OPTION_MESSAGE","PRODUCT_OPTION_MESSAGE_ICON","PRODUCT_OPTION_MESSAGE_TEXT","FILTER_OPTION","MESSAGE_ACTIVE","productModel","productOptions","createProductOptions","createOptionFilters","productOptionFilterItemsEl","productOptionWrapperEl","productOptionMessageTextEl","productOptionMessageEl","onModelUpdate","context","getState","productFilterOptions","pendingOptions","setProductOptionMessage","hasModifiedSelectedOption","optionMessages","message","modifiedOption","setFilter","autoApply","getCurrentBreakpoint","setOption","applyOptions","cancelOptions","data","optionGroup","scripts","ProductShare","shareTooltip","shareCopy","sharePinterest","successMessage","product","share","pinterest","copy","copySuccess","loadPinterestScript","copyHandler","isPinterestLoaded","window","PinUtils","onPinterestClick","navigator","clipboard","writeText","then","hasAttribute","showSuccessMessage","trackShare","showShareCopy","urlPath","onComplete","headElm","script","src","defer","onload","onerror","loadDependency","onPinterestLoaded","isLoaded","pinOne","media","product_name","product_share_type","ProductTools","PRODUCT_SAVE","PRODUCT_SHARE","createProductSave","createProductShare","productSaveEl","productShareEl","productSave","ProductSave","showCta","productShare","ProductMediaThumbnails","THUMBAIL_BUTTON","THUMBNAIL_ACTIVE","mediaGallery","mediaItem","isSlab","playIconTemplate","PLAY_BUTTON_POSITIONS","PLAY_BUTTON_SIZES","poster","alt","thumbnailButtons","button","setActiveThumbnail","contains","ProductMediaImage","ProductMediaVideo","VIDEO_PLAYER","videoPlayer","videoPlayerTemplate","hidePlayButtonAfterPlay","playButtonPosition","playsInline","posterSrc","showPlayButton","videoSrc","videoPlayerEl","VideoPlayer","visualizer","arModalMessage","ProductMediaVisualizer","HIDE","VISUALIZER_BUTTON","initialData","getInitialData","hasDependency","focusableElements","createPlayer","setupButtonClone","isMobileDevice","userAgent","opera","test","checkForButton","arButton","newButton","setupModal","parentNode","insertBefore","style","addEventListeners","viewDoorButton","click","onVisualizerButtonClick","masonite","pip","JSON","parse","console","error","body","onModalOpen","attachVisualizerButtonEvents","visualizerButton","showARModal","OPEN_MODAL","detachVisualizerButtonEvents","Promise","resolve","reject","library","Error","isInterior","threekitPlayer","authToken","customId","initialConfiguration","getConfiguration","cache","maxAge","cacheMaxAge","scope","cacheScope","showConfigurator","showAR","showShare","classnames","mobile","popup","ar","fullscreen","help","showLoadingThumbnail","showLoadingProgress","publishStage","async","player","when","configurator","getConfigurator","stageConfigurator","getStageConfigurator","getSnapshot","convertHexToRgbScale","hexValue","parseInt","substring","sku","disabledOptions","getOptions","optionParams","getOptionParams","configuration","Door","isDisabledOption","some","Color","PaintColorPicker","log","setConfiguration","setScene","sceneId","Backplate","savedScene","snapshotAsync","mimeType","setVisualizerSnapshot","hideVisualizer","getFocusableElements","showVisualizer","ProductMediaGallery","THUMBNAILS","MEDIA","MEDIA_VISUALIZER","MEDIA_WRAPPER","TOOLS","SLOT_1","SLOT_2","createProductTools","createThumbnails","createMediaPlayer","setContentOrder","thumbnailsEl","mediaEl","mediaVisualizerEl","productToolsEl","productMediaWrapperEl","productMediaSlot1El","productMediaSlot2El","productMediaThumbnails","onThumbnailSelect","isVisualizerEnabled","empty","mediaVisualizer","isVisualizer","createMediaVisualizer","createMediaVideo","createMediaImage","mediaImage","mediaVideo","backplateScene","customOptions","tools","visualizerSnapshot","productTools","location","MEDIUM","trackThumbnailClick","image_title","_state","_event","contentMap","doorFeatures","features","additionalFeaturesLabel","additionalFeatures","BODY_LG","TEXT_THEMES","feature","displayFeatures","BODY_MD_INLINE","BODY_MD","displayAdditionalFeatures","productSpecifications","specs","measurements","measurementText","measurementLink","measurementLinkText","widthLabel","heightLabel","widths","heights","available","EYEBROW","technicalDocuments","documents","showAsDownloadLink","file_extension","file_name","click_url","displayDocumentsLinks","ProductDetails","TABS_CMP","DOOR_FEATURES","PRODUCT_SPECIFICATIONS","MEASUREMENTS","TECHNICAL_DOCUMENTS","TOOLTIP","details","productDetails","entries","contentFunc","generateProductDetails","createTooltips","doorFeaturesEl","productSpecificationsEl","measurementsEl","technicalDocumentsEl","productDetailsCategories","tabsCmpEl","ProductRelatedContent","ProductInformationModel","initialState","queryFilters","queryOptions","listeners","parseInitialData","machine","createMachine","initial","states","idle","UPDATE_FILTERS","actions","UPDATE_OPTIONS","APPLY_OPTIONS","CANCEL_OPTIONS","SET_VISUALIZER_SNAPSHOT","updateFilters","assign","updatedFilters","updateOptions","updatedOptions","meta","snapshot","machineService","interpret","start","subscribe","onUpdate","listener","l","filterOption","idx","isCustomColorOption","isCustomColorQuery","parsedOptions","parseOptions","controlledOptions","selectedOptionValues","values","parseSelectedOptions","controls","control","hasDisabledSelectedOption","updatedOptionGroup","prototype","hasOwnProperty","call","mustHaveOne","hasMustHave","mustHave","isDefaultSelected","j","send","o","c","params","selectedOptions","getSelectedOptions","ProductInformationRouter","History","setOptions","origin","pathname","searchParams","URLSearchParams","search","has","delete","replaceState","get","hasParam","isValidOption","ProductInformation","PRODUCT_INFO","PRODUCT_OPTIONS","PRODUCT_MEDIA_GALLERY","PRODUCT_DETAILS","PRODUCT_RELATED_CONTENT","PRODUCT_CONFIG_SLOT_1","PRODUCT_CONFIG_SLOT_2","PRODUCT_CONFIG_SLOT_3","PRODUCT_CONFIG_SLOT_4","createProductInformationRouter","createProductInformationModel","createProductInfo","createProductMediaGallery","creatProductDetails","createProductRelatedContent","productInfoEl","productOptionsEl","productMediaGalleryEl","productDetailsEl","productRelatedContentEl","productConfigSlot1El","productConfigSlot2El","productConfigSlot3El","productConfigSlot4El","productInformationModel","renoveListener","productInformationRouter","productInfo","wtbCta","productMediaGallery","productRelatedContent","relatedArticles","trackOptions","payload","product_info_selection","Notification","NOTIFICATION_BUTTON","NOTIFICATION_CONTAINER","NOTIFICATION","Link","args","showAsListLink","initializeNotificationTimeout","closeButton","handleClose","notificationTimeout","clearTimeout","TIMERS","parentElement","SAVE_BUTTON","SAVE_ICON","STATUS","BLANK_SAVED","BUTTON_SAVED","ACTIVE","NOTIFICATION_ITEM","SAVED","REMOVED","ERROR","SAVE","REMOVE","DISMISS_NOTIFICATION","ATTRIBUTE","VALUE","isFavorite","linesToDisplay","saved","save","initializeSavedState","createNotificationContainer","saveButton","saveIcon","saveLabel","lastElementChild","handleClick","notification","productExists","localStorage","getItem","stringify","sortObjectKeys","applyState","ProductSaveSaved","innerText","notificationContainer","DATA_ATTRIBUTES","createNotification","notificationEl","saveSuccess","previousNotification","handleSave","favoriteObject","doorFavorites","setItem","handleRemove","filteredProducts","saveRemove","MESSAGES","trackSave","saveError","isSave","product_favorite_type","VIDEO","PLAY_BUTTON","PLAY_BUTTON_STATUS","PLAY_BUTTON_LABEL","PAUSE_BUTTON_LABEL","PLAY_BUTTON_POSITION","HIDE_PLAY_BUTTON_AFTER_PLAY","PLAY","PAUSE","STOP","PLAY_VIDEO","PAUSE_VIDEO","HIDDEN","videoProgressMarkers","Map","trackInteractionDebounce","debounce","hasStarted","initPlayButton","videoEl","playButtonEl","hasControls","videoElId","playButton","togglePlay","handleVideoEnd","remotePlay","remotePause","removeEvents","videoType","filterAnalyticsEvent","video_title","video_status","video_view","video_url","currentSrc","video_provider","progress","Math","floor","currentTime","duration","progressMarkers","video_percent","slice","eventThreshold","hasPlayButton","getAttribute","ATTRIBUTES","fromTemplate","playIcon","autoplay","paused","play","pause","_this","forcePlay","triggerAnalyticsEvent","videoId","stop","_this2","forcePause","load","buttonClassName","hideControls","muted","videoCaptions","srclang"],"sourceRoot":""}