diff --git a/blocks/product-hero/product-hero.css b/blocks/product-hero/product-hero.css index 990e2326d..3200ed7fa 100644 --- a/blocks/product-hero/product-hero.css +++ b/blocks/product-hero/product-hero.css @@ -64,29 +64,29 @@ } .product-hero .vertical-gallery-container > div { - @apply grid grid-rows-1 gap-2.5 bg-transparent overflow-hidden md:grid-cols-4; + @apply grid grid-rows-1 gap-y-3 bg-transparent overflow-hidden md:grid-cols-5; } .product-hero .vertical-gallery-container > div div:nth-child(1) { - @apply relative col-span-3 bg-white; + @apply relative col-auto md:col-span-4 bg-white shadow-lg md:shadow-none; } .product-hero .vertical-gallery-container > div div:nth-child(1) img { - @apply w-full h-80 max-w-[360px] mx-auto rounded shadow object-contain transition duration-700; + @apply w-[400px] h-[400px] max-w-[400px] mx-auto shadow-none md:shadow-lg object-contain transition duration-700; } .product-hero .vertical-gallery-container > div > div:not(:nth-child(1)) { - @apply flex flex-row md:flex-col col-span-1 gap-2 md:order-first overflow-auto bg-transparent scroll-pl-6 snap-x; + @apply flex flex-row md:flex-col col-auto md:col-span-1 gap-2 md:order-first overflow-auto bg-transparent scroll-pl-6 snap-x; } .product-hero .vertical-gallery-container .view-more { - @apply flex flex-col p-2 my-auto bg-opacity-50 text-sm text-danaherpurple-500 font-semibold bg-white rounded text-center cursor-pointer; + @apply flex flex-col p-2 my-auto bg-opacity-50 text-sm text-danaherpurple-500 font-semibold bg-white cursor-pointer; } .product-hero .vertical-gallery-container > div > div:not(:nth-child(1)) img { - @apply w-32 h-20 object-cover rounded cursor-pointer transition duration-500 hover:border hover:border-danaherpurple-500 hover:scale-95; + @apply w-[75px] h-[75px] object-cover border border-gray-300 cursor-pointer transition duration-500 hover:border hover:border-danaherpurple-500 hover:scale-95; } -.product-hero .vertical-gallery-container > div div:not(:nth-child(1)) img.active { - @apply border border-4 border-danaherpurple-500 opacity-80 scale-95; +.product-hero .vertical-gallery-container > div div:not(:nth-child(1)) picture.active img { + @apply border border-2 border-danaherpurple-500 opacity-80 scale-95; } \ No newline at end of file diff --git a/blocks/product-hero/product-hero.js b/blocks/product-hero/product-hero.js index 991c0a44b..c21af3188 100644 --- a/blocks/product-hero/product-hero.js +++ b/blocks/product-hero/product-hero.js @@ -8,12 +8,10 @@ function showImage(e) { const selectedImage = document.querySelector('.image-content picture'); if (e.target) { const currentPicture = e.target.parentElement; - const currentActive = currentPicture.querySelector('.active'); - if (currentActive) currentActive.classList.toggle('active'); - if (e.target.src !== selectedImage.querySelector('img').src) { - selectedImage.replaceWith(currentPicture.cloneNode(true)); - currentPicture.classList.toggle('active'); - } + const currentActive = currentPicture.parentElement.querySelector('.active'); + if (currentActive && currentActive.className.includes('active')) currentActive.classList.toggle('active'); + currentPicture.classList.toggle('active'); + selectedImage.replaceWith(currentPicture.cloneNode(true)); } } @@ -36,10 +34,10 @@ function loadMore() { } function imageSlider(allImages, productName = 'product') { - const slideContent = div({ class: 'image-content' }, createOptimizedS7Picture(allImages[0], `${productName} - image`, true, [{ width: '360' }])); + const slideContent = div({ class: 'image-content' }, createOptimizedS7Picture(allImages[0], `${productName} - image`, true)); const verticalSlides = div(); allImages.map((image, index) => { - const imageElement = createOptimizedS7Picture(image, `${productName} - image ${index + 1}`, false, [{ width: '360' }]); + const imageElement = createOptimizedS7Picture(image, `${productName} - image ${index + 1}`, false); let imageClass = (index === 0) ? 'active' : ''; if (index > 2) imageClass += ' hidden'; if (imageClass !== '') imageElement.className = imageClass.trim(); @@ -76,7 +74,7 @@ function addBundleDetails(title, bundleDetails) { { class: 'flex justify-between py-2 border-b w-[98%]' }, div( { class: 'flex col-span-10 gap-x-4' }, - createOptimizedS7Picture(product.image, product.title, false, [{ width: '64' }]), + createOptimizedS7Picture(product.image, product.title, false), div( { class: 'flex flex-col items-start' }, p(`${product.title}`), diff --git a/scripts/scripts.js b/scripts/scripts.js index 4e996a5d3..923fc2b89 100644 --- a/scripts/scripts.js +++ b/scripts/scripts.js @@ -23,10 +23,7 @@ import { img, } from './dom-builder.js'; -// eslint-disable-next-line import/no-named-default -import { default as decorateEmbed } from '../blocks/embed/embed.js'; - -const LCP_BLOCKS = ['breadcrumb']; // add your LCP blocks to the list +const LCP_BLOCKS = ['breadcrumb', 'product-hero']; // add your LCP blocks to the list const TEMPLATE_LIST = { blog: 'blog', news: 'blog', @@ -61,30 +58,10 @@ export function imageHelper(imageUrl, imageAlt, eager = false) { return cardImage; } -export function createOptimizedS7Picture(src, alt = '', eager = false, breakpoints = [{ media: '(min-width: 600px)', width: '2000' }, { width: '750' }]) { +export function createOptimizedS7Picture(src, alt = '', eager = false) { if (src.startsWith('/is/image') || src.indexOf('.scene7.com') > -1) { const picture = document.createElement('picture'); - - // webp - breakpoints.forEach((br) => { - const source = document.createElement('source'); - if (br.media) source.setAttribute('media', br.media); - source.setAttribute('type', 'image/webp'); - source.setAttribute('srcset', `${src}?wid=${br.width}&fmt=webp`); - picture.appendChild(source); - }); - - // fallback - breakpoints.forEach((br, i) => { - if (i < breakpoints.length - 1) { - const source = document.createElement('source'); - if (br.media) source.setAttribute('media', br.media); - source.setAttribute('srcset', `${src}?wid=${br.width}`); - picture.appendChild(source); - } else { - picture.appendChild(img({ src: `${src}?wid=${br.width}`, alt, loading: eager ? 'eager' : 'lazy' })); - } - }); + picture.appendChild(img({ src: `${src}?$danaher-mobile$`, alt, loading: eager ? 'eager' : 'lazy' })); return picture; } return img({ @@ -280,12 +257,16 @@ export function setCookie(cname, cvalue, expTime = 30 * 1000 * 60 * 60 * 24, pat * Builds embeds for video links * @param {Element} main The container element */ -function buildVideo(main) { - main.querySelectorAll('a[href*="youtube.com"],a[href*="vimeo.com"],a[href*="vidyard.com"]').forEach((link) => { - if (link.closest('.embed, .hero') == null) { - decorateEmbed(link.parentNode); - } - }); +async function buildVideo(main) { + const videoLinks = main.querySelectorAll('a[href*="youtube.com"],a[href*="vimeo.com"],a[href*="vidyard.com"]'); + if (videoLinks.length > 0) { + const { default: decorateEmbed } = await import('../blocks/embed/embed.js'); + videoLinks.forEach((link) => { + if (link.closest('.embed, .hero') == null) { + decorateEmbed(link.parentNode); + } + }); + } } /** @@ -588,7 +569,7 @@ async function loadEager(doc) { if (main) { await decorateTemplates(main); decorateMain(main); - document.body.classList.add('block'); + document.body.classList.add('appear'); await waitForLCP(LCP_BLOCKS); } diff --git a/styles/styles.css b/styles/styles.css index f8adf4bb8..0ab9b9dd1 100644 --- a/styles/styles.css +++ b/styles/styles.css @@ -1449,7 +1449,7 @@ button.suggestion.selected { .product-hero .vertical-gallery-container > div { display: grid; grid-template-rows: repeat(1, minmax(0, 1fr)); - gap: 0.625rem; + row-gap: 0.75rem; overflow: hidden; background-color: transparent; } @@ -1457,28 +1457,40 @@ button.suggestion.selected { @media (min-width: 768px) { .product-hero .vertical-gallery-container > div { - grid-template-columns: repeat(4, minmax(0, 1fr)); + grid-template-columns: repeat(5, minmax(0, 1fr)); } } .product-hero .vertical-gallery-container > div div:nth-child(1) { position: relative; - grid-column: span 3 / span 3; + grid-column: auto; --tw-bg-opacity: 1; background-color: rgb(255 255 255 / var(--tw-bg-opacity)); + --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +@media (min-width: 768px) { + + .product-hero .vertical-gallery-container > div div:nth-child(1) { + grid-column: span 4 / span 4; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + } } .product-hero .vertical-gallery-container > div div:nth-child(1) img { margin-left: auto; margin-right: auto; - height: 20rem; - width: 100%; - max-width: 360px; - border-radius: 0.25rem; + height: 400px; + width: 400px; + max-width: 400px; -o-object-fit: contain; object-fit: contain; - --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); - --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; @@ -1487,8 +1499,17 @@ button.suggestion.selected { transition-duration: 700ms; } +@media (min-width: 768px) { + + .product-hero .vertical-gallery-container > div div:nth-child(1) img { + --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + } +} + .product-hero .vertical-gallery-container > div > div:not(:nth-child(1)) { - grid-column: span 1 / span 1; + grid-column: auto; display: flex; scroll-snap-type: x var(--tw-scroll-snap-strictness); scroll-padding-left: 1.5rem; @@ -1502,6 +1523,7 @@ button.suggestion.selected { .product-hero .vertical-gallery-container > div > div:not(:nth-child(1)) { order: -9999; + grid-column: span 1 / span 1; flex-direction: column; } } @@ -1512,11 +1534,9 @@ button.suggestion.selected { display: flex; cursor: pointer; flex-direction: column; - border-radius: 0.25rem; background-color: rgb(255 255 255 / var(--tw-bg-opacity)); --tw-bg-opacity: 0.5; padding: 0.5rem; - text-align: center; font-size: 0.875rem; line-height: 1.25rem; font-weight: 600; @@ -1534,10 +1554,12 @@ button.suggestion.selected { } .product-hero .vertical-gallery-container > div > div:not(:nth-child(1)) img { - height: 5rem; - width: 8rem; + height: 75px; + width: 75px; cursor: pointer; - border-radius: 0.25rem; + border-width: 1px; + --tw-border-opacity: 1; + border-color: rgb(209 213 219 / var(--tw-border-opacity)); -o-object-fit: cover; object-fit: cover; transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; @@ -1556,11 +1578,11 @@ button.suggestion.selected { border-color: rgb(117 35 255 / var(--tw-border-opacity)); } -.product-hero .vertical-gallery-container > div div:not(:nth-child(1)) img.active { +.product-hero .vertical-gallery-container > div div:not(:nth-child(1)) picture.active img { --tw-scale-x: .95; --tw-scale-y: .95; transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); - border-width: 4px; + border-width: 2px; --tw-border-opacity: 1; border-color: rgb(117 35 255 / var(--tw-border-opacity)); opacity: 0.8; @@ -2529,6 +2551,78 @@ main .default-content-wrapper h2, main .accordion-wrapper h2 { } } +body.appear { + display: block; +} + +body.appear.social-media { + position: relative; + z-index: 10; + margin-bottom: 1rem; + display: flex; + align-items: center; + justify-content: space-between; + padding-top: 1.5rem; + padding-bottom: 0.5rem; + --tw-text-opacity: 1; + color: rgb(75 85 99 / var(--tw-text-opacity)); +} + +body.appear.social-media .back-btn,body.appear.social-media .social-links > a { + display: inline-flex; + align-items: center; + gap: 1rem; + border-radius: 0.5rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + padding-left: 0.375rem; + padding-right: 0.375rem; + font-weight: 400; + line-height: 1.5rem; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +body.appear.social-media .back-btn:hover,body.appear.social-media .social-links > a:hover { + background-color: rgb(15 23 42 / 0.03); +} + +body.appear.social-media .back-btn,body.appear.social-media .social-links > a { + display: inline-flex; + align-items: center; + gap: 1rem; + border-radius: 0.5rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + padding-left: 0.375rem; + padding-right: 0.375rem; + font-weight: 400; + line-height: 1.5rem; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +body.appear.social-media .back-btn:hover,body.appear.social-media .social-links > a:hover { + background-color: rgb(15 23 42 / 0.03); +} + +body.appear.social-media .back-btn > a > span { + margin-top: auto; + margin-bottom: auto; +} + +body.appear.social-media .social-links { + display: flex; + align-items: center; + gap: 0.75rem; +} + #categories { margin-top: 4rem; } diff --git a/styles/tailwind.css b/styles/tailwind.css index bc8cf0fc0..a172a2ad8 100644 --- a/styles/tailwind.css +++ b/styles/tailwind.css @@ -81,6 +81,10 @@ } @layer components { + body.appear { + @apply block; + } + #categories { @apply mt-16; }