forked from adobecom/milo
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MWPW-137717 | New block - Basic Brick & Masonry (adobecom#1515)
* Basic brick and masonry block block * latest update * Cleanup * Cleanup * Masonry brick height * Unit tests * Cleanup * Cleanup * CHanginf block name * Target non empty p tags only * Reduce line of code for button * Fixing font-weight * Fixing font-weight * Review comments * Fixing object fit issue * Adding brick block * Filter the p tag to remove empty and whitespace ones * MWPW-139392 * MWPW-139392 * MWPW-139392 * MWPW-139812 * Tmp change * revert Tmp change * Review comments * Review comments * Unit tests * Fix * Fix * Fix * Fix * Fix * Align bricks * Unit tests * Remove extra span 12 * Update class name * fixing lint error --------- Co-authored-by: Blaine Gunn <[email protected]>
- Loading branch information
Showing
10 changed files
with
1,055 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,245 @@ | ||
.brick { | ||
position: relative; | ||
display: flex; | ||
text-size-adjust: none; | ||
min-height: 300px; | ||
} | ||
|
||
.brick, | ||
.brick.click a.foreground { | ||
color: inherit; | ||
} | ||
|
||
.brick.light, | ||
.brick.light.click a.foreground { | ||
color: var(--text-color); | ||
} | ||
|
||
.brick.dark, | ||
.dark.brick.click a.foreground { | ||
color: var(--color-white); | ||
} | ||
|
||
.brick .background { | ||
position: absolute; | ||
bottom: 0; | ||
left: 0; | ||
right: 0; | ||
top: 0; | ||
overflow: hidden; | ||
} | ||
|
||
.brick .foreground { | ||
position: relative; | ||
display: flex; | ||
flex-grow: 1; | ||
padding: var(--spacing-m); | ||
} | ||
|
||
.brick.rounded-corners, | ||
.brick.rounded-corners .background, | ||
.brick.rounded-corners .foreground { | ||
border-radius: var(--spacing-xs); | ||
} | ||
|
||
.brick.align-center .foreground, | ||
.brick.align-center .foreground .action-area, | ||
.brick.center .foreground, | ||
.brick.center .foreground .action-area { | ||
align-items: center; | ||
text-align: center; | ||
justify-content: center; | ||
} | ||
|
||
.brick.center .foreground { | ||
align-items: flex-start; | ||
} | ||
|
||
.brick .background div, | ||
.brick .background p, | ||
.brick .background picture { | ||
height: 100%; | ||
margin: 0; | ||
padding: 0; | ||
} | ||
|
||
.brick .background p, | ||
.brick .background picture { | ||
display: block; | ||
} | ||
|
||
.brick .background img { | ||
object-fit: contain; | ||
object-position: bottom center; | ||
width: 100%; | ||
height: 100%; | ||
} | ||
|
||
.brick .mobile-only, | ||
.brick .tablet-only, | ||
.brick .desktop-only { | ||
display: none; | ||
} | ||
|
||
.brick .foreground p { | ||
padding: 0; | ||
margin: 0; | ||
} | ||
|
||
.brick .foreground div > * { | ||
margin-top: var(--spacing-xs); | ||
} | ||
|
||
.brick .foreground p:first-child, | ||
.brick .foreground p.icon-area, | ||
.brick .foreground p.icon-area + p { | ||
margin-top: 0; | ||
} | ||
|
||
.brick .foreground p.icon-area { | ||
display: inline-block; | ||
margin-bottom: var(--spacing-s); | ||
} | ||
|
||
.brick .foreground p.action-area { | ||
display: flex; | ||
flex-wrap: wrap; | ||
gap: 24px; | ||
margin-top: var(--spacing-s); | ||
} | ||
|
||
.brick .icon-stack-area li picture { | ||
display: flex; | ||
margin: 0; | ||
padding: 0; | ||
flex-shrink: 0; | ||
} | ||
|
||
.brick .foreground .icon-area picture { | ||
display: flex; | ||
} | ||
|
||
.brick .icon-stack-area li img { | ||
width: var(--icon-size-s); | ||
height: auto; | ||
} | ||
|
||
.brick .foreground .icon-area img { | ||
height: var(--icon-size-l); | ||
width: auto; | ||
} | ||
|
||
.brick.click > a { | ||
text-decoration: none; | ||
} | ||
|
||
.brick .icon-stack-area { | ||
display: flex; | ||
flex-flow: row wrap; | ||
flex-direction: column; | ||
gap: var(--spacing-xs); | ||
width: 100%; | ||
margin: 0; | ||
padding: 0; | ||
list-style-type: none; | ||
} | ||
|
||
.brick.center .icon-stack-area, | ||
.brick.align-center .icon-stack-area { | ||
display: inline-flex; | ||
width: auto; | ||
} | ||
|
||
.brick .icon-stack-area li, | ||
.brick .icon-stack-area li a { | ||
display: flex; | ||
align-items: center; | ||
gap: var(--spacing-xs); | ||
text-align: left; | ||
} | ||
|
||
.brick .foreground a:not([class]), | ||
.brick .foreground span.first-link { | ||
font-weight: 700; | ||
} | ||
|
||
[dir="rtl"] .brick .icon-stack-area li, | ||
[dir="rtl"] .brick .icon-stack-area li a { | ||
text-align: right; | ||
} | ||
|
||
.brick.click a.foreground .first-link:not([class*="button"]) { | ||
color: var(--link-color); | ||
text-decoration: none; | ||
} | ||
|
||
.brick.click:hover a.foreground .first-link:not([class*="button"]) { | ||
text-decoration: underline; | ||
color: var(--link-hover-color); | ||
} | ||
|
||
.static-links .brick.click a.foreground .first-link:not([class*="button"]), | ||
.static-links .brick.click a.foreground a:not([class*="button"]), | ||
.brick.static-links.click a.foreground .first-link:not([class*="button"]), | ||
.brick.static-links.click a.foreground a:not([class*="button"]) { | ||
color: inherit; | ||
text-decoration: underline; | ||
} | ||
|
||
.brick.click:hover .first-link.con-button.blue, | ||
.brick.click:active .first-link.con-button.blue { | ||
background: var(--color-accent-hover); | ||
border-color: var(--color-accent-hover); | ||
color: var(--color-white); | ||
} | ||
|
||
.brick.click:hover .first-link.con-button, | ||
.brick.click:active .first-link.con-button, | ||
.brick.light.click:hover .first-link.con-button, | ||
.brick.light.click:active .first-link.con-button, | ||
.light .brick.click:hover .first-link.con-button, | ||
.light .brick.click:active .first-link.con-button { | ||
background-color: var(--color-black); | ||
border-color: var(--color-black); | ||
color: var(--color-white); | ||
} | ||
|
||
.dark .brick.click:hover .first-link.con-button, | ||
.brick.dark.click:active .first-link.con-button { | ||
background-color: var(--color-white); | ||
color: var(--color-black); | ||
text-decoration: none; | ||
} | ||
|
||
|
||
@media screen and (max-width: 600px) { | ||
.brick .mobile-only { | ||
display: block; | ||
} | ||
} | ||
|
||
@media screen and (min-width: 600px) { | ||
.brick { | ||
min-height: 384px; | ||
} | ||
|
||
.brick .foreground { | ||
padding: var(--spacing-l); | ||
} | ||
} | ||
|
||
@media screen and (min-width: 600px) and (max-width: 1199px) { | ||
.brick .tablet-only { | ||
display: block; | ||
} | ||
} | ||
|
||
@media screen and (min-width: 1200px) { | ||
.brick .desktop-only { | ||
display: block; | ||
} | ||
|
||
.brick.large { | ||
min-height: 500px; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
import { decorateTextOverrides, decorateBlockText, decorateBlockBg, decorateIconStack, decorateButtons } from '../../utils/decorate.js'; | ||
import { createTag } from '../../utils/utils.js'; | ||
|
||
const blockTypeSizes = { | ||
large: ['xxl', 'm', 'l'], | ||
default: ['xl', 'm', 'l'], | ||
}; | ||
const objFitOptions = ['fill', 'contain', 'cover', 'none', 'scale-down']; | ||
|
||
function getBlockSize(el) { | ||
const sizes = Object.keys(blockTypeSizes); | ||
const size = sizes.find((s) => el.classList.contains(`${s}`)) || 'default'; | ||
return blockTypeSizes[size]; | ||
} | ||
|
||
function handleSupplementalText(foreground) { | ||
if (!foreground.querySelector('.action-area')) return; | ||
const nextP = foreground.querySelector('.action-area + p'); | ||
const lastP = foreground.querySelector('.action-area ~ p:last-child'); | ||
if (nextP) nextP.className = ''; | ||
if (lastP) lastP.className = 'supplemental-text'; | ||
} | ||
|
||
function setObjectFitAndPos(text, pic, bgEl) { | ||
const backgroundConfig = text.split(',').map((c) => c.toLowerCase().trim()); | ||
const fitOption = objFitOptions.filter((c) => backgroundConfig.includes(c)); | ||
const focusOption = backgroundConfig.filter((c) => !fitOption.includes(c)); | ||
if (fitOption) [pic.querySelector('img').style.objectFit] = fitOption; | ||
bgEl.innerHTML = ''; | ||
bgEl.append(pic); | ||
bgEl.append(document.createTextNode(focusOption.join(','))); | ||
} | ||
|
||
function handleObjectFit(bgRow) { | ||
const bgConfig = bgRow.querySelectorAll('div'); | ||
[...bgConfig].forEach((r) => { | ||
const pic = r.querySelector('picture'); | ||
if (!pic) return; | ||
let text = ''; | ||
const pchild = [...r.querySelectorAll('p:not(:empty)')].filter((p) => p.innerHTML.trim() !== ''); | ||
if (pchild.length > 2) text = pchild[1]?.textContent.trim(); | ||
if (!text && r.textContent) text = r.textContent; | ||
if (!text) return; | ||
setObjectFitAndPos(text, pic, r); | ||
}); | ||
} | ||
|
||
function handleClickableBrick(el, foreground) { | ||
if (!el.classList.contains('click')) return; | ||
const links = foreground.querySelectorAll('a'); | ||
if (links.length !== 1) { el.classList.remove('click'); return; } | ||
const a = links[0]; | ||
const linkDiv = createTag('span', { class: [...a.classList, 'first-link'].join(' ') }, a.innerHTML); | ||
a.replaceWith(linkDiv, a); | ||
a.className = 'foreground'; | ||
el.appendChild(a); | ||
a.innerHTML = foreground.innerHTML; | ||
foreground.remove(); | ||
} | ||
|
||
function decorateSupplementalText(el) { | ||
const supplementalEl = el.querySelector('.foreground p.supplemental-text'); | ||
if (!supplementalEl) return; | ||
supplementalEl.className = 'body-xs supplemental-text'; | ||
} | ||
|
||
function decorateBricks(el) { | ||
if (!el.classList.contains('light')) el.classList.add('dark'); | ||
const elems = el.querySelectorAll(':scope > div'); | ||
if (elems.length > 1) { | ||
handleObjectFit(elems[elems.length - 2]); | ||
decorateBlockBg(el, elems[elems.length - 2], { useHandleFocalpoint: true }); | ||
} | ||
if (elems.length > 2) { | ||
el.querySelector('.background').style.background = elems[0].textContent; | ||
elems[0].remove(); | ||
} | ||
const foreground = elems[elems.length - 1]; | ||
foreground.classList.add('foreground'); | ||
const hasIconArea = foreground.querySelector('p')?.querySelector('img'); | ||
if (hasIconArea) foreground.querySelector('p').classList.add('icon-area'); | ||
const blockFormatting = getBlockSize(el); | ||
decorateButtons(foreground, 'button-l'); | ||
decorateBlockText(foreground, blockFormatting); | ||
decorateIconStack(el); | ||
el.querySelector('.icon-stack-area')?.classList.add('body-xs'); | ||
handleSupplementalText(foreground); | ||
handleClickableBrick(el, foreground); | ||
return foreground; | ||
} | ||
|
||
export default async function init(el) { | ||
decorateBricks(el); | ||
decorateTextOverrides(el); | ||
decorateSupplementalText(el); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.