refactoring of cmaps, widgets, etc.
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Coordinate tabs and their aria-controls panels inside one tab list.
|
||||
*
|
||||
* Tabs identify their logical name with data-tab. Selecting a tab updates the
|
||||
* ARIA state, panel visibility and roving keyboard focus.
|
||||
*/
|
||||
export class TabSet {
|
||||
constructor(element) {
|
||||
this.element = element;
|
||||
this.tabs = Array.from(element.querySelectorAll('[role="tab"]'));
|
||||
this.selectionHandlers = [];
|
||||
|
||||
this.element.addEventListener("click", (event) => {
|
||||
const tab = event.target.closest('[role="tab"]');
|
||||
if (tab && this.element.contains(tab)) this.select(tab.dataset.tab);
|
||||
});
|
||||
this.element.addEventListener("keydown", (event) => this.handleKeydown(event));
|
||||
}
|
||||
|
||||
/** Select a named tab and show the panel named by its aria-controls value. */
|
||||
select(name) {
|
||||
for (const tab of this.tabs) {
|
||||
const selected = tab.dataset.tab === name;
|
||||
tab.setAttribute("aria-selected", String(selected));
|
||||
tab.tabIndex = selected ? 0 : -1;
|
||||
const panel = document.getElementById(tab.getAttribute("aria-controls"));
|
||||
if (panel) panel.classList.toggle("hidden", !selected);
|
||||
}
|
||||
for (const handler of this.selectionHandlers) handler(name);
|
||||
}
|
||||
|
||||
onSelect(handler) {
|
||||
this.selectionHandlers.push(handler);
|
||||
return this;
|
||||
}
|
||||
|
||||
handleKeydown(event) {
|
||||
if (!["ArrowLeft", "ArrowRight", "Home", "End"].includes(event.key)) return;
|
||||
const current = this.tabs.indexOf(event.target.closest('[role="tab"]'));
|
||||
if (current < 0) return;
|
||||
event.preventDefault();
|
||||
const next = event.key === "Home" ? 0 : event.key === "End" ? this.tabs.length - 1 :
|
||||
(current + (event.key === "ArrowRight" ? 1 : -1) + this.tabs.length) % this.tabs.length;
|
||||
this.select(this.tabs[next].dataset.tab);
|
||||
this.tabs[next].focus();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user