<section class="relative flex flex-col gap-4 adjusted-marg-y-xs" x-data="initSlider" x-init="calcPageSize(); $nextTick(() => calcActive())" @resize.window.debounce="calcPageSize(); $nextTick(() => calcActive())" role="group" aria-roledescription="Carousel" aria-label="échantillons offerts">
    <h3 class="text-body-base font-bold">Je souhaite recevoir 3 échantillons offerts: <span class="text-brand-700">3</span> restants</h3>
    <div class="relative w-full flex flex-row justify-between items-center gap-4 px-1 overflow-x-hidden">
        <div class="flex flex-row gap-4">
            <button type="button" :class="{ 'opacity-25 pointer-events-none' : active === 0 }" @click="scrollPrevious" :disabled="active === 0" aria-label="Voir le slide précédent" class=" btn  btn-dark  btn-subtle btn-border btn-size-sm btn-only-icon">
                <svg class=" shrink-0" width="24" height="24" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
                    <path d="M10.5 19.5L3 12M3 12L10.5 4.5M3 12H21" stroke="currentColor" stroke-width="1.5" fill="none" />

                </svg>

            </button>
        </div>
        <div class="relative flex flex-nowrap w-full overflow-auto js_slides snap snap-x gap-1.5" @scroll.debounce="calcActive" aria-label="Échantillons">
            <label class="js_slide selection-control-label selection-control-checkbox
                            w-[268px] sm:w-[218px] md:w-[248px] 3xl:w-[328px]
                            flex flex-row gap-4 flex-shrink-0 px-2 py-4 snap-start cursor-pointer transition-all duration-200
                            bg-white border-dashed border border-black/16 hover:!border-brand-500
                            has-[input:checked]:border-solid has-[input:checked]:border-black" role="tabpanel" :aria-hidden="active !== 0">
                <input type="checkbox" name="La crème riche" value="La crème riche" class="peer">
                <div>
                    <p class="text-body-sm font-bold">La crème riche - <span class="text-black/64">(2ml)</span></p>
                    <a href="#" class="
         underline 
         link-medium
         link-dark
        
        
    ">

                        En savoir plus

                    </a>
                </div>
            </label>
            <label class="js_slide selection-control-label selection-control-checkbox
                            w-[268px] sm:w-[218px] md:w-[248px] 3xl:w-[328px]
                            flex flex-row gap-4 flex-shrink-0 px-2 py-4 snap-start cursor-pointer transition-all duration-200
                            bg-white border-dashed border border-black/16 hover:!border-brand-500
                            has-[input:checked]:border-solid has-[input:checked]:border-black" role="tabpanel" :aria-hidden="active !== 1">
                <input type="checkbox" name="La crème légère" value="La crème légère" class="peer">
                <div>
                    <p class="text-body-sm font-bold">La crème légère - <span class="text-black/64">(2ml)</span></p>
                    <a href="#" class="
         underline 
         link-medium
         link-dark
        
        
    ">

                        En savoir plus

                    </a>
                </div>
            </label>
            <label class="js_slide selection-control-label selection-control-checkbox
                            w-[268px] sm:w-[218px] md:w-[248px] 3xl:w-[328px]
                            flex flex-row gap-4 flex-shrink-0 px-2 py-4 snap-start cursor-pointer transition-all duration-200
                            bg-white border-dashed border border-black/16 hover:!border-brand-500
                            has-[input:checked]:border-solid has-[input:checked]:border-black" role="tabpanel" :aria-hidden="active !== 2">
                <input type="checkbox" name="Niacinamide 5%" value="Niacinamide 5%" class="peer">
                <div>
                    <p class="text-body-sm font-bold">Niacinamide 5% - <span class="text-black/64">(1ml)</span></p>
                    <a href="#" class="
         underline 
         link-medium
         link-dark
        
        
    ">

                        En savoir plus

                    </a>
                </div>
            </label>
            <label class="js_slide selection-control-label selection-control-checkbox
                            w-[268px] sm:w-[218px] md:w-[248px] 3xl:w-[328px]
                            flex flex-row gap-4 flex-shrink-0 px-2 py-4 snap-start cursor-pointer transition-all duration-200
                            bg-white border-dashed border border-black/16 hover:!border-brand-500
                            has-[input:checked]:border-solid has-[input:checked]:border-black" role="tabpanel" :aria-hidden="active !== 3">
                <input type="checkbox" name="La crème riche" value="La crème riche" class="peer">
                <div>
                    <p class="text-body-sm font-bold">La crème riche - <span class="text-black/64">(2ml)</span></p>
                    <a href="#" class="
         underline 
         link-medium
         link-dark
        
        
    ">

                        En savoir plus

                    </a>
                </div>
            </label>
            <label class="js_slide selection-control-label selection-control-checkbox
                            w-[268px] sm:w-[218px] md:w-[248px] 3xl:w-[328px]
                            flex flex-row gap-4 flex-shrink-0 px-2 py-4 snap-start cursor-pointer transition-all duration-200
                            bg-white border-dashed border border-black/16 hover:!border-brand-500
                            has-[input:checked]:border-solid has-[input:checked]:border-black" role="tabpanel" :aria-hidden="active !== 4">
                <input type="checkbox" name="La crème légère" value="La crème légère" class="peer">
                <div>
                    <p class="text-body-sm font-bold">La crème légère - <span class="text-black/64">(2ml)</span></p>
                    <a href="#" class="
         underline 
         link-medium
         link-dark
        
        
    ">

                        En savoir plus

                    </a>
                </div>
            </label>
            <label class="js_slide selection-control-label selection-control-checkbox
                            w-[268px] sm:w-[218px] md:w-[248px] 3xl:w-[328px]
                            flex flex-row gap-4 flex-shrink-0 px-2 py-4 snap-start cursor-pointer transition-all duration-200
                            bg-white border-dashed border border-black/16 hover:!border-brand-500
                            has-[input:checked]:border-solid has-[input:checked]:border-black" role="tabpanel" :aria-hidden="active !== 5">
                <input type="checkbox" name="Niacinamide 5%" value="Niacinamide 5%" class="peer">
                <div>
                    <p class="text-body-sm font-bold">Niacinamide 5% - <span class="text-black/64">(1ml)</span></p>
                    <a href="#" class="
         underline 
         link-medium
         link-dark
        
        
    ">

                        En savoir plus

                    </a>
                </div>
            </label>
        </div>

        <div class="flex flex-row gap-4">
            <button type="button" :class="{ 'opacity-25 pointer-events-none' : active >= itemCount - pageSize }" @click="scrollNext" :disabled="active >= itemCount - pageSize" aria-label="Voir le slide suivant" class=" btn  btn-dark  btn-subtle btn-border btn-size-sm btn-only-icon">
                <svg class=" shrink-0" width="24" height="24" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
                    <path d="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3" stroke="currentColor" stroke-width="1.5" fill="none" />

                </svg>

            </button>
        </div>
    </div>
