progress on modal functionality and form styling

This commit is contained in:
Adam Piontek 2021-03-03 16:07:59 -05:00
parent c7e12f7d49
commit be155d7b98
16 changed files with 417 additions and 308 deletions

View File

@ -1,9 +1,32 @@
/* LiveView specific classes for your customizations */
/* hides the feedback field help if liveview indicates field not touched yet */
.phx-no-feedback.invalid-feedback,
.phx-no-feedback .invalid-feedback {
display: none;
}
/* sets default bootstrap form-control styles if field not touched yet */
.phx-no-feedback .form-control.is-valid,
.phx-no-feedback .form-control.is-invalid {
padding: $input-padding-y $input-padding-x;
border: $input-border-width solid $input-border-color;
background-image: none;
&:focus {
color: $input-focus-color;
background-color: $input-focus-bg;
border-color: $input-focus-border-color;
outline: 0;
@if $enable-shadows {
@include box-shadow($input-box-shadow, $input-focus-box-shadow);
} @else {
// Avoid using mixin so we can pass custom focus shadow properly
box-shadow: $input-focus-box-shadow;
}
}
}
.phx-click-loading {
opacity: 0.5;
transition: opacity 1s ease-out;
@ -15,38 +38,3 @@
.phx-disconnected * {
pointer-events: none;
}
.phx-modal {
opacity: 1 !important;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0, 0, 0.4);
}
.phx-modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
}
.phx-modal-close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.phx-modal-close:hover,
.phx-modal-close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}

34
assets/js/_bs_modal.js Normal file
View File

@ -0,0 +1,34 @@
// Helping bootstrap modals work with liveview
// preserving animations
import Modal from "bootstrap/js/dist/modal";
// import { Modal } from "bootstrap";
export const BsModal = {
mounted() {
// when the liveview mounts, create the BS modal
const modal = new Modal(this.el);
// and trigger BS modal to show
modal.show();
// when the BS modal hides, send 'close' to the liveview
this.el.addEventListener("hidden.bs.modal", (event) => {
this.pushEventTo(`#${this.el.getAttribute("id")}`, "close", {});
modal.dispose();
});
// liveview can send this event to tell BS modal to close
// ex.: on successful form save, instead of immediate redirect
// this event hides the BS modal, which triggers the above,
// which sends 'close' to liveview and disposes the BS modal
this.handleEvent("modal-please-hide", (payload) => {
modal.hide();
});
},
destroyed() {
// when the liveview is destroyed,
// modal-backdrop must be forcibly removed
const backdrop = document.querySelector(".modal-backdrop");
if (backdrop) backdrop.parentElement.removeChild(backdrop);
},
};

View File

@ -37,17 +37,20 @@ import topbar from "topbar";
import { LiveSocket } from "phoenix_live_view";
// Bootstrap v5 js imports
import "bootstrap/js/dist/alert";
import "bootstrap/js/dist/collapse";
import "bootstrap/js/dist/dropdown";
import "bootstrap/js/dist/alert";
// Boostrap helpers
// Bootstrap helpers
import "./_hamburger-helper";
import "./_form-validity";
// Bootstrap-liveview helpers
import { AlertRemover } from "./_alert-remover";
import { BsModal } from "./_bs_modal";
// LiveSocket setup
let Hooks = {};
Hooks.AlertRemover = AlertRemover;
Hooks.BsModal = BsModal;
let csrfToken = document
.querySelector("meta[name='csrf-token']")
.getAttribute("content");

430
assets/package-lock.json generated
View File

