2024-06-13 00:00:00 -04:00
< html >
< head >
< title > Pattern< / title >
< / head >
< body data-prismjs-copy-timeout = "1500" >
2024-07-11 21:05:34 -04:00
< h2 > What is it< / h2 >
2024-07-16 03:57:34 -04:00
< p > A tabs component that provides different sections of content that are displayed one at a time when the user selects that information. < / p >
2024-07-28 15:30:51 -04:00
< h2 > When to use it< / h2 >
2024-06-13 00:00:00 -04:00
< p > The tabbed user interface enables users to jump to their target section quickly. Tabs present like logically group information on the same page. Information should < / p >
< ul >
< li > be logically chunked and ordered< / li >
< li > be arallel in nature< / li >
< li > show user's context< / li >
< li > obvious where they begin and end < / li >
< / ul >
< p > Users should not need to see content of multiple tabs simultaneously and the user should be able to easily recognise where they are within the content. < / p >
2024-07-28 15:30:51 -04:00
< h2 > How to use it< / h2 >
< p > The structure of the tab set is defined in html. There are two forms supported. Adding a class of < code class = "inline" > .tab-group< / code > to the container element will work in place of the < code class = "inline" > tabset< / code > tag, and the tab panels can be defined using either < code class = "inline" > tab=""< / code > or < code class = "inline" > data-tab=""< / code > . Passing an optional element to the init function will initialise tabs within that element. < / p >
2024-07-11 21:05:34 -04:00
< tabset id = "tabs" >
< pre class = "language-html" tab = "html" >
2024-07-23 20:50:36 -04:00
< tabset id = "uniqueID" >
< div tab = "[tab title]" > < / div >
< div tab = "[tab title]" > < / div >
< / tabset > < / pre >
< pre class = "language-pug" tab = "pug" > tabset#uniqueID
div(tab="[tab title]")
div(tab="[tab title]")
2024-07-16 02:49:53 -04:00
< / pre >
2024-07-11 21:05:34 -04:00
< pre class = "language-css" tab = "css" > tabset, .tab-group {
2024-06-13 00:00:00 -04:00
margin: 2rem 0 1rem 0;
}
2024-07-11 21:05:34 -04:00
tabset > ul, .tab-group > ul {
2024-06-13 00:00:00 -04:00
display: -webkit-box;
display: -ms-flexbox;
display: flex;
margin: 0;
padding: 0;
}
2024-07-11 21:05:34 -04:00
tabset > ul li.separator, .tab-group > ul li.separator {
2024-07-28 15:30:51 -04:00
border-bottom: 1px solid #7f7f7f;
border-left: 1px solid #7f7f7f;
2024-06-13 00:00:00 -04:00
display: inline-block;
margin: 0.45rem 0 0 0;
width: 100%;
}
2024-07-11 21:05:34 -04:00
tabset .tab-hidden, .tab-group .tab-hidden {
2024-06-13 00:00:00 -04:00
display: none;
}
2024-07-11 21:05:34 -04:00
tabset [role=tab], .tab-group [role=tab] {
2024-07-28 15:30:51 -04:00
background-color: #FFF;
border-left: 1px solid #7f7f7f;
border-top: 1px solid #7f7f7f;
2024-06-13 00:00:00 -04:00
border-radius: 0.5rem 0.5rem 0 0;
2024-07-11 21:05:34 -04:00
cursor: pointer;
2024-06-13 00:00:00 -04:00
margin: 0;
display: inline;
padding: 1rem 1.5rem 0.14rem 1.5rem;
z-index: 2;
}
2024-07-11 21:05:34 -04:00
tabset [role=tab]:last-of-type, .tab-group [role=tab]:last-of-type {
2024-07-28 15:30:51 -04:00
border-right: 1px solid #7f7f7f;
2024-06-13 00:00:00 -04:00
}
2024-07-11 21:05:34 -04:00
tabset [role=tab]:not(.selected), .tab-group [role=tab]:not(.selected) {
2024-07-28 15:30:51 -04:00
background-color: #f0f0f0;
border-bottom: 1px solid #7f7f7f;
2024-06-13 00:00:00 -04:00
}
2024-07-11 21:05:34 -04:00
tabset [role=tab] span, .tab-group [role=tab] span {
2024-06-13 00:00:00 -04:00
display: block;
margin: 0 0 0.5rem 0;
}
2024-07-11 21:05:34 -04:00
tabset [role=tabpanel], .tab-group [role=tabpanel] {
2024-07-28 15:30:51 -04:00
background-color: #FFF;
border: 1px solid #7f7f7f;
2024-06-13 00:00:00 -04:00
border-top: none;
padding: 1rem;
z-index: 1;
}
2024-07-11 21:05:34 -04:00
tabset [role=tabpanel]:not(.open), .tab-group [role=tabpanel]:not(.open) {
2024-06-13 00:00:00 -04:00
display: none;
}< / pre >
2024-07-28 15:30:51 -04:00
< div tab = "scss" >
2024-07-29 19:12:22 -04:00
< pre class = "language-sass" > @import "scss/core/tabs/_tabs";
2024-07-28 15:30:51 -04:00
@include tabs{
// optional content block
};
< / pre >
< pre class = "language-sass" > // DS2 core (c) 2024 Alexander McIlwraith
2024-07-12 23:35:29 -04:00
// Licensed under CC BY-SA 4.0
2024-07-11 21:05:34 -04:00
2024-07-16 02:49:53 -04:00
$tab-border: #7f7f7f !default;
$tab-selected: #FFF !default;
$tab-notselected: #f0f0f0 !default;
2024-07-11 21:05:34 -04:00
@mixin tabs {
tabset, .tab-group {
2024-06-13 00:00:00 -04:00
margin: 2rem 0 1rem 0;
> ul {
display: flex;
margin: 0;
padding: 0;
li.separator {
2024-07-11 21:05:34 -04:00
border-bottom: 1px solid $tab-border;
border-left: 1px solid $tab-border;
2024-06-13 00:00:00 -04:00
display: inline-block;
margin: .45rem 0 0 0;
width: 100%;
}
}
.tab-hidden {
display: none;
}
[role="tab"] {
2024-07-11 21:05:34 -04:00
background-color: $tab-selected;
border-left: 1px solid $tab-border;
border-top: 1px solid $tab-border;
2024-06-13 00:00:00 -04:00
border-radius: .5rem .5rem 0 0;
2024-07-11 21:05:34 -04:00
cursor:pointer;
2024-06-13 00:00:00 -04:00
margin: 0;
display: inline;
padding: 1rem 1.5rem .14rem 1.5rem;
z-index: 2;
& :last-of-type {
2024-07-11 21:05:34 -04:00
border-right: 1px solid $tab-border;
2024-06-13 00:00:00 -04:00
}
& :not(.selected) {
2024-07-11 21:05:34 -04:00
background-color: $tab-notselected;
border-bottom: 1px solid $tab-border;
2024-06-13 00:00:00 -04:00
}
span {
display: block;
margin: 0 0 .5rem 0;
}
}
[role="tabpanel"] {
2024-07-11 21:05:34 -04:00
background-color: $tab-selected;
border: 1px solid $tab-border;
2024-06-13 00:00:00 -04:00
border-top: none;
padding: 1rem;
z-index: 1;
& :not(.open) {
display: none;
}
@content;
}
}
}< / pre >
2024-07-28 15:30:51 -04:00
< / div >
< div tab = "js" >
2024-07-29 19:12:22 -04:00
< pre class = "language-js" > import * as tabs from "./js/core/tabs/_tabs.js";
2024-07-28 15:30:51 -04:00
tabs.init();< / pre >
< pre class = "language-js" > /* DS2 core (c) 2024 Alexander McIlwraith
2024-07-12 22:19:12 -04:00
import * as tabs from "../pg/patterns/layouts/tabs/_tabs.js";
tabs.init();
*/
2024-07-11 21:05:34 -04:00
2024-07-12 22:19:12 -04:00
export function init(p = document) {
p.querySelectorAll(".tab-group, tabset").forEach(tabGroup => {
2024-07-11 21:05:34 -04:00
if (tabGroup.querySelector("[role=tablist]") === null) {
const tabgroup = tabGroup.getAttribute("id");
let tablist = "";
Array.from(tabGroup.children).forEach(child => {
const tab = child.getAttribute("tab") || child.getAttribute("data-tab");
if (tab !== null) {
const tabID = tab.replace(/\W+/g, "-").toLowerCase();
const tabPanel = document.createElement('div');
tabPanel.id = `tab-panel-${tabgroup}-${tabID}`;
tabPanel.className = tablist === "" ? "open" : "";
tabPanel.setAttribute("role", "tabpanel");
tabPanel.setAttribute("tabindex", "0");
tabPanel.setAttribute("aria-labelledby", `tab-${tabgroup}-${tabID}`);
tabPanel.appendChild(child.cloneNode(true));
child.parentNode.replaceChild(tabPanel, child);
tablist += `< li tabindex = "0" role = "tab" $ { tablist = == " " ? " class = 'selected' " : " " } id = "tab-${tabgroup}-${tabID}" > < span > ${tab}< / span > < / li > `;
} else {
child.classList.add("tab-hidden");
}
});
const ul = document.createElement('ul');
ul.setAttribute("role", "tablist");
ul.innerHTML = `${tablist}< li role = "separator" class = "separator" > < / li > `;
tabGroup.insertBefore(ul, tabGroup.firstChild);
tabGroup.querySelectorAll('[role="tab"]').forEach(tab => {
tab.addEventListener("click", () => {
const siblings = Array.from(tab.parentNode.children);
siblings.forEach(sibling => sibling.classList.remove("selected"));
tab.classList.add("selected");
const tabPanels = Array.from(tab.parentNode.parentNode.children)
.filter(child => child.getAttribute("role") === "tabpanel");
tabPanels.forEach(panel => panel.classList.remove("open"));
const tabPanelId = tab.getAttribute("id").replace("tab", "tab-panel");
document.getElementById(tabPanelId).classList.add("open");
});
});
2024-06-13 00:00:00 -04:00
2024-07-11 21:05:34 -04:00
}
});
}
< / pre >
2024-07-28 15:30:51 -04:00
< / div >
2024-07-11 21:05:34 -04:00
< / tabset >
2024-06-13 00:00:00 -04:00
< / body >
< / html >