</section>

<script>
    function initSlider() {
        return {
            active: 0,
            itemCount: 0,
            getSlider() {
                return this.$root.querySelector('.js_slides');
            },
            pageSize: 3,
            pageFillers: 0,
            calcPageSize() {
                const slider = this.getSlider();
                if (slider) {
                    this.itemCount = slider.querySelectorAll('.js_slide').length;
                    this.pageSize = Math.round(slider.clientWidth / slider.querySelector('.js_slide').clientWidth);
                    this.pageFillers = (this.pageSize * Math.ceil(this.itemCount / this.pageSize)) - this.itemCount;
                }
            },
            calcActive() {
                const slider = this.getSlider();
                if (slider) {
                    const sliderItems = this.itemCount + this.pageFillers;
                    const calculatedActiveSlide = slider.scrollLeft / (slider.scrollWidth / sliderItems);
                    this.active = Math.round(calculatedActiveSlide / this.pageSize) * this.pageSize;
                }
            },
            scrollPrevious() {
                this.scrollTo(this.active - this.pageSize);
            },
            scrollNext() {
                this.scrollTo(this.active + this.pageSize);
            },
            scrollTo(idx) {
                const slider = this.getSlider();
                if (slider) {
                    const slideWidth = slider.scrollWidth / (this.itemCount + this.pageFillers);
                    slider.scrollLeft = Math.floor(slideWidth) * idx;
                    this.active = idx;
                }
            },
        }
    }
</script>
<section class="relative flex flex-col gap-4 adjusted-marg-y-xs"
         x-data="initSlider"
         x-init="calcPageSize(); $nextTick(() => calcActive())"
         @resize.window.debounce="calcPageSize(); $nextTick(() => calcActive())"
         role="group"
         aria-roledescription="Carousel"
         aria-label="échantillons offerts"
