components/modal: Updated modal to work with forms
This commit is contained in:
@@ -1,5 +1,111 @@
|
|||||||
module.exports = class {
|
module.exports = class {
|
||||||
|
onCreate() {
|
||||||
|
this.mounted = false
|
||||||
|
}
|
||||||
|
|
||||||
closeModal() {
|
closeModal() {
|
||||||
this.emit("close")
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
<if(input.enabled)>
|
<if(input.enabled)>
|
||||||
<div class=["overlay", (input.notification ? "notification-overlay" : "normal-overlay")]>
|
<div class=["overlay", (input.notification ? "notification-overlay" : "normal-overlay")]>
|
||||||
<div class="overlay-options color-menu">
|
<div class="overlay-options color-menu">
|
||||||
<div if(input.closable) on-click("closeModal")>X</div>
|
<div if(input.closable) on-click("closeModal")>Close</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal color-text">
|
<div class=input.class>
|
||||||
<include(input.renderBody) />
|
<include(input.renderBody) />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ div.overlay {
|
|||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
padding-top: 4em;
|
padding-top: 1em;
|
||||||
z-index: 999;
|
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 {
|
h1 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -19,6 +19,70 @@ div.overlay {
|
|||||||
width: 60ch;
|
width: 60ch;
|
||||||
max-width: 95%;
|
max-width: 95%;
|
||||||
margin: auto;
|
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 {
|
div.overlay-options {
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ body.theme-story {
|
|||||||
.menu-link:hover, .menu > .head-menu > a:hover {
|
.menu-link:hover, .menu > .head-menu > a:hover {
|
||||||
background-color: rgba(17, 187, 255, 0.25);
|
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: #4BF;
|
||||||
}
|
}
|
||||||
.color-text {
|
.color-text, input, textarea {
|
||||||
color: #ABC;
|
color: #ABC;
|
||||||
}
|
}
|
||||||
.color-highlight-primary {
|
.color-highlight-primary {
|
||||||
@@ -33,10 +33,10 @@ body.theme-logs {
|
|||||||
.menu-link:hover, .Menu > .head-menu > a:hover {
|
.menu-link:hover, .Menu > .head-menu > a:hover {
|
||||||
background-color: rgba(255, 187, 17, 0.25);
|
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: #DA1;
|
||||||
}
|
}
|
||||||
.color-text {
|
.color-text, input, textarea {
|
||||||
color: #AAA;
|
color: #AAA;
|
||||||
}
|
}
|
||||||
.color-highlight-dark {
|
.color-highlight-dark {
|
||||||
@@ -58,10 +58,10 @@ body.theme-logs {
|
|||||||
.menu-link:hover, .menu > .head-menu > a:hover {
|
.menu-link:hover, .menu > .head-menu > a:hover {
|
||||||
background-color: rgba(35, 255, 128, 0.25);
|
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: #1F8;
|
||||||
}
|
}
|
||||||
.color-text {
|
.color-text, input, textarea {
|
||||||
color: #ACB;
|
color: #ACB;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user