@ -9,6 +9,7 @@
"@fontsource/lato": "^4.2.1",
"@mdi/svg": "^5.9.55",
"@popperjs/core": "^2.8.4",
"alpinejs": "^2.8.1",
"bootstrap": "^5.0.0-beta2",
"bootstrap-icons": "^1.4.0",
"hamburgers": "^1.1.3",
@ -61,23 +62,23 @@
}
},
"node_modules/@babel/compat-data": {
"version": "7.13.6",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.6.tgz",
"integrity": "sha512-VhgqKOWYVm7lQXlvbJnWOzwfAQATd2nV52koT0HZ/LdDH0m4DUDwkKYsH+IwpXb+bKPyBJzawA4I6nBKqZcpQw==",
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.8.tgz",
"integrity": "sha512-EaI33z19T4qN3xLXsGf48M2cDqa6ei9tPZlfLdb2HC+e/cFtREiRd8hdSqDbwdLB0/+gLwqJmCYASH0z2bUdog==",
"dev": true
},
"node_modules/@babel/core": {
"version": "7.13.1",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.1.tgz",
"integrity": "sha512-FzeKfFBG2rmFtGiiMdXZPFt/5R5DXubVi82uYhjGX4Msf+pgYQMCFIqFXZWs5vbIYbf14VeBIgdGI03CDOOM1w==",
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.8.tgz",
"integrity": "sha512-oYapIySGw1zGhEFRd6lzWNLWFX2s5dA/jm+Pw/+59ZdXtjyIuwlXbrId22Md0rgZVop+aVoqow2riXhBLNyuQg==",
"dev": true,
"dependencies": {
"@babel/code-frame": "^7.12.13",
"@babel/generator": "^7.13.0",
"@babel/helper-compilation-targets": "^7.13.0",
"@babel/helper-compilation-targets": "^7.13.8",
"@babel/helper-module-transforms": "^7.13.0",
"@babel/helpers": "^7.13.0",
"@babel/parser": "^7.13.0",
"@babel/parser": "^7.13.4",
"@babel/template": "^7.12.13",
"@babel/traverse": "^7.13.0",
"@babel/types": "^7.13.0",
@ -86,7 +87,7 @@
"gensync": "^1.0.0-beta.2",
"json5": "^2.1.2",
"lodash": "^4.17.19",
"semver": "7.0.0",
"semver": "^6.3.0",
"source-map": "^0.5.0"
},
"engines": {
@ -97,6 +98,15 @@
"url": "https://opencollective.com/babel"
}
},
"node_modules/@babel/core/node_modules/semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/@babel/generator": {
"version": "7.13.0",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.0.tgz",
@ -128,20 +138,29 @@
}
},
"node_modules/@babel/helper-compilation-targets": {
"version": "7.13.0",
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.0.tgz",
"integrity": "sha512-SOWD0JK9+MMIhTQiUVd4ng8f3NXhPVQvTv7D3UN4wbp/6cAHnB2EmMaU1zZA2Hh1gwme+THBrVSqTFxHczTh0Q==",
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.8.tgz",
"integrity": "sha512-pBljUGC1y3xKLn1nrx2eAhurLMA8OqBtBP/JwG4U8skN7kf8/aqwwxpV1N6T0e7r6+7uNitIa/fUxPFagSXp3A==",
"dev": true,
"dependencies": {
"@babel/compat-data": "^7.13.0",
"@babel/compat-data": "^7.13.8",
"@babel/helper-validator-option": "^7.12.17",
"browserslist": "^4.14.5",
"semver": "7.0.0"
"semver": "^6.3.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0"
}
},
"node_modules/@babel/helper-compilation-targets/node_modules/semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/@babel/helper-create-class-features-plugin": {
"version": "7.13.0",
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.0.tgz",
@ -397,14 +416,14 @@
}
},
"node_modules/@babel/plugin-proposal-async-generator-functions": {
"version": "7.13.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.5.tgz",
"integrity": "sha512-8cErJEDzhZgNKzYyjCKsHuyPqtWxG8gc9h4OFSUDJu0vCAOsObPU2LcECnW0kJwh/b+uUz46lObVzIXw0fzAbA==",
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.8.tgz",
"integrity": "sha512-rPBnhj+WgoSmgq+4gQUtXx/vOcU+UYtjy1AA/aeD61Hwj410fwYyqfUcRP3lR8ucgliVJL/G7sXcNUecC75IXA==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.13.0",
"@babel/helper-remap-async-to-generator": "^7.13.0",
"@babel/plugin-syntax-async-generators": "^7.8.0"
"@babel/plugin-syntax-async-generators": "^7.8.4"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
@ -424,13 +443,13 @@
}
},
"node_modules/@babel/plugin-proposal-dynamic-import": {
"version": "7.12.17",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.17.tgz",
"integrity": "sha512-ZNGoFZqrnuy9H2izB2jLlnNDAfVPlGl5NhFEiFe4D84ix9GQGygF+CWMGHKuE+bpyS/AOuDQCnkiRNqW2IzS1Q==",
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz",
"integrity": "sha512-ONWKj0H6+wIRCkZi9zSbZtE/r73uOhMVHh256ys0UzfM7I3d4n+spZNWjOnJv2gzopumP2Wxi186vI8N0Y2JyQ==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.12.13",
"@babel/plugin-syntax-dynamic-import": "^7.8.0"
"@babel/helper-plugin-utils": "^7.13.0",
"@babel/plugin-syntax-dynamic-import": "^7.8.3"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
@ -450,25 +469,25 @@
}
},
"node_modules/@babel/plugin-proposal-json-strings": {
"version": "7.12.13",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.13.tgz",
"integrity": "sha512-v9eEi4GiORDg8x+Dmi5r8ibOe0VXoKDeNPYcTTxdGN4eOWikrJfDJCJrr1l5gKGvsNyGJbrfMftC2dTL6oz7pg==",
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.13.8.tgz",
"integrity": "sha512-w4zOPKUFPX1mgvTmL/fcEqy34hrQ1CRcGxdphBc6snDnnqJ47EZDIyop6IwXzAC8G916hsIuXB2ZMBCExC5k7Q==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.12.13",
"@babel/plugin-syntax-json-strings": "^7.8.0"
"@babel/helper-plugin-utils": "^7.13.0",
"@babel/plugin-syntax-json-strings": "^7.8.3"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@babel/plugin-proposal-logical-assignment-operators": {
"version": "7.12.13",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.13.tgz",
"integrity": "sha512-fqmiD3Lz7jVdK6kabeSr1PZlWSUVqSitmHEe3Z00dtGTKieWnX9beafvavc32kjORa5Bai4QNHgFDwWJP+WtSQ==",
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz",
"integrity": "sha512-aul6znYB4N4HGweImqKn59Su9RS8lbUIqxtXTOcAGtNIDczoEFv+l1EhmX8rUBp3G1jMjKJm8m0jXVp63ZpS4A==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.12.13",
"@babel/helper-plugin-utils": "^7.13.0",
"@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
},
"peerDependencies": {
@ -476,13 +495,13 @@
}
},
"node_modules/@babel/plugin-proposal-nullish-coalescing-operator": {
"version": "7.13.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.0.tgz",
"integrity": "sha512-UkAvFA/9+lBBL015gjA68NvKiCReNxqFLm3SdNKaM3XXoDisA7tMAIX4PmIwatFoFqMxxT3WyG9sK3MO0Kting==",
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz",
"integrity": "sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.13.0",
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0"
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
@ -502,13 +521,15 @@
}
},
"node_modules/@babel/plugin-proposal-object-rest-spread": {
"version": "7.13.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.0.tgz",
"integrity": "sha512-B4qphdSTp0nLsWcuei07JPKeZej4+Hd22MdnulJXQa1nCcGSBlk8FiqenGERaPZ+PuYhz4Li2Wjc8yfJvHgUMw==",
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.8.tgz",
"integrity": "sha512-DhB2EuB1Ih7S3/IRX5AFVgZ16k3EzfRbq97CxAVI1KSYcW+lexV8VZb7G7L8zuPVSdQMRn0kiBpf/Yzu9ZKH0g==",
"dev": true,
"dependencies": {
"@babel/compat-data": "^7.13.8",
"@babel/helper-compilation-targets": "^7.13.8",
"@babel/helper-plugin-utils": "^7.13.0",
"@babel/plugin-syntax-object-rest-spread": "^7.8.0",
"@babel/plugin-syntax-object-rest-spread": "^7.8.3",
"@babel/plugin-transform-parameters": "^7.13.0"
},
"peerDependencies": {
@ -516,27 +537,27 @@
}
},
"node_modules/@babel/plugin-proposal-optional-catch-binding": {
"version": "7.12.13",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.13.tgz",
"integrity": "sha512-9+MIm6msl9sHWg58NvqpNpLtuFbmpFYk37x8kgnGzAHvX35E1FyAwSUt5hIkSoWJFSAH+iwU8bJ4fcD1zKXOzg==",
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.13.8.tgz",
"integrity": "sha512-0wS/4DUF1CuTmGo+NiaHfHcVSeSLj5S3e6RivPTg/2k3wOv3jO35tZ6/ZWsQhQMvdgI7CwphjQa/ccarLymHVA==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.12.13",
"@babel/plugin-syntax-optional-catch-binding": "^7.8.0"
"@babel/helper-plugin-utils": "^7.13.0",
"@babel/plugin-syntax-optional-catch-binding": "^7.8.3"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@babel/plugin-proposal-optional-chaining": {
"version": "7.13.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.0.tgz",
"integrity": "sha512-OVRQOZEBP2luZrvEbNSX5FfWDousthhdEoAOpej+Tpe58HFLvqRClT89RauIvBuCDFEip7GW1eT86/5lMy2RNA==",
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.8.tgz",
"integrity": "sha512-hpbBwbTgd7Cz1QryvwJZRo1U0k1q8uyBmeXOSQUjdg/A2TASkhR/rz7AyqZ/kS8kbpsNA80rOYbxySBJAqmhhQ==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.13.0",
"@babel/helper-skip-transparent-expression-wrappers": "^7.12.1",
"@babel/plugin-syntax-optional-chaining": "^7.8.0"
"@babel/plugin-syntax-optional-chaining": "^7.8.3"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
@ -909,9 +930,9 @@
}
},
"node_modules/@babel/plugin-transform-modules-commonjs": {
"version": "7.13.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.13.0.tgz",
"integrity": "sha512-j7397PkIB4lcn25U2dClK6VLC6pr2s3q+wbE8R3vJvY6U1UTBBj0n6F+5v6+Fd/UwfDPAorMOs2TV+T4M+owpQ==",
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.13.8.tgz",
"integrity": "sha512-9QiOx4MEGglfYZ4XOnU79OHr6vIWUakIj9b4mioN8eQIoEh+pf5p/zEB36JpDFWA12nNMiRf7bfoRvl9Rn79Bw==",
"dev": true,
"dependencies": {
"@babel/helper-module-transforms": "^7.13.0",
@ -924,14 +945,14 @@
}
},
"node_modules/@babel/plugin-transform-modules-systemjs": {
"version": "7.12.13",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.13.tgz",
"integrity": "sha512-aHfVjhZ8QekaNF/5aNdStCGzwTbU7SI5hUybBKlMzqIMC7w7Ho8hx5a4R/DkTHfRfLwHGGxSpFt9BfxKCoXKoA==",
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz",
"integrity": "sha512-hwqctPYjhM6cWvVIlOIe27jCIBgHCsdH2xCJVAYQm7V5yTMoilbVMi9f6wKg0rpQAOn6ZG4AOyvCqFF/hUh6+A==",
"dev": true,
"dependencies": {
"@babel/helper-hoist-variables": "^7.12.13",
"@babel/helper-module-transforms": "^7.12.13",
"@babel/helper-plugin-utils": "^7.12.13",
"@babel/helper-hoist-variables": "^7.13.0",
"@babel/helper-module-transforms": "^7.13.0",
"@babel/helper-plugin-utils": "^7.13.0",
"@babel/helper-validator-identifier": "^7.12.11",
"babel-plugin-dynamic-import-node": "^2.3.3"
},
@ -1124,39 +1145,39 @@
}
},
"node_modules/@babel/preset-env": {
"version": "7.13.5",
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.13.5.tgz",
"integrity": "sha512-xUeKBIIcbwxGevyWMSWZOW98W1lp7toITvVsMxSddCEQy932yYiF4fCB+CG3E/MXzFX3KbefgvCqEQ7TDoE6UQ==",
"version": "7.13.9",
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.13.9.tgz",
"integrity": "sha512-mcsHUlh2rIhViqMG823JpscLMesRt3QbMsv1+jhopXEb3W2wXvQ9QoiOlZI9ZbR3XqPtaFpZwEZKYqGJnGMZTQ==",
"dev": true,
"dependencies": {
"@babel/compat-data": "^7.13.5",
"@babel/helper-compilation-targets": "^7.13.0",
"@babel/compat-data": "^7.13.8",
"@babel/helper-compilation-targets": "^7.13.8",
"@babel/helper-plugin-utils": "^7.13.0",
"@babel/helper-validator-option": "^7.12.17",
"@babel/plugin-proposal-async-generator-functions": "^7.13.5",
"@babel/plugin-proposal-async-generator-functions": "^7.13.8",
"@babel/plugin-proposal-class-properties": "^7.13.0",
"@babel/plugin-proposal-dynamic-import": "^7.12.17",
"@babel/plugin-proposal-dynamic-import": "^7.13.8",
"@babel/plugin-proposal-export-namespace-from": "^7.12.13",
"@babel/plugin-proposal-json-strings": "^7.12.13",
"@babel/plugin-proposal-logical-assignment-operators": "^7.12.13",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.0",
"@babel/plugin-proposal-json-strings": "^7.13.8",
"@babel/plugin-proposal-logical-assignment-operators": "^7.13.8",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8",
"@babel/plugin-proposal-numeric-separator": "^7.12.13",
"@babel/plugin-proposal-object-rest-spread": "^7.13.0",
"@babel/plugin-proposal-optional-catch-binding": "^7.12.13",
"@babel/plugin-proposal-optional-chaining": "^7.13.0",
"@babel/plugin-proposal-object-rest-spread": "^7.13.8",
"@babel/plugin-proposal-optional-catch-binding": "^7.13.8",
"@babel/plugin-proposal-optional-chaining": "^7.13.8",
"@babel/plugin-proposal-private-methods": "^7.13.0",
"@babel/plugin-proposal-unicode-property-regex": "^7.12.13",
"@babel/plugin-syntax-async-generators": "^7.8.0",
"@babel/plugin-syntax-async-generators": "^7.8.4",
"@babel/plugin-syntax-class-properties": "^7.12.13",
"@babel/plugin-syntax-dynamic-import": "^7.8.0",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-syntax-export-namespace-from": "^7.8.3",
"@babel/plugin-syntax-json-strings": "^7.8.0",
"@babel/plugin-syntax-json-strings": "^7.8.3",
"@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0",
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
"@babel/plugin-syntax-numeric-separator": "^7.10.4",
"@babel/plugin-syntax-object-rest-spread": "^7.8.0",
"@babel/plugin-syntax-optional-catch-binding": "^7.8.0",
"@babel/plugin-syntax-optional-chaining": "^7.8.0",
"@babel/plugin-syntax-object-rest-spread": "^7.8.3",
"@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
"@babel/plugin-syntax-optional-chaining": "^7.8.3",
"@babel/plugin-syntax-top-level-await": "^7.12.13",
"@babel/plugin-transform-arrow-functions": "^7.13.0",
"@babel/plugin-transform-async-to-generator": "^7.13.0",
@ -1173,8 +1194,8 @@
"@babel/plugin-transform-literals": "^7.12.13",
"@babel/plugin-transform-member-expression-literals": "^7.12.13",
"@babel/plugin-transform-modules-amd": "^7.13.0",
"@babel/plugin-transform-modules-commonjs": "^7.13.0",
"@babel/plugin-transform-modules-systemjs": "^7.12.13",
"@babel/plugin-transform-modules-commonjs": "^7.13.8",
"@babel/plugin-transform-modules-systemjs": "^7.13.8",
"@babel/plugin-transform-modules-umd": "^7.13.0",
"@babel/plugin-transform-named-capturing-groups-regex": "^7.12.13",
"@babel/plugin-transform-new-target": "^7.12.13",
@ -1190,18 +1211,27 @@
"@babel/plugin-transform-typeof-symbol": "^7.12.13",
"@babel/plugin-transform-unicode-escapes": "^7.12.13",
"@babel/plugin-transform-unicode-regex": "^7.12.13",
"@babel/preset-modules": "^0.1.3",
"@babel/preset-modules": "^0.1.4",
"@babel/types": "^7.13.0",
"babel-plugin-polyfill-corejs2": "^0.1.4",
"babel-plugin-polyfill-corejs3": "^0.1.3",
"babel-plugin-polyfill-regenerator": "^0.1.2",
"core-js-compat": "^3.9.0",
"semver": "7.0.0"
"semver": "^6.3.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@babel/preset-env/node_modules/semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/@babel/preset-modules": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz",
@ -1334,9 +1364,9 @@
}
},
"node_modules/@popperjs/core": {
"version": "2.8.4",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.8.4.tgz",
"integrity": "sha512-h0lY7g36rhjNV8KVHKS3/BEOgfsxu0AiRI8+ry5IFBGEsQFkpjxtcpVc9ndN8zrKUeMZXAWMc7eQMepfgykpxQ==",
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.9.0.tgz",
"integrity": "sha512-wjtKehFAIARq2OxK8j3JrggNlEslJfNuSm2ArteIbKyRMts2g0a7KzTxfRVNUM+O0gnBJ2hNV8nWPOYBgI1sew==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/popperjs"
@ -1642,6 +1672,11 @@
"integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=",
"dev": true
},
"node_modules/alpinejs": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-2.8.1.tgz",
"integrity": "sha512-ETJ/k0fbiBeP+OSd5Fhj70c+zb+YRzcVbyh5DVeLT3FBWMUeUvjOSWLi53IVLPSehaT2SKmB7w08WGF2jYTqNA=="
},
"node_modules/ansi-colors": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
@ -2583,9 +2618,9 @@
}
},
"node_modules/css-loader": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.1.0.tgz",
"integrity": "sha512-mFs3Xe2UrzRzL0+ML6e7Q2e/Ozp/WpDcam0l1X+rXgkuFjjsNSrjiyimG6malUOZGVuEjzKp1NqEqN3exG7ZqQ==",
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.1.1.tgz",
"integrity": "sha512-5FfhpjwtuRgxqmusDidowqmLlcb+1HgnEDMsi2JhiUrZUcoc+cqw+mUtMIF/+OfeMYaaFCLYp1TaIt9H6I/fKA==",
"dev": true,
"dependencies": {
"camelcase": "^6.2.0",
@ -4856,9 +4891,9 @@
}
},
"node_modules/mini-css-extract-plugin": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.3.8.tgz",
"integrity": "sha512-u+2kVov/Gcs74iz+x3phEBWMAGw2djjnKfYez+Pl/b5dyXL7aM4Lp5QQtIq16CDwRHT/woUJki49gBNMhfm1eA==",
"version": "1.3.9",
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.3.9.tgz",
"integrity": "sha512-Ac4s+xhVbqlyhXS5J/Vh/QXUz3ycXlCqoCPpg0vdfhsIBH9eg/It/9L1r1XhSCH737M1lqcWnMuWL13zcygn5A==",
"dev": true,
"dependencies": {
"loader-utils": "^2.0.0",
@ -9798,23 +9833,23 @@
}
},
"@babel/compat-data": {
"version": "7.13.6",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.6.tgz",
"integrity": "sha512-VhgqKOWYVm7lQXlvbJnWOzwfAQATd2nV52koT0HZ/LdDH0m4DUDwkKYsH+IwpXb+bKPyBJzawA4I6nBKqZcpQw==",
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.8.tgz",
"integrity": "sha512-EaI33z19T4qN3xLXsGf48M2cDqa6ei9tPZlfLdb2HC+e/cFtREiRd8hdSqDbwdLB0/+gLwqJmCYASH0z2bUdog==",
"dev": true
},
"@babel/core": {
"version": "7.13.1",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.1.tgz",
"integrity": "sha512-FzeKfFBG2rmFtGiiMdXZPFt/5R5DXubVi82uYhjGX4Msf+pgYQMCFIqFXZWs5vbIYbf14VeBIgdGI03CDOOM1w==",
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.8.tgz",
"integrity": "sha512-oYapIySGw1zGhEFRd6lzWNLWFX2s5dA/jm+Pw/+59ZdXtjyIuwlXbrId22Md0rgZVop+aVoqow2riXhBLNyuQg==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.12.13",
"@babel/generator": "^7.13.0",
"@babel/helper-compilation-targets": "^7.13.0",
"@babel/helper-compilation-targets": "^7.13.8",
"@babel/helper-module-transforms": "^7.13.0",
"@babel/helpers": "^7.13.0",
"@babel/parser": "^7.13.0",
"@babel/parser": "^7.13.4",
"@babel/template": "^7.12.13",
"@babel/traverse": "^7.13.0",
"@babel/types": "^7.13.0",
@ -9823,8 +9858,16 @@
"gensync": "^1.0.0-beta.2",
"json5": "^2.1.2",
"lodash": "^4.17.19",
"semver": "7.0.0",
"semver": "^6.3.0",
"source-map": "^0.5.0"
},
"dependencies": {
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
}
}
},
"@babel/generator": {
@ -9858,15 +9901,23 @@
}
},
"@babel/helper-compilation-targets": {
"version": "7.13.0",
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.0.tgz",
"integrity": "sha512-SOWD0JK9+MMIhTQiUVd4ng8f3NXhPVQvTv7D3UN4wbp/6cAHnB2EmMaU1zZA2Hh1gwme+THBrVSqTFxHczTh0Q==",
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.8.tgz",
"integrity": "sha512-pBljUGC1y3xKLn1nrx2eAhurLMA8OqBtBP/JwG4U8skN7kf8/aqwwxpV1N6T0e7r6+7uNitIa/fUxPFagSXp3A==",
"dev": true,
"requires": {
"@babel/compat-data": "^7.13.0",
"@babel/compat-data": "^7.13.8",
"@babel/helper-validator-option": "^7.12.17",
"browserslist": "^4.14.5",
"semver": "7.0.0"
"semver": "^6.3.0"
},
"dependencies": {
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
}
}
},
"@babel/helper-create-class-features-plugin": {
@ -10108,14 +10159,14 @@
"dev": true
},
"@babel/plugin-proposal-async-generator-functions": {
"version": "7.13.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.5.tgz",
"integrity": "sha512-8cErJEDzhZgNKzYyjCKsHuyPqtWxG8gc9h4OFSUDJu0vCAOsObPU2LcECnW0kJwh/b+uUz46lObVzIXw0fzAbA==",
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.8.tgz",
"integrity": "sha512-rPBnhj+WgoSmgq+4gQUtXx/vOcU+UYtjy1AA/aeD61Hwj410fwYyqfUcRP3lR8ucgliVJL/G7sXcNUecC75IXA==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.13.0",
"@babel/helper-remap-async-to-generator": "^7.13.0",
"@babel/plugin-syntax-async-generators": "^7.8.0"
"@babel/plugin-syntax-async-generators": "^7.8.4"
}
},
"@babel/plugin-proposal-class-properties": {
@ -10129,13 +10180,13 @@
}
},
"@babel/plugin-proposal-dynamic-import": {
"version": "7.12.17",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.17.tgz",
"integrity": "sha512-ZNGoFZqrnuy9H2izB2jLlnNDAfVPlGl5NhFEiFe4D84ix9GQGygF+CWMGHKuE+bpyS/AOuDQCnkiRNqW2IzS1Q==",
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz",
"integrity": "sha512-ONWKj0H6+wIRCkZi9zSbZtE/r73uOhMVHh256ys0UzfM7I3d4n+spZNWjOnJv2gzopumP2Wxi186vI8N0Y2JyQ==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.12.13",
"@babel/plugin-syntax-dynamic-import": "^7.8.0"
"@babel/helper-plugin-utils": "^7.13.0",
"@babel/plugin-syntax-dynamic-import": "^7.8.3"
}
},
"@babel/plugin-proposal-export-namespace-from": {
@ -10149,33 +10200,33 @@
}
},
"@babel/plugin-proposal-json-strings": {
"version": "7.12.13",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.13.tgz",
"integrity": "sha512-v9eEi4GiORDg8x+Dmi5r8ibOe0VXoKDeNPYcTTxdGN4eOWikrJfDJCJrr1l5gKGvsNyGJbrfMftC2dTL6oz7pg==",
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.13.8.tgz",
"integrity": "sha512-w4zOPKUFPX1mgvTmL/fcEqy34hrQ1CRcGxdphBc6snDnnqJ47EZDIyop6IwXzAC8G916hsIuXB2ZMBCExC5k7Q==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.12.13",
"@babel/plugin-syntax-json-strings": "^7.8.0"
"@babel/helper-plugin-utils": "^7.13.0",
"@babel/plugin-syntax-json-strings": "^7.8.3"
}
},
"@babel/plugin-proposal-logical-assignment-operators": {
"version": "7.12.13",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.13.tgz",
"integrity": "sha512-fqmiD3Lz7jVdK6kabeSr1PZlWSUVqSitmHEe3Z00dtGTKieWnX9beafvavc32kjORa5Bai4QNHgFDwWJP+WtSQ==",
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz",
"integrity": "sha512-aul6znYB4N4HGweImqKn59Su9RS8lbUIqxtXTOcAGtNIDczoEFv+l1EhmX8rUBp3G1jMjKJm8m0jXVp63ZpS4A==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.12.13",
"@babel/helper-plugin-utils": "^7.13.0",
"@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
}
},
"@babel/plugin-proposal-nullish-coalescing-operator": {
"version": "7.13.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.0.tgz",
"integrity": "sha512-UkAvFA/9+lBBL015gjA68NvKiCReNxqFLm3SdNKaM3XXoDisA7tMAIX4PmIwatFoFqMxxT3WyG9sK3MO0Kting==",
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz",
"integrity": "sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.13.0",
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0"
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3"
}
},
"@babel/plugin-proposal-numeric-separator": {
@ -10189,35 +10240,37 @@
}
},
"@babel/plugin-proposal-object-rest-spread": {
"version": "7.13.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.0.tgz",
"integrity": "sha512-B4qphdSTp0nLsWcuei07JPKeZej4+Hd22MdnulJXQa1nCcGSBlk8FiqenGERaPZ+PuYhz4Li2Wjc8yfJvHgUMw==",
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.8.tgz",
"integrity": "sha512-DhB2EuB1Ih7S3/IRX5AFVgZ16k3EzfRbq97CxAVI1KSYcW+lexV8VZb7G7L8zuPVSdQMRn0kiBpf/Yzu9ZKH0g==",
"dev": true,
"requires": {
"@babel/compat-data": "^7.13.8",
"@babel/helper-compilation-targets": "^7.13.8",
"@babel/helper-plugin-utils": "^7.13.0",
"@babel/plugin-syntax-object-rest-spread": "^7.8.0",
"@babel/plugin-syntax-object-rest-spread": "^7.8.3",
"@babel/plugin-transform-parameters": "^7.13.0"
}
},
"@babel/plugin-proposal-optional-catch-binding": {
"version": "7.12.13",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.13.tgz",
"integrity": "sha512-9+MIm6msl9sHWg58NvqpNpLtuFbmpFYk37x8kgnGzAHvX35E1FyAwSUt5hIkSoWJFSAH+iwU8bJ4fcD1zKXOzg==",
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.13.8.tgz",
"integrity": "sha512-0wS/4DUF1CuTmGo+NiaHfHcVSeSLj5S3e6RivPTg/2k3wOv3jO35tZ6/ZWsQhQMvdgI7CwphjQa/ccarLymHVA==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.12.13",
"@babel/plugin-syntax-optional-catch-binding": "^7.8.0"
"@babel/helper-plugin-utils": "^7.13.0",
"@babel/plugin-syntax-optional-catch-binding": "^7.8.3"
}
},
"@babel/plugin-proposal-optional-chaining": {
"version": "7.13.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.0.tgz",
"integrity": "sha512-OVRQOZEBP2luZrvEbNSX5FfWDousthhdEoAOpej+Tpe58HFLvqRClT89RauIvBuCDFEip7GW1eT86/5lMy2RNA==",
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.8.tgz",
"integrity": "sha512-hpbBwbTgd7Cz1QryvwJZRo1U0k1q8uyBmeXOSQUjdg/A2TASkhR/rz7AyqZ/kS8kbpsNA80rOYbxySBJAqmhhQ==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.13.0",
"@babel/helper-skip-transparent-expression-wrappers": "^7.12.1",
"@babel/plugin-syntax-optional-chaining": "^7.8.0"
"@babel/plugin-syntax-optional-chaining": "^7.8.3"
}
},
"@babel/plugin-proposal-private-methods": {
@ -10497,9 +10550,9 @@
}
},
"@babel/plugin-transform-modules-commonjs": {
"version": "7.13.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.13.0.tgz",
"integrity": "sha512-j7397PkIB4lcn25U2dClK6VLC6pr2s3q+wbE8R3vJvY6U1UTBBj0n6F+5v6+Fd/UwfDPAorMOs2TV+T4M+owpQ==",
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.13.8.tgz",
"integrity": "sha512-9QiOx4MEGglfYZ4XOnU79OHr6vIWUakIj9b4mioN8eQIoEh+pf5p/zEB36JpDFWA12nNMiRf7bfoRvl9Rn79Bw==",
"dev": true,
"requires": {
"@babel/helper-module-transforms": "^7.13.0",
@ -10509,14 +10562,14 @@
}
},
"@babel/plugin-transform-modules-systemjs": {
"version": "7.12.13",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.13.tgz",
"integrity": "sha512-aHfVjhZ8QekaNF/5aNdStCGzwTbU7SI5hUybBKlMzqIMC7w7Ho8hx5a4R/DkTHfRfLwHGGxSpFt9BfxKCoXKoA==",
"version": "7.13.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz",
"integrity": "sha512-hwqctPYjhM6cWvVIlOIe27jCIBgHCsdH2xCJVAYQm7V5yTMoilbVMi9f6wKg0rpQAOn6ZG4AOyvCqFF/hUh6+A==",
"dev": true,
"requires": {
"@babel/helper-hoist-variables": "^7.12.13",
"@babel/helper-module-transforms": "^7.12.13",
"@babel/helper-plugin-utils": "^7.12.13",
"@babel/helper-hoist-variables": "^7.13.0",
"@babel/helper-module-transforms": "^7.13.0",
"@babel/helper-plugin-utils": "^7.13.0",
"@babel/helper-validator-identifier": "^7.12.11",
"babel-plugin-dynamic-import-node": "^2.3.3"
}
@ -10661,39 +10714,39 @@
}
},
"@babel/preset-env": {
"version": "7.13.5",
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.13.5.tgz",
"integrity": "sha512-xUeKBIIcbwxGevyWMSWZOW98W1lp7toITvVsMxSddCEQy932yYiF4fCB+CG3E/MXzFX3KbefgvCqEQ7TDoE6UQ==",
"version": "7.13.9",
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.13.9.tgz",
"integrity": "sha512-mcsHUlh2rIhViqMG823JpscLMesRt3QbMsv1+jhopXEb3W2wXvQ9QoiOlZI9ZbR3XqPtaFpZwEZKYqGJnGMZTQ==",
"dev": true,
"requires": {
"@babel/compat-data": "^7.13.5",
"@babel/helper-compilation-targets": "^7.13.0",
"@babel/compat-data": "^7.13.8",
"@babel/helper-compilation-targets": "^7.13.8",
"@babel/helper-plugin-utils": "^7.13.0",
"@babel/helper-validator-option": "^7.12.17",
"@babel/plugin-proposal-async-generator-functions": "^7.13.5",
"@babel/plugin-proposal-async-generator-functions": "^7.13.8",
"@babel/plugin-proposal-class-properties": "^7.13.0",
"@babel/plugin-proposal-dynamic-import": "^7.12.17",
"@babel/plugin-proposal-dynamic-import": "^7.13.8",
"@babel/plugin-proposal-export-namespace-from": "^7.12.13",
"@babel/plugin-proposal-json-strings": "^7.12.13",
"@babel/plugin-proposal-logical-assignment-operators": "^7.12.13",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.0",
"@babel/plugin-proposal-json-strings": "^7.13.8",
"@babel/plugin-proposal-logical-assignment-operators": "^7.13.8",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8",
"@babel/plugin-proposal-numeric-separator": "^7.12.13",
"@babel/plugin-proposal-object-rest-spread": "^7.13.0",
"@babel/plugin-proposal-optional-catch-binding": "^7.12.13",
"@babel/plugin-proposal-optional-chaining": "^7.13.0",
"@babel/plugin-proposal-object-rest-spread": "^7.13.8",
"@babel/plugin-proposal-optional-catch-binding": "^7.13.8",
"@babel/plugin-proposal-optional-chaining": "^7.13.8",
"@babel/plugin-proposal-private-methods": "^7.13.0",
"@babel/plugin-proposal-unicode-property-regex": "^7.12.13",
"@babel/plugin-syntax-async-generators": "^7.8.0",
"@babel/plugin-syntax-async-generators": "^7.8.4",
"@babel/plugin-syntax-class-properties": "^7.12.13",
"@babel/plugin-syntax-dynamic-import": "^7.8.0",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-syntax-export-namespace-from": "^7.8.3",
"@babel/plugin-syntax-json-strings": "^7.8.0",
"@babel/plugin-syntax-json-strings": "^7.8.3",
"@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0",
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
"@babel/plugin-syntax-numeric-separator": "^7.10.4",
"@babel/plugin-syntax-object-rest-spread": "^7.8.0",
"@babel/plugin-syntax-optional-catch-binding": "^7.8.0",
"@babel/plugin-syntax-optional-chaining": "^7.8.0",
"@babel/plugin-syntax-object-rest-spread": "^7.8.3",
"@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
"@babel/plugin-syntax-optional-chaining": "^7.8.3",
"@babel/plugin-syntax-top-level-await": "^7.12.13",
"@babel/plugin-transform-arrow-functions": "^7.13.0",
"@babel/plugin-transform-async-to-generator": "^7.13.0",
@ -10710,8 +10763,8 @@
"@babel/plugin-transform-literals": "^7.12.13",
"@babel/plugin-transform-member-expression-literals": "^7.12.13",
"@babel/plugin-transform-modules-amd": "^7.13.0",
"@babel/plugin-transform-modules-commonjs": "^7.13.0",
"@babel/plugin-transform-modules-systemjs": "^7.12.13",
"@babel/plugin-transform-modules-commonjs": "^7.13.8",
"@babel/plugin-transform-modules-systemjs": "^7.13.8",
"@babel/plugin-transform-modules-umd": "^7.13.0",
"@babel/plugin-transform-named-capturing-groups-regex": "^7.12.13",
"@babel/plugin-transform-new-target": "^7.12.13",
@ -10727,13 +10780,21 @@
"@babel/plugin-transform-typeof-symbol": "^7.12.13",
"@babel/plugin-transform-unicode-escapes": "^7.12.13",
"@babel/plugin-transform-unicode-regex": "^7.12.13",
"@babel/preset-modules": "^0.1.3",
"@babel/preset-modules": "^0.1.4",
"@babel/types": "^7.13.0",
"babel-plugin-polyfill-corejs2": "^0.1.4",
"babel-plugin-polyfill-corejs3": "^0.1.3",
"babel-plugin-polyfill-regenerator": "^0.1.2",
"core-js-compat": "^3.9.0",
"semver": "7.0.0"
"semver": "^6.3.0"
},
"dependencies": {
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
}
}
},
"@babel/preset-modules": {
@ -10850,9 +10911,9 @@
}
},
"@popperjs/core": {
"version": "2.8.4",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.8.4.tgz",
"integrity": "sha512-h0lY7g36rhjNV8KVHKS3/BEOgfsxu0AiRI8+ry5IFBGEsQFkpjxtcpVc9ndN8zrKUeMZXAWMc7eQMepfgykpxQ=="
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.9.0.tgz",
"integrity": "sha512-wjtKehFAIARq2OxK8j3JrggNlEslJfNuSm2ArteIbKyRMts2g0a7KzTxfRVNUM+O0gnBJ2hNV8nWPOYBgI1sew=="
},
"@types/eslint": {
"version": "7.2.6",
@ -11126,6 +11187,11 @@
"integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=",
"dev": true
},
"alpinejs": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-2.8.1.tgz",
"integrity": "sha512-ETJ/k0fbiBeP+OSd5Fhj70c+zb+YRzcVbyh5DVeLT3FBWMUeUvjOSWLi53IVLPSehaT2SKmB7w08WGF2jYTqNA=="
},
"ansi-colors": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
@ -11850,9 +11916,9 @@
}
},
"css-loader": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.1.0.tgz",
"integrity": "sha512-mFs3Xe2UrzRzL0+ML6e7Q2e/Ozp/WpDcam0l1X+rXgkuFjjsNSrjiyimG6malUOZGVuEjzKp1NqEqN3exG7ZqQ==",
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.1.1.tgz",
"integrity": "sha512-5FfhpjwtuRgxqmusDidowqmLlcb+1HgnEDMsi2JhiUrZUcoc+cqw+mUtMIF/+OfeMYaaFCLYp1TaIt9H6I/fKA==",
"dev": true,
"requires": {
"camelcase": "^6.2.0",
@ -13572,9 +13638,9 @@
"dev": true
},
"mini-css-extract-plugin": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.3.8.tgz",
"integrity": "sha512-u+2kVov/Gcs74iz+x3phEBWMAGw2djjnKfYez+Pl/b5dyXL7aM4Lp5QQtIq16CDwRHT/woUJki49gBNMhfm1eA==",
"version": "1.3.9",
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.3.9.tgz",
"integrity": "sha512-Ac4s+xhVbqlyhXS5J/Vh/QXUz3ycXlCqoCPpg0vdfhsIBH9eg/It/9L1r1XhSCH737M1lqcWnMuWL13zcygn5A==",
"dev": true,
"requires": {
"loader-utils": "^2.0.0",

View File

@ -10,6 +10,7 @@
"@fontsource/lato": "^4.2.1",
"@mdi/svg": "^5.9.55",
"@popperjs/core": "^2.8.4",
"alpinejs": "^2.8.1",
"bootstrap": "^5.0.0-beta2",
"bootstrap-icons": "^1.4.0",
"hamburgers": "^1.1.3",

View File

@ -4,16 +4,26 @@ defmodule Bones73kWeb.ModalComponent do
@impl true
def render(assigns) do
~L"""
<div id="<%= @id %>" class="phx-modal"
phx-capture-click="close"
phx-window-keydown="close"
<div id="<%= @id %>" class="modal fade"
phx-hook="BsModal"
phx-window-keydown="hide"
phx-key="escape"
phx-target="#<%= @id %>"
phx-page-loading>
<div class="phx-modal-content">
<%= live_patch raw("&times;"), to: @return_to, class: "phx-modal-close" %>
<%= live_component @socket, @component, @opts %>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><%= Keyword.get(@opts, :title, "Modal title") %></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<%= live_component @socket, @component, @opts %>
</div>
</div>
</div>
</div>
"""
@ -23,4 +33,9 @@ defmodule Bones73kWeb.ModalComponent do
def handle_event("close", _, socket) do
{:noreply, push_patch(socket, to: socket.assigns.return_to)}
end
@impl true
def handle_event("hide", _, socket) do
{:noreply, push_event(socket, "modal-please-hide", %{})}
end
end

View File

@ -5,12 +5,10 @@ defmodule Bones73kWeb.PropertyLive.FormComponent do
@impl true
def update(%{property: property} = assigns, socket) do
changeset = Properties.change_property(property)
{:ok,
socket
|> assign(assigns)
|> assign(:changeset, changeset)}
socket
|> assign(assigns)
|> assign(:changeset, Properties.change_property(property))
|> live_okreply()
end
@impl true
@ -30,10 +28,10 @@ defmodule Bones73kWeb.PropertyLive.FormComponent do
defp save_property(socket, :edit, property_params) do
case Properties.update_property(socket.assigns.property, property_params) do
{:ok, _property} ->
{:noreply,
socket
|> put_flash(:info, "Property updated successfully")
|> push_redirect(to: socket.assigns.return_to)}
socket
|> put_flash(:info, "Property updated successfully")
|> push_event("modal-please-hide", %{})
|> live_noreply()
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, :changeset, changeset)}
@ -46,10 +44,10 @@ defmodule Bones73kWeb.PropertyLive.FormComponent do
case Properties.create_property(property_params) do
{:ok, _property} ->
{:noreply,
socket
|> put_flash(:info, "Property created successfully")
|> push_redirect(to: socket.assigns.return_to)}
socket
|> put_flash(:info, "Property created successfully")
|> push_event("modal-please-hide", %{})
|> live_noreply()
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, changeset: changeset)}

