2022-11-16 21:04:22 +08:00
|
|
|
import {Component} from "./component";
|
|
|
|
|
2020-07-01 05:12:45 +08:00
|
|
|
/**
|
|
|
|
* Tabs
|
2023-01-28 20:50:51 +08:00
|
|
|
* Uses accessible attributes to drive its functionality.
|
|
|
|
* On tab wrapping element:
|
|
|
|
* - role=tablist
|
|
|
|
* On tabs (Should be a button):
|
|
|
|
* - id
|
|
|
|
* - role=tab
|
|
|
|
* - aria-selected=true/false
|
|
|
|
* - aria-controls=<id-of-panel-section>
|
|
|
|
* On panels:
|
|
|
|
* - id
|
|
|
|
* - tabindex=0
|
|
|
|
* - role=tabpanel
|
|
|
|
* - aria-labelledby=<id-of-tab-for-panel>
|
|
|
|
* - hidden (If not shown by default).
|
2020-07-01 05:12:45 +08:00
|
|
|
*/
|
2022-11-16 21:04:22 +08:00
|
|
|
export class Tabs extends Component {
|
2020-07-01 05:12:45 +08:00
|
|
|
|
|
|
|
setup() {
|
2023-01-28 20:50:51 +08:00
|
|
|
this.container = this.$el;
|
|
|
|
this.tabs = Array.from(this.container.querySelectorAll('[role="tab"]'));
|
|
|
|
this.panels = Array.from(this.container.querySelectorAll('[role="tabpanel"]'));
|
2020-07-01 05:12:45 +08:00
|
|
|
|
2023-01-28 20:50:51 +08:00
|
|
|
this.container.addEventListener('click', event => {
|
|
|
|
const button = event.target.closest('[role="tab"]');
|
|
|
|
if (button) {
|
|
|
|
this.show(button.getAttribute('aria-controls'));
|
2020-07-01 05:12:45 +08:00
|
|
|
}
|
2023-01-28 20:50:51 +08:00
|
|
|
});
|
2020-07-01 05:12:45 +08:00
|
|
|
}
|
|
|
|
|
2023-01-28 20:50:51 +08:00
|
|
|
show(sectionId) {
|
|
|
|
for (const panel of this.panels) {
|
|
|
|
panel.toggleAttribute('hidden', panel.id !== sectionId);
|
|
|
|
}
|
2020-07-01 05:12:45 +08:00
|
|
|
|
2023-01-28 20:50:51 +08:00
|
|
|
for (const tab of this.tabs) {
|
|
|
|
const tabSection = tab.getAttribute('aria-controls');
|
|
|
|
const selected = tabSection === sectionId;
|
|
|
|
tab.setAttribute('aria-selected', selected ? 'true' : 'false');
|
2020-07-01 05:12:45 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-16 21:04:22 +08:00
|
|
|
}
|