]> BookStack Code Mirror - bookstack/blob - resources/js/wysiwyg/ui/framework/buttons.ts
Lexical: Added button icon system
[bookstack] / resources / js / wysiwyg / ui / framework / buttons.ts
1 import {BaseSelection} from "lexical";
2 import {EditorUiContext, EditorUiElement, EditorUiStateUpdate} from "./core";
3 import {el} from "../../helpers";
4
5 export interface EditorBasicButtonDefinition {
6     label: string;
7     icon?: string|undefined;
8 }
9
10 export interface EditorButtonDefinition extends EditorBasicButtonDefinition {
11     action: (context: EditorUiContext) => void;
12     isActive: (selection: BaseSelection|null) => boolean;
13 }
14
15 export class EditorButton extends EditorUiElement {
16     protected definition: EditorButtonDefinition;
17     protected active: boolean = false;
18
19     constructor(definition: EditorButtonDefinition) {
20         super();
21         this.definition = definition;
22     }
23
24     protected buildDOM(): HTMLButtonElement {
25
26         const label = this.getLabel();
27         let child: string|HTMLElement = label;
28         if (this.definition.icon) {
29             child = el('span', {class: 'editor-button-icon'});
30             child.innerHTML = this.definition.icon;
31         }
32
33         const button = el('button', {
34             type: 'button',
35             class: 'editor-button',
36             title: this.definition.icon ? label : null,
37         }, [child]) as HTMLButtonElement;
38
39         button.addEventListener('click', this.onClick.bind(this));
40
41         return button;
42     }
43
44     protected onClick() {
45         this.definition.action(this.getContext());
46     }
47
48     updateActiveState(selection: BaseSelection|null) {
49         this.active = this.definition.isActive(selection);
50         this.dom?.classList.toggle('editor-button-active', this.active);
51     }
52
53     updateState(state: EditorUiStateUpdate): void {
54         this.updateActiveState(state.selection);
55     }
56
57     isActive(): boolean {
58         return this.active;
59     }
60
61     getLabel(): string {
62         return this.trans(this.definition.label);
63     }
64 }