Skip to content

Commit f6dcfbb

Browse files
committed
feat: add tabs
1 parent f1d00e7 commit f6dcfbb

2 files changed

Lines changed: 112 additions & 0 deletions

File tree

blocks/tabs/tabs.css

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
.tabs .tabs-list {
2+
display: flex;
3+
gap: 0.5ch;
4+
max-width: 100%;
5+
font-size: var(--body-font-size-xs);
6+
overflow-x: auto;
7+
}
8+
9+
@media (width >= 600px) {
10+
.tabs .tabs-list {
11+
font-size: var(--body-font-size-s);
12+
}
13+
}
14+
15+
@media (width >= 900px) {
16+
.tabs .tabs-list {
17+
font-size: var(--body-font-size-m);
18+
}
19+
}
20+
21+
.tabs .tabs-list button {
22+
flex: 0 0 max-content;
23+
margin: 0;
24+
border: 0;
25+
border-bottom: 2px solid transparent;
26+
border-radius: 0;
27+
padding: var(--spacing-small) var(--spacing-medium);
28+
background-color: var(--light-color);
29+
color: var(--color-brand-500);
30+
font-size: 1.8rem;
31+
font-weight: 500;
32+
line-height: 1;
33+
text-align: initial;
34+
text-overflow: unset;
35+
overflow: unset;
36+
white-space: unset;
37+
transition: background-color 0.2s;
38+
cursor: pointer;
39+
}
40+
41+
.tabs .tabs-list button:hover {
42+
color: var(--color-brand-600);
43+
}
44+
45+
.tabs .tabs-list button p {
46+
margin: 0;
47+
}
48+
49+
50+
.tabs .tabs-list button[aria-selected='true'] {
51+
border-bottom: 2px solid var(--color-black);
52+
background-color: var(--background-color);
53+
color: var(--color-black);
54+
cursor: initial;
55+
}
56+
57+
.tabs .tabs-panel {
58+
margin-top: -2px;
59+
border-top: 2px solid var(--color-neutral-300);
60+
overflow: auto;
61+
}
62+
63+
.tabs .tabs-panel[aria-hidden='true'] {
64+
display: none;
65+
}

blocks/tabs/tabs.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// eslint-disable-next-line import/no-unresolved
2+
import { toClassName } from '../../scripts/aem.js';
3+
4+
export default async function decorate(block) {
5+
// build tablist
6+
const tablist = document.createElement('div');
7+
tablist.className = 'tabs-list';
8+
tablist.setAttribute('role', 'tablist');
9+
10+
// decorate tabs and tabpanels
11+
const tabs = [...block.children].map((child) => child.firstElementChild);
12+
tabs.forEach((tab, i) => {
13+
const id = toClassName(tab.textContent);
14+
15+
// decorate tabpanel
16+
const tabpanel = block.children[i];
17+
tabpanel.className = 'tabs-panel';
18+
tabpanel.id = `tabpanel-${id}`;
19+
tabpanel.setAttribute('aria-hidden', !!i);
20+
tabpanel.setAttribute('aria-labelledby', `tab-${id}`);
21+
tabpanel.setAttribute('role', 'tabpanel');
22+
23+
// build tab button
24+
const button = document.createElement('button');
25+
button.className = 'tabs-tab';
26+
button.id = `tab-${id}`;
27+
button.innerHTML = tab.innerHTML;
28+
button.setAttribute('aria-controls', `tabpanel-${id}`);
29+
button.setAttribute('aria-selected', !i);
30+
button.setAttribute('role', 'tab');
31+
button.setAttribute('type', 'button');
32+
button.addEventListener('click', () => {
33+
block.querySelectorAll('[role=tabpanel]').forEach((panel) => {
34+
panel.setAttribute('aria-hidden', true);
35+
});
36+
tablist.querySelectorAll('button').forEach((btn) => {
37+
btn.setAttribute('aria-selected', false);
38+
});
39+
tabpanel.setAttribute('aria-hidden', false);
40+
button.setAttribute('aria-selected', true);
41+
});
42+
tablist.append(button);
43+
tab.remove();
44+
});
45+
46+
block.prepend(tablist);
47+
}

0 commit comments

Comments
 (0)