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";
8 // :: ([MenuElement], ?Object)
9 // The following options are recognized:
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];
19 this.closeMouseDownListener = null;
23 // :: (EditorView) → {dom: dom.Node, update: (EditorState) → bool}
24 // Renders the submenu.
26 const items = renderItems(this.content, view)
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);
36 this.closeMouseDownListener = (event) => {
37 if (!dialog.contains(event.target) || titleClose.contains(event.target)) {
42 wrap.addEventListener("click", this.closeMouseDownListener);
44 function update(state) {
45 let inner = items.update(state)
46 wrap.style.display = inner ? "" : "none"
49 return {dom: wrap, update}
53 if (this.options.closer) {
54 this.options.closer();
59 export default DialogBox;