>
    <h3 class="text-body-base font-bold">Je souhaite recevoir 3 échantillons offerts: <span class="text-brand-700">3</span> restants</h3>
    <div class="relative w-full flex flex-row justify-between items-center gap-4 px-1 overflow-x-hidden">
        {% if samples|length > 1 %}
            <div class="flex flex-row gap-4">
                {% render "@template-button" with {
                    color: 'dark',
                    type: 'subtle',
                    icon_type: "only-icon",
                    size: 'sm',
                    border: true,
                    label: 'Voir le slide précédent',
                    icon: {
                        name: "heroicons--arrow-left-outline",
                    },
                    button_attribute: (":class=\"{ 'opacity-25 pointer-events-none' : active === 0 }\" @click=\"scrollPrevious\" :disabled=\"active === 0\"")|replace({'\"': '"'})
                } %}
            </div>
        {% endif %}
        <div class="relative flex flex-nowrap w-full overflow-auto js_slides snap snap-x gap-1.5"
             @scroll.debounce="calcActive"
             aria-label="Échantillons"
        >
            {% for sample in samples %}
                <label class="js_slide selection-control-label selection-control-checkbox
                            w-[268px] sm:w-[218px] md:w-[248px] 3xl:w-[328px]
                            flex flex-row gap-4 flex-shrink-0 px-2 py-4 snap-start cursor-pointer transition-all duration-200
                            bg-white border-dashed border border-black/16 hover:!border-brand-500
                            has-[input:checked]:border-solid has-[input:checked]:border-black"
                       role="tabpanel"
                       :aria-hidden="active !== {{ loop.index0 }}"
                >
                    <input
                            type="checkbox"
                            name="{{ sample.name }}"
                            value="{{ sample.name }}"
                            class="peer"
                    >
                    <div>
                        <p class="text-body-sm font-bold">{{ sample.name }} - <span
                                    class="text-black/64">({{ sample.size }})</span></p>
                        {% render "@template-link" with {
                            size: 'medium',
                            type: 'dark',
                            underlined: true,
                            href: '#',
                            label: "En savoir plus"
                        } %}
                    </div>
                </label>
            {% endfor %}
        </div>

        {% if samples|length > 1 %}
            <div class="flex flex-row gap-4">
                {% render "@template-button" with {
                    color: 'dark',
                    type: 'subtle',
                    icon_type: "only-icon",
                    size: 'sm',
                    border: true,
                    label: 'Voir le slide suivant',
                    icon: {
                        name: "heroicons--arrow-right-outline",
                    },
                    button_attribute: (":class=\"{ 'opacity-25 pointer-events-none' : active >= itemCount - pageSize }\" @click=\"scrollNext\" :disabled=\"active >= itemCount - pageSize\"")|replace({'\"': '"'})
                } %}
            </div>
        {% endif %}
    </div>
</section>

<script>
	function initSlider() {
		return {
			active: 0,
			itemCount: 0,
			getSlider() {
				return this.$root.querySelector('.js_slides');
			},
			pageSize: 3,
			pageFillers: 0,
			calcPageSize() {
				const slider = this.getSlider();
				if (slider) {
					this.itemCount = slider.querySelectorAll('.js_slide').length;
					this.pageSize = Math.round(slider.clientWidth / slider.querySelector('.js_slide').clientWidth);
					this.pageFillers = (this.pageSize * Math.ceil(this.itemCount / this.pageSize)) - this.itemCount;
				}
			},
			calcActive() {
				const slider = this.getSlider();
				if (slider) {
					const sliderItems = this.itemCount + this.pageFillers;
					const calculatedActiveSlide = slider.scrollLeft / (slider.scrollWidth / sliderItems);
					this.active = Math.round(calculatedActiveSlide / this.pageSize) * this.pageSize;
				}
			},
			scrollPrevious() {
				this.scrollTo(this.active - this.pageSize);
			},
			scrollNext() {
				this.scrollTo(this.active + this.pageSize);
			},
			scrollTo(idx) {
				const slider = this.getSlider();
				if (slider) {
					const slideWidth = slider.scrollWidth / (this.itemCount + this.pageFillers);
					slider.scrollLeft = Math.floor(slideWidth) * idx;
					this.active = idx;
				}
			},
		}
	}
</script>
{
  "title": "Hero Product Slider",
  "maxVisibleSlides": 1,
  "showNavigation": true,
  "showPagination": true,
  "samples": [
    {
      "name": "La crème riche",
      "size": "2ml",
      "cta": "#"
    },
    {
      "name": "La crème légère",
      "size": "2ml",
      "cta": "#"
    },
    {
      "name": "Niacinamide 5%",
      "size": "1ml",
      "cta": "#"
    },
    {
      "name": "La crème riche",
      "size": "2ml",
      "cta": "#"
    },
    {
      "name": "La crème légère",
      "size": "2ml",
      "cta": "#"
    },
    {
      "name": "Niacinamide 5%",
      "size": "1ml",
      "cta": "#"
    }
  ]
}

No notes defined.