Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

329 multicolour accordion #344

Merged
merged 15 commits into from
Aug 10, 2023
78 changes: 78 additions & 0 deletions blocks/multicolor-accordion/multicolor-accordion.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
.multicolor-accordion-wrap {
list-style: none;
padding: 0;
margin: 0;
}

.accordion-item {
margin: 0 0 20px;
}

.accordion-trigger {
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
width: 100%;
border: none;
padding: 23px 16px;
}

.accordion-trigger div {
font-size: 34px;
color: var(--c-white);
font-weight: 700;
}

.multicolor-accordion-wrap > li:nth-child(odd) {
background: var(--c-dark-plum);
}

.multicolor-accordion-wrap > li:nth-child(even) {
background: var(--c-dark-blue);
}

.accordion-trigger .btn {
border-radius: 16px;
font-weight: 600;
text-transform: uppercase;
padding: 8px 24px;
min-width: 56px;
cursor: pointer;
font-size: 15px;
border: 1px solid var(--c-light-teal);
transition: background-color 0.5s, color 0.5s;
}

.accordion-trigger .details-button {
background: var(--c-light-teal);
color: var(--c-dark-plum);
}

.accordion-trigger .details-button:hover,
.accordion-trigger .details-button-open {
background: transparent;
color: var(--c-light-teal);
}

.accordion-content {
transition: height 0.3s;
height: 0;
overflow: hidden;
color: var(--c-white);
padding: 0 16px;
}

@media (max-width: 600px) {
.accordion-trigger div {
font-size: 20px;
}

.accordion-trigger .btn {
display: none;
}

.accordion-trigger {
padding: 23px 7px;
}
}
83 changes: 83 additions & 0 deletions blocks/multicolor-accordion/multicolor-accordion.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
const btnTextOpen = `${window.placeholders?.default?.Details || 'Details'}`;
const btnTextClose = `${window.placeholders?.default?.Close || 'Close'}`;

function closePrevItem(item) {
const button = item.previousElementSibling;
button.setAttribute('aria-expanded', false);
const [, span] = button.children;
span.innerText = btnTextOpen;
span.classList.remove('details-button-open');

item.setAttribute('aria-hidden', true);
item.style.height = null;
}

function openCurrentItem(item, button) {
item.setAttribute('aria-hidden', false);
item.style.height = `${item.scrollHeight}px`;

button.setAttribute('aria-expanded', true);
const [, span] = button.children;
span.innerText = btnTextClose;
span.classList.add('details-button-open');
}

function toggleAccordian(event) {
const button = event.currentTarget;

const openedItem = button.closest('ul').querySelector('.accordion-content[aria-hidden="false"]');

if (openedItem) {
closePrevItem(openedItem);
}

const itemToOpen = button.nextElementSibling;

if (openedItem !== itemToOpen) {
openCurrentItem(itemToOpen, button);
}
}

function createDetailsButton(title, index) {
const span = document.createElement('span');
span.classList.add('btn', 'details-button');
span.innerText = btnTextOpen;

const button = document.createElement('button');
button.classList.add('accordion-trigger');
button.setAttribute('aria-expanded', false);
button.setAttribute('aria-controls', `panel-${index}`);
button.append(title, span);
button.addEventListener('click', toggleAccordian);

return button;
}

function createAccordianItems({ children }, index) {
const [title, content] = children;

const button = createDetailsButton(title, index);

content.classList.add('accordion-content');
content.setAttribute('aria-hidden', true);
content.id = `panel-${index}`;
content.querySelectorAll('a').forEach((link) => {
link.target = '_blank';
});

const li = document.createElement('li');
li.classList.add('accordion-item');
li.append(button, content);

return li;
}

export default async function decorate(block) {
const ul = document.createElement('ul');
ul.classList.add('multicolor-accordion-wrap');

const items = [...block.children].map(createAccordianItems);
ul.append(...items);

block.replaceWith(ul);
}