]> BookStack Code Mirror - bookstack/blob - resources/js/components/tabs.js
Merge pull request #3617 from BookStackApp/codemirror6
[bookstack] / resources / js / components / tabs.js
1 import {Component} from "./component";
2
3 /**
4  * Tabs
5  * Uses accessible attributes to drive its functionality.
6  * On tab wrapping element:
7  * - role=tablist
8  * On tabs (Should be a button):
9  * - id
10  * - role=tab
11  * - aria-selected=true/false
12  * - aria-controls=<id-of-panel-section>
13  * On panels:
14  * - id
15  * - tabindex=0
16  * - role=tabpanel
17  * - aria-labelledby=<id-of-tab-for-panel>
18  * - hidden (If not shown by default).
19  */
20 export class Tabs extends Component {
21
22     setup() {
23         this.container = this.$el;
24         this.tabs = Array.from(this.container.querySelectorAll('[role="tab"]'));
25         this.panels = Array.from(this.container.querySelectorAll('[role="tabpanel"]'));
26
27         this.container.addEventListener('click', event => {
28             const button = event.target.closest('[role="tab"]');
29             if (button) {
30                 this.show(button.getAttribute('aria-controls'));
31             }
32         });
33     }
34
35     show(sectionId) {
36         for (const panel of this.panels) {
37             panel.toggleAttribute('hidden', panel.id !== sectionId);
38         }
39
40         for (const tab of this.tabs) {
41             const tabSection = tab.getAttribute('aria-controls');
42             const selected = tabSection === sectionId;
43             tab.setAttribute('aria-selected', selected ? 'true' : 'false');
44         }
45
46         this.$emit('change', {showing: sectionId});
47     }
48
49 }