]> BookStack Code Mirror - bookstack/blob - resources/js/components/editor-toolbox.ts
Comments: Fixed a range of TS errors + other
[bookstack] / resources / js / components / editor-toolbox.ts
1 import {Component} from './component';
2
3 export interface EditorToolboxChangeEventData {
4     tab: string;
5     open: boolean;
6 }
7
8 export class EditorToolbox extends Component {
9
10     protected container!: HTMLElement;
11     protected buttons!: HTMLButtonElement[];
12     protected contentElements!: HTMLElement[];
13     protected toggleButton!: HTMLElement;
14     protected editorWrapEl!: HTMLElement;
15
16     protected open: boolean = false;
17     protected tab: string = '';
18
19     setup() {
20         // Elements
21         this.container = this.$el;
22         this.buttons = this.$manyRefs.tabButton as HTMLButtonElement[];
23         this.contentElements = this.$manyRefs.tabContent;
24         this.toggleButton = this.$refs.toggle;
25         this.editorWrapEl = this.container.closest('.page-editor') as HTMLElement;
26
27         this.setupListeners();
28
29         // Set the first tab as active on load
30         this.setActiveTab(this.contentElements[0].dataset.tabContent || '');
31     }
32
33     protected setupListeners(): void {
34         // Toolbox toggle button click
35         this.toggleButton.addEventListener('click', () => this.toggle());
36         // Tab button click
37         this.container.addEventListener('click', (event: MouseEvent) => {
38             const button = (event.target as HTMLElement).closest('button');
39             if (button instanceof HTMLButtonElement && this.buttons.includes(button)) {
40                 const name = button.dataset.tab || '';
41                 this.setActiveTab(name, true);
42             }
43         });
44     }
45
46     protected toggle(): void {
47         this.container.classList.toggle('open');
48         const isOpen = this.container.classList.contains('open');
49         this.toggleButton.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
50         this.editorWrapEl.classList.toggle('toolbox-open', isOpen);
51         this.open = isOpen;
52         this.emitState();
53     }
54
55     protected setActiveTab(tabName: string, openToolbox: boolean = false): void {
56         // Set button visibility
57         for (const button of this.buttons) {
58             button.classList.remove('active');
59             const bName = button.dataset.tab;
60             if (bName === tabName) button.classList.add('active');
61         }
62
63         // Set content visibility
64         for (const contentEl of this.contentElements) {
65             contentEl.style.display = 'none';
66             const cName = contentEl.dataset.tabContent;
67             if (cName === tabName) contentEl.style.display = 'block';
68         }
69
70         if (openToolbox && !this.container.classList.contains('open')) {
71             this.toggle();
72         }
73
74         this.tab = tabName;
75         this.emitState();
76     }
77
78     protected emitState(): void {
79         const data: EditorToolboxChangeEventData = {tab: this.tab, open: this.open};
80         this.$emit('change', data);
81     }
82
83 }