diff --git a/docs/assets/javascript/shop.js b/docs/assets/javascript/shop.js index 71002ef7..bcd08fd2 100644 --- a/docs/assets/javascript/shop.js +++ b/docs/assets/javascript/shop.js @@ -58,6 +58,22 @@ document.addEventListener("DOMContentLoaded", () => { }; }; + const getPreviousIndex = (list, current) => { + if (current === 0) { + return list.length - 1; + } + + return current - 1; + } + + const getNextIndex = (list, current) => { + if (current === list.length - 1) { + return 0; + } + + return current + 1; + } + const THEME_COLOR = "success"; const STORAGE_CART_ID = "bulma-shop-cart-id"; @@ -366,10 +382,9 @@ document.addEventListener("DOMContentLoaded", () => { }; const openModal = (product) => { - $title = $modal.querySelector(".modal-title"); - $body = $modal.querySelector(".modal-body"); - $buttons = $modal.querySelector(".modal .buttons"); - $close = $modal.querySelector(".modal .buttons .button.is-close"); + const $title = $modal.querySelector(".modal-title"); + const $body = $modal.querySelector(".modal-body"); + const $buttons = $modal.querySelector(".modal .buttons"); $title.replaceChildren(); buildHeading($title, product); @@ -462,19 +477,14 @@ document.addEventListener("DOMContentLoaded", () => { const $option = El("", "option"); $option.dataset.id = id; $option.innerText = title; - - // $option.addEventListener("click", (event) => { - // event.preventDefault(); - // product.selectedVariant = id; - // update(); - // }); + $option.value = id; $options.appendChild($option); }); $select.addEventListener("change", (event) => { event.preventDefault(); - product.selectedVariant = id; + product.selectedVariant = event.target.value; update(); }); @@ -507,7 +517,7 @@ document.addEventListener("DOMContentLoaded", () => { } state.products.forEach((product) => { - const { id, availableForSale, featuredImage } = product; + const { id, availableForSale, images } = product; if (!availableForSale) { return; @@ -518,16 +528,51 @@ document.addEventListener("DOMContentLoaded", () => { const el = El("card-content"); - const $figure = El("shop-product-image image is-square", "figure"); - const $img = document.createElement("img"); - $img.src = featuredImage.url; - $figure.appendChild($img); - $card.appendChild($figure); + const $images = El("shop-product-images image is-square"); + const $carousel = El("shop-product-carousel image is-square"); - $figure.addEventListener("click", async (event) => { - event.preventDefault(); - openModal(product); - }); + if (images) { + images.forEach(img => { + const $figure = El("shop-product-image image is-square", "figure"); + const $img = document.createElement("img"); + $img.src = img.url; + $figure.appendChild($img); + $carousel.appendChild($figure); + }); + + $images.appendChild($carousel); + + if (images.length > 1) { + const $prev = El("shop-product-arrow shop-product-prev", "button"); + const $prevArrow = El("icon", "button"); + const $prevIcon = El("fa-solid fa-arrow-left", "i"); + $prevArrow.appendChild($prevIcon); + $prev.appendChild($prevArrow); + + $prev.addEventListener("click", event => { + event.preventDefault(); + product.selectedImage = getPreviousIndex(images, product.selectedImage); + update(); + }); + + const $next = El("shop-product-arrow shop-product-next", "button"); + const $nextArrow = El("icon", "button"); + const $nextIcon = El("fa-solid fa-arrow-right", "i"); + $nextArrow.appendChild($nextIcon); + $next.appendChild($nextArrow); + + $next.addEventListener("click", event => { + event.preventDefault(); + product.selectedImage = getNextIndex(images, product.selectedImage); + update(); + }); + + $images.appendChild($prev); + $images.appendChild($next); + } + } + + $card.appendChild($images); buildHeading(el, product); buildDescription(el, product); @@ -552,6 +597,20 @@ document.addEventListener("DOMContentLoaded", () => { }); }; + const updateImages = () => { + state.products.forEach((product) => { + const $blocs = document.querySelectorAll( + `.shop-product-${getId(product.id)}`, + ); + + $blocs.forEach(($bloc) => { + const $carousel = $bloc.querySelector(`.shop-product-carousel`); + const offset = product.selectedImage * 100; + $carousel.style.transform = `translateX(-${offset}%`; + }); + }); + } + const updateCart = () => { if (isEmpty(state.cart)) { return; @@ -577,13 +636,23 @@ document.addEventListener("DOMContentLoaded", () => { $item.dataset.id = line.id; const $left = El("media-left"); + // const $images = El("shop-item-images"); const $image = El("shop-item-image image is-64x64"); const $img = El("", "img"); - if (product.featuredImage) { $img.src = product.featuredImage.url; } + // if (product.images) { + // product.images.forEach(img => { + // const $image = El("shop-item-image image is-64x64"); + // const $img = El("", "img"); + // $img.src = img.url; + // $image.appendChild($img); + // $images.appendChild($image); + // }); + // } + $image.appendChild($img); $left.appendChild($image); @@ -720,17 +789,17 @@ document.addEventListener("DOMContentLoaded", () => { `.shop-product-${getId(product.id)}`, ); - // $blocs.forEach(($bloc) => { - // const $variants = $bloc.querySelectorAll(`.variants .button`); + $blocs.forEach(($bloc) => { + const $variants = $bloc.querySelectorAll(`.shop-product-select option`); - // $variants.forEach(($el) => { - // if ($el.dataset.id === product.selectedVariant) { - // $el.classList.add(`is-${THEME_COLOR}`); - // } else { - // $el.classList.remove(`is-${THEME_COLOR}`); - // } - // }); - // }); + $variants.forEach(($el) => { + if ($el.dataset.id === product.selectedVariant) { + $el.setAttribute("selected", ""); + } else { + $el.removeAttribute("selected"); + } + }); + }); }); }; @@ -739,6 +808,7 @@ document.addEventListener("DOMContentLoaded", () => { updateCart(); updateButtons(); updateVariants(); + updateImages(); }; // HTML Elements @@ -855,6 +925,7 @@ document.addEventListener("DOMContentLoaded", () => { state.products = clean.products.map((product) => { return { ...product, + selectedImage: 0, selectedVariant: product.variants[0].id, }; }); diff --git a/docs/shop.html b/docs/shop.html index 67ccfe57..1bce695c 100644 --- a/docs/shop.html +++ b/docs/shop.html @@ -235,7 +235,58 @@ breadcrumb: flex-direction: column; } + .shop-product-images { + position: relative; + } + + .shop-product-images:hover .shop-product-arrow { + opacity: 1; + } + + .shop-product-arrow { + position: absolute; + opacity: 0; + top: 0; + bottom: 0; + display: flex; + align-items: center; + justify-content: center; + padding: 1em; + } + + .shop-product-arrow .icon { + background-color: rgb(0 0 0 / 10%); + border-radius: 9999px; + transition-duration: var(--shop-duration); + transition-property: background-color, color, opacity; + } + + .shop-product-arrow:hover .icon { + background-color: rgb(0 0 0 / 50%); + color: white; + } + + .shop-product-arrow:active .icon { + background-color: rgb(0 0 0 / 70%); + color: white; + } + + .shop-product-prev { + left: 0; + } + + .shop-product-next { + right: 0; + } + + .shop-product-carousel { + display: flex; + transition-duration: 300ms; + transition-property: transform; + } + .shop-product-image { + flex-shrink: 0; cursor: pointer; overflow: hidden; } @@ -246,7 +297,7 @@ breadcrumb: transform-origin: center; } - .shop-product-image:hover img { + .shop-product-images:hover img { transform: scale(1.1); } @@ -343,29 +394,33 @@ breadcrumb: {% include global/header.html %} {% capture shop_placeholder %} -
+
-
-

The Bulma T-Shirt

-
- $15 +
+
+

The Bulma T-Shirt

+
+ $15 +
-
-
-
- Show your CSS skills and add a little extra motivation with the - official Bulma sticker. A perfect reminder that design can be easy - with your favorite framework. + +
+
+ Show your CSS skills and add a little extra motivation with the + official Bulma sticker. A perfect reminder that design can be easy + with your favorite framework. +
+
+ +
+
-
-
-
{% endcapture %}