Skip to content

Commit

Permalink
Merge pull request #10 from hlxsites/feature-navigation
Browse files Browse the repository at this point in the history
[wip] Navigation
  • Loading branch information
FelipeSimoes authored Jan 16, 2024
2 parents a798cca + 74fc56c commit c1fcca1
Show file tree
Hide file tree
Showing 9 changed files with 242 additions and 23 deletions.
79 changes: 79 additions & 0 deletions blocks/accordion/accordion.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
raqn-accordion {
--scope-icon-size: 1em;
--accordion-background-color: var(--scope-background, black);
--accordion-color: var(--scope-color, white);

background-color: var(--accordion-background-color);
color: var(--accordion-color);
margin: var(--scope-margin, 0);
display: grid;

& .accordion-control {
border-block-start: var(--scope-border-block-start, none);
border-inline-start: var(--scope-border-inline-start, none);
border-inline-end: var(--scope-border-inline-end, none);

&:first-child {
border-block-start: none
}

& > * {
--scope-headings-color: var(--scope-color, black);
--scope-hover-color: var(--scope-accent-color, gray);

width: 100%;
display: flex;
justify-content: space-between;
min-width: 100%;
}

cursor: pointer;
display: flex;
align-items: center;
justify-content: start;
width: 100%;

&:hover {
--scope-color: var(--scope-headings-color);
}
}

& raqn-icon {
align-self: end;
transform: rotate(90deg);
transition: transform 0.2s ease-in-out;
}

& accordion-control.active raqn-icon {
transform: rotate(270deg);
}

& .accordion-content {
display: grid;
max-height: 0;
overflow: hidden;
opacity: 0;
border-block-end: var(--scope-border-block-end, none);
border-block-start: var(--scope-border-block-start, none);
margin-block-end: -1px;
transition: max-height 0.5s ease-in-out,
opacity 0.5s ease-in-out;


&:last-child {
border-block-end: none
}

&.active {
opacity: 1;
grid-template-rows: 1fr;
max-height: 100vw;

}
}

& .accordion-content-wrapper {
margin-block: 1em;
display: grid;
}
}
70 changes: 70 additions & 0 deletions blocks/accordion/accordion.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import Column from '../column/column.js';

export default class Accordion extends Column {
ready() {
this.setAttribute('role', 'navigation');
let children = Array.from(this.children);
children = children.map((child) => {
if (child.tagName !== 'DIV') {
const div = document.createElement('div');
div.append(child);
this.append(div);
return div;
}
return child;
});
// console.log(children)
this.setupControls(children.filter((_, ind) => ind % 2 === 0));
this.setupContent(children.filter((_, ind) => ind % 2 === 1));
}

setupControls(controls) {
controls.forEach((control,index) => {
const icon = document.createElement('raqn-icon');
icon.setAttribute('icon', 'chevron-right');
const children = Array.from(control.children);
if (children.length === 0) {
const child = document.createElement('span');
child.textContent = control.textContent;
control.innerHTML = '';
control.append(child);
}
control.children[0].append(icon);
control.setAttribute('role', 'button');
control.setAttribute('aria-expanded', 'false');
control.setAttribute('tabindex', '0');
control.classList.add('accordion-control');
control.id = `accordion-${this.id}-${index}`;
control.addEventListener('click', () => this.toggleControl(control));
control.addEventListener('keypress', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
this.toggleControl(control);
}
});
});
}

toggleControl(control) {
const content = control.nextElementSibling;
if (content) {
content.classList.toggle('active');
control.classList.toggle('active');
control.setAttribute('aria-expanded', content.classList.contains('active'));
content.setAttribute('aria-hidden', !content.classList.contains('active'));
}
}

setupContent(contents) {
contents.forEach((content) => {
const internal = content.children;
const wrapper = document.createElement('div');
wrapper.classList.add('accordion-content-wrapper');
wrapper.append(...internal);
content.append(wrapper);
content.setAttribute('role', 'region');
content.setAttribute('aria-hidden',true);
content.classList.add('accordion-content');
content.setAttribute('aria-labelledby', content.previousElementSibling.id);
});
}
}
13 changes: 10 additions & 3 deletions blocks/column/column.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,16 @@ export default class Column extends ComponentBase {
}

connected() {
const firstChild = this.children[0];
const content = this.querySelector('div > div');
firstChild.replaceWith(...content.children);
const content = this.querySelectorAll('div > div');
// clean up dom structure (div div div div div div) and save the content
this.contentChildren = Array.from(content).map((child) => {
const {children} = child;
const parent = child.parentNode;
if (children.length > 0) {
child.replaceWith(...children);
}
return parent;
})
this.calculateGridTemplateColumns();
}

Expand Down
33 changes: 30 additions & 3 deletions blocks/navigation/navigation.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ raqn-navigation {
& p {
display: none;
}

& ul {
overflow-y: auto;
max-height: calc(100vh - var(--scope-header-height));
}
}

&.active > nav {
& ul,
& p {
display: block;
}
}

