]> BookStack Code Mirror - bookstack/blob - resources/js/wysiwyg/ui/framework/blocks/dropdown-button.ts
Lexical: Completed out table menu elements, logic pending
[bookstack] / resources / js / wysiwyg / ui / framework / blocks / dropdown-button.ts
1 import {el} from "../../../helpers";
2 import {handleDropdown} from "../helpers/dropdowns";
3 import {EditorContainerUiElement, EditorUiElement} from "../core";
4 import {EditorBasicButtonDefinition, EditorButton} from "../buttons";
5
6 export type EditorDropdownButtonOptions = {
7     showOnHover?: boolean;
8     direction?: 'vertical'|'horizontal';
9     button: EditorBasicButtonDefinition|EditorButton;
10 };
11
12 const defaultOptions: EditorDropdownButtonOptions = {
13     showOnHover: false,
14     direction: 'horizontal',
15     button: {label: 'Menu'},
16 }
17
18 export class EditorDropdownButton extends EditorContainerUiElement {
19     protected button: EditorButton;
20     protected childItems: EditorUiElement[];
21     protected open: boolean = false;
22     protected options: EditorDropdownButtonOptions;
23
24     constructor(options: EditorDropdownButtonOptions, children: EditorUiElement[]) {
25         super(children);
26         this.childItems = children;
27         this.options = Object.assign({}, defaultOptions, options);
28
29         if (options.button instanceof EditorButton) {
30             this.button = options.button;
31         } else {
32             this.button = new EditorButton({
33                 ...options.button,
34                 action() {
35                     return false;
36                 },
37                 isActive: () => {
38                     return this.open;
39                 }
40             });
41         }
42
43         this.addChildren(this.button);
44     }
45
46     insertItems(...items: EditorUiElement[]) {
47         this.addChildren(...items);
48         this.childItems.push(...items);
49     }
50
51     protected buildDOM(): HTMLElement {
52         const button = this.button.getDOMElement();
53
54         const childElements: HTMLElement[] = this.childItems.map(child => child.getDOMElement());
55         const menu = el('div', {
56             class: `editor-dropdown-menu editor-dropdown-menu-${this.options.direction}`,
57             hidden: 'true',
58         }, childElements);
59
60         const wrapper = el('div', {
61             class: 'editor-dropdown-menu-container',
62         }, [button, menu]);
63
64         handleDropdown({toggle: button, menu : menu,
65             showOnHover: this.options.showOnHover,
66             onOpen : () => {
67             this.open = true;
68             this.getContext().manager.triggerStateUpdateForElement(this.button);
69         }, onClose : () => {
70             this.open = false;
71             this.getContext().manager.triggerStateUpdateForElement(this.button);
72         }});
73
74         return wrapper;
75     }
76 }