<style>
/* Outer section spans 100% width */
#products-slider-{{ section.id }} {
width: 100%;
}
/* Common container for heading and slider */
#products-slider-{{ section.id }} .products-slider-container {
margin: 0 auto;
}
#products-slider-{{ section.id }} .section-heading {
text-align: {{ section.settings.heading_alignment }};
margin-bottom: 20px;
font-size: {% if section.settings.heading_size == 'small' %}24px{% elsif section.settings.heading_size == 'medium' %}32px{% elsif section.settings.heading_size == 'large' %}40px{% endif %};
}
#products-slider-{{ section.id }} .featured-collection-wrapper {
overflow: hidden;
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
#products-slider-{{ section.id }} .featured-collection-slider {
overflow: hidden;
position: relative;
}
#products-slider-{{ section.id }} .slider-track {
display: flex;
gap: 15px;
transition: transform 0.5s ease-in-out;
will-change: transform;
}
/* Desktop slide width calculated based on slides_to_show */
#products-slider-{{ section.id }} .slide {
flex: 0 0 calc((100% - ({{ section.settings.slides_to_show | minus: 1 }} * 15px)) / {{ section.settings.slides_to_show }});
text-align: {{ section.settings.title_price_alignment }};
{% if section.settings.card_shadow %}
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);
{% endif %}
}
/* Mobile override: use visible_mobile setting */
@media (max-width: 767px) {
#products-slider-{{ section.id }} .slide {
flex: 0 0 calc((100% - ({{ section.settings.visible_mobile | minus: 1 }} * 15px)) / {{ section.settings.visible_mobile }});
}
}
#products-slider-{{ section.id }} .slide a {
text-decoration: none;
color: inherit;
}
#products-slider-{{ section.id }} .product-image {
width: 100%;
object-fit: cover;
{% if section.settings.image_ratio == 'portrait' %}
aspect-ratio: 2 / 3;
{% elsif section.settings.image_ratio == 'square' %}
aspect-ratio: 1 / 1;
{% elsif section.settings.image_ratio == 'circle' %}
aspect-ratio: 1 / 1;
border-radius: 50%;
{% else %}
height: auto;
{% endif %}
}
#products-slider-{{ section.id }} .product-title {
font-size: {{ section.settings.product_title_font_size }}px;
margin: 10px 0 5px;
text-align: {{ section.settings.title_price_alignment }};
}
#products-slider-{{ section.id }} .product-price {
text-align: {{ section.settings.title_price_alignment }};
}
/* Arrow Buttons */
#products-slider-{{ section.id }} .arrow {
background: {{ section.settings.arrow_bg_color }};
color: white;
border: none;
cursor: pointer;
font-size: 24px;
padding: 10px 15px;
position: absolute;
top: 50%;
transform: translateY(-50%);
z-index: 10;
transition: background 0.3s ease;
border-radius: {% if section.settings.arrow_shape == 'circle' %}50%{% else %}0{% endif %};
display: flex;
align-items: center;
justify-content: center;
padding: 0px 0px;
width: 50px;
height: 50px;
}
#products-slider-{{ section.id }} .arrow:hover {
opacity: 0.8;
}
#products-slider-{{ section.id }} .left-arrow {
left: 10px;
}
#products-slider-{{ section.id }} .right-arrow {
right: 10px;
}
</style>
{%- comment -%}
Wrap both the section heading and slider inside a common container whose width is controlled by the full_width setting.
{%- endcomment -%}
<div id="products-slider-{{ section.id }}" class="page-width featured-collection-section" style="background-color: {{ section.settings.section_bg_color }}; padding-top: {{ section.settings.section_padding_top }}px; padding-bottom: {{ section.settings.section_padding_bottom }}px;">
<div class="products-slider-container" style="width: {% if section.settings.full_width %}100%{% else %}80%{% endif %}; margin: 0 auto;">
{% if section.settings.section_heading != blank %}
<h2 class="section-heading">{{ section.settings.section_heading }}</h2>
{% endif %}
<div class="featured-collection-wrapper">
<button class="arrow left-arrow">❮</button>
<div class="featured-collection-slider">
<div class="slider-track">
{% for product in section.settings.collection.products %}
<div class="slide">
<a href="{{ product.url }}">
<img class="product-image" src="{{ product.featured_image | img_url: 'medium' }}" alt="{{ product.title }}">
<p class="product-title">{{ product.title }}</p>
<p class="product-price">{{ product.price | money }}</p>
</a>
</div>
{% endfor %}
{% comment %}
Clone the first few slides to create a seamless infinite loop
{% endcomment %}
{% for product in section.settings.collection.products limit: section.settings.slides_to_show %}
<div class="slide clone">
<a href="{{ product.url }}">
<img class="product-image" src="{{ product.featured_image | img_url: 'medium' }}" alt="{{ product.title }}">
<p class="product-title">{{ product.title }}</p>
<p class="product-price">{{ product.price | money }}</p>
</a>
</div>
{% endfor %}
</div>
</div>
<button class="arrow right-arrow">❯</button>
</div>
</div>
</div>
<script>
document.addEventListener("DOMContentLoaded", function () {
var container = document.getElementById("products-slider-{{ section.id }}");
if (!container) return;
var sliderTrack = container.querySelector(".slider-track");
var slides = container.querySelectorAll(".slide");
if (slides.length === 0) return;
// Define gap (must match the CSS gap)
var gap = 15;
// Calculate slide width (including gap)
var slideWidth = slides[0].offsetWidth + gap;
// Output proper JS values for autoplay settings
var autoplay = {{ section.settings.autoplay | json }};
var autoplaySpeed = {{ section.settings.autoplay_speed | json }};
var index = 0;
var totalSlides = slides.length;
var clonedSlides = container.querySelectorAll(".clone").length;
function updateSlidePosition() {
sliderTrack.style.transform = "translateX(-" + (index * slideWidth) + "px)";
}
function slideNext() {
index++;
sliderTrack.style.transition = "transform 0.5s ease-in-out";
updateSlidePosition();
}
function slidePrev() {
index--;
sliderTrack.style.transition = "transform 0.5s ease-in-out";
updateSlidePosition();
}
sliderTrack.addEventListener("transitionend", function () {
if (index >= totalSlides - clonedSlides) {
sliderTrack.style.transition = "none";
index = 0;
updateSlidePosition();
void sliderTrack.offsetWidth;
sliderTrack.style.transition = "transform 0.5s ease-in-out";
}
if (index < 0) {
sliderTrack.style.transition = "none";
index = totalSlides - clonedSlides - 1;
updateSlidePosition();
void sliderTrack.offsetWidth;
sliderTrack.style.transition = "transform 0.5s ease-in-out";
}
});
var rightArrow = container.querySelector(".right-arrow");
var leftArrow = container.querySelector(".left-arrow");
if (rightArrow) {
rightArrow.addEventListener("click", slideNext);
}
if (leftArrow) {
leftArrow.addEventListener("click", slidePrev);
}
if (autoplay) {
setInterval(slideNext, autoplaySpeed);
}
window.addEventListener("resize", function () {
slideWidth = slides[0].offsetWidth + gap;
sliderTrack.style.transition = "none";
updateSlidePosition();
});
});
</script>
{% schema %}
{
"name": "Products Slider",
"settings": [
{
"type": "collection",
"id": "collection",
"label": "Select Collection"
},
{
"type": "text",
"id": "section_heading",
"label": "Section Heading",
"default": "Featured Collection"
},
{
"type": "select",
"id": "heading_alignment",
"label": "Section Heading Alignment",
"options": [
{ "value": "left", "label": "Left" },
{ "value": "center", "label": "Center" },
{ "value": "right", "label": "Right" }
],
"default": "center"
},
{
"type": "select",
"id": "heading_size",
"label": "Section Heading Size",
"options": [
{ "value": "small", "label": "Small" },
{ "value": "medium", "label": "Medium" },
{ "value": "large", "label": "Large" }
],
"default": "medium"
},
{
"type": "checkbox",
"id": "full_width",
"label": "Full Width Section",
"default": false
},
{
"type": "range",
"id": "slides_to_show",
"label": "Slides to Show (Desktop)",
"min": 2,
"max": 6,
"step": 1,
"default": 4
},
{
"type": "range",
"id": "visible_mobile",
"label": "Slides to Show (Mobile)",
"min": 1,
"max": 3,
"step": 1,
"default": 1
},
{
"type": "select",
"id": "image_ratio",
"label": "Product Image Ratio",
"options": [
{ "value": "portrait", "label": "Portrait (2:3)" },
{ "value": "square", "label": "Square (1:1)" },
{ "value": "adapt", "label": "Adapt to Image" },
{ "value": "circle", "label": "Circle" }
],
"default": "adapt"
},
{
"type": "checkbox",
"id": "autoplay",
"label": "Enable Autoplay",
"default": true
},
{
"type": "range",
"id": "autoplay_speed",
"label": "Autoplay Speed (ms)",
"min": 1000,
"max": 7000,
"step": 500,
"default": 6000
},
{
"type": "color",
"id": "section_bg_color",
"label": "Section Background Color",
"default": "#ffffff"
},
{
"type": "range",
"id": "section_padding_top",
"label": "Section Top Padding (px)",
"min": 0,
"max": 200,
"step": 5,
"default": 20
},
{
"type": "range",
"id": "section_padding_bottom",
"label": "Section Bottom Padding (px)",
"min": 0,
"max": 200,
"step": 5,
"default": 20
},
{
"type": "color",
"id": "arrow_bg_color",
"label": "Arrow Background Color",
"default": "#000000"
},
{
"type": "select",
"id": "arrow_shape",
"label": "Arrow Shape",
"options": [
{ "value": "circle", "label": "Circle" },
{ "value": "square", "label": "Square" }
],
"default": "circle"
},
{
"type": "select",
"id": "title_price_alignment",
"label": "Product Title and Price Alignment",
"options": [
{ "value": "left", "label": "Left" },
{ "value": "center", "label": "Center" },
{ "value": "right", "label": "Right" }
],
"default": "center"
},
{
"type": "range",
"id": "product_title_font_size",
"label": "Product Title Font Size (px)",
"min": 10,
"max": 30,
"step": 1,
"default": 16
},
{
"type": "checkbox",
"id": "card_shadow",
"label": "Enable Product Card Shadow",
"default": false
}
],
"presets": [
{
"name": "Featured Collection Slider"
}
]
}
{% endschema %}