Skip to content

Commit

Permalink
add tabs block
Browse files Browse the repository at this point in the history
  • Loading branch information
msagolj committed Oct 9, 2024
1 parent cd5cbb1 commit 81a334f
Show file tree
Hide file tree
Showing 2 changed files with 177 additions and 0 deletions.
64 changes: 64 additions & 0 deletions blocks/tabs/tabs.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
.tabs {
background-color: var(--spectrum-gray-100);
padding: 14px 21px 21px;
border-radius: 7px;
margin-bottom: 28px;
}

.tabs::before {
content: "";
display: block;
width: 100%;
height: 2px;
background: var(--spectrum-gray-300);
position: relative;
top: 56px;
}

.tabs .tab-list {
overflow-x: auto;
white-space: nowrap;
}

.tabs .tab-list button.tab-title {
background: none;
color: var(--spectrum-gray-700);
padding: 0;
margin: 0;
height: 56px;
line-height: 56px;
white-space: nowrap;
font-family: var(--body-font-family);
font-size: var(--exlm-font-size-content);
font-weight: 400;
border: 0;
border-radius: 0;
position: relative;
}

.tabs .tab-list button.tab-title:not(:first-child) {
margin-left: 24px;
}

.tabs .tab-list button.tab-title[aria-selected=true] {
color: var(--text-color);
border-bottom: 2px solid var(--text-color);
border-radius: 0;
}

.tabs .tab-content {
padding: 10.5px 0;
color: var(--spectrum-gray-800);
font-family: var(--body-font-family);
font-size: var(--exlm-font-size-content);
font-weight: 400;
}

.tabs .tab-content .tabpanel {
display: none;
margin-bottom: 12px;
}

.tabs .tab-content .tabpanel.active {
display: block;
}
113 changes: 113 additions & 0 deletions blocks/tabs/tabs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { loadBlocks } from '../../scripts/lib-franklin.js';

Check failure on line 1 in blocks/tabs/tabs.js

View workflow job for this annotation

GitHub Actions / build

Unable to resolve path to module '../../scripts/lib-franklin.js'
import { createTag, moveInstrumentation } from '../../scripts/scripts.js';

Check failure on line 2 in blocks/tabs/tabs.js

View workflow job for this annotation

GitHub Actions / build

createTag not found in '../../scripts/scripts.js'

function changeTabs(e) {
const { target } = e;
const tabMenu = target.parentNode;
const tabContent = tabMenu.nextElementSibling;

tabMenu.querySelectorAll('[aria-selected="true"]').forEach((t) => t.setAttribute('aria-selected', false));

target.setAttribute('aria-selected', true);

tabContent.querySelectorAll('[role="tabpanel"]').forEach((p) => p.classList.remove('active'));

tabContent.parentNode.querySelector(`#${target.getAttribute('aria-controls')}`).classList.add('active');
}

function initTabs(block) {
const tabs = block.querySelectorAll('[role="tab"]');

tabs.forEach((tab) => {
tab.addEventListener('click', changeTabs);
});
}

let initCount = 0;
export default async function decorate(block) {
const tabIndex = block?.dataset?.tabIndex;
if (tabIndex) {
block.textContent = '';
document.querySelectorAll(`div.tab-section.tab-index-${tabIndex}`).forEach((tabSection, i) => {
tabSection.querySelectorAll('h1, h2, h3, h4, h5, h6').forEach((heading) => {
heading.classList.add('no-mtoc');
});
const tabTitle = tabSection?.dataset.title || `tab-${i}`;
const container = document.createElement('div');
moveInstrumentation(tabSection, container);
const titleContainer = document.createElement('div');
titleContainer.textContent = tabTitle.trim();
container.append(titleContainer);
container.append(tabSection);
block.append(container);
});
await loadBlocks(block);
}
const tabList = createTag('div', { class: 'tab-list', role: 'tablist' });
const tabContent = createTag('div', { class: 'tab-content' });

const tabNames = [];
const tabContents = [];
// list of Universal Editor instrumented 'tab content' divs
const tabInstrumentedDiv = [];

[...block.children].forEach((child) => {
// keep the div that has been instrumented for UE
tabInstrumentedDiv.push(child);

[...child.children].forEach((el, index) => {
if (index === 0) {
tabNames.push(el.textContent.trim());
} else {
tabContents.push(el.childNodes);
}
});
});

tabNames.forEach((name, i) => {
const tabBtnAttributes = {
role: 'tab',
class: 'tab-title',
id: `tab-${initCount}-${i}`,
tabindex: i > 0 ? '0' : '-1',
'aria-selected': i === 0 ? 'true' : 'false',
'aria-controls': `tab-panel-${initCount}-${i}`,
'aria-label': name,
'data-tab-id': i,
};

const tabNameDiv = createTag('button', tabBtnAttributes);
tabNameDiv.textContent = name;
tabList.appendChild(tabNameDiv);
});

tabContents.forEach((content, i) => {
const tabContentAttributes = {
id: `tab-panel-${initCount}-${i}`,
role: 'tabpanel',
class: 'tabpanel',
tabindex: '0',
'aria-labelledby': `tab-${initCount}-${i}`,
};

// get the instrumented div
const tabContentDiv = tabInstrumentedDiv[i];
// add all additional attributes
Object.entries(tabContentAttributes).forEach(([key, val]) => {
tabContentDiv.setAttribute(key, val);
});

// default first tab is active
if (i === 0) tabContentDiv.classList.add('active');
tabContentDiv.replaceChildren(...Array.from(content));
tabContent.appendChild(tabContentDiv);
});

// Replace the existing content with the new tab list and tab content
block.innerHTML = ''; // Clear the existing content
block.appendChild(tabList);
block.appendChild(tabContent);

initTabs(block);
initCount += 1;
}

0 comments on commit 81a334f

Please sign in to comment.