Tab Manager
A demonstration and test page for the core TabManager JavaScript class.
Disclaimer
This page is for testing the behavior of the TabManager JavaScript class directly. It does not demonstrate the fully-styled tabs SCSS component. The styles here are minimal and utilitarian, designed only to make the underlying class's functionality visible.
1. Basic Functionality & Keyboard Navigation
Standard horizontal tabs. Test with Arrow Keys, Home, and End.
2a. `orientation: 'vertical'`
Test with Up/Down arrows.
2b. `initialIndex: 1`, `allArrows: true`
Should start on Tab B. All arrow keys should work.
3. URL Hash Options
This instance uses { openByUrlHash: true, setUrlHash: true }. Clicking a tab will update the URL. Refreshing the page with a hash (e.g., #url-tab-2) should open the correct tab.
4. API Methods & Callbacks
This instance tests programmatic control and callbacks.
API Panel 1
This panel has extra content to test `equalHeights`.
API Panel 3
This panel also has extra content to test `equalHeights`.
Some more content.
<script>
document.addEventListener("DOMContentLoaded", () => {
const { TabManager } = Ulu;
// --- Test 1: Basic ---
const basicTablistEl = document.getElementById('basic-tablist');
const basicTabs = [
{ tab: document.getElementById('basic-tab-1'), panel: document.getElementById('basic-panel-1') },
{ tab: document.getElementById('basic-tab-2'), panel: document.getElementById('basic-panel-2') },
{ tab: document.getElementById('basic-tab-3'), panel: document.getElementById('basic-panel-3') },
];
basicTabs.forEach(item => item.tab.setAttribute('aria-controls', item.panel.id));
new TabManager(basicTablistEl);
// --- Test 2a: Vertical ---
const verticalTablistEl = document.getElementById('vertical-tablist');
const verticalTabs = [
{ tab: document.getElementById('vert-tab-1'), panel: document.getElementById('vert-panel-1') },
{ tab: document.getElementById('vert-tab-2'), panel: document.getElementById('vert-panel-2') },
];
verticalTabs.forEach(item => item.tab.setAttribute('aria-controls', item.panel.id));
new TabManager(verticalTablistEl, { orientation: 'vertical' });
// --- Test 2b: Options ---
const optionsTablistEl = document.getElementById('options-tablist');
const optionsTabs = [
{ tab: document.getElementById('opts-tab-1'), panel: document.getElementById('opts-panel-1') },
{ tab: document.getElementById('opts-tab-2'), panel: document.getElementById('opts-panel-2') },
{ tab: document.getElementById('opts-tab-3'), panel: document.getElementById('opts-panel-3') },
];
optionsTabs.forEach(item => item.tab.setAttribute('aria-controls', item.panel.id));
new TabManager(optionsTablistEl, { initialIndex: 1, allArrows: true });
// --- Test 3: URL Hash ---
const urlTablistEl = document.getElementById('url-tablist');
const urlTabs = [
{ tab: document.getElementById('url-tab-1'), panel: document.getElementById('url-panel-1') },
{ tab: document.getElementById('url-tab-2'), panel: document.getElementById('url-panel-2') },
{ tab: document.getElementById('url-tab-3'), panel: document.getElementById('url-panel-3') },
];
urlTabs.forEach(item => item.tab.setAttribute('aria-controls', item.panel.id));
new TabManager(urlTablistEl, { openByUrlHash: true, setUrlHash: true });
// --- Test 4: API & Callbacks ---
const apiTablistEl = document.getElementById('api-tablist');
const apiStatusEl = document.getElementById('api-status');
const apiTabs = [
{ tab: document.getElementById('api-tab-1'), panel: document.getElementById('api-panel-1') },
{ tab: document.getElementById('api-tab-2'), panel: document.getElementById('api-panel-2') },
{ tab: document.getElementById('api-tab-3'), panel: document.getElementById('api-panel-3') },
];
let apiManager;
const initApiManager = () => {
apiStatusEl.innerHTML = "Status: Initializing...";
// Manually add aria-controls to demonstrate class discovering them
apiTabs.forEach(item => item.tab.setAttribute('aria-controls', item.panel.id));
apiManager = new TabManager(apiTablistEl, {
equalHeights: true,
onReady: (instance) => {
console.log("TabManager Ready:", instance);
apiStatusEl.innerHTML += "<br>Event: onReady fired. Instance created.";
},
onChange: (active, previous) => {
console.log("TabManager Change:", { active, previous });
const prevIndex = previous.index > -1 ? previous.index : 'null';
apiStatusEl.innerHTML += `<br>Event: onChange fired. Active: ${ active.index }, Previous: ${ prevIndex }`;
}
});
};
initApiManager();
document.getElementById('api-btn-activate-2').addEventListener('click', () => {
apiStatusEl.innerHTML = "Action: activate(2)";
apiManager.activate(2);
});
document.getElementById('api-btn-activate-1-id').addEventListener('click', () => {
apiStatusEl.innerHTML = "Action: activateById('api-tab-1')";
apiManager.activateById('api-tab-1');
});
document.getElementById('api-btn-destroy').addEventListener('click', () => {
apiStatusEl.innerHTML = "Action: destroy()";
apiManager.destroy();
apiStatusEl.innerHTML += "<br>Instance destroyed. Listeners and attributes should be removed.";
});
document.getElementById('api-btn-reinit').addEventListener('click', () => {
initApiManager();
});
});
</script>