diff --git a/blocks/header/header.css b/blocks/header/header.css index e2dd2b97..d669bae7 100644 --- a/blocks/header/header.css +++ b/blocks/header/header.css @@ -1,3 +1,6 @@ raqn-header { - max-width: var(--scope-max-width, 100%); + display: grid; + max-width: var(--scope-max-width, 90vw); + margin: 0 auto; + align-items: center; } diff --git a/blocks/header/header.js b/blocks/header/header.js index 1539db6c..5d373996 100644 --- a/blocks/header/header.js +++ b/blocks/header/header.js @@ -6,7 +6,6 @@ export default class Header extends ComponentBase { async processExternal(response) { await super.processExternal(response); - this.parentElement.style.opacity = 1; eagerImage(this, 1); } } diff --git a/blocks/hero/hero.css b/blocks/hero/hero.css index b263bcb5..60df96b1 100644 --- a/blocks/hero/hero.css +++ b/blocks/hero/hero.css @@ -1,39 +1,16 @@ /* block specific CSS goes here */ -main .hero-container > div { - max-width: unset; -} - -main .hero-container { - padding: 0; -} - -main .hero { - position: relative; - padding: 32px; - min-height: 300px; -} - -main .hero h1 { - max-width: 1200px; - margin-left: auto; - margin-right: auto; - color: white; -} +raqn-hero { + --raqn-background-color: var(--scope-background, transparent); + --raqn-color: var(--scope-color, transparent); + --raqn-grid-template-columns: 0.6fr 0.4fr; -main .hero picture { - position: absolute; - z-index: -1; - top: 0; - left: 0; - bottom: 0; - right: 0; - object-fit: cover; - box-sizing: border-box; -} + background-color: var(--raqn-background-color); + color: var(--raqn-color); + grid-template-columns: var(--raqn-grid-template-columns, 1fr); + align-items: center; -main .hero img { - object-fit: cover; - width: 100%; - height: 100%; + & > div:first-child { + max-width: 30vw; + } } diff --git a/blocks/hero/hero.js b/blocks/hero/hero.js index e69de29b..67c2f5e6 100644 --- a/blocks/hero/hero.js +++ b/blocks/hero/hero.js @@ -0,0 +1,12 @@ +import ComponentBase from '../../scripts/component-base.js'; + +export default class Hero extends ComponentBase { + connected() { + const child = this.children[0]; + child.replaceWith(...child.children); + this.classList.add('full-width'); + this.setAttribute('role', 'banner'); + this.setAttribute('aria-label', 'hero'); + this.style.setProperty('--hero-columns', this.getAttribute('height')); + } +} diff --git a/blocks/icon/icon.css b/blocks/icon/icon.css index 29149d81..bd707aa0 100644 --- a/blocks/icon/icon.css +++ b/blocks/icon/icon.css @@ -11,10 +11,6 @@ raqn-icon { -moz-osx-font-smoothing: grayscale; } -raqn-icon:not(.loaded) { - animation: placeholder ease-in-out 1s infinite; -} - raqn-icon svg { display: inline-block; max-height: 100%; diff --git a/blocks/navigation/navigation.css b/blocks/navigation/navigation.css index e7db897c..d9b52177 100644 --- a/blocks/navigation/navigation.css +++ b/blocks/navigation/navigation.css @@ -1,24 +1,35 @@ +/* stylelint-disable CssSyntaxError */ raqn-navigation { + --raqn-navigation-background: var(--scope-background, #fff); + --raqn-navigation-color: var(--scope-color, #000); + --raqn-navigation-level-1: var(--raqn-font-size-4, 1.25rem); + --raqn-navigation-level-2: var(--raqn-font-size-5, 1rem); + margin: var(--scope-margin); width: 100%; display: grid; justify-content: center; /* mobile */ - & > div div { + & > nav { ul, p { display: none; } } - ul li a { + a { display: inline-flex; align-items: center; text-decoration: none; - color: var(--scope-color, #000); + color: var(--raqn-navigation-color, #000); border-radius: var(--border-radius); transition: background-color 0.2s ease-in-out; + font-size: var(--raqn-navigation-level-1); + } + + .level-2 a { + font-size: var(--raqn-navigation-level-2); } div { @@ -44,7 +55,7 @@ raqn-navigation { color: var(--scope-color-hover, #fff); } - & > div > div > ul { + & > nav > ul { position: fixed; display: block; list-style: none; @@ -64,7 +75,11 @@ raqn-navigation { } /* desktop */ - &:not([compact='true']) > div > div { + &:not([compact='true']) > nav { + a { + line-height: var(--scope-icon-size, 24px); + } + ul { list-style: none; display: flex; @@ -74,37 +89,52 @@ raqn-navigation { display: inline-flex; } - ul li { - position: relative; + [icon='chevron-right'] { + transform: rotate(90deg); } - ul li a { + .level-1 a { padding: var(--padding-vertical, 20px) var(--padding-horizontal, 20px); } - & > ul > li > ul { - display: none; - padding: 0; + .level-1 > ul { + display: flex; + clip-path: inset(0% -100vw 100% -100vw); position: absolute; - top: 100%; - left: 0; - background-color: var(--scope-background, #fff); + padding: 0; + inset-block-start: var(--scope-header-height, 64px); + inset-inline-start: calc((100vw - var(--scope-max-width)) / 2); padding: var(--padding-vertical) var(--padding-horizontal); - border-radius: var(--border-radius); - box-shadow: var(--box-shadow); - } + transition: clip-path 0.4s ease-in-out; + overflow: visible; - & > ul > li:hover > ul { - display: block; + .level-2 { + padding-block: 1.2em; + opacity: 0; + transition: opacity 0.4s ease; + z-index: 2; + } + + &::after { + content: ' '; + margin-inline: calc(-1 * ((100vw - var(--scope-max-width)) / 2)); + position: absolute; + height: 100%; + width: 100vw; + inset-inline-start: 0; + background-color: var(--scope-background, #fff); + border-block-start: 1px solid var(--scope-color, #000); + box-shadow: 0px 0px 30px #000; + z-index: 1; + } } - ul > li > ul::after { - /* display: none; */ - content: ' '; - position: absolute; - height: 100%; - width: 100vw; - inset-inline-start: 0; + .level-1:hover > ul { + display: flex; + clip-path: inset(0 -100vw -100% -100vw); + & > li { + opacity: 1; + } } } } diff --git a/blocks/navigation/navigation.js b/blocks/navigation/navigation.js index d397c75a..210e2651 100644 --- a/blocks/navigation/navigation.js +++ b/blocks/navigation/navigation.js @@ -18,11 +18,44 @@ export default class Navigation extends Column { } render() { + this.list = this.querySelector('ul'); + this.nav = document.createElement('nav'); + this.nav.append(this.list); + this.setAttribute('role', 'navigation'); this.compact = this.getAttribute('compact') === 'true' || false; this.icon = this.getAttribute('icon') || 'menu'; - console.log('render', this.compact, this.getAttribute('compact')); if (this.compact) { - this.appendChild(this.createButton()); + this.nav.append(this.createButton()); + } + this.firstChild.replaceWith(this.nav); + this.setupClasses(this.list); + this.addEventListener('click', (e) => this.activate(e)); + } + + setupClasses(ul, level = 1) { + const children = Array.from(ul.children); + children.forEach((child) => { + child.classList.add(`level-${level}`); + const hasChildren = child.querySelector('ul'); + if (hasChildren) { + const anchor = child.querySelector('a'); + const icon = document.createElement('raqn-icon'); + icon.setAttribute('icon', 'chevron-right'); + anchor.append(icon); + child.classList.add('has-children'); + this.setupClasses(hasChildren, level + 1); + } + }); + } + + activate(e) { + if (e.target.tagName.toLowerCase() === 'a') { + const current = e.target.closest('li'); + if (this.active && this.active !== current) { + this.active.classList.remove('active'); + } + this.active = current; + this.active.classList.toggle('active'); } } } diff --git a/blocks/theme/theme.js b/blocks/theme/theme.js index 2b7e09a4..a73b6036 100644 --- a/blocks/theme/theme.js +++ b/blocks/theme/theme.js @@ -13,6 +13,9 @@ export default class Theme extends ComponentBase { 'font-family', 'icon-size', 'max-width', + 'header-height', + 'header-background', + 'header-color', 'gap', ]; this.defaultScope = [ diff --git a/styles/styles.css b/styles/styles.css index 73a5d0f8..d3de18de 100644 --- a/styles/styles.css +++ b/styles/styles.css @@ -33,10 +33,10 @@ body { header { min-height: var(--scope-header-height, 64px); - - > div { - display: none; - } + display: grid; + background-color: var(--raqn-header-background-1, #fff); + --scope-background: var(--raqn-header-background-1, #fff); + --scope-color: var(--raqn-header-color-1, #000); } main > * { @@ -45,6 +45,15 @@ main > * { font-family: custom; } +.full-width { + display: grid; + width: 100vw; + --scope-outer-gap: calc((var(--scope-max-width) - 100vw) / 2); + margin-inline-start: var(--scope-outer-gap); + padding-inline: calc(-1 * var(--scope-outer-gap)); + box-sizing: border-box; +} + a { display: inline-flex; line-height: 1em; @@ -75,15 +84,15 @@ img { @keyframes placeholder { 0% { - background-color: var(--placeholder-primary, #fff); + background-color: var(--scope-background, #fff); } 50% { - background-color: var(--placeholder-secondary, #ccc); + background-color: var(--scope-color, #999); } 100% { - background-color: var(--placeholder-primary, #fff); + background-color: var(--scope-background, #fff); } }