Tabs

Overview content goes here.

Lorem ipsum dolor sit amet.

Lorem ipsum dolor, sit amet consectetur adipisicing elit. Amet voluptate fugiat aut natus deleniti reiciendis, labore recusandae! Neque debitis est amet? Minima veniam deleniti amet minus repudiandae aliquid omnis delectus.

Notes content goes here.

Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet. consectetur adipisicing elit. Facilis, fugiat.

Resources content goes here.

Lorem ipsum dolor sit amet consectetur adipisicing elit. Eum, fugiat! Molestiae debitis quisquam nobis Lorem ipsum dolor sit amet. in repellendus iste deleniti officia cupiditate nam velit. Dignissimos corporis, unde rem odit tempore, ex modi officia dolore quia natus consequuntur.

The HTML

							
								<section class="section tabs_component">
								    <h2 class="secondary_heading">Tabs</h2>
								    <div class="tabs">
								        <div class="tab_list" role="tablist" aria-label="Sample Tabs">
								            <button class="button" type="button" role="tab" aria-selected="false" aria-controls="tab-panel-1" id="tab-1" class="tab_button" data-tab-target="tab-panel-1" tabindex="-1">
								                Overview
								            </button>
								            <button class="button" type="button" role="tab" aria-selected="false" aria-controls="tab-panel-2" id="tab-2" class="tab_button" data-tab-target="tab-panel-2" tabindex="-1">
								                Notes
								            </button>
								            <button class="button" type="button" role="tab" aria-selected="false" aria-controls="tab-panel-3" id="tab-3" class="tab_button" data-tab-target="tab-panel-3" tabindex="-1">
								                Resources
								            </button>
								        </div>
								        <div class="tab_panels">
								            <div class="tab_item" id="tab-panel-1" role="tabpanel">
								                <p>Overview content goes here.</p>
								                <p><a href="#">Lorem ipsum dolor sit amet.</a></p>
								                <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Amet voluptate fugiat aut natus deleniti reiciendis, labore recusandae! Neque debitis est amet? Minima veniam deleniti amet minus repudiandae aliquid omnis delectus.</p>
								            </div>
								            <div class="tab_item" id="tab-panel-2" role="tabpanel">
								                <p>Notes content goes here.</p>
								                <p>Lorem ipsum dolor sit amet, <a href="#">Lorem ipsum dolor sit amet.</a> consectetur adipisicing elit. Facilis, fugiat.</p>
								            </div>
								            <div class="tab_item" id="tab-panel-3" role="tabpanel">
								                <p>Resources content goes here.</p>
								                <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eum, fugiat! Molestiae debitis quisquam nobis <a href="#">Lorem ipsum dolor sit amet.</a> in repellendus iste deleniti officia cupiditate nam velit. Dignissimos corporis, unde rem odit tempore, ex modi officia dolore quia natus consequuntur.</p>
								            </div>
								        </div>
								    </div>
								</section>
							
						

The JavaScript

							
								function initTabsComponent() {
								    const root = document.querySelector(".tabs_component");
								    if (!root) return;
								    const buttons = root.querySelectorAll(".button");
								    const panels = root.querySelectorAll(".tab_item");

								    // activate first panel
								    buttons[0].classList.add("active");
								    buttons[0].setAttribute("aria-selected", "true");
								    buttons[0].setAttribute("tabindex", "0");
								    panels[0].classList.add("active");

								    function activateTab(button) {
								        // deactivate all buttons
								        buttons.forEach((btn) => {
								            btn.classList.remove("active");
								            btn.setAttribute("aria-selected", "false");
								            btn.setAttribute("tabindex", "-1");
								        });

								        // activate button clicked
								        button.classList.add("active");
								        button.setAttribute("aria-selected", "true");
								        button.setAttribute("tabindex", "0");

								        // deactivate, then activate matching panel
								        panels.forEach((item) => {
								            item.classList.remove("active");
								            if (button.dataset.tabTarget === item.id) {
								                item.classList.add("active");
								            }
								        });
								    }

								    buttons.forEach((button, index) => {
								        ["click", "keydown"].forEach((eventType) => {
								            button.addEventListener(eventType, (e) => {
								                // activate and focus via keyboard arrows
								                let newIndex = index;
								                if (e.key === "ArrowRight") {
								                    newIndex = (index + 1) % buttons.length;
								                }

								                if (e.key === "ArrowLeft") {
								                    newIndex = (index - 1 + buttons.length) % buttons.length;
								                }

								                if (newIndex !== index) {
								                    e.preventDefault();
								                    buttons[newIndex].focus();
								                    activateTab(buttons[newIndex]);
								                    return;
								                }

								                if (e.key === "Home") newIndex = 0;
								                if (e.key === "End") newIndex = buttons.length - 1;

								                // activate tabs on click
								                if (eventType === "click") {
								                    activateTab(button);
								                }
								            });
								        });
								    });
								}
								initTabsComponent();