{"version":3,"file":"blocks.js","names":["#MAX_RECENT_SWATCHES"],"sources":["../resources/javascript/swatch/RecentSwatches.js","../resources/javascript/blocks.js"],"sourcesContent":["import { renderSwatchGrid } from './render-swatch-grid';\nimport { initSwatchPanel, swatchSelectedEvent } from '../swatch/swatch';\nimport { openSwatchOverlay } from './open-swatch-overlay';\nimport { isTabletOrSmaller } from '../util/viewport';\nimport { renderSwatchTicks } from './render-swatch-ticks';\n\n/**\n * Class representing recent swatches functionality.\n * Manages the rendering and interactions of recent swatches in the UI.\n */\nexport class RecentSwatches {\n    /**\n     * Maximum number of recent swatches to display, varies based on viewport size.\n     * @private\n     */\n    #MAX_RECENT_SWATCHES = isTabletOrSmaller ? 6 : 7;\n\n    constructor() {}\n\n    /**\n     * Renders the recent swatches in the UI.\n     * @param {Array} modifiers - Optional CSS class modifiers for custom styling.\n     */\n    renderRecentSwatches = modifiers => {\n        let recentSwatches =\n            JSON.parse(localStorage.getItem('recentSwatches')) ?? [];\n        const recentSwatchesContainer = document.querySelector(\n            '[data-recent-swatches]'\n        );\n\n        // Limit the number of swatches to #MAX_RECENT_SWATCHES\n        recentSwatches = recentSwatches.slice(0, this.#MAX_RECENT_SWATCHES);\n\n        // Toggles a class to denote an empty state if no recent swatches exist\n        recentSwatchesContainer.parentElement.classList.toggle(\n            'recent-swatches--empty',\n            recentSwatches.length === 0\n        );\n\n        const swatchGrid = renderSwatchGrid(recentSwatches, modifiers, {\n            addSwatchCategoryName: true,\n        });\n\n        recentSwatchesContainer.innerHTML = '';\n        recentSwatchesContainer.appendChild(swatchGrid);\n\n        // Initializes swatch panel and attaches event listeners\n        initSwatchPanel(recentSwatchesContainer);\n\n        // Render ticks on the swatches if we have any\n        renderSwatchTicks(recentSwatchesContainer);\n\n        // Listens for swatch selection events to trigger overlay\n        recentSwatchesContainer?.addEventListener(\n            swatchSelectedEvent,\n            event => {\n                openSwatchOverlay(event);\n            }\n        );\n    };\n\n    /**\n     * Adds a swatch to the list of recent swatches.\n     * @param {Object} swatchObject - The swatch object to add to recent swatches.\n     */\n    addRecentSwatches = swatchObject => {\n        const recentSwatches =\n            JSON.parse(localStorage.getItem('recentSwatches')) ?? [];\n\n        // Checks if the swatch is already in the list to avoid duplicates\n        for (const swatch of recentSwatches ?? []) {\n            if (swatch.value === swatchObject.value) {\n                return;\n            }\n        }\n\n        // Limits the number of recent swatches and adds the new swatch\n        if (recentSwatches.length >= this.#MAX_RECENT_SWATCHES) {\n            recentSwatches.pop();\n        }\n\n        recentSwatches.unshift(swatchObject);\n        localStorage.setItem('recentSwatches', JSON.stringify(recentSwatches));\n\n        this.renderRecentSwatches();\n    };\n}\n","import { initialiseSwiper } from './swiper/swiper.js';\nimport { initShowroomFinders } from './showrooms/showroomFinder.js';\nimport { RecentSwatches } from './swatch/RecentSwatches.js';\nimport { handleFragmentInit } from './pdp/fragments';\nimport { replaceElementHTML } from './pdp/replace';\n\ninitShowroomFinders();\n\nconst initRecentSwatches = () => {\n    const recentSwatchContainer = document.querySelector(\n        '[data-recent-swatches]'\n    );\n\n    if (!recentSwatchContainer) {\n        return;\n    }\n\n    const recentSwatches = new RecentSwatches();\n    const swatchGridModifierClasses = ['swiper-wrapper', 'swatch-grid--block'];\n\n    recentSwatches.renderRecentSwatches(swatchGridModifierClasses);\n};\n\ninitRecentSwatches();\n\nconst getActiveExploreFabricsSlide = carousel =>\n    carousel.querySelector('.swiper-slide-active') ??\n    carousel.querySelector('.swiper-slide:not(.swiper-slide-duplicate)') ??\n    carousel.querySelector('.swiper-slide');\n\nconst updateApplyFabricButton = (applyBtn, activeSlide) => {\n    if (applyBtn && activeSlide?.dataset.variantUrl) {\n        applyBtn.setAttribute('lp-get', activeSlide.dataset.variantUrl);\n    }\n};\n\nconst initExploreFabricsCarousel = carousel => {\n    if (carousel.swiper) {\n        carousel.swiper.destroy(true, true);\n    }\n\n    const thumbsSwiper = initialiseSwiper(carousel);\n\n    if (!thumbsSwiper) {\n        return;\n    }\n\n    const updateActiveFabric = () => {\n        const block = carousel.closest('.block') ?? document;\n        const activeSlide = getActiveExploreFabricsSlide(carousel);\n\n        const updates = [\n            { selector: '[data-insert-fabric-name]', key: 'fabricName' },\n            {\n                selector: '[data-insert-fabric-description]',\n                key: 'fabricDescription',\n            },\n            { selector: '[data-insert-fabric-price]', key: 'fabricPrice' },\n            { selector: '[data-insert-cylindo-image]', key: 'cylindoUrl' },\n        ];\n\n        updates.forEach(({ selector, key }) => {\n            block.querySelectorAll(selector).forEach(element => {\n                if (element.tagName === 'IMG') {\n                    element.src = activeSlide?.dataset[key] ?? '';\n                } else {\n                    element.textContent = activeSlide?.dataset[key] ?? '';\n                }\n            });\n        });\n\n        updateApplyFabricButton(\n            block.querySelector('[data-apply-fabric-btn]'),\n            activeSlide\n        );\n    };\n\n    thumbsSwiper.on('slideChangeTransitionEnd', updateActiveFabric);\n};\n\ndocument.addEventListener(\n    'click',\n    e => {\n        if (!(e.target instanceof Element)) {\n            return;\n        }\n\n        const applyBtn = e.target.closest('[data-apply-fabric-btn]');\n        if (!applyBtn) {\n            return;\n        }\n\n        const block = applyBtn.closest('.block') ?? document;\n        const carousel = block.querySelector(\n            '.swiper[data-carousel-type=\"exploreFabrics\"]'\n        );\n        const activeSlide = carousel\n            ? getActiveExploreFabricsSlide(carousel)\n            : null;\n        updateApplyFabricButton(applyBtn, activeSlide);\n    },\n    true\n);\n\nhandleFragmentInit(({ replace }) => {\n    if (replace?.range) {\n        replaceElementHTML('.block--range', replace.range);\n    }\n\n    const carousels = document.querySelectorAll('.block .swiper');\n    for (const carousel of carousels ?? []) {\n        if (carousel.dataset.carouselType === 'exploreFabrics') {\n            initExploreFabricsCarousel(carousel);\n            continue;\n        }\n\n        initialiseSwiper(carousel);\n    }\n});\n\ndocument.addEventListener('d3r.live.replaced', () => {\n    for (const carousel of document.querySelectorAll(\n        '.block .swiper[data-carousel-type=\"exploreFabrics\"]'\n    )) {\n        initExploreFabricsCarousel(carousel);\n    }\n});\n\nconst initReadMore = () => {\n    const readMoreContainers = document.querySelectorAll(\n        '.block__content .read-more'\n    );\n\n    if (!readMoreContainers) {\n        return;\n    }\n\n    readMoreContainers.forEach(container => {\n        const button = container.querySelector('.js-read_more');\n\n        if (!button) {\n            return;\n        }\n\n        button.addEventListener('click', () => {\n            container.classList.toggle('read-more--active');\n\n            if (container.classList.contains('read-more--active')) {\n                button.textContent = 'Read less';\n            } else {\n                button.textContent = '... Read more';\n            }\n        });\n    });\n};\n\ninitReadMore();\n"],"mappings":"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"}