<html> 
  <head>
    <title>Pattern</title>
  </head>
  <body data-prismjs-copy-timeout="1500">
    <h2>What is it</h2>
    <p>A tabs component that provides different sections of content that are displayed one at a time when the user selects that information. </p>
    <h2>When to use it</h2>
    <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>
    <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>
    <tabset id="tabs">
      <pre class="language-html" tab="html">
        <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]")
		</pre>
      <pre class="language-css" tab="css">tabset, .tab-group {
	margin: 2rem 0 1rem 0;
}
tabset > ul, .tab-group > ul {
	display: -webkit-box;
	display: -ms-flexbox;
	display: flex;
	margin: 0;
	padding: 0;
}
tabset > ul li.separator, .tab-group > ul li.separator {
	border-bottom: 1px solid #7f7f7f;
	border-left: 1px solid #7f7f7f;
	display: inline-block;
	margin: 0.45rem 0 0 0;
	width: 100%;
}
tabset .tab-hidden, .tab-group .tab-hidden {
	display: none;
}
tabset [role=tab], .tab-group [role=tab] {
	background-color: #FFF;
	border-left: 1px solid #7f7f7f;
	border-top: 1px solid #7f7f7f;
	border-radius: 0.5rem 0.5rem 0 0;
	cursor: pointer;
	margin: 0;
	display: inline;
	padding: 1rem 1.5rem 0.14rem 1.5rem;
	z-index: 2;
}
tabset [role=tab]:last-of-type, .tab-group [role=tab]:last-of-type {
	border-right: 1px solid #7f7f7f;
}
tabset [role=tab]:not(.selected), .tab-group [role=tab]:not(.selected) {
	background-color: #f0f0f0;
	border-bottom: 1px solid #7f7f7f;
}
tabset [role=tab] span, .tab-group [role=tab] span {
	display: block;
	margin: 0 0 0.5rem 0;
}
tabset [role=tabpanel], .tab-group [role=tabpanel] {
	background-color: #FFF;
	border: 1px solid #7f7f7f;
	border-top: none;
	padding: 1rem;
	z-index: 1;
}
tabset [role=tabpanel]:not(.open), .tab-group [role=tabpanel]:not(.open) {
	display: none;
}</pre>
      <div tab="scss">
        <pre class="language-sass">@import "scss/core/tabs/_tabs";
@include tabs{ 
	// optional content block
};
</pre>
        <pre class="language-sass">//		DS2 core (c) 2024 Alexander McIlwraith 
//		Licensed under CC BY-SA 4.0 

$tab-border: #7f7f7f !default; 
$tab-selected: #FFF !default;
$tab-notselected: #f0f0f0 !default;

@mixin tabs {
	tabset, .tab-group {
		margin: 2rem 0 1rem 0;
		> ul {
			display: flex;
			margin: 0;
			padding: 0;

			li.separator {	
				border-bottom: 1px solid $tab-border;
				border-left: 1px solid $tab-border;
				display: inline-block;
				margin: .45rem 0 0 0;
				width: 100%;
			}
		}

		.tab-hidden {
			display: none;
		}

		[role="tab"] {
			background-color: $tab-selected;
			border-left: 1px solid $tab-border;
			border-top: 1px solid $tab-border;
			border-radius: .5rem .5rem 0 0;
			cursor:pointer;
			margin: 0;
			display: inline;
			padding: 1rem 1.5rem .14rem 1.5rem;
			z-index: 2;
			
			&:last-of-type {
				border-right: 1px solid $tab-border;
			}

			&:not(.selected) {
				background-color: $tab-notselected;
				border-bottom: 1px solid $tab-border;
			}

			span {
				display: block;
				margin: 0 0 .5rem 0;
			}

		}
		[role="tabpanel"] {
			background-color: $tab-selected;
			border: 1px solid $tab-border;
			border-top: none;
			padding: 1rem;
			z-index: 1;

			&:not(.open) {
				display: none;
			}
			@content;

		}
	}
}</pre>
      </div>
      <div tab="js">
        <pre class="language-js">import * as tabs from "./js/core/tabs/_tabs.js";
tabs.init();</pre>
        <pre class="language-js">/*  DS2 core (c) 2024 Alexander McIlwraith 
	import * as tabs from "../pg/patterns/layouts/tabs/_tabs.js";
	tabs.init();
 */

export function init(p = document) { 
	p.querySelectorAll(".tab-group, tabset").forEach(tabGroup => {

		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");
				});
			});
			
		}
	});
}
</pre>
      </div>
    </tabset>
  </body>
</html>