From 2666069a270dd399e6786d5e47b46c7dbb44dc3c Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Thu, 6 Jan 2022 15:10:03 -0500 Subject: [PATCH] add modal dialog --- src/main/mesh.js | 9 ++++++++ src/mesh/build.js | 51 ++++++++++++++++++++++++++++++++++++++++--- src/moto/webui.js | 6 +++++- web/mesh/index.css | 54 +++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 113 insertions(+), 7 deletions(-) diff --git a/src/main/mesh.js b/src/main/mesh.js index 6c9e7e12..fc544965 100644 --- a/src/main/mesh.js +++ b/src/main/mesh.js @@ -131,6 +131,9 @@ function space_init(data) { platform.setColor(platcolor); }, 'keypress', evt => { + if (api.modal.showing) { + return; + } let { shiftKey, metaKey, ctrlKey, code } = evt; switch (code) { case 'KeyC': @@ -173,6 +176,12 @@ function space_init(data) { 'keydown', evt => { let rv = Math.PI / 16; let { shiftKey, metaKey, ctrlKey, code } = evt; + if (api.modal.showing) { + if (code === 'Escape') { + api.modal.hide(); + } + return; + } switch (code) { case 'KeyA': if (metaKey || ctrlKey) { diff --git a/src/mesh/build.js b/src/mesh/build.js index 10067f51..9c0b7dfa 100644 --- a/src/mesh/build.js +++ b/src/mesh/build.js @@ -6,6 +6,7 @@ gapp.register("mesh.build",[ "moto.broker", // dep: moto.broker + "mesh.api", // dep: mesh.api ]); let mesh = self.mesh = self.mesh || {}; @@ -17,6 +18,34 @@ broker.listeners({ ui_build }); +let modal = mesh.api.modal = { + show(title, contents) { + h.bind($('modal'), contents); + $('modal_title_text').innerText = title; + $('modal_page').style.display = 'flex'; + modal.info = { title, contents, showing: true }; + broker.publish('modal_show'); + }, + + hide() { + $('modal_page').style.display = 'none'; + modal.info.showing = false; + broker.publish('modal_hide'); + }, + + info: { + showing: false + }, + + get title() { + return modal.info.title; + }, + + get showing() { + return modal.info.showing; + } +}; + // create html elements function ui_build() { // set app version @@ -25,9 +54,25 @@ function ui_build() { // create top level app areas let bound = h.bind($('app-body'), [ - h.div({id: 'actions' }), - h.div({id: 'grouplist'}), - h.div({id: 'selectlist'}), + // modal dialog and page blocker + h.div({ id: 'modal_page' }, [ + h.div({ id: 'modal_frame' }, [ + h.div({ id: 'modal_title'}, [ + h.div({ id: 'modal_title_text', _: 'title' }), + h.div({ class: 'pad' }), + h.div({ id: 'modal_title_close', onclick: modal.hide }, [ + h.i({ class: "far fa-window-close" }) + ]) + ]), + h.div({ id: 'modal' }, [ + h.div({ _: 'this is a modal test' }) + ]) + ]) + ]), + // display and action areas + h.div({ id: 'actions' }), + h.div({ id: 'grouplist'}), + h.div({ id: 'selectlist'}), ]); let { actions, grouplist, selectlist } = bound; diff --git a/src/moto/webui.js b/src/moto/webui.js index c2ce2ab4..84181efa 100644 --- a/src/moto/webui.js +++ b/src/moto/webui.js @@ -43,6 +43,10 @@ function build(data, context) { return html; } let { type, attr, innr } = data; + // auto text content + if (typeof attr === 'string') { + attr = { _: attr }; + } let elid; let html = []; let text @@ -119,7 +123,7 @@ let h = self.h = moto.webui = { }; // add common element types -["a", "div", "span", "label", "input", "button"].forEach(type => { +["a", "i", "div", "span", "label", "input", "button"].forEach(type => { h[type] = (attr, innr) => { return h.el(type, attr, innr); } diff --git a/web/mesh/index.css b/web/mesh/index.css index 7250d496..03e87034 100644 --- a/web/mesh/index.css +++ b/web/mesh/index.css @@ -151,9 +151,57 @@ button:hover { background-color: rgba(200,200,200,1); } +/** modal dialogs **/ + +#modal_page { + background-color: rgba(0,0,0,0.5); + justify-content: center; + align-items: center; + position: absolute; + z-index: 50 !important; + bottom: 0; + right: 0; + left: 0; + top: 0; + display: none; +} + +#modal_frame { + background-color: white; + flex-direction: column; + padding: 0 !important; // override common below + z-index: 51; + gap: 2px; +} + +#modal_frame > div { + padding: 3px; // compensate for removing padding above +} + +#modal_title { + border-bottom: 1px solid gray; + background-color: #ccc; +} + +#modal_title .pad { + flex-grow: 1; + width: 5px; +} + +#modal_title_close { + color: #555; +} + +#modal_title_close:hover { + color: black; +} + +#modal { +} + /** common child look & feel */ -#actions > div, #grouplist > div { +#modal_frame, #actions > div, #grouplist > div { border: 1px solid gray; border-radius: 3px; margin: 0 0 2px 0; @@ -180,7 +228,7 @@ button:hover { gap: 2px; } -/** group/model buttons top/right of workspace */ +/** group/model buttons top/right of workspace **/ #grouplist { position: absolute; @@ -216,7 +264,7 @@ button:hover { background-color: rgba(0,255,0,1) } -/** selection info bottom/right of workspace */ +/** selection info bottom/right of workspace **/ #selectlist { font-size: smaller;