From a5ee38ca779a87411e14f0c1f6b2c38f96e14134 Mon Sep 17 00:00:00 2001 From: Eric S Chen Date: Tue, 2 Apr 2024 12:55:48 -0700 Subject: [PATCH 1/7] initial This block requires minimal changes to work --- .../browse-by-category/browse-by-category.css | 198 ++++++++++++++++++ .../browse-by-category/browse-by-category.js | 79 +++++++ 2 files changed, 277 insertions(+) create mode 100644 express/blocks/browse-by-category/browse-by-category.css create mode 100644 express/blocks/browse-by-category/browse-by-category.js diff --git a/express/blocks/browse-by-category/browse-by-category.css b/express/blocks/browse-by-category/browse-by-category.css new file mode 100644 index 00000000..d3197d83 --- /dev/null +++ b/express/blocks/browse-by-category/browse-by-category.css @@ -0,0 +1,198 @@ +main .browse-by-category.fullwidth { + margin: 0; + padding: 0 28px; + max-width: fit-content; +} + +main .browse-by-category { + max-width: max-content; +} + +main .browse-by-category .carousel-container .carousel-platform { + align-items: start; +} + +main .browse-by-category.card .carousel-container .carousel-platform { + gap: 14px; + margin: 6px 0 0 0; +} + +main .browse-by-category .carousel-container .button.carousel-arrow { + position: absolute; + top: 46px; +} + +main .browse-by-category .browse-by-category-heading-section { + display: flex; + justify-content: space-between; + flex-direction: column; + margin-left: auto; + margin-right: auto; + margin-bottom: 10px; +} + +main .browse-by-category .browse-by-category-heading-section .browse-by-category-heading { + text-align: left; + font-size: 28px; + line-height: 30px; +} + +main .browse-by-category .browse-by-category-heading-section .browse-by-category-link-wrapper { + margin: 8px 0 0; +} + +main .browse-by-category .browse-by-category-link { + font-size: 16px; + line-height: 22px; + display: flex; + padding: 0; + white-space: nowrap; + width: max-content; +} + +main .browse-by-category .browse-by-category-link::after { + display: flex; + width: 6px; + height: 6px; + border-top-width: 0; + border-left-width: 0; + border-bottom-width: 2px; + border-right-width: 2px; + border-style: solid; + border-color: var(--color-info-accent); + transform-origin: 75% 75%; + transform: rotate(-45deg); + content: ""; + margin-top: 5px; + margin-left: 5px; + margin-right: 2.25px; +} + +main .browse-by-category:not(.card) .browse-by-category-card { + position: relative; + display: flex; + gap: 8px; + flex-direction: column; + align-items: center; + min-width: 123px; + margin: 0; + padding: 10px 8px 0 8px; +} + +main .browse-by-category.card .browse-by-category-card { + position: relative; + display: flex; + flex-direction: column; +} + +main .browse-by-category .browse-by-category-card-link { + position: absolute; + height: 100%; + width: 100%; +} + +main .browse-by-category:not(.card) .browse-by-category-card-link:hover ~ .browse-by-category-image-wrapper img { + transform: scale(1.1) matrix(1, -0.07, 0.05, 1, 0, 0); +} + +main .browse-by-category.card .browse-by-category-card-link:hover ~ .browse-by-category-image-wrapper img { + transform: scale(1.1) matrix(1, -0.01, 0.01, 1, 0, 0); +} + +main .browse-by-category .browse-by-category-image-wrapper { + background-color: var(--color-gray-200); + min-height: 90px; + width: 148px; + border-radius: 90px; + display: flex; + justify-content: center; + align-items: center; + pointer-events: none; +} + +main .browse-by-category:not(.card) .browse-by-category-image-wrapper img { + display: block; + object-fit: cover; + width: 80px; + height: 80px; + transform: matrix(1, -0.07, 0.07, 1, 0, 0); + box-shadow: 0 0 6px #0000001f; + border-radius: 8px; + opacity: 1; + transition: transform 0.2s ease-in-out; +} + +main .browse-by-category .browse-by-category-image-wrapper .browse-by-category-image-shadow { + position: absolute; + width: 76px; + height: 76px; + transform: matrix(0.97, -0.22, 0.22, 0.97, -6, 0); + background: var(--color-gray-300) 0 0 no-repeat padding-box; + border-radius: 10px; + opacity: 1; +} + +main .browse-by-category.card .browse-by-category-image-shadow-wrapper { + display: block; + object-fit: cover; + transform: matrix(1, -0.07, 0.07, 1, 0, 0); + box-shadow: 0 0 6px #0000001f; + border-radius: 8px; + opacity: 1; + transition: transform 0.2s ease-in-out; +} + +main .browse-by-category.card .browse-by-category-image-wrapper { + background-color: #f8f8f8; + min-height: 90px; + height: 116px; + width: 182px; + border-radius: 10px; + display: flex; + justify-content: center; + align-items: center; + pointer-events: none; +} + +main .browse-by-category.card .browse-by-category-image-wrapper img { + display: block; + object-fit: contain; + max-width: 110px; + max-height: 97px; + transform: matrix(1, -0.01, 0.01, 1, 0, 0); + box-shadow: 0 0 6px #0000001f; + border-radius: 8px; + opacity: 1; + transition: transform 0.2s ease-in-out; +} + +main .browse-by-category.card .browse-by-category-image-wrapper .browse-by-category-image-shadow { + position: absolute; + width: 100%; + height: 100%; + transform: matrix(0.90, -0.18, 0.20, 0.90, -14, 0); + background: #d6d6d6e5; +} + +main .browse-by-category:not(.card) .browse-by-category-card-title { + margin: 0; + font-size: 18px; + line-height: 24px; + font-weight: 700; + max-width: 148px; +} + +main .browse-by-category.card .browse-by-category-card-title { + margin: 6px 0; + font-size: 16px; + line-height: 24px; + font-weight: 700; + align-self: start; +} + +@media (min-width: 900px) { + main .browse-by-category .browse-by-category-heading-section { + flex-direction: row; + padding: 0 0 0 20px; + } +} diff --git a/express/blocks/browse-by-category/browse-by-category.js b/express/blocks/browse-by-category/browse-by-category.js new file mode 100644 index 00000000..ba69bd69 --- /dev/null +++ b/express/blocks/browse-by-category/browse-by-category.js @@ -0,0 +1,79 @@ +import { getLibs } from '../../scripts/utils.js'; +import buildCarousel from '../../scripts/widgets/carousel.js'; + +const { createTag } = await import(`${getLibs()}/utils/utils.js`); + +export function decorateHeading(block, payload) { + const headingSection = createTag('div', { class: 'browse-by-category-heading-section' }); + const heading = createTag('h3', { class: 'browse-by-category-heading' }); + const viewAllButtonWrapper = createTag('p', { class: 'browse-by-category-link-wrapper' }); + + if (payload.viewAllLink.href !== '') { + const viewAllButton = createTag('a', { class: 'browse-by-category-link', href: payload.viewAllLink.href }); + viewAllButton.textContent = payload.viewAllLink.text; + viewAllButtonWrapper.append(viewAllButton); + } + + heading.textContent = payload.heading; + headingSection.append(heading, viewAllButtonWrapper); + block.append(headingSection); +} + +export function decorateCategories(block, payload) { + const categoriesWrapper = createTag('div', { class: 'browse-by-category-categories-wrapper' }); + + payload.categories.forEach((categoryCard) => { + const category = createTag('div', { class: 'browse-by-category-card' }); + const categoryImageWrapper = createTag('div', { class: 'browse-by-category-image-wrapper' }); + const categoryImageShadowWrapper = createTag('div', { class: 'browse-by-category-image-shadow-wrapper' }); + const categoryImageShadow = createTag('div', { class: 'browse-by-category-image-shadow' }); + const categoryImage = categoryCard.image; + const categoryTitle = createTag('h4', { class: 'browse-by-category-card-title' }); + const categoryAnchor = createTag('a', { class: 'browse-by-category-card-link' }); + + categoryTitle.textContent = categoryCard.text; + categoryAnchor.href = categoryCard.link; + categoryImageShadowWrapper.append(categoryImageShadow, categoryImage); + categoryImageWrapper.append(categoryImageShadowWrapper); + category.append(categoryAnchor, categoryImageWrapper, categoryTitle); + categoriesWrapper.append(category); + }); + + block.append(categoriesWrapper); +} + +export default async function decorate(block) { + const rows = Array.from(block.children); + const headingDiv = rows.shift(); + + const payload = { + heading: headingDiv.querySelector('h4') ? headingDiv.querySelector('h4').textContent.trim() : '', + viewAllLink: { + text: headingDiv.querySelector('a.button') ? headingDiv.querySelector('a.button').textContent.trim() : '', + href: headingDiv.querySelector('a.button') ? headingDiv.querySelector('a.button').href : '', + }, + categories: [], + }; + + rows.forEach((row) => { + payload.categories.push({ + image: row.querySelector('picture'), + text: row.querySelector('a.button') ? row.querySelector('a.button').textContent.trim() : 'missing category text', + link: row.querySelector('a.button') ? row.querySelector('a.button').href : 'missing category link', + }); + }); + + block.innerHTML = ''; + + decorateHeading(block, payload); + decorateCategories(block, payload); + buildCarousel('.browse-by-category-card', block.querySelector('.browse-by-category-categories-wrapper') || block); + + if (block.classList.contains('fullwidth')) { + const blockWrapper = block.parentNode; + + if (blockWrapper && blockWrapper.classList.contains('browse-by-category-wrapper')) { + blockWrapper.classList.add('fullwidth'); + } + } +} From 9f9d9e2cb23c863cc0b96a710f9fdd4d683f2083 Mon Sep 17 00:00:00 2001 From: Eric S Chen Date: Tue, 2 Apr 2024 13:03:20 -0700 Subject: [PATCH 2/7] Update browse-by-category.js --- express/blocks/browse-by-category/browse-by-category.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/express/blocks/browse-by-category/browse-by-category.js b/express/blocks/browse-by-category/browse-by-category.js index ba69bd69..680ec5e5 100644 --- a/express/blocks/browse-by-category/browse-by-category.js +++ b/express/blocks/browse-by-category/browse-by-category.js @@ -58,8 +58,8 @@ export default async function decorate(block) { rows.forEach((row) => { payload.categories.push({ image: row.querySelector('picture'), - text: row.querySelector('a.button') ? row.querySelector('a.button').textContent.trim() : 'missing category text', - link: row.querySelector('a.button') ? row.querySelector('a.button').href : 'missing category link', + text: row.querySelector('a')?.textContent.trim() || 'missing category text', + link: row.querySelector('a')?.href || 'missing category link', }); }); From bb28686ffab3a5658aedad39cb7a3406c12494da Mon Sep 17 00:00:00 2001 From: Eric S Chen Date: Tue, 2 Apr 2024 13:05:50 -0700 Subject: [PATCH 3/7] Update browse-by-category.js --- express/blocks/browse-by-category/browse-by-category.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/express/blocks/browse-by-category/browse-by-category.js b/express/blocks/browse-by-category/browse-by-category.js index 680ec5e5..e01d9e54 100644 --- a/express/blocks/browse-by-category/browse-by-category.js +++ b/express/blocks/browse-by-category/browse-by-category.js @@ -63,7 +63,7 @@ export default async function decorate(block) { }); }); - block.innerHTML = ''; + block.replaceChildren(); decorateHeading(block, payload); decorateCategories(block, payload); From efc8409855a490dba26e435aa95ff65b483fcce2 Mon Sep 17 00:00:00 2001 From: Eric S Chen Date: Tue, 2 Apr 2024 13:08:24 -0700 Subject: [PATCH 4/7] Added existing test --- .../browse-by-category.test.js | 50 +++ .../blocks/browse-by-category/mocks/body.html | 423 ++++++++++++++++++ 2 files changed, 473 insertions(+) create mode 100644 test/blocks/browse-by-category/browse-by-category.test.js create mode 100644 test/blocks/browse-by-category/mocks/body.html diff --git a/test/blocks/browse-by-category/browse-by-category.test.js b/test/blocks/browse-by-category/browse-by-category.test.js new file mode 100644 index 00000000..2f59eb6b --- /dev/null +++ b/test/blocks/browse-by-category/browse-by-category.test.js @@ -0,0 +1,50 @@ +/* eslint-env mocha */ +/* eslint-disable no-unused-vars */ + +import { readFile } from '@web/test-runner-commands'; +import { expect } from '@esm-bundle/chai'; + +const { default: decorate } = await import( + '../../../../express/blocks/browse-by-category/browse-by-category.js' +); +document.body.innerHTML = await readFile({ path: './mocks/body.html' }); + +describe('Browse-by-category', () => { + before(() => { + window.istestEnv = true; + }); + + it('Browse by category exists', async () => { + const categories = document.querySelector('#browse-by-category-pure'); + await decorate(categories); + expect(categories).to.exist; + + expect( + categories.querySelector('.browse-by-category-heading').textContent, + ).to.equal('Browse by Category'); + + expect( + categories.querySelectorAll('.browse-by-category-card').length, + ).to.equal(4); + }); + + it('Browse by category with empty head', async () => { + const categories = document.querySelector('#browse-by-category-empty-head'); + await decorate(categories); + expect(categories).to.exist; + + expect( + categories.querySelector('.browse-by-category-heading').textContent, + ).to.equal(''); + }); + + it('Browse by category with fullwidth', async () => { + const categories = document.querySelector('#browse-by-category-fullwidth'); + await decorate(categories); + expect(categories).to.exist; + + expect( + categories.querySelector('.browse-by-category-heading').textContent, + ).to.equal('Browse by Category'); + }); +}); diff --git a/test/blocks/browse-by-category/mocks/body.html b/test/blocks/browse-by-category/mocks/body.html new file mode 100644 index 00000000..a0579b06 --- /dev/null +++ b/test/blocks/browse-by-category/mocks/body.html @@ -0,0 +1,423 @@ +
+
+
+
+

Browse by Category

+

+ View All +

+
+
+
+
+ + + + + + +
+
+ Logos +
+
+
+
+ + + + + Inserting image... + +
+
+ Collages +
+
+
+
+ + + + + Inserting image... + +
+
+ Posters +
+
+
+
+ + + + + Inserting image... + +
+ +
+
+
+
+
+
+
+
+ + + + + + +
+
+ Logos +
+
+
+
+ + + + + Inserting image... + +
+
+ Collages +
+
+
+
+ + + + + Inserting image... + +
+
+ Posters +
+
+
+
+ + + + + Inserting image... + +
+ +
+
+
+
+
+
+
+

Browse by Category

+

+ View All +

+
+
+
+
+ + + + + + +
+
+ Logos +
+
+
+
+ + + + + Inserting image... + +
+
+ Collages +
+
+
+
From e30e72539083a0ee9363a7add6787d56d152068b Mon Sep 17 00:00:00 2001 From: Eric S Chen Date: Tue, 2 Apr 2024 13:12:42 -0700 Subject: [PATCH 5/7] Update browse-by-category.test.js --- test/blocks/browse-by-category/browse-by-category.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/blocks/browse-by-category/browse-by-category.test.js b/test/blocks/browse-by-category/browse-by-category.test.js index 2f59eb6b..7030fac6 100644 --- a/test/blocks/browse-by-category/browse-by-category.test.js +++ b/test/blocks/browse-by-category/browse-by-category.test.js @@ -5,7 +5,7 @@ import { readFile } from '@web/test-runner-commands'; import { expect } from '@esm-bundle/chai'; const { default: decorate } = await import( - '../../../../express/blocks/browse-by-category/browse-by-category.js' + '../../../express/blocks/browse-by-category/browse-by-category.js' ); document.body.innerHTML = await readFile({ path: './mocks/body.html' }); From 7c3f6de7956d226fdb0005609e9b605a6da1c99d Mon Sep 17 00:00:00 2001 From: Eric S Chen Date: Wed, 3 Apr 2024 11:09:32 -0700 Subject: [PATCH 6/7] Update browse-by-category.js --- express/blocks/browse-by-category/browse-by-category.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/express/blocks/browse-by-category/browse-by-category.js b/express/blocks/browse-by-category/browse-by-category.js index e01d9e54..3c1da197 100644 --- a/express/blocks/browse-by-category/browse-by-category.js +++ b/express/blocks/browse-by-category/browse-by-category.js @@ -7,7 +7,6 @@ export function decorateHeading(block, payload) { const headingSection = createTag('div', { class: 'browse-by-category-heading-section' }); const heading = createTag('h3', { class: 'browse-by-category-heading' }); const viewAllButtonWrapper = createTag('p', { class: 'browse-by-category-link-wrapper' }); - if (payload.viewAllLink.href !== '') { const viewAllButton = createTag('a', { class: 'browse-by-category-link', href: payload.viewAllLink.href }); viewAllButton.textContent = payload.viewAllLink.text; @@ -49,8 +48,8 @@ export default async function decorate(block) { const payload = { heading: headingDiv.querySelector('h4') ? headingDiv.querySelector('h4').textContent.trim() : '', viewAllLink: { - text: headingDiv.querySelector('a.button') ? headingDiv.querySelector('a.button').textContent.trim() : '', - href: headingDiv.querySelector('a.button') ? headingDiv.querySelector('a.button').href : '', + text: headingDiv.querySelector('a') ? headingDiv.querySelector('a').textContent.trim() : '', + href: headingDiv.querySelector('a') ? headingDiv.querySelector('a').href : '', }, categories: [], }; From c146e180bd030dd187c72fc60608f522a8552ea0 Mon Sep 17 00:00:00 2001 From: Eric S Chen Date: Mon, 22 Apr 2024 14:00:23 -0700 Subject: [PATCH 7/7] Update browse-by-category.test.js --- test/blocks/browse-by-category/browse-by-category.test.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/blocks/browse-by-category/browse-by-category.test.js b/test/blocks/browse-by-category/browse-by-category.test.js index 7030fac6..e353032d 100644 --- a/test/blocks/browse-by-category/browse-by-category.test.js +++ b/test/blocks/browse-by-category/browse-by-category.test.js @@ -4,6 +4,8 @@ import { readFile } from '@web/test-runner-commands'; import { expect } from '@esm-bundle/chai'; +await import('../../../express/scripts/scripts.js'); + const { default: decorate } = await import( '../../../express/blocks/browse-by-category/browse-by-category.js' );