]> BookStack Code Mirror - bookstack/blob - resources/js/editor/menu/DialogBox.js
Got link insert/editor working
[bookstack] / resources / js / editor / menu / DialogBox.js
1 // ::- Represents a submenu wrapping a group of elements that start
2 // hidden and expand to the right when hovered over or tapped.
3 import {prefix, renderItems} from "./menu-utils";
4 import crel from "crelt";
5 import {getIcon, icons} from "./icons";
6
7 class DialogBox {
8     // :: ([MenuElement], ?Object)
9     // The following options are recognized:
10     //
11     // **`label`**`: string`
12     //   : The label to show on the dialog.
13     // **`closer`**`: function`
14     //   : The function to run when the dialog should close.
15     constructor(content, options) {
16         this.options = options || {};
17         this.content = Array.isArray(content) ? content : [content];
18
19         this.closeMouseDownListener = null;
20         this.wrap = null;
21     }
22
23     // :: (EditorView) → {dom: dom.Node, update: (EditorState) → bool}
24     // Renders the submenu.
25     render(view) {
26         const items = renderItems(this.content, view)
27
28         const titleText = crel("div", {class: prefix + "-dialog-title-text"}, this.options.label);
29         const titleClose = crel("button", {class: prefix + "-dialog-title-close primary-background", type: "button"}, getIcon(icons.close));
30         const titleContent = crel("div", {class: prefix + "-dialog-title"}, titleText, titleClose);
31         const dialog = crel("div", {class: prefix + "-dialog"}, titleContent,
32             crel("div", {class: prefix + "-dialog-content"}, items.dom));
33         const wrap = crel("div", {class: prefix + "-dialog-wrap"}, dialog);
34         this.wrap = wrap;
35
36         this.closeMouseDownListener = (event) => {
37             if (!dialog.contains(event.target) || titleClose.contains(event.target)) {
38                 this.close();
39             }
40         }
41
42         wrap.addEventListener("click", this.closeMouseDownListener);
43
44         function update(state) {
45             let inner = items.update(state)
46             wrap.style.display = inner ? "" : "none"
47             return inner;
48         }
49         return {dom: wrap, update}
50     }
51
52     close() {
53         if (this.options.closer) {
54             this.options.closer();
55         }
56     }
57 }
58
59 export default DialogBox;