theme
This commit is contained in:
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+71
-24
@@ -9,14 +9,13 @@
|
||||
|
||||
body {
|
||||
font-family:
|
||||
"IBM Plex Sans",
|
||||
"Poppins",
|
||||
"Avenir Next",
|
||||
"Segoe UI",
|
||||
sans-serif;
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(241, 196, 110, 0.24), transparent 28%),
|
||||
radial-gradient(circle at top right, rgba(157, 217, 210, 0.16), transparent 34%),
|
||||
linear-gradient(180deg, #fbfaf6 0%, #f5efe3 55%, #f7f3ea 100%);
|
||||
radial-gradient(circle at top left, rgba(245, 158, 11, 0.12), transparent 24%),
|
||||
linear-gradient(180deg, #fffdfa 0%, #faf7f1 100%);
|
||||
@apply text-stone-900;
|
||||
}
|
||||
|
||||
@@ -24,9 +23,10 @@
|
||||
h2,
|
||||
h3 {
|
||||
font-family:
|
||||
"Cormorant Garamond",
|
||||
"IBM Plex Sans",
|
||||
serif;
|
||||
"Poppins",
|
||||
"Avenir Next",
|
||||
"Segoe UI",
|
||||
sans-serif;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,16 +36,15 @@
|
||||
}
|
||||
|
||||
.site-header {
|
||||
@apply sticky top-0 z-40 backdrop-blur;
|
||||
@apply sticky top-0 z-40 bg-white/95 backdrop-blur;
|
||||
}
|
||||
|
||||
.utility-bar {
|
||||
background: linear-gradient(90deg, rgba(20, 33, 61, 0.98), rgba(37, 58, 89, 0.94));
|
||||
@apply border-b border-white/10 text-stone-100;
|
||||
@apply border-b border-stone-200 bg-white text-stone-700;
|
||||
}
|
||||
|
||||
.header-locale {
|
||||
@apply flex w-full flex-wrap items-center justify-start gap-2 text-sm text-stone-100 sm:w-auto sm:justify-end;
|
||||
@apply flex w-full flex-wrap items-center justify-start gap-2 text-sm text-stone-700 sm:w-auto sm:justify-end;
|
||||
}
|
||||
|
||||
.locale-picker {
|
||||
@@ -53,11 +52,11 @@
|
||||
}
|
||||
|
||||
.locale-picker__summary {
|
||||
@apply flex w-full cursor-pointer list-none items-center justify-between gap-2 rounded-full border border-white/0 px-3 py-1.5 text-stone-100 transition hover:border-white/20 hover:bg-white/10 hover:text-white sm:w-auto sm:justify-start;
|
||||
@apply flex w-full cursor-pointer list-none items-center justify-between gap-2 rounded-full border border-stone-200 px-3 py-1.5 text-stone-700 transition hover:border-stone-300 hover:bg-stone-50 hover:text-stone-900 sm:w-auto sm:justify-start;
|
||||
}
|
||||
|
||||
.locale-picker[open] .locale-picker__summary {
|
||||
@apply border-white/20 bg-white/10 text-white;
|
||||
@apply border-stone-300 bg-stone-50 text-stone-900;
|
||||
}
|
||||
|
||||
.locale-picker__summary::-webkit-details-marker {
|
||||
@@ -71,7 +70,7 @@
|
||||
.locale-picker__code,
|
||||
.locale-picker__item-meta,
|
||||
.locale-picker__chevron {
|
||||
@apply text-[0.74rem] uppercase tracking-[0.16em] text-stone-300/80;
|
||||
@apply text-[0.74rem] uppercase tracking-[0.16em] text-stone-400;
|
||||
}
|
||||
|
||||
.locale-picker__panel {
|
||||
@@ -91,8 +90,7 @@
|
||||
}
|
||||
|
||||
.main-nav {
|
||||
background: rgba(255, 251, 245, 0.82);
|
||||
@apply border-b border-white/60 shadow-[0_10px_30px_rgba(20,33,61,0.08)];
|
||||
@apply border-b border-stone-200 bg-white shadow-[0_8px_24px_rgba(20,33,61,0.05)];
|
||||
}
|
||||
|
||||
.header-bar {
|
||||
@@ -100,7 +98,7 @@
|
||||
}
|
||||
|
||||
.brand-mark {
|
||||
@apply inline-flex items-end gap-0.5 text-4xl font-black leading-none tracking-tight text-black transition-transform duration-300 hover:-translate-y-0.5 sm:text-5xl;
|
||||
@apply inline-flex items-end gap-0.5 text-4xl font-black leading-none tracking-tight text-black transition-transform duration-300 hover:-translate-y-0.5 sm:text-[3.2rem];
|
||||
}
|
||||
|
||||
.brand-mark__accent {
|
||||
@@ -108,11 +106,11 @@
|
||||
}
|
||||
|
||||
.menu-toggle {
|
||||
@apply inline-flex h-11 items-center justify-center rounded-full border border-stone-300/70 bg-white/90 px-5 text-[0.68rem] font-semibold uppercase tracking-[0.28em] text-stone-900 shadow-[0_10px_24px_rgba(20,33,61,0.08)] transition hover:border-amber-500 hover:text-amber-600;
|
||||
@apply inline-flex h-11 items-center justify-center border border-stone-300 bg-white px-5 text-[0.68rem] font-semibold uppercase tracking-[0.28em] text-stone-900 shadow-[0_8px_18px_rgba(20,33,61,0.05)] transition hover:border-amber-500 hover:text-amber-600;
|
||||
}
|
||||
|
||||
.menu-panel {
|
||||
@apply order-last mt-2 w-full rounded-[1.75rem] border border-white/70 bg-white/95 p-4 shadow-[0_16px_34px_rgba(20,33,61,0.12)] backdrop-blur lg:order-none lg:mt-0 lg:rounded-none lg:border-0 lg:bg-transparent lg:p-0 lg:shadow-none;
|
||||
@apply order-last mt-2 w-full rounded-[1.75rem] border border-stone-200 bg-white p-4 shadow-[0_16px_34px_rgba(20,33,61,0.08)] backdrop-blur lg:order-none lg:mt-0 lg:rounded-none lg:border-0 lg:bg-transparent lg:p-0 lg:shadow-none;
|
||||
}
|
||||
|
||||
.desktop-nav {
|
||||
@@ -120,7 +118,7 @@
|
||||
}
|
||||
|
||||
.desktop-nav__link {
|
||||
@apply inline-flex items-center py-4 text-[1.04rem] font-medium text-stone-800 transition hover:text-amber-600;
|
||||
@apply inline-flex items-center py-4 text-[1rem] font-medium text-stone-800 transition hover:text-amber-600;
|
||||
}
|
||||
|
||||
.desktop-nav__toggle {
|
||||
@@ -133,8 +131,8 @@
|
||||
}
|
||||
|
||||
.mega-menu {
|
||||
background: linear-gradient(180deg, rgba(255, 252, 247, 0.98), rgba(252, 248, 240, 0.98));
|
||||
@apply absolute inset-x-0 top-full z-50 border-t border-white/70 shadow-[0_28px_60px_rgba(20,33,61,0.16)] backdrop-blur;
|
||||
background: linear-gradient(180deg, rgba(255, 253, 250, 0.98), rgba(250, 247, 241, 0.98));
|
||||
@apply absolute inset-x-0 top-full z-50 border-t border-stone-200 shadow-[0_24px_54px_rgba(20,33,61,0.1)] backdrop-blur;
|
||||
}
|
||||
|
||||
.mega-menu__grid {
|
||||
@@ -158,11 +156,60 @@
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
@apply order-2 ml-auto flex items-center gap-2 text-2xl text-stone-900 lg:ml-auto lg:gap-4;
|
||||
@apply order-2 ml-auto flex items-center gap-2 text-2xl text-stone-900 lg:ml-auto lg:gap-3;
|
||||
}
|
||||
|
||||
.nav-icon {
|
||||
@apply flex h-11 w-11 items-center justify-center rounded-full bg-white/80 text-[1.2rem] shadow-[0_10px_24px_rgba(20,33,61,0.08)] transition hover:-translate-y-0.5 hover:text-amber-600 sm:text-[1.35rem];
|
||||
@apply flex h-11 w-11 items-center justify-center rounded-full border border-transparent bg-white text-[1.2rem] shadow-[0_8px_18px_rgba(20,33,61,0.05)] transition hover:-translate-y-0.5 hover:border-stone-200 hover:text-amber-600 sm:text-[1.35rem];
|
||||
}
|
||||
|
||||
[data-product-gallery-main] .splide__track,
|
||||
[data-gallery-main-splide] .splide__track {
|
||||
@apply overflow-hidden;
|
||||
}
|
||||
|
||||
[data-product-gallery-thumbs] .splide__slide,
|
||||
[data-gallery-thumb-splide] .splide__slide {
|
||||
@apply cursor-pointer opacity-70 transition;
|
||||
}
|
||||
|
||||
[data-product-gallery-thumbs] .splide__slide.is-active,
|
||||
[data-gallery-thumb-splide] .splide__slide.is-active {
|
||||
@apply border-amber-500 opacity-100;
|
||||
}
|
||||
|
||||
[data-product-gallery-thumbs] .splide__slide img,
|
||||
[data-gallery-thumb-splide] .splide__slide img {
|
||||
@apply block h-full w-full;
|
||||
}
|
||||
|
||||
.category-description {
|
||||
@apply max-w-none;
|
||||
}
|
||||
|
||||
.category-description p:first-child {
|
||||
@apply mt-0;
|
||||
}
|
||||
|
||||
.category-description p:last-child {
|
||||
@apply mb-0;
|
||||
}
|
||||
|
||||
.category-description p + p {
|
||||
@apply mt-4;
|
||||
}
|
||||
|
||||
.category-description ul,
|
||||
.category-description ol {
|
||||
@apply my-4 pl-5;
|
||||
}
|
||||
|
||||
.category-description li + li {
|
||||
@apply mt-2;
|
||||
}
|
||||
|
||||
.category-description a {
|
||||
@apply text-amber-600 underline underline-offset-4;
|
||||
}
|
||||
|
||||
@media (max-width: 1023px) {
|
||||
|
||||
+305
-158
@@ -107,85 +107,221 @@ if (cartButton) {
|
||||
});
|
||||
}
|
||||
|
||||
const productMainImage = document.querySelector("[data-product-main-image]");
|
||||
const defaultProductImage = productMainImage?.dataset.defaultImage || productMainImage?.getAttribute("src") || "";
|
||||
const productThumbCarousel = document.querySelector("[data-product-thumb-carousel]");
|
||||
const productThumbViewport = productThumbCarousel?.querySelector("[data-product-thumb-viewport]");
|
||||
const productThumbTrack = productThumbCarousel?.querySelector("[data-product-thumb-track]");
|
||||
const productThumbPrev = productThumbCarousel?.querySelector("[data-product-thumb-prev]");
|
||||
const productThumbNext = productThumbCarousel?.querySelector("[data-product-thumb-next]");
|
||||
const productThumbs = [...document.querySelectorAll("[data-product-thumb-index]")];
|
||||
const attachSwipeNavigation = (element, onPrev, onNext, options = {}) => {
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (productMainImage && productThumbCarousel && productThumbViewport && productThumbTrack && productThumbs.length > 0) {
|
||||
let activeProductThumbIndex = 0;
|
||||
const threshold = options.threshold ?? 48;
|
||||
const getAxis = () => (typeof options.axis === "function" ? options.axis() : options.axis ?? "x");
|
||||
const allowMouse = options.allowMouse ?? true;
|
||||
const suppressClickAfterSwipe = options.suppressClickAfterSwipe ?? false;
|
||||
let pointerId = null;
|
||||
let startX = 0;
|
||||
let startY = 0;
|
||||
let deltaX = 0;
|
||||
let deltaY = 0;
|
||||
let moved = false;
|
||||
let swallowClick = false;
|
||||
|
||||
const updateProductThumbState = () => {
|
||||
productThumbs.forEach((thumb, index) => {
|
||||
if (index === activeProductThumbIndex) {
|
||||
thumb.classList.remove("border-stone-800");
|
||||
thumb.classList.add("border-amber-400/60", "ring-1", "ring-amber-300/40");
|
||||
thumb.setAttribute("aria-current", "true");
|
||||
return;
|
||||
}
|
||||
thumb.classList.remove("border-amber-400/60", "ring-1", "ring-amber-300/40");
|
||||
thumb.classList.add("border-stone-800");
|
||||
thumb.removeAttribute("aria-current");
|
||||
});
|
||||
const reset = () => {
|
||||
pointerId = null;
|
||||
startX = 0;
|
||||
startY = 0;
|
||||
deltaX = 0;
|
||||
deltaY = 0;
|
||||
moved = false;
|
||||
};
|
||||
|
||||
const scrollProductThumbIntoView = (index) => {
|
||||
const thumb = productThumbs[index];
|
||||
thumb?.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "center" });
|
||||
};
|
||||
|
||||
const showProductThumb = (index) => {
|
||||
const normalizedIndex = (index + productThumbs.length) % productThumbs.length;
|
||||
const thumb = productThumbs[normalizedIndex];
|
||||
const nextSrc = thumb?.dataset.productThumbLarge || thumb?.dataset.productThumbLargeFallback || "";
|
||||
if (!thumb || !nextSrc) {
|
||||
element.addEventListener("pointerdown", (event) => {
|
||||
if (!allowMouse && event.pointerType === "mouse") {
|
||||
return;
|
||||
}
|
||||
activeProductThumbIndex = normalizedIndex;
|
||||
productMainImage.setAttribute("src", nextSrc);
|
||||
if (thumb.dataset.productThumbAlt) {
|
||||
productMainImage.setAttribute("alt", thumb.dataset.productThumbAlt);
|
||||
if (event.pointerType === "mouse" && event.button !== 0) {
|
||||
return;
|
||||
}
|
||||
updateProductThumbState();
|
||||
scrollProductThumbIntoView(normalizedIndex);
|
||||
pointerId = event.pointerId;
|
||||
startX = event.clientX;
|
||||
startY = event.clientY;
|
||||
deltaX = 0;
|
||||
deltaY = 0;
|
||||
moved = false;
|
||||
});
|
||||
|
||||
element.addEventListener("pointermove", (event) => {
|
||||
if (event.pointerId !== pointerId) {
|
||||
return;
|
||||
}
|
||||
deltaX = event.clientX - startX;
|
||||
deltaY = event.clientY - startY;
|
||||
if (Math.abs(deltaX) > 6 || Math.abs(deltaY) > 6) {
|
||||
moved = true;
|
||||
}
|
||||
});
|
||||
|
||||
const finish = (event) => {
|
||||
if (event.pointerId !== pointerId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const axis = getAxis();
|
||||
const primaryDelta = axis === "y" ? deltaY : deltaX;
|
||||
const crossDelta = axis === "y" ? deltaX : deltaY;
|
||||
|
||||
if (moved && Math.abs(primaryDelta) >= threshold && Math.abs(primaryDelta) > Math.abs(crossDelta)) {
|
||||
swallowClick = suppressClickAfterSwipe;
|
||||
if (primaryDelta > 0) {
|
||||
onPrev();
|
||||
} else {
|
||||
onNext();
|
||||
}
|
||||
}
|
||||
|
||||
reset();
|
||||
};
|
||||
|
||||
const stepProductThumbs = (direction) => {
|
||||
showProductThumb(activeProductThumbIndex + direction);
|
||||
element.addEventListener("pointerup", finish);
|
||||
element.addEventListener("pointercancel", reset);
|
||||
element.addEventListener("pointerleave", (event) => {
|
||||
if (event.pointerId === pointerId && event.pointerType !== "touch") {
|
||||
finish(event);
|
||||
}
|
||||
});
|
||||
|
||||
if (suppressClickAfterSwipe) {
|
||||
element.addEventListener(
|
||||
"click",
|
||||
(event) => {
|
||||
if (!swallowClick) {
|
||||
return;
|
||||
}
|
||||
swallowClick = false;
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
},
|
||||
true,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const attachDragScroll = (element, options = {}) => {
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
const getAxis = () => (typeof options.axis === "function" ? options.axis() : options.axis ?? "x");
|
||||
let pointerId = null;
|
||||
let startPosition = 0;
|
||||
let startScroll = 0;
|
||||
let dragging = false;
|
||||
|
||||
element.addEventListener("pointerdown", (event) => {
|
||||
if (event.pointerType === "mouse" && event.button !== 0) {
|
||||
return;
|
||||
}
|
||||
const axis = getAxis();
|
||||
pointerId = event.pointerId;
|
||||
startPosition = axis === "y" ? event.clientY : event.clientX;
|
||||
startScroll = axis === "y" ? element.scrollTop : element.scrollLeft;
|
||||
dragging = true;
|
||||
element.setPointerCapture?.(event.pointerId);
|
||||
});
|
||||
|
||||
element.addEventListener("pointermove", (event) => {
|
||||
if (!dragging || event.pointerId !== pointerId) {
|
||||
return;
|
||||
}
|
||||
const axis = getAxis();
|
||||
const currentPosition = axis === "y" ? event.clientY : event.clientX;
|
||||
const delta = currentPosition - startPosition;
|
||||
if (axis === "y") {
|
||||
element.scrollTop = startScroll - delta;
|
||||
} else {
|
||||
element.scrollLeft = startScroll - delta;
|
||||
}
|
||||
});
|
||||
|
||||
const stopDragging = (event) => {
|
||||
if (event.pointerId !== pointerId) {
|
||||
return;
|
||||
}
|
||||
dragging = false;
|
||||
pointerId = null;
|
||||
};
|
||||
|
||||
element.addEventListener("pointerup", stopDragging);
|
||||
element.addEventListener("pointercancel", stopDragging);
|
||||
};
|
||||
|
||||
const SplideCtor = window.Splide;
|
||||
const productMainImage = document.querySelector("[data-product-main-image]");
|
||||
const productGalleryRoot = document.querySelector("[data-product-gallery-main]");
|
||||
const productGalleryThumbRoot = document.querySelector("[data-product-gallery-thumbs]");
|
||||
const productThumbPrev = document.querySelector("[data-product-thumb-prev]");
|
||||
const productThumbNext = document.querySelector("[data-product-thumb-next]");
|
||||
const productGalleryImages = [...document.querySelectorAll("[data-product-gallery-image]")];
|
||||
const defaultProductImage = productMainImage?.dataset.defaultImage
|
||||
|| productGalleryImages[0]?.dataset.imageUrl
|
||||
|| productMainImage?.getAttribute("src")
|
||||
|| "";
|
||||
|
||||
let productMainSplide = null;
|
||||
let productThumbSplide = null;
|
||||
let galleryMainSplide = null;
|
||||
let galleryThumbSplide = null;
|
||||
|
||||
const findImageIndex = (nodes, url) => nodes.findIndex((node) => (node.dataset.imageUrl || node.getAttribute("src") || "") === url);
|
||||
|
||||
if (SplideCtor && productGalleryRoot && productGalleryThumbRoot && productGalleryImages.length > 1) {
|
||||
productMainSplide = new SplideCtor(productGalleryRoot, {
|
||||
type: "slide",
|
||||
arrows: false,
|
||||
pagination: false,
|
||||
rewind: true,
|
||||
drag: true,
|
||||
speed: 520,
|
||||
});
|
||||
|
||||
productThumbSplide = new SplideCtor(productGalleryThumbRoot, {
|
||||
fixedWidth: 64,
|
||||
fixedHeight: 64,
|
||||
gap: 12,
|
||||
rewind: true,
|
||||
pagination: false,
|
||||
arrows: false,
|
||||
isNavigation: true,
|
||||
focus: "center",
|
||||
dragMinThreshold: {
|
||||
mouse: 4,
|
||||
touch: 8,
|
||||
},
|
||||
breakpoints: {
|
||||
640: {
|
||||
fixedWidth: 64,
|
||||
fixedHeight: 64,
|
||||
},
|
||||
1024: {
|
||||
fixedWidth: 80,
|
||||
fixedHeight: 80,
|
||||
},
|
||||
1280: {
|
||||
fixedWidth: 96,
|
||||
fixedHeight: 96,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
productMainSplide.sync(productThumbSplide);
|
||||
productMainSplide.mount();
|
||||
productThumbSplide.mount();
|
||||
|
||||
productThumbPrev?.addEventListener("click", () => {
|
||||
stepProductThumbs(-1);
|
||||
productMainSplide.go("<");
|
||||
});
|
||||
|
||||
productThumbNext?.addEventListener("click", () => {
|
||||
stepProductThumbs(1);
|
||||
productMainSplide.go(">");
|
||||
});
|
||||
|
||||
productThumbs.forEach((thumb, index) => {
|
||||
thumb.addEventListener("click", () => {
|
||||
showProductThumb(index);
|
||||
});
|
||||
});
|
||||
|
||||
const initialIndex = productThumbs.findIndex((thumb) => thumb.dataset.productThumbLarge === productMainImage.getAttribute("src"));
|
||||
showProductThumb(initialIndex >= 0 ? initialIndex : 0);
|
||||
|
||||
productThumbViewport.addEventListener(
|
||||
"wheel",
|
||||
(event) => {
|
||||
if (Math.abs(event.deltaY) <= Math.abs(event.deltaX)) {
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
productThumbViewport.scrollBy({ left: event.deltaY, behavior: "smooth" });
|
||||
},
|
||||
{ passive: false },
|
||||
);
|
||||
}
|
||||
|
||||
const variantPicker = document.querySelector("[data-variant-picker]");
|
||||
@@ -390,25 +526,15 @@ if (variantPicker && variantCombinationInput) {
|
||||
const combinationID = String(matched[0]);
|
||||
variantCombinationInput.value = combinationID;
|
||||
const combinationData = combinationImageByID.get(combinationID);
|
||||
if (productMainImage) {
|
||||
const nextImage = combinationData?.imageLarge || defaultProductImage;
|
||||
if (nextImage) {
|
||||
productMainImage.setAttribute("src", nextImage);
|
||||
const matchingThumbIndex = productThumbs.findIndex((thumb) => thumb.dataset.productThumbLarge === nextImage);
|
||||
if (matchingThumbIndex >= 0) {
|
||||
productThumbs.forEach((thumb, index) => {
|
||||
if (index === matchingThumbIndex) {
|
||||
thumb.classList.remove("border-stone-800");
|
||||
thumb.classList.add("border-amber-400/60", "ring-1", "ring-amber-300/40");
|
||||
thumb.setAttribute("aria-current", "true");
|
||||
} else {
|
||||
thumb.classList.remove("border-amber-400/60", "ring-1", "ring-amber-300/40");
|
||||
thumb.classList.add("border-stone-800");
|
||||
thumb.removeAttribute("aria-current");
|
||||
}
|
||||
});
|
||||
productThumbs[matchingThumbIndex]?.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "center" });
|
||||
const nextImage = combinationData?.imageLarge || defaultProductImage;
|
||||
if (nextImage) {
|
||||
if (productMainSplide && productGalleryImages.length > 0) {
|
||||
const matchingIndex = findImageIndex(productGalleryImages, nextImage);
|
||||
if (matchingIndex >= 0) {
|
||||
productMainSplide.go(matchingIndex);
|
||||
}
|
||||
} else if (productMainImage) {
|
||||
productMainImage.setAttribute("src", nextImage);
|
||||
}
|
||||
}
|
||||
if (productPriceGross) {
|
||||
@@ -504,25 +630,99 @@ const galleryModal = document.querySelector("[data-gallery-modal]");
|
||||
const galleryMain = galleryModal?.querySelector("[data-gallery-main]");
|
||||
const galleryOpeners = [...document.querySelectorAll("[data-gallery-open]")];
|
||||
const galleryClosers = [...document.querySelectorAll("[data-gallery-close]")];
|
||||
const galleryThumbs = [...document.querySelectorAll("[data-gallery-thumb]")];
|
||||
const galleryMainRoot = galleryModal?.querySelector("[data-gallery-main-splide]");
|
||||
const galleryThumbRoot = galleryModal?.querySelector("[data-gallery-thumb-splide]");
|
||||
const galleryImages = [...document.querySelectorAll("[data-gallery-image]")];
|
||||
const galleryPrev = galleryModal?.querySelector("[data-gallery-prev]");
|
||||
const galleryNext = galleryModal?.querySelector("[data-gallery-next]");
|
||||
const galleryThumbViewport = galleryModal?.querySelector("[data-gallery-thumb-viewport]");
|
||||
const galleryThumbPrev = galleryModal?.querySelector("[data-gallery-thumb-prev]");
|
||||
const galleryThumbNext = galleryModal?.querySelector("[data-gallery-thumb-next]");
|
||||
|
||||
if (galleryModal && galleryMain && galleryOpeners.length > 0) {
|
||||
let activeIndex = 0;
|
||||
if (SplideCtor && galleryMainRoot && galleryThumbRoot && galleryImages.length > 1) {
|
||||
galleryMainSplide = new SplideCtor(galleryMainRoot, {
|
||||
type: "slide",
|
||||
arrows: false,
|
||||
pagination: false,
|
||||
rewind: true,
|
||||
drag: true,
|
||||
speed: 520,
|
||||
});
|
||||
|
||||
galleryThumbSplide = new SplideCtor(galleryThumbRoot, {
|
||||
fixedWidth: 64,
|
||||
fixedHeight: 64,
|
||||
gap: 12,
|
||||
rewind: true,
|
||||
pagination: false,
|
||||
arrows: false,
|
||||
isNavigation: true,
|
||||
focus: "center",
|
||||
dragMinThreshold: {
|
||||
mouse: 4,
|
||||
touch: 8,
|
||||
},
|
||||
breakpoints: {
|
||||
640: {
|
||||
fixedWidth: 64,
|
||||
fixedHeight: 64,
|
||||
},
|
||||
1024: {
|
||||
fixedWidth: 80,
|
||||
fixedHeight: 80,
|
||||
},
|
||||
1280: {
|
||||
fixedWidth: 96,
|
||||
fixedHeight: 96,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
galleryMainSplide.sync(galleryThumbSplide);
|
||||
galleryMainSplide.mount();
|
||||
galleryThumbSplide.mount();
|
||||
}
|
||||
|
||||
if (galleryModal && (galleryMain || galleryMainSplide) && galleryOpeners.length > 0) {
|
||||
let wheelLocked = false;
|
||||
|
||||
const openGallery = () => {
|
||||
const productMainImage = document.querySelector("[data-product-main-image]");
|
||||
const currentMainSrc = productMainImage?.getAttribute("src") || "";
|
||||
if (currentMainSrc) {
|
||||
const matchingIndex = galleryThumbs.findIndex((thumb) => thumb.dataset.galleryThumb === currentMainSrc);
|
||||
if (matchingIndex >= 0) {
|
||||
showGalleryImage(matchingIndex);
|
||||
}
|
||||
const currentProductImageURL = () => {
|
||||
if (productMainSplide && productGalleryImages.length > 0) {
|
||||
return productGalleryImages[productMainSplide.index]?.dataset.imageUrl || defaultProductImage;
|
||||
}
|
||||
return productMainImage?.getAttribute("src") || defaultProductImage;
|
||||
};
|
||||
|
||||
const showGalleryImage = (index) => {
|
||||
if (galleryMainSplide && galleryImages.length > 0) {
|
||||
const normalizedIndex = (index + galleryImages.length) % galleryImages.length;
|
||||
galleryMainSplide.go(normalizedIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!galleryMain) {
|
||||
return;
|
||||
}
|
||||
|
||||
const nextImage = galleryImages[index];
|
||||
const nextSrc = nextImage?.dataset.imageUrl || "";
|
||||
if (!nextSrc) {
|
||||
return;
|
||||
}
|
||||
galleryMain.setAttribute("src", nextSrc);
|
||||
};
|
||||
|
||||
const stepGallery = (direction) => {
|
||||
if (galleryMainSplide) {
|
||||
galleryMainSplide.go(direction > 0 ? ">" : "<");
|
||||
return;
|
||||
}
|
||||
showGalleryImage(0);
|
||||
};
|
||||
|
||||
const openGallery = (index) => {
|
||||
const nextIndex = Number.isInteger(index) ? index : findImageIndex(galleryImages, currentProductImageURL());
|
||||
if (nextIndex >= 0) {
|
||||
showGalleryImage(nextIndex);
|
||||
}
|
||||
galleryModal.classList.remove("hidden");
|
||||
galleryModal.setAttribute("aria-hidden", "false");
|
||||
@@ -535,61 +735,17 @@ if (galleryModal && galleryMain && galleryOpeners.length > 0) {
|
||||
document.body.style.overflow = "";
|
||||
};
|
||||
|
||||
const setActiveThumb = (activeThumb) => {
|
||||
galleryThumbs.forEach((thumb) => {
|
||||
thumb.classList.remove("border-amber-400/60");
|
||||
thumb.classList.add("border-stone-800");
|
||||
});
|
||||
if (activeThumb) {
|
||||
activeThumb.classList.remove("border-stone-800");
|
||||
activeThumb.classList.add("border-amber-400/60");
|
||||
activeThumb.scrollIntoView({ block: "nearest", inline: "nearest" });
|
||||
}
|
||||
};
|
||||
|
||||
const showGalleryImage = (index) => {
|
||||
if (galleryThumbs.length === 0) return;
|
||||
const normalizedIndex = (index + galleryThumbs.length) % galleryThumbs.length;
|
||||
const thumb = galleryThumbs[normalizedIndex];
|
||||
const nextSrc = thumb.dataset.galleryThumb;
|
||||
const nextAlt = thumb.dataset.galleryAlt || galleryMain.getAttribute("alt") || "";
|
||||
if (!nextSrc) return;
|
||||
activeIndex = normalizedIndex;
|
||||
galleryMain.setAttribute("src", nextSrc);
|
||||
galleryMain.setAttribute("alt", nextAlt);
|
||||
setActiveThumb(thumb);
|
||||
};
|
||||
|
||||
const stepGallery = (direction) => {
|
||||
if (galleryThumbs.length <= 1) return;
|
||||
showGalleryImage(activeIndex + direction);
|
||||
};
|
||||
|
||||
galleryThumbPrev?.addEventListener("click", () => {
|
||||
stepGallery(-1);
|
||||
});
|
||||
|
||||
galleryThumbNext?.addEventListener("click", () => {
|
||||
stepGallery(1);
|
||||
});
|
||||
|
||||
galleryOpeners.forEach((trigger) => {
|
||||
trigger.addEventListener("click", openGallery);
|
||||
trigger.addEventListener("click", () => {
|
||||
const index = Number.parseInt(trigger.dataset.galleryIndex || "", 10);
|
||||
openGallery(Number.isInteger(index) ? index : undefined);
|
||||
});
|
||||
});
|
||||
|
||||
galleryClosers.forEach((trigger) => {
|
||||
trigger.addEventListener("click", closeGallery);
|
||||
});
|
||||
|
||||
galleryThumbs.forEach((thumb, index) => {
|
||||
if (index === 0) {
|
||||
showGalleryImage(0);
|
||||
}
|
||||
thumb.addEventListener("click", () => {
|
||||
showGalleryImage(index);
|
||||
});
|
||||
});
|
||||
|
||||
galleryPrev?.addEventListener("click", () => {
|
||||
stepGallery(-1);
|
||||
});
|
||||
@@ -598,22 +754,13 @@ if (galleryModal && galleryMain && galleryOpeners.length > 0) {
|
||||
stepGallery(1);
|
||||
});
|
||||
|
||||
galleryThumbViewport?.addEventListener(
|
||||
"wheel",
|
||||
(event) => {
|
||||
if (window.innerWidth >= 1024) {
|
||||
event.preventDefault();
|
||||
galleryThumbViewport.scrollBy({ top: event.deltaY, behavior: "smooth" });
|
||||
return;
|
||||
}
|
||||
if (Math.abs(event.deltaY) <= Math.abs(event.deltaX)) {
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
galleryThumbViewport.scrollBy({ left: event.deltaY, behavior: "smooth" });
|
||||
},
|
||||
{ passive: false },
|
||||
);
|
||||
galleryThumbPrev?.addEventListener("click", () => {
|
||||
galleryMainSplide?.go("<");
|
||||
});
|
||||
|
||||
galleryThumbNext?.addEventListener("click", () => {
|
||||
galleryMainSplide?.go(">");
|
||||
});
|
||||
|
||||
galleryModal.addEventListener("click", (event) => {
|
||||
if (event.target === galleryModal) {
|
||||
@@ -624,7 +771,7 @@ if (galleryModal && galleryMain && galleryOpeners.length > 0) {
|
||||
galleryModal.addEventListener(
|
||||
"wheel",
|
||||
(event) => {
|
||||
if (galleryModal.getAttribute("aria-hidden") !== "false" || galleryThumbs.length <= 1) {
|
||||
if (galleryModal.getAttribute("aria-hidden") !== "false" || !galleryMainSplide) {
|
||||
return;
|
||||
}
|
||||
if (Math.abs(event.deltaY) < 10) {
|
||||
|
||||
Reference in New Issue
Block a user