View File

@ -1,22 +1,44 @@
<h2><%= @title %></h2>
<%= form_for @changeset, "#", [
phx_target: @myself,
phx_change: "validate",
phx_submit: "save"
], fn f -> %>
<%= f = form_for @changeset, "#",
id: "property-form",
phx_target: @myself,
phx_change: "validate",
phx_submit: "save" %>
<%= label f, :name %>
<%= text_input f, :name %>
<%= error_tag f, :name %>
<div class="mb-3" phx-feedback-for="<%= input_id(f, :name)%>">
<%= label f, :name, class: "form-label" %>
<div class="input-group has-validation">
<%= text_input f, :name,
class: input_class(f, :name, "form-control"),
aria_describedby: error_id(f, :name)
%>
<%= error_tag f, :name %>
</div>
</div>
<%= label f, :price %>
<%= number_input f, :price, step: "any" %>
<%= error_tag f, :price %>
<div class="mb-3" phx-feedback-for="<%= input_id(f, :price)%>">
<%= label f, :price, class: "form-label" %>
<div class="input-group has-validation">
<%= number_input f, :price,
class: input_class(f, :price, "form-control"),
step: "any",
aria_describedby: error_id(f, :price)
%>
<%= error_tag f, :price %>
</div>
</div>
<%= label f, :description %>
<%= textarea f, :description %>
<%= error_tag f, :description %>
<div class="mb-3" phx-feedback-for="<%= input_id(f, :description)%>">
<%= label f, :description, class: "form-label" %>
<div class="input-group has-validation">
<%= textarea f, :description,
class: input_class(f, :description, "form-control"),
aria_describedby: error_id(f, :description)
%>
<%= error_tag f, :description %>
</div>
</div>
<%= submit "Save", phx_disable_with: "Saving..." %>
</form>
<%= submit "Save", phx_disable_with: "Saving...", class: "btn btn-primary" %>
<% end %>

