diff --git a/client/css/app.css b/client/css/app.css index 6e753aa..7abbdcf 100644 --- a/client/css/app.css +++ b/client/css/app.css @@ -533,3 +533,27 @@ span.tag { margin-right: 0.5em; } } + +.overlay-wrapper { + position: fixed; + left: 0; + right: 0; + top: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.2); + z-index: 100; + transition: opacity var(--fade), top var(--fade); + display: flex; + align-items: center; + justify-content: center; + + & > .overlay { + max-width: 90%; + max-height: 90%; + background-color: white; + border: 1px solid var(--color1); + border-radius: 10px; + padding: 10px; + box-shadow: 0 0 15px #aaa; + } +} diff --git a/client/layout.js b/client/layout.js index c4bc4b1..b2d3ecf 100644 --- a/client/layout.js +++ b/client/layout.js @@ -5,6 +5,7 @@ import m from "mithril"; import menu from "./menu"; import drawerComponent from "./drawer-component"; import userMenu from "./user-menu"; +import * as overlay from "./overlay"; const layout = { view: vnode => { @@ -15,7 +16,8 @@ const layout = { m(menu, { page: vnode.attrs.page }), m(drawerComponent) ]), - m("#content", { class: `page-${vnode.attrs.page}` }, [vnode.children]) + m("#content", { class: `page-${vnode.attrs.page}` }, [vnode.children]), + overlay.render() ]; } }; diff --git a/client/overlay.js b/client/overlay.js new file mode 100644 index 0000000..9cc6c1e --- /dev/null +++ b/client/overlay.js @@ -0,0 +1,61 @@ +"use strict"; + +import m from "mithril"; + +let overlayCallback = null; + +function open(callback) { + overlayCallback = callback; +} + +function close(callback) { + if (callback === overlayCallback) { + overlayCallback = null; + return true; + } + + return false; +} + +function render() { + if (overlayCallback) + return m( + ".overlay-wrapper", + { + tabindex: 0, + onclick: () => { + close(overlayCallback); + }, + style: "opacity: 0", + oncreate: vnode => { + vnode.dom.focus(); + vnode.dom.style.opacity = 1; + }, + onbeforeremove: vnode => { + vnode.dom.style.opacity = 0; + return new Promise(resolve => { + setTimeout(() => { + resolve(); + }, 500); + }); + } + }, + m( + ".overlay", + { + onclick: e => { + e.stopPropagation(); + } + }, + overlayCallback() + ) + ); + + return null; +} + +document.addEventListener("keydown", e => { + if (e.keyCode === 27 && close(overlayCallback)) m.redraw(); +}); + +export { open, close, render };