& a {
Expand Down Expand Up @@ -50,7 +62,7 @@ raqn-navigation {
}

&.active {
button {
& button {
background-color: var(--scope-background-hover, #000);
color: var(--scope-color-hover, #fff);
}
Expand All @@ -65,6 +77,7 @@ raqn-navigation {
inset-inline-start: 0;
inset-block-start: var(--scope-header-height, 64px);
min-height: 100%;
max-height: calc(100vh - var(--scope-header-height, 64px));
margin: 0 auto;
padding: 0;

Expand All @@ -76,8 +89,12 @@ raqn-navigation {
}
}

/* desktop */
&:not([compact='true']) > nav {
& .accordion-content-wrapper {
margin: 0;
}


&:not([compact='true']) > nav {
& a {
line-height: var(--scope-icon-size, 24px);
}
Expand All @@ -104,6 +121,16 @@ raqn-navigation {
padding: var(--padding-vertical, 20px) var(--padding-horizontal, 20px);
}

& .level-2 > a {
color: var(--scope-link-color-hover);
font-size: 1.2em;
font-weight: bold;

&:hover {
color: var(--scope-color, #fff);
}
}

& .level-2,
& .level-2 > ul {
display: inline-flex;
Expand Down
27 changes: 23 additions & 4 deletions blocks/navigation/navigation.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { start } from '../../scripts/init.js';
import Column from '../column/column.js';

export default class Navigation extends Column {

createButton() {
const button = document.createElement('button');
button.setAttribute('aria-label', 'Menu');
Expand All @@ -27,6 +29,7 @@ export default class Navigation extends Column {
this.icon = this.getAttribute('icon') || 'menu';
if (this.compact) {
this.nav.append(this.createButton());
start({name:'accordion'});
}
this.append(this.nav);
this.setupClasses(this.list);
Expand All @@ -35,17 +38,33 @@ export default class Navigation extends Column {
}
}

createIcon(name = this.icon) {
const icon = document.createElement('raqn-icon');
icon.setAttribute('icon', name);
return icon;
}

creaeteAccordion(replaceChildrenElement) {
const accordion = document.createElement('raqn-accordion');
const children = Array.from(replaceChildrenElement.children);
accordion.append(...children);
replaceChildrenElement.append(accordion);
}

setupClasses(ul, level = 1) {
const children = Array.from(ul.children);
children.forEach((child) => {
const hasChildren = child.querySelector('ul');
child.classList.add(`level-${level}`);
child.dataset.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);
if (this.compact) {
this.creaeteAccordion(child);
} else if (level === 1) {
anchor.append(this.createIcon('chevron-right'));
}
child.classList.add('has-children');
this.setupClasses(hasChildren, level + 1);
}
Expand Down
Empty file added blocks/navigation/navigation.md
Empty file.
20 changes: 14 additions & 6 deletions scripts/component-base.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ export default class ComponentBase extends HTMLElement {
}

async connectedCallback() {
this.setAttribute('id', this.uuid);
if (this.external) {
await this.load(this.external);
const inicialized = this.getAttribute('inicialized');
if (!inicialized) {
this.setAttribute('inicialized', true);
this.setAttribute('id', this.uuid);
if (this.external) {
await this.load(this.external);
}
this.connected();
this.ready();
}
this.connected();
this.ready();
}

async load(block) {
Expand All @@ -28,11 +32,15 @@ export default class ComponentBase extends HTMLElement {
if (response.ok) {
const html = await response.text();
this.innerHTML = html;
return init(this);
return this.refresh(this);
}
return response;
}

refresh(el = this) {
init(el);
}

connected() {}

ready() {}
Expand Down
11 changes: 6 additions & 5 deletions scripts/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ function lcpPriority() {
window.raqnLCP = lcp ? lcp.split(',').map((name) => ({ name })) : [];
}


export async function start({ name, el }) {
const loader = new ComponentLoader(name, el);
return loader.decorate();
};

export async function init(node = document) {
let blocks = Array.from(node.querySelectorAll('[class]:not([class^=style]'));

Expand All @@ -54,17 +60,12 @@ export async function init(node = document) {
const rest = data.filter(
({ name }) => !lcp.includes(name) && !delay.includes(name),
);
const start = ({ name, el }) => {
const loader = new ComponentLoader(name, el);
return loader.decorate();
};

// start with lcp and priority
Promise.all([
...lcp.map(({ name, el }) => start({ name, el })),
...priority.map(({ name, el }) => start({ name, el })),
]);

// timeout for the rest to proper prioritize in case of stalled loading
rest.map(({ name, el }) => setTimeout(() => start({ name, el })));

Expand Down
12 changes: 10 additions & 2 deletions styles/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ time, mark, audio, video {
font: inherit;
font-size: 100%;
vertical-align: baseline;
color: inherit;
color: var(--scope-color, inherit);
}

header {
Expand Down Expand Up @@ -86,7 +86,6 @@ main > div > div > div {
display: grid;
grid-template-columns: var(--scope-grid-template-columns, 1fr);
gap: var(--scope-gap, 20px);
padding: var(--scope-padding, 20px 0);
align-items: center;
justify-items: start;
min-height: var(--scope-font-size, 1.2em);
Expand Down Expand Up @@ -153,3 +152,12 @@ h6 {
#franklin-svg-sprite {
display: none;
}

/* component setup styles */

raqn-navigation {
& > ul,
& > button {
display: none;
}
}

0 comments on commit c1fcca1

Please sign in to comment.