View File

@ -30,7 +30,7 @@ defmodule Bones73kWeb.UserLive.Registration do
@impl true
def handle_event("validate", %{"user" => user_params}, socket) do
cs = Accounts.change_user_registration(%User{}, user_params)
{:noreply, assign(socket, changeset: %{cs | action: :update})}
{:noreply, assign(socket, changeset: %{cs | action: :validate})}
end
@impl true

View File

@ -19,7 +19,7 @@ defmodule Bones73kWeb.UserLive.ResetPassword do
@impl true
def handle_event("validate", %{"user" => user_params}, socket) do
cs = Accounts.change_user_password(socket.assigns.user, user_params)
{:noreply, socket |> assign(changeset: %{cs | action: :update})}
{:noreply, socket |> assign(changeset: %{cs | action: :validate})}
end
def handle_event("save", %{"user" => user_params}, socket) do
@ -34,7 +34,7 @@ defmodule Bones73kWeb.UserLive.ResetPassword do
{:noreply,
socket
|> put_flash(:error, "Please check the errors below.")
|> assign(changeset: %{changeset | action: :update})}
|> assign(changeset: changeset)}
end
end
end

View File

@ -20,7 +20,7 @@ defmodule Bones73kWeb.UserLive.Settings.Email do
@impl true
def handle_event("validate", %{"user" => user_params}, socket) do
cs = get_changeset(socket.assigns.current_user, user_params)
{:noreply, assign(socket, changeset: %{cs | action: :update})}
{:noreply, assign(socket, changeset: %{cs | action: :validate})}
end
# user_settings_path GET /users/settings/confirm_email/:token Bones73kWeb.UserSettingsController :confirm_email

