From da0f472d6ec2aa70c3af49e413b5910cb643ed9b Mon Sep 17 00:00:00 2001 From: Gisle Aune Date: Wed, 19 Sep 2018 18:52:42 +0200 Subject: [PATCH] components/modal: Updated modal to work with forms --- marko/components/modal/component.js | 106 ++++++++++++++++++++++++++++ marko/components/modal/index.marko | 4 +- marko/components/modal/style.less | 70 +++++++++++++++++- marko/global/colors.less | 12 ++-- 4 files changed, 181 insertions(+), 11 deletions(-) diff --git a/marko/components/modal/component.js b/marko/components/modal/component.js index d74a693..acbdb4c 100644 --- a/marko/components/modal/component.js +++ b/marko/components/modal/component.js @@ -1,5 +1,111 @@ module.exports = class { + onCreate() { + this.mounted = false + } + closeModal() { this.emit("close") + + if (this.mounted) { + window.removeEventListener("keydown", this.onPress) + } + } + + onInput(input) { + if (!this.mounted) { + return + } + + if (input) { + if (input.enabled && (!this.input || !this.input.enabled)) { + this.emit("open") + } + + if (input.closable) { + if (input.enabled && (!this.input || !this.input.enabled)) { + window.addEventListener("keydown", this.onPress) + } else if (!input.enabled && (this.input && this.input.enabled)) { + window.removeEventListener("keydown", this.onPress) + } + } + } + } + + onMount() { + this.onPress = this.onPress.bind(this) + this.mounted = true + + if (this.input.enabled && this.input.closable) { + window.addEventListener("keydown", this.onPress) + } + } + + onUnmount() { + if (this.input.enabled) { + window.removeEventListener("keydown", this.onPress) + } + } + + /** + * + * @param {KeyboardEvent} ev + */ + onPress(ev) { + if (ev.key === "Escape" && ev.ctrlKey ) { + this.closeModal() + } + } + + getValues() { + /** @type {HTMLElement[]} */ + const elems = this.findInputs() + const map = {} + + for (const component of this.getComponents()) { + if (component.getFormData != null) { + Object.assign(map, component.getFormData() || {}) + } + } + + return elems.reduce((map, elem) => { + let path = elem.getAttribute("name").split(".") + let node = map + for (const part of path.slice(0, -1)) { + if (node[part] == null) { + node[part] = {} + } + + node = node[part] + } + + node[path[path.length - 1]] = elem.value; + return map + }, map) + } + + /** + * @param {HTMLElement} elem + */ + findInputs(elem = this.getEl()) { + let results = [] + + if (elem.childNodes.length === 0) { + return [] + } + + for (let i = 0; i < elem.children.length; ++i) { + const child = elem.children.item(i) + if (child.dataset.formboundary != null) { + continue + } + + if (child.nodeName === "INPUT" || child.nodeName === "TEXTAREA") { + results.push(child) + } else { + results = results.concat(this.findInputs(child)) + } + } + + return results } } \ No newline at end of file diff --git a/marko/components/modal/index.marko b/marko/components/modal/index.marko index 52a9f71..918b12a 100644 --- a/marko/components/modal/index.marko +++ b/marko/components/modal/index.marko @@ -1,9 +1,9 @@
-
X
+
Close
- diff --git a/marko/components/modal/style.less b/marko/components/modal/style.less index 54965f5..54ee9b2 100644 --- a/marko/components/modal/style.less +++ b/marko/components/modal/style.less @@ -4,12 +4,12 @@ div.overlay { right: 0; top: 0; bottom: 0; - padding-top: 4em; + padding-top: 1em; z-index: 999; - background-color: rgba(0, 0, 0, 0.75); + background-color: rgba(0, 0, 0, 0.90); - overflow-y: auto; + overflow-y: scroll; h1 { text-align: center; @@ -19,6 +19,70 @@ div.overlay { width: 60ch; max-width: 95%; margin: auto; + + label { + display: block; + margin-top: 1em; + font-size: 0.75em; + } + + input { + display: block; + width: 100%; + padding: 0 0.5ch; + + border: none; + font-family: inherit; + background: none; + outline: none; + opacity: 0.5; + } + input.big { + font-size: 1.5em; + padding: 0 0.3333ch; + } + + textarea { + display: block; + width: 100%; + height: 8em; + padding: 0 0.5ch; + + border: none; + font-family: inherit; + background: none; + outline: none; + opacity: 0.5; + + resize: none; + overflow-y: scroll; + } + textarea.tall { + height: 24em; + } + + input:focus, textarea:focus { + opacity: 1; + } + + button { + border: 1px solid; + background-color: rgba(0, 0, 0, 0.75); + margin: 2em auto; + display: block; + padding: 0.5em 4ch; + + opacity: 0.75; + } + button:hover { + opacity: 1; + cursor: pointer; + } + } + div.modal.nolabel { + input, textarea { + margin-bottom: 0.5em; + } } div.overlay-options { diff --git a/marko/global/colors.less b/marko/global/colors.less index 5fceb71..2959901 100644 --- a/marko/global/colors.less +++ b/marko/global/colors.less @@ -8,10 +8,10 @@ body.theme-story { .menu-link:hover, .menu > .head-menu > a:hover { background-color: rgba(17, 187, 255, 0.25); } - .color-primary, .modal h1, .modal h2, .markdown-content h1, .markdown-content h2, .markdown-content h3, .markdown-content h4, .markdown-content hr, .markdown-content a { + .color-primary, button, input:focus, textarea:focus, .modal h1, .modal h2, .modal label, .markdown-content h1, .markdown-content h2, .markdown-content h3, .markdown-content h4, .markdown-content hr, .markdown-content a { color: #4BF; } - .color-text { + .color-text, input, textarea { color: #ABC; } .color-highlight-primary { @@ -33,10 +33,10 @@ body.theme-logs { .menu-link:hover, .Menu > .head-menu > a:hover { background-color: rgba(255, 187, 17, 0.25); } - .color-primary, .modal h1, .modal h2, .markdown-content h1, .markdown-content h2, .markdown-content h3, .markdown-content h4, .markdown-content hr, .markdown-content a { + .color-primary, button, .modal h1, .modal h2, .modal label, .markdown-content h1, .markdown-content h2, .markdown-content h3, .markdown-content h4, .markdown-content hr, .markdown-content a { color: #DA1; } - .color-text { + .color-text, input, textarea { color: #AAA; } .color-highlight-dark { @@ -58,10 +58,10 @@ body.theme-logs { .menu-link:hover, .menu > .head-menu > a:hover { background-color: rgba(35, 255, 128, 0.25); } - .color-primary, .modal h1, .modal h2, .markdown-content h1, .markdown-content h2, .markdown-content h3, .markdown-content h4, .markdown-content hr, .markdown-content a { + .color-primary, button, .modal h1, .modal h2, .modal label, .markdown-content h1, .markdown-content h2, .markdown-content h3, .markdown-content h4, .markdown-content hr, .markdown-content a { color: #1F8; } - .color-text { + .color-text, input, textarea { color: #ACB; } }