{"version":3,"file":"variant-selector-elements-section-xxxxxxxxxxxxxxxxxxxx.min.js","mappings":"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","sources":["webpack://lange/./scripts/sections/variant-selector-elements/variant-category/index.ts","webpack://lange/./scripts/sections/variant-selector-elements/variant-selector-option/index.ts","webpack://lange/webpack/bootstrap","webpack://lange/./scripts/sections/variant-selector-elements/variant-selector/index.ts","webpack://lange/./scripts/sections/variant-selector-elements/variant-selector/index.scss","webpack://lange/./scripts/sections/variant-selector-elements/variant-selector/index.html"],"sourcesContent":["/**\n * This is a placeholder element that carries data properties for a variant category. It has no\n * functionality, just for semantic mark-up. Used to group product variants in the variant selector\n * under categories.\n */\nclass VariantCategory extends HTMLElement {\n  readonly dataset: {\n    /**\n     * Product description for the category.\n     * When the user select a variant from this category, this description will be shown instead of\n     * the main product description.\n     */\n    description?: string;\n\n    /**\n     * Unique ID for the category.\n     * Used to match variants to their categories.\n     */\n    id: string;\n\n    /**\n     * Title of the category.\n     * Category title shown to the user on the page.\n     */\n    title: string;\n  };\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    'variant-category': VariantCategory;\n  }\n}\n\nif (!customElements.get('variant-category')) {\n  customElements.define('variant-category', VariantCategory);\n}\n","/**\n * This is a placeholder element that carries product variant option data, needed for the variant\n * selector functionality. It has no functionality itself.\n */\nclass VariantSelectorOption extends HTMLElement {\n  readonly dataset: {\n    /**\n     * Boolean represented as string representing product availability\n     */\n    available: 'false' | 'true';\n\n    /**\n     * CSS class to set a color associated with variant option as a background for the color swatch\n     */\n    backgroundClass: string;\n\n    /**\n     * Color swatch badge label, e.g. \"New\"\n     */\n    badge: string;\n\n    /**\n     * Badge style, only \"default\", \"highlighted\" are supported now\n     */\n    badgeStyle: string;\n\n    /**\n     * Option group name of a subproduct's bundle product. The name is a combination of the\n     * product title and option group name in parentheses to ensure uniqueness among multiple\n     * bundle options with the same option group name, e.g. \"ELATION (Shade)\"\n     */\n    bundleOptionGroup: string;\n\n    /**\n     * Category ID this variant option belongs to.\n     * Categories are used to group product variants in the variant selector. Passing category ID\n     * here allows to match variant options to their categories.\n     */\n    categoryId: string;\n\n    /**\n     * Variant's compare at price, a stringified integer representing cents, e.g. \"1200\" means $12\n     */\n    compareAtPrice: string;\n\n    /**\n     * Content to be displayed in the compare at price modal for a particular variant\n     */\n    compareAtPriceModalContent: string;\n\n    /**\n     * Variant additional short description\n     */\n    description: string;\n\n    /**\n     * Discount offer message\n     */\n    discountMessage: string;\n\n    /**\n     * List of filter groups this variant option belongs to, separated by \"|\", e.g.\n     * \"Light|Bright|Warm\". It's optional and used for some products for filtering variant options\n     * in the variant selector.\n     */\n    filterGroup: string;\n\n    /**\n     * Options group name, e.g. \"Color\", \"Shade\"\n     */\n    group: string;\n\n    /**\n     * Variant image src\n     */\n    image: string;\n\n    /**\n     * Variant's price, a stringified integer representing cents, e.g. \"1200\" means $12\n     */\n    price: string;\n\n    /**\n     * Top badge label, e.g. \"50% off\", \"Sale\"\n     */\n    topBadge: string;\n\n    /**\n     * Top badge style (black or red color), e.g. \"default\", \"highlighted\"\n     */\n    topBadgeStyle: 'default' | 'highlighted';\n\n    /**\n     * Variant associated option name\n     */\n    value: string;\n\n    /**\n     * Variant ID, a stringified integer\n     */\n    variantId: string;\n  };\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    'variant-selector-option': VariantSelectorOption;\n  }\n}\n\nif (!customElements.get('variant-selector-option')) {\n  customElements.define('variant-selector-option', VariantSelectorOption);\n}\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","import type { CustomElement } from '@integrabeauty/custom-elements';\nimport html from './index.html';\nimport styles from './index.scss';\n\n/**\n * A custom element for selecting product variants. Includes list of selectable options and\n * the title and description of the selected variant.\n *\n * The data for all variants are stored as `<variant-selector-option>` elements. Each element\n * contains data-attributes, which store the values needed to handle the variant selector's\n * functionality.\n *\n * This component can optionally group variants into categories using `<variant-category>` elements.\n * Each category can have its own title and alternative product description that should be displayed\n * when a variant from that category is selected.\n *\n * TODO: Check accessibility. Since we change the description dynamically, there might be\n * accessibility issues or improvements we need to make.\n *\n * This custom element doesn't gather all variants data to an object. It's easily accessible via\n * `querySelector`, we don't need to access it frequently, nor process this data. The selected\n * variant is also not stored as a class property and taken via `querySelector('input:checked')`.\n *\n * Currently, only one option group is used for products, but technically a Shopify product can have\n * multiple options, e.g. \"Color\", \"Size\" etc.\n */\nclass VariantSelector extends HTMLElement implements CustomElement {\n  readonly dataset!: {\n    /**\n     * Boolean represented as string that indicates whether the element is expandable or not.\n     * If categories are used, expandable must be false.\n     */\n    expandable: 'false' | 'true';\n\n    /**\n     * Set the horizontal alignment of the component on desktop. Depending on where it's placed we\n     * need to make the elements of the component centered.\n     */\n    horizontalAlignmentDesktop: 'center';\n\n    /**\n     * Set the horizontal alignment of the component on mobile. Depending on where it's placed we\n     * need to make the elements of the component centered.\n     */\n    horizontalAlignmentMobile: 'center';\n\n    /**\n     * The ID of the initially selected product variant, a stringified integer\n     */\n    initSelectedVariantId: string;\n\n    /**\n     * A string representing a boolean that indicates whether the component is being used for a\n     * gift card product.\n     *\n     * Depending on whether this is a basic product or a gift card, the component should be\n     * rendered and styled differently.\n     */\n    isGiftCard: 'false' | 'true';\n\n    /**\n     * Product ID, a stringified integer\n     */\n    productId: string;\n\n    /**\n     * Set the size of the component. We need the variant selector component in different sizes\n     * depending on where it's placed. It affects only styles.\n     *\n     * TODO: The `lagre` option is not in use for now and most likely we won't need it. I'll keep it\n     * here for now and remove later if really not needed.\n     */\n    size: 'large' | 'medium' | 'small';\n\n    /**\n     * Represents the possible variants for the title style.\n     *\n     * <strong>Berry</strong> - Muted Plum with Cool Undertones\"\n     * Default: variant name + variant short description, e.g.\"Berry - Muted Plum with Cool\n     * Undertones\"\n     * Condensed: variant name, e.g. \"Berry\"\n     */\n    titleFormat: 'condensed' | 'default' | 'none';\n  };\n\n  public shadowRoot!: ShadowRoot;\n  private onInputChangedBound = this.onInputChanged.bind(this);\n  private onExpandButtonClickedBound = this.onExpandButtonClicked.bind(this);\n  private onFilterClickedBound = this.onFilterClicked.bind(this);\n  private onSlotChangeBound = this.onSlotChange.bind(this);\n\n  public constructor() {\n    super();\n    this.attachShadow({ mode: 'open' });\n    this.shadowRoot.innerHTML = `<style>${styles}</style>${html}`;\n  }\n\n  public connectedCallback() {\n    this.render();\n  }\n\n  public disconnectedCallback() {\n    const slot = this.shadowRoot.querySelector('slot');\n    slot.removeEventListener('slotchange', this.onSlotChangeBound);\n\n    this.shadowRoot.removeEventListener('change', this.onInputChangedBound);\n\n    const expandButton = this.shadowRoot.querySelector('.expand');\n    if (expandButton) {\n      // Checking this condition is important. The expand buttons are added only if the attribute\n      // data-expandable=\"true\" is set and the variant selector contains more than 4 options. Also,\n      // we remove it after clicking.\n      expandButton.removeEventListener('click', this.onExpandButtonClickedBound);\n    }\n\n    const filters = this.shadowRoot.querySelectorAll('.filters button');\n    for (const filter of filters) {\n      filter.removeEventListener('click', this.onFilterClickedBound);\n    }\n  }\n\n  private render() {\n    const slot = this.shadowRoot.querySelector('slot');\n    slot.addEventListener('slotchange', this.onSlotChangeBound);\n  }\n\n  /**\n   * Handles the `slotchange` event. When the slot is populated with `<variant-selector-option>`\n   * elements, it calls the `onSlotReady` method to proceed with rendering and event setup.\n   * DOMContentLoaded is not reliable for cases when this component is slotted into another\n   * component, like in the upsell modal.\n   */\n  private onSlotChange(e: Event) {\n    const slot = <HTMLSlotElement>e.target;\n    const assignedElements = slot.assignedElements();\n    if (assignedElements.length > 0) {\n      this.onSlotReady();\n    }\n  }\n\n  /**\n   * Renders the variant selector options when the default slot is populated with child elements.\n   */\n  private onSlotReady() {\n    this.renderFilters();\n\n    // Checking for categories\n    const categories =\n      this.querySelectorAll<HTMLElementTagNameMap['variant-category']>('variant-category');\n\n    // Having categories affects some logic later, so we store this info\n    const hasCategories = categories.length > 0;\n\n    if (hasCategories) {\n      // Rendering categories if they exist. Creating a document fragment which will be appended\n      // to the DOM in one operation for better performance.\n      const categoriesFragment = document.createDocumentFragment();\n\n      for (const category of categories) {\n        const categoryContainer = document.createElement('div');\n        categoryContainer.classList.add('category');\n\n        const title = document.createElement('h3');\n        title.classList.add('category-title');\n        title.textContent = category.dataset.title;\n        categoryContainer.appendChild(title);\n\n        categoriesFragment.appendChild(categoryContainer);\n\n        // Rendering options container. We don't need to check if there are options, because\n        // category data is stored in the variant metafield, which means that if there are\n        // categories, there will be options for each category.\n        const optionsContainer = document.createElement('div');\n        optionsContainer.classList.add('options');\n        categoryContainer.appendChild(optionsContainer);\n\n        // Searching for options that belong to this category, rendering and appending them to\n        // the options container.\n        const options = this.querySelectorAll<HTMLElementTagNameMap['variant-selector-option']>(\n          `variant-selector-option[data-category-id=\"${category.dataset.id}\"]`);\n        for (const variant of options) {\n          const optionElement = this.createOptionElement(variant);\n          optionsContainer.appendChild(optionElement);\n        }\n      }\n\n      // All categories elements are created, appending them to the shadow DOM\n      const categoriesContainer = this.shadowRoot.querySelector('.categories');\n      categoriesContainer.appendChild(categoriesFragment);\n    }\n\n    // Rendering the remaining variant options that don't belong to any category based on data\n    // stored in `<variant-selector-option>` elements. These options will be rendered in the\n    // main options container. Creating a document fragment to improve performance.\n    //\n    // We don't expect to have options that don't belong to any category when categories are used,\n    // but just in case we handle this scenario too.\n    const options = this.querySelectorAll<HTMLElementTagNameMap['variant-selector-option']>(\n      'variant-selector-option:not([data-category-id])');\n    if (options.length > 0) {\n      const optionsFragment = document.createDocumentFragment();\n      for (const variant of options) {\n        const optionElement = this.createOptionElement(variant);\n        optionsFragment.appendChild(optionElement);\n      }\n\n      const optionsContainer = this.shadowRoot.querySelector('.options');\n\n      // Handling expandable variant selector.\n      // It's turned on via the `data-expandable=\"true\"` attribute but only if there are more than\n      // 4 options.\n      //\n      // Also, we need to force-disable it if there are categories, categories are designed to\n      // be used on the PDP only, while expandable variant selector is for product cards, but\n      // just for safety we add this check.\n      if (this.dataset.expandable === 'true' && options.length > 4 && !hasCategories) {\n        optionsContainer.classList.add('collapsed');\n\n        // Creating expand button and add it to the options container. We store the button HTML\n        // in a template element in the shadow DOM to keep the code clean and not create the\n        // button via explicit DOM methods.\n        const expandButtonTemplate =\n          this.shadowRoot.querySelector<HTMLTemplateElement>('#expand-button');\n        optionsFragment.appendChild(expandButtonTemplate.content.cloneNode(true));\n\n        // The HTMLTemplateElement.content.cloneNode() method returns a DocumentFragment, so we\n        // can't attach any event listener directly to it. We need to query the button\n        // after appending the fragment. Hovever, optionsFragment is a DocumentFragment too it's\n        // possible to add the event listener before appending to the DOM to any element inside but\n        // not to the fragment itself.\n        const expandButton = optionsFragment.querySelector('.expand');\n        expandButton.addEventListener('click', this.onExpandButtonClickedBound);\n      }\n\n      // Appending remaining options to the main options container.\n      optionsContainer.appendChild(optionsFragment);\n    }\n\n    this.renderTitle();\n\n    // attaching event listeners\n    this.shadowRoot.addEventListener('change', this.onInputChangedBound);\n\n    // Sending initial event\n    const selector =\n      `variant-selector-option[data-variant-id=\"${this.dataset.initSelectedVariantId}\"]`;\n    type VariantSelectorOptionType = HTMLElementTagNameMap['variant-selector-option'];\n    let initialVariant = this.querySelector<VariantSelectorOptionType>(selector);\n    if (!initialVariant) {\n      // There's a strange error in Sentry. I cannot reproduce so trying to catch it. I assume\n      // that `this.dataset.initSelectedVariantId` is not passed sometimes. If it helps we\n      // will investigate more why it happens.\n      const variantOptions = this.querySelectorAll('variant-selector-option');\n      const options = [];\n      for (const variantOption of variantOptions) {\n        options.push({\n          variantId: variantOption.dataset.variantId,\n          value: variantOption.dataset.value,\n          available: variantOption.dataset.available\n        });\n      }\n\n      Sentry.captureMessage('Variant selector initial variant not found', {\n        level: 'warning',\n        extra: {\n          initSelectedVariantId: this.dataset.initSelectedVariantId,\n          productId: this.dataset.productId,\n          parentElement: this.parentElement,\n          options\n        }\n      });\n\n      // Fallback to the first variant\n      initialVariant = this.querySelector<VariantSelectorOptionType>('variant-selector-option');\n    }\n\n    const category = this.findCategoryForVariant(initialVariant);\n\n    const variantChangedEvent = new CustomEvent<VariantChangedEvent['detail']>('variant-changed', {\n      cancelable: false,\n      bubbles: true,\n      detail: {\n        initial: true,\n        source: 'variant-selector',\n        variant: {\n          available: initialVariant.dataset.available === 'true',\n          description: initialVariant.dataset.description,\n          id: parseInt(initialVariant.dataset.variantId, 10),\n          product_id: parseInt(this.dataset.productId, 10),\n          coming_soon: false,\n          bundleOptionGroup: initialVariant.dataset.bundleOptionGroup,\n          option: initialVariant.dataset.value,\n          price: parseInt(initialVariant.dataset.price, 10),\n          compareAtPrice: initialVariant.dataset.compareAtPrice,\n          compareAtPriceModalContent: initialVariant.dataset.compareAtPriceModalContent,\n          image: initialVariant.dataset.image ?? '',\n          color: this.getVariantColor(initialVariant.dataset.backgroundClass),\n          discountMessage: initialVariant.dataset.discountMessage ?? '',\n          topBadge: initialVariant.dataset.topBadge ?? '',\n          topBadgeStyle: initialVariant.dataset.topBadgeStyle ?? 'default',\n          categoryDescription: category?.dataset.description ?? null\n        }\n      }\n    });\n    this.dispatchEvent(variantChangedEvent);\n  }\n\n  private onInputChanged(_event: Event) {\n    this.renderTitle();\n\n    const input = this.shadowRoot.querySelector('input:checked');\n    type Variant = HTMLElementTagNameMap['variant-selector-option'];\n    const selector = `variant-selector-option[data-variant-id=\"${input.id}\"]`;\n    const variant = this.querySelector<Variant>(selector);\n    const category = this.findCategoryForVariant(variant);\n\n    const variantChangedEvent = new CustomEvent<VariantChangedEvent['detail']>('variant-changed', {\n      cancelable: false,\n      bubbles: true,\n      detail: {\n        initial: false,\n        source: 'variant-selector',\n        variant: {\n          available: variant.dataset.available === 'true',\n          description: variant.dataset.description,\n          id: parseInt(variant.dataset.variantId, 10),\n          product_id: parseInt(this.dataset.productId, 10),\n          coming_soon: false,\n          bundleOptionGroup: variant.dataset.bundleOptionGroup,\n          option: variant.dataset.value,\n          price: parseInt(variant.dataset.price, 10),\n          compareAtPrice: variant.dataset.compareAtPrice,\n          compareAtPriceModalContent: variant.dataset.compareAtPriceModalContent,\n          image: variant.dataset.image ?? '',\n          color: this.getVariantColor(variant.dataset.backgroundClass),\n          discountMessage: variant.dataset.discountMessage,\n          topBadge: variant.dataset.topBadge ?? '',\n          topBadgeStyle: variant.dataset.topBadgeStyle ?? 'default',\n          categoryDescription: category?.dataset.description ?? null\n        }\n      }\n    });\n    this.dispatchEvent(variantChangedEvent);\n  }\n\n  private onExpandButtonClicked(event: Event) {\n    const button = <HTMLElement>event.currentTarget;\n    button.remove();\n\n    const options = this.shadowRoot.querySelector('.options');\n    options.classList.remove('collapsed');\n  }\n\n  private onFilterClicked(event: Event) {\n    const filter = <HTMLButtonElement>event.currentTarget;\n    const activeFilter = this.shadowRoot.querySelector('.filters button[aria-pressed=\"true\"]');\n\n    if (activeFilter === filter) {\n      return;\n    }\n\n    if (activeFilter) {\n      activeFilter.setAttribute('aria-pressed', 'false');\n    }\n\n    filter.setAttribute('aria-pressed', 'true');\n\n    const name = filter.textContent.toLowerCase();\n    const optionContainers = this.shadowRoot.querySelectorAll<HTMLElement>('.options>div');\n    for (const optionContainer of optionContainers) {\n      const filterGroup = optionContainer.dataset.filterGroup;\n      if (name === 'all' || filterGroup?.includes(name)) {\n        optionContainer.classList.remove('hidden');\n      } else {\n        optionContainer.classList.add('hidden');\n      }\n    }\n  }\n\n  /**\n   * Renders the title and short description based on the selected variant.\n   */\n  private renderTitle() {\n    const titleElement = this.shadowRoot.querySelector('.title');\n    if (this.dataset.titleFormat === 'none') {\n      if (titleElement) {\n        titleElement.remove();\n      }\n\n      return;\n    }\n\n    let checkedInput = this.shadowRoot.querySelector('input:checked');\n    if (!checkedInput) {\n      // This is a fallback, it should not happen normally. Trying to fix a strange Sentry error\n      checkedInput = this.shadowRoot.querySelector('input');\n    }\n\n    type Variant = HTMLElementTagNameMap['variant-selector-option'];\n    const selector = `variant-selector-option[data-variant-id=\"${checkedInput.id}\"]`;\n    const selectedVariant = this.querySelector<Variant>(selector);\n    const { value, description } = selectedVariant.dataset;\n\n    let title = '';\n\n    if (value) {\n      if (this.dataset.isGiftCard === 'true') {\n        title += `<strong>${removeDecimals(value)}</strong>`;\n      } else {\n        title += `<strong>${value}</strong>`;\n      }\n    }\n\n    if (this.dataset.titleFormat !== 'condensed' && description) {\n      title += ` - ${description}`;\n    }\n\n    titleElement.innerHTML = title;\n  }\n\n  private renderFilters() {\n    const options = this.querySelectorAll<HTMLElementTagNameMap['variant-selector-option']>(\n      'variant-selector-option[data-filter-group]');\n    if (options.length === 0) {\n      return;\n    }\n\n    // Gather filters from all variants\n    const allFilters = new Set<string>();\n\n    // We need to always render 'All' filter as the first one, so adding it to the set in advance\n    allFilters.add('all');\n\n    for (const option of options) {\n      const filtersString = option.dataset.filterGroup;\n      if (!filtersString) {\n        continue;\n      }\n\n      const filters = filtersString.split('|');\n      for (const filter of filters) {\n        allFilters.add(filter);\n      }\n    }\n\n    // `size` 1 means that we have only \"All\" filter, which is not really a filter, but just a\n    // way to show all options. So if it's the only filter we have, we don't render the filters\n    // section at all.\n    if (allFilters.size === 1) {\n      return;\n    }\n\n    // render filters\n    const container = this.shadowRoot.querySelector('.filters');\n    for (const filter of allFilters) {\n      const element = document.createElement('button');\n      element.textContent = filter;\n\n      if (filter === 'all') {\n        element.setAttribute('aria-pressed', 'true');\n      } else {\n        element.setAttribute('aria-pressed', 'false');\n      }\n\n      element.addEventListener('click', this.onFilterClickedBound);\n      container.appendChild(element);\n    }\n\n    // Show filters container when we have filters. By default, it's hidden via CSS\n    container.classList.remove('hidden');\n\n    const wrapper = this.shadowRoot.querySelector('.wrapper');\n    wrapper.classList.add('has-filters');\n  }\n\n  /**\n   * Creates an element containing a radio input and label element for a given variant option.\n   * We need to create option elements from different places, so it's separated into its own method.\n   */\n  private createOptionElement(variant: HTMLElementTagNameMap['variant-selector-option']) {\n    // Creating a radia input representing the variant option. It's visually hidden, the label\n    // element is styled to look like the option swatch.\n    const input = document.createElement('input');\n    input.id = variant.dataset.variantId;\n    input.type = 'radio';\n    input.name = variant.dataset.group;\n    input.value = variant.dataset.value;\n    input.classList.add('visually-hidden');\n    if (variant.dataset.available !== 'true') {\n      input.classList.add('unavailable');\n    }\n\n    input.checked = variant.dataset.variantId === this.dataset.initSelectedVariantId;\n\n    // Creating the label element associated with the input. This is the visible part of the option\n    // swatch that the user interacts with.\n    const label = document.createElement('label');\n    label.setAttribute('for', variant.dataset.variantId);\n    label.setAttribute('title', variant.dataset.value);\n    if (variant.dataset.backgroundClass) {\n      label.classList.add(variant.dataset.backgroundClass);\n    }\n\n    // Preparing label inner HTML. We add conditionally different content and then set it to the\n    // label element in one operation.\n    let labelHtml = '';\n\n    // Adding a text label inside the label element. For gift cards, we show the price directly. For\n    // regular products, we add a visually hidden span for screen readers.\n    if (this.dataset.isGiftCard === 'true') {\n      labelHtml = removeDecimals(variant.dataset.value);\n    } else {\n      labelHtml = `<span class=\"visually-hidden\">${variant.dataset.value}</span>`;\n    }\n\n    // Adding badge if exists. It's a small marketing label shown on the color swatch, e.g. \"New\"\n    if (variant.dataset.badge) {\n      const badgeStyleClass = variant.dataset.badgeStyle ?? '';\n      labelHtml += `<span class=\"badge ${badgeStyleClass}\">${variant.dataset.badge}</span>`;\n    }\n\n    // Adding prepared HTML to the label element\n    label.innerHTML = labelHtml;\n\n    // Creating a container for the input and label to return as a single element. We need to wrap\n    // them in a container to keep the structure clean and easier to style.\n    const container = document.createElement('div');\n\n    // If the variant has a filter group, we add this information to the container's dataset. It\n    // will be used later to show/hide options when a filter is applied.\n    if (variant.dataset.filterGroup) {\n      container.dataset.filterGroup = variant.dataset.filterGroup;\n    }\n\n    container.appendChild(input);\n    container.appendChild(label);\n\n    return container;\n  }\n\n  /**\n   * Finds the category element associated with a given variant\n   */\n  private findCategoryForVariant(variant: HTMLElementTagNameMap['variant-selector-option']) {\n    let category: HTMLElementTagNameMap['variant-category'];\n    const categoryId = variant.dataset.categoryId;\n    if (categoryId) {\n      category = this.querySelector<HTMLElementTagNameMap['variant-category']>(\n        `variant-category[data-id=\"${categoryId}\"]`);\n    }\n\n    return category;\n  }\n\n  /**\n   * Retrieves the background color defined in the CSS for a variant color swatch.\n   *\n   * @todo This approach isn't ideal, but it's set up like this for now to get things working.\n   * We need to start discussing a better way to handle variant colors. One idea is to store them in\n   * Shopify so the content team can manage them directly, but this would require more investigation\n   */\n  private getVariantColor(backgroundClass: string) {\n    // e.g., gift card\n    if (!backgroundClass) {\n      return '';\n    }\n\n    const style = this.shadowRoot.querySelector('style');\n    const rules: CSSRuleList = style.sheet.cssRules;\n\n    // Escape exclamation marks and other common problematic characters\n    const escapedBackgroundClass = backgroundClass\n      .replace(/[!\"#$%&'()*+,.:;?@^`{|}~]/g, '\\\\$&');\n\n    for (const rule of rules) {\n      if (rule instanceof CSSStyleRule && rule.selectorText === `.${escapedBackgroundClass}`) {\n        const backgroundColor = rule.style.backgroundColor;\n        if (backgroundColor) {\n          return backgroundColor;\n        }\n      }\n    }\n\n    return '';\n  }\n}\n\n/**\n * Removes the decimal part from a price string if it ends with \".00\".\n *\n * @param priceString - e.g. \"$10.00\"\n */\nfunction removeDecimals(priceString: string): string {\n  return priceString.replace(/\\.00$/, '');\n}\n\n// TODO The detail of the event should be refactored, it's very old and tends to copy the structure\n// and key names of some Shopify object, but there's no sense to do that, we don't need all these\n// values. This object has to be reviewed and only the parameters we need for the variant selector\n// functionality should stay. For now, I leave them as optional for compatibility until the old\n// variant selector is replaced with this custom element for all places.\ntype VariantChangedEvent = CustomEvent<{\n  initial: boolean;\n  source: string;\n  variant: {\n    /**\n     * Indicates whether the variant is available or not.\n     */\n    available: boolean;\n\n    /**\n     * Option group name of a subproduct's bundle product. The name is a combination of the\n     * product title and option group name in parentheses to ensure uniqueness among multiple\n     * bundle options with the same option group name, e.g. \"ELATION (Shade)\"\n     */\n    bundleOptionGroup: string;\n\n    /**\n     * The category description for the variant's category.\n     * It's null if no category description is set or if the variant doesn't belong to any category.\n     */\n    categoryDescription: string | null;\n\n    /**\n     * The variant's color in CSS RGB format, used in the UI to display color swatches.\n     * Returns an empty string if no color is found.\n     *\n     * @example \"rgb(51, 47, 33)\"\n     */\n    color: string;\n\n    /**\n     * Indicates whether the coming soon variant.\n     */\n    coming_soon: boolean | null;\n\n    /**\n     * Variant compare at price. It's possible, that's different variants will have each own\n     * compare at price. Represented as string with currency symbol, e.g. \"$12\"\n     */\n    compareAtPrice: string;\n\n    /**\n     * Content to be displayed in the compare at price modal for a particular variant\n     */\n    compareAtPriceModalContent: string;\n\n    /**\n     * Variant additional short description\n     */\n    description: string | null;\n\n    /**\n     * Discount offer message\n     */\n    discountMessage: string;\n\n    /**\n     * Product variant ID\n     */\n    id: number;\n\n    /**\n     * Variant image src\n     */\n    image: string;\n\n    /**\n     * Variant main media ID\n     *\n     * @todo check if we need it anywhere\n     */\n    media_id?: number | null;\n\n    /**\n     * Variant associated option name\n     */\n    option?: string;\n\n    /**\n     * List of all variant options\n     *\n     * @todo check if we need it anywhere\n     */\n    options?: string[];\n\n    /**\n     * Variant price. It's possible, that's different variants will have each own price, e.g. the\n     * gift card. Represented as cents, e.g. \"1200\" means $12\n     */\n    price?: number;\n\n    /**\n     * Variant product ID\n     */\n    product_id: number;\n\n    /**\n     * Top badge label, e.g. \"50% off\", \"Sale\"\n     */\n    topBadge: string;\n\n    /**\n     * Top badge style (black or red color), e.g. \"default\", \"highlighted\"\n     */\n    topBadgeStyle: 'default' | 'highlighted';\n  };\n}>;\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    'variant-selector': VariantSelector;\n  }\n\n  interface WindowEventMap {\n    'variant-changed': VariantChangedEvent;\n  }\n\n  interface HTMLElementEventMap {\n    'variant-changed': VariantChangedEvent;\n  }\n}\n\nif (!customElements.get('variant-selector')) {\n  customElements.define('variant-selector', VariantSelector);\n}\n","export default \":host{display:block}@media only screen and (max-width:767px){:host([data-horizontal-alignment-mobile=center]){text-align:center}:host([data-horizontal-alignment-mobile=center]) .options{justify-content:center}}@media only screen and (min-width:768px){:host([data-horizontal-alignment-desktop=center]){text-align:center}:host([data-horizontal-alignment-desktop=center]) .options{justify-content:center}}:host([data-size=large]) .expand,:host([data-size=large]) label{height:42px;width:42px}:host([data-size=medium]) .title{font-size:.75rem}@media only screen and (min-width:768px){:host([data-size=medium]) .title{font-size:.875rem}}:host([data-size=medium]) .options{column-gap:0}@media only screen and (min-width:768px){:host([data-size=medium]) .options{column-gap:3px}}:host([data-size=medium]) .expand,:host([data-size=medium]) label{height:28px;width:28px}@media only screen and (min-width:768px){:host([data-size=medium]) .expand,:host([data-size=medium]) label{height:32px;width:32px}}:host([data-size=small]) .title{font-size:.75rem}:host([data-size=small]) .expand,:host([data-size=small]) label{height:24px;width:24px}:host([data-size=small]) .badge{font-size:9px;padding:1px 3px}:host([data-is-gift-card=true]) label{background-color:#000;font-size:.875rem;font-weight:500;height:auto;line-height:1;padding:8px 12px;text-align:center;width:auto}:host([data-is-gift-card=true]) .expand{background-color:#000;border-radius:100px;height:30px;width:36px}:host([data-is-gift-card=true]) .expand svg{stroke:#fff}:host([data-is-gift-card=true]) input:checked+label:before{border-color:#000}:host([data-is-gift-card=true]):host([data-size=small]) label{padding:6px 8px}:host([data-is-gift-card=true]):host([data-size=small]) .expand{height:28px}strong{font-weight:600}.wrapper.has-filters{display:flex;flex-direction:column}.wrapper.has-filters .title{border-top:1px solid #dbdbdb;margin-bottom:0;margin-top:16px;order:1;padding-top:16px}.filters{display:flex;flex-wrap:wrap;gap:12px;margin-bottom:24px}.filters button{appearance:none;background:none;border:1px solid #cdcfd1;color:inherit;cursor:pointer;display:block;font:inherit;margin:0;outline:none;padding:4px 12px;text-transform:uppercase}.filters button[aria-pressed=true]{border-color:#000}.title{margin-bottom:8px}@media only screen and (min-width:768px){.categories{margin-top:8px}}.categories:empty{display:none}.category{border-bottom:1px solid #dbdbdb;margin-bottom:10px;padding-bottom:10px}.category:last-child{border-bottom:none;margin-bottom:0;padding-bottom:0}.category-title{font-size:.825rem;font-weight:300;letter-spacing:.07em;margin-bottom:4px;margin-top:0;text-transform:uppercase}@media only screen and (min-width:768px){.category-title{margin-bottom:6px}}.options{align-items:center;column-gap:3px;display:flex;flex-wrap:wrap;margin-left:-4px;margin-right:-4px}@media only screen and (min-width:768px){.options{row-gap:4px}}.options.collapsed>div:nth-of-type(n+5){display:none}.expand,label{background-clip:padding-box;border:4px solid #0000;border-radius:100px;box-sizing:initial;color:#fff;cursor:pointer;display:block;position:relative}label:hover:before{border-color:#cdcfd1}label:before{border:1px solid #0000;border-radius:100px;bottom:-4px;content:\\\"\\\";left:-4px;position:absolute;right:-4px;top:-4px}label:after{border-right:1px solid #fff;bottom:-5px;left:50%;position:absolute;top:-5px;transform:rotate(-45deg)}@media only screen and (min-width:768px){label:after{bottom:-4px;top:-4px}}.badge{background-color:#000;bottom:-4px;color:#fff;font-size:.625rem;font-weight:600;left:50%;line-height:1;padding:2px 3px;position:absolute;text-transform:uppercase;transform:translateX(-50%)}@media only screen and (min-width:768px){.badge{font-size:.6875rem;padding-left:4px;padding-right:4px}}.badge.highlighted{background-color:#e71d13}input:checked+label:before{border-color:#1e1e1e}input:focus+label:before{border-color:#000;border-width:2px}.unavailable+label:after{content:\\\"\\\"}.expand{align-items:center;appearance:none;background-color:#e6e7e8;border-radius:50%;cursor:pointer;display:flex;justify-content:center;min-width:unset;padding:0}.expand:hover{background-color:#cdcfd1;border-color:#0000}.expand svg{width:20px}.visually-hidden{height:1px;overflow:hidden;position:absolute;width:1px;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);white-space:nowrap}.hidden{display:none}.bg-120ml{background-color:#e9ecee}.bg-6pm{background-color:#b16a56}.bg-all-that{background-color:#683431}.bg-allspice{background-color:#774212}.bg-almond-fruit{background-color:#9f5f54}.bg-apricot{background-color:#f09491}.bg-bare-rice{background-color:#dbc8b6}.bg-berry{background-color:#b66c6d}.bg-biscuit{background-color:#debc8b}.bg-black{background-color:#0f171f}.bg-blonde-shot{background-color:#bba370}.bg-blush{background-color:#dea39c}.bg-brick{background-color:#7c2629}.bg-burgundy{background-color:#992359}.bg-burgundy-2{background-color:#7c0d3f}.bg-burgundy-3{background-color:#b24d76}.bg-cacao{background-color:#7e694f}.bg-cardinal{background-color:#ab2328}.bg-carob{background-color:#4f3324}.bg-celestial-cool-tones{background-color:#b4b5df}.bg-ceramic{background-color:#ce9464}.bg-chalkshine{background-color:#d9d2ca}.bg-charcoal{background-color:#212721}.bg-cherry{background-color:#d6001c}.bg-chili{background-color:#c10016}.bg-chocolate{background-color:#5c3d31}.bg-clear{background-color:#e6e6e6}.bg-cloudless{background-color:#a7bcd6}.bg-coral{background-color:#fa4616}.bg-cork{background-color:#f3d3b0}.bg-cotton{background-color:#f3d8bb}.bg-cranberry{background-color:#971b2f}.bg-crimson{background-color:#9b2242}.bg-currant{background-color:#ad5389}.bg-daydream{background-color:#b47d75}.bg-deep{background-color:#c48e50}.bg-deep-hunter-green{background-color:#183029}.bg-dewy{background-color:#f7f7f7}.bg-enamel{background-color:#fee8d3}.bg-espresso{background-color:#382e2c}.bg-fair{background-color:#fce7c4}.bg-fig{background-color:#6f2c3f}.bg-future-dusk{background-color:#3b3a4a}.bg-glacier{background-color:#e0e0e0}.bg-go-there\\\\!{background-color:#905e7b}.bg-gold-dust{background-color:#db9900}.bg-graphite{background-color:#545859}.bg-guava{background-color:#df7a99}.bg-henna{background-color:#965c2c}.bg-hibiscus{background-color:#b46b7a}.bg-high-desert{background-color:#dda69d}.bg-ink{background-color:#0f171f}.bg-jute{background-color:#ddb182}.bg-latte{background-color:#ad7c59}.bg-leather{background-color:#4e3629}.bg-licorice{background-color:#0f171f}.bg-lilac{background-color:#d6c1d7}.bg-linen{background-color:#f4d1ab}.bg-longan-berry{background-color:#bf9474}.bg-lychee{background-color:#e4aeb1}.bg-matte{background-color:#f8eeee}.bg-matte-finish\\\\/standard{background-color:#7e4d4d}.bg-medium{background-color:#f3d098}.bg-millet{background-color:#9d6e46}.bg-sapphire{background-color:#002f6c}.bg-nudesicle{background-color:#dfb8a7}.bg-off-pink{background-color:#bc8a7e}.bg-opal-shades{background-color:#8b5a6b}.bg-orange-caves{background-color:#f38e58}.bg-original{background-color:#f6ece5}.bg-onyx{background-color:#332f21}.bg-papyrus{background-color:#bf9474}.bg-pecan{background-color:#8c5c30}.bg-peony{background-color:#fac0b8}.bg-pepper{background-color:#4e4b48}.bg-pink-smoothie{background-color:#dea09a}.bg-porcelain{background-color:#fdecd8}.bg-quinoa{background-color:#cda890}.bg-rattan{background-color:#e6ba8b}.bg-red-clay{background-color:#b0493d}.bg-rich-brown{background-color:#4f2c1d}.bg-rose{background-color:#cf6f77}.bg-rye{background-color:#c09c83}.bg-sable{background-color:#b27846}.bg-sand{background-color:#edcea2}.bg-silk{background-color:#eddbc1}.bg-smudge-proof-licorice{background-color:#0f171f}.bg-sumac{background-color:#89532f}.bg-marine{background-color:#003b49}.bg-toffee{background-color:#8f3237}.bg-ultra-violet{background-color:#512a44}.bg-waterproof-licorice{background-color:#0f171f}.bg-what-eh-ver\\\\!{background-color:#c48672}.bg-silver-ice{background-color:#f2ebe7}.bg-sunset-spark{background-color:#c48672}.bg-radiant-rose{background-color:#dea39c}.bg-gold-rush{background-color:#d4b59e}.bg-diva{background-color:#dd5680}.bg-doll{background-color:#e3aeb1}.bg-muse{background-color:#be625e}.bg-dew{background-color:#e7e6e6}.bg-pink-ice{background-color:#dda69d}.bg-golden-hour{background-color:#d9ac95}.bg-copper-glow{background-color:#cf7b69}.bg-pink-apple{background-color:#e17974}.bg-watermelon{background-color:#c52f40}.bg-dragon-fruit{background-color:#9f2842}.bg-raisin{background-color:#b66b7a}.bg-rhubarb{background-color:#9a4856}.bg-brown-pear{background-color:#a75247}.bg-clay{background-color:#cc9a8d}.bg-bluff{background-color:#ad7f66}.bg-oasis{background-color:#af6f53}.bg-cove{background-color:#7f4c3a}.bg-mesa{background-color:#5b3427}.bg-poppy{background-color:#b06f76}.bg-sangria{background-color:#852c4d}.bg-mocha-glow{background-color:#ae6a61}.bg-desert-rose{background-color:#a94545}.bg-zest{background-color:#de754b}.bg-ivory-pearl{background-color:#dfb8a7}.bg-satin-cloud{background-color:#f1c6a6}.bg-golden-olive{background-color:#d7a179}.bg-honey-beige{background-color:#e59e6d}.bg-toasted-brown{background-color:#ac7052}.bg-coral-mist{background-color:#dd7975}.bg-pink-pearl{background-color:#f5e0cf}.bg-gold-glow{background-color:#f3e4cd}.bg-butter{background-color:#efd4b7}.bg-hazelnut{background-color:#d39973}.bg-glaze{background-color:#f1e3e3}.bg-oat{background-color:#ecc4aa}.bg-eggshell{background-color:#f7e5d7}.bg-cream{background-color:#e8cab2}.bg-milk{background-color:#fde4ce}.bg-barley{background-color:#e2b496}.bg-ginger,.bg-sesame{background-color:#dcad83}.bg-cashew{background-color:#d3a279}.bg-honey{background-color:#e3a36d}.bg-terracotta{background-color:#dba583}.bg-almond{background-color:#d8a47d}.bg-praline{background-color:#d8a282}.bg-caramel{background-color:#d2a57c}.bg-coriander{background-color:#cb9573}.bg-nutmeg{background-color:#dca86e}.bg-cardamon{background-color:#cc9667}.bg-amber{background-color:#c69062}.bg-cumin{background-color:#c6925c}.bg-flax{background-color:#d0905a}.bg-tamarind{background-color:#c78c62}.bg-cinnamon{background-color:#ae7947}.bg-anise{background-color:#a86531}.bg-cocoa{background-color:#855338}.bg-coffee{background-color:#713d1e}.bg-chai{background-color:#7f4721}.bg-truffle{background-color:#562d0f}.bg-clove{background-color:#4c2812}\";","// Module\nvar code = \"<div class=\\\"wrapper\\\"><div class=\\\"filters hidden\\\"></div><div class=\\\"title\\\"></div><div class=\\\"options\\\"></div><div class=\\\"categories\\\"></div></div><slot></slot><template id=\\\"expand-button\\\"><button class=\\\"expand\\\" aria-label=\\\"Show all options\\\"><svg role=\\\"presentation\\\" width=\\\"20\\\" height=\\\"20\\\" viewBox=\\\"0 0 20 20\\\" fill=\\\"none\\\" stroke=\\\"#83888C\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><title>Show all options</title><path d=\\\"M1 9.99976L19 9.99992M9.99965 0.999969L9.99982 19\\\" stroke-linecap=\\\"square\\\"></path></svg></button></template>\";\n// Exports\nexport default code;"],"names":["VariantCategory","HTMLElement","customElements","get","define","VariantSelectorOption","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","exports","module","__webpack_modules__","VariantSelector","constructor","super","onInputChangedBound","this","onInputChanged","bind","onExpandButtonClickedBound","onExpandButtonClicked","onFilterClickedBound","onFilterClicked","onSlotChangeBound","onSlotChange","attachShadow","mode","shadowRoot","innerHTML","concat","connectedCallback","render","disconnectedCallback","querySelector","removeEventListener","expandButton","filters","querySelectorAll","filter","addEventListener","e","target","assignedElements","length","onSlotReady","_initialVariant$datas","_initialVariant$datas2","_initialVariant$datas3","_initialVariant$datas4","_category$dataset$des","renderFilters","categories","hasCategories","categoriesFragment","document","createDocumentFragment","category","categoryContainer","createElement","classList","add","title","textContent","dataset","appendChild","optionsContainer","options","id","variant","optionElement","createOptionElement","optionsFragment","expandable","expandButtonTemplate","content","cloneNode","renderTitle","selector","initSelectedVariantId","initialVariant","variantOptions","variantOption","push","variantId","value","available","Sentry","captureMessage","level","extra","productId","parentElement","findCategoryForVariant","variantChangedEvent","CustomEvent","cancelable","bubbles","detail","initial","source","description","parseInt","product_id","coming_soon","bundleOptionGroup","option","price","compareAtPrice","compareAtPriceModalContent","image","color","getVariantColor","backgroundClass","discountMessage","topBadge","topBadgeStyle","categoryDescription","dispatchEvent","_event","_variant$dataset$imag","_variant$dataset$topB","_variant$dataset$topB2","_category$dataset$des2","input","event","currentTarget","remove","activeFilter","setAttribute","name","toLowerCase","optionContainers","optionContainer","filterGroup","includes","titleElement","titleFormat","checkedInput","selectedVariant","isGiftCard","removeDecimals","allFilters","Set","filtersString","split","size","container","element","type","group","checked","label","labelHtml","badge","_variant$dataset$badg","badgeStyleClass","badgeStyle","categoryId","rules","sheet","cssRules","escapedBackgroundClass","replace","rule","CSSStyleRule","selectorText","backgroundColor","style","priceString"],"sourceRoot":""}