View File

@ -30,6 +30,7 @@
<%= icon_div @socket, "bi-lock", [class: "icon fs-5"] %>
</span>
<%= password_input f, :current_password,
value: input_value(f, :current_password),
class: "form-control",
required: true,
aria_describedby: error_id(f, :current_password)

View File

@ -30,7 +30,7 @@ defmodule Bones73kWeb.UserLive.Settings.Password do
@impl true
def handle_event("validate", %{"user" => user_params}, socket) do
cs = get_changeset(socket.assigns.current_user, user_params)
{:noreply, assign(socket, changeset: %{cs | action: :update})}
{:noreply, assign(socket, changeset: %{cs | action: :validate})}
end
@impl true

View File

@ -44,6 +44,7 @@
<%= icon_div @socket, "bi-lock", [class: "icon fs-5"] %>
</span>
<%= password_input f, :current_password,
value: input_value(f, :current_password),
class: "form-control",
required: true,
aria_describedby: error_id(f, :current_password)

View File

@ -11,27 +11,31 @@
<div class="border-4 border-dashed border-gray-200 rounded-lg h-96"></div>
</div> %>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptatibus dolore sunt quia aperiam sint id
reprehenderit? Dolore incidunt alias inventore accusantium nulla optio, ducimus eius aliquam hic, pariatur
voluptate distinctio.
Praesent velit justo, auctor ut nibh id, fermentum eleifend nunc. Cras sed purus dignissim, ornare elit et, ultrices elit. Sed quis neque consequat, laoreet ante a, hendrerit elit. Maecenas dapibus sed nulla vitae consectetur. Duis sollicitudin augue nisl, et rhoncus enim tempor at. Fusce scelerisque sollicitudin purus sit amet iaculis. Phasellus lacinia mi ut laoreet accumsan. Sed sagittis erat nec sem placerat, ut volutpat neque porttitor. Suspendisse tempor mauris vel mollis sagittis. In ut laoreet arcu. Duis sed felis in dui imperdiet luctus nec faucibus sem. Donec commodo urna ut enim fringilla, quis lacinia ligula malesuada. Quisque feugiat fermentum pretium. Integer sed porttitor lacus, sed bibendum diam. Aliquam dapibus neque et pharetra interdum.
</p>
<!-- /End replace -->
</div>
<%# <div class="columns is-centered">
<div class="column is-three-fifths">
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
Launch demo modal
</button>
<div class="title is-4">
<span>Other Page</span>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
Aliquam ultrices elit purus, eget dignissim orci pulvinar id. Curabitur tincidunt, ligula eu condimentum porttitor, nibh sapien scelerisque urna, nec cursus nisi nisi a neque. Mauris hendrerit orci blandit, suscipit ante nec, porttitor neque. Nunc.
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
<div class="subtitle">With a subtitle no less!</div>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptatibus dolore sunt quia aperiam sint id
reprehenderit? Dolore incidunt alias inventore accusantium nulla optio, ducimus eius aliquam hic, pariatur
voluptate distinctio.
</p>
</div>
</div> %>
</div>

View File

@ -30,37 +30,13 @@ defmodule Bones73kWeb.ErrorHelpers do
def error_id(input_id) when is_binary(input_id), do: "#{input_id}_feedback"
def input_class(form, field, classes \\ "") do
case field_status(form, field) do
:ok -> "#{classes} is-valid"
:error -> "#{classes} is-invalid"
_ -> classes
end
end
defp field_status(form, field) do
case field_has_data?(form, field) do
true ->
form.errors
|> Keyword.get_values(field)
|> Enum.empty?()
|> case do
true -> :ok
false -> :error
case form.source.action do
nil -> classes
_ ->
case Keyword.has_key?(form.errors, field) do
true -> "#{classes} is-invalid"
_ -> "#{classes} is-valid"
end
false ->
:default
end
end
defp field_has_data?(form, field) when is_atom(field),
do: field_has_data?(form, Atom.to_string(field))
defp field_has_data?(form, field) when is_binary(field) do
case Map.get(form.params, field) do
nil -> false
"" -> false
_ -> true
end
end