{"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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"}