diff --git a/public/assets/css/modal.css b/public/assets/css/modal.css index 25ea816..5dfca60 100644 --- a/public/assets/css/modal.css +++ b/public/assets/css/modal.css @@ -6,11 +6,13 @@ body { body main .screen { transition: var(--transition) transform; + transition-delay: calc(var(--transition) / 2); } -body.modalActive main .screen { - transition: 300ms; - transform: scale(.9,.95); +body .modal.active ~ main .screen { + transition: var(--transition); + transition-delay: 1ms; + transform: scale(.95); opacity: .5; pointer-events: none; } @@ -31,11 +33,6 @@ body.modalActive main .screen { padding: var(--padding); } -.modal + .modal { - transition: var(--transition) backdrop-filter; - backdrop-filter: blur(5px); -} - .modal.active { pointer-events: all; background-color: rgba(var(--comp-inverted),.4); diff --git a/public/assets/css/style.css b/public/assets/css/style.css index 624edab..543df92 100644 --- a/public/assets/css/style.css +++ b/public/assets/css/style.css @@ -91,6 +91,10 @@ main.active { flex-direction: column; } +body.dark .screen.dark { + background-color: black; +} + .screen .content { box-sizing: border-box; padding: calc(var(--padding) * 1.5); diff --git a/public/assets/js/modules/Components.mjs b/public/assets/js/modules/Components.mjs index a7395a7..d026a59 100644 --- a/public/assets/js/modules/Components.mjs +++ b/public/assets/js/modules/Components.mjs @@ -5,10 +5,6 @@ class Component { constructor(tag) { this.element = document.createElement(tag); // Root element } - - getElement() { - return this.element; - } } // ⬇ UI Components ⬇ diff --git a/public/assets/js/modules/Debugging.mjs b/public/assets/js/modules/Debugging.mjs index 0780fca..e067b62 100644 --- a/public/assets/js/modules/Debugging.mjs +++ b/public/assets/js/modules/Debugging.mjs @@ -38,6 +38,20 @@ class Debug { card.open(); }); } + + invalidCard() { + const module = import("./Modals.mjs"); + const interactions = { + hello: () => { + console.log("Hello world"); + } + }; + + module.then(modals => { + const card = new modals.Card(interactions); + card.openPage("invalid_card"); + }); + } } export default window._debug = new Debug(); \ No newline at end of file diff --git a/public/assets/js/modules/Modals.mjs b/public/assets/js/modules/Modals.mjs index 0292c3a..9a3e03a 100644 --- a/public/assets/js/modules/Modals.mjs +++ b/public/assets/js/modules/Modals.mjs @@ -17,12 +17,13 @@ class Modal extends Interaction { super(interactions,element); this.element = this.applyTemplate(element); - document.body.appendChild(this.element); + this.element.close = () => this.close(); // Bind close to element prototype + document.body.insertAdjacentElement("afterbegin",this.element); } // Fetch page html from "assets/pages" async getPage(page) { - const url = `assets/pages/${page}.html`; + const url = `assets/pages/${page}`; const response = await fetch(url); if(!response.ok) { throw new Error(`Modal: Failed to fetch page "${page}"`); @@ -57,18 +58,11 @@ class Modal extends Interaction { } open() { - document.body.classList.add("modalActive"); setTimeout(() => this.element.classList.add("active"),this.transition / 2); } // Close the modal and remove it from the DOM close() { - const activeModals = document.getElementsByClassName("modal"); - if(!activeModals || activeModals.length === 1) { - // Remove active effects if all modals have been closed - setTimeout(() => document.body.classList.remove("modalActive"),this.transition / 2); - } - this.element.classList.remove("active"); setTimeout(() => destroy(this.element),this.transition + 1); // Wait for transition } @@ -90,10 +84,27 @@ export class Card extends Modal { text: "close", action: "close" }); - const closeButtonElement = closeButton.getElement(); - this.bind(closeButtonElement); - this.inner.appendChild(closeButtonElement); + this.bind(closeButton.element); + this.inner.appendChild(closeButton.element); + } + + error(message) { + const oops = document.createElement("p"); + const infoButton = new Button({ + text: "more info" + }); + + oops.classList.add("error"); + oops.innerText = "🤯\nSomething went wrong"; + + infoButton.element.addEventListener("click",() => { + oops.innerText = "📋\n" + message; + destroy(infoButton.element); + }); + + this.insertElement(infoButton.element); + this.insertElement(oops); } // Open page from "assets/pages" @@ -107,11 +118,9 @@ export class Card extends Modal { // Fetch the requested page this.getPage(page).then(html => { this.insertHTML(html); - }).catch(error => { - const element = document.createElement("p"); - element.classList.add("error"); - element.innerText = "🤯\nSomething went wrong"; - this.insertElement(element); - }).finally(() => destroy(spinner)); + this.bindAll(this.inner); + }) + .catch(error => this.error(error)) + .finally(() => destroy(spinner)); } } \ No newline at end of file diff --git a/public/assets/js/modules/UI.mjs b/public/assets/js/modules/UI.mjs index 086e2d0..2464ae0 100644 --- a/public/assets/js/modules/UI.mjs +++ b/public/assets/js/modules/UI.mjs @@ -17,17 +17,31 @@ export default class Interaction extends Logging { this.interactions = interactions; this.attribute = "data-action"; // Target elements with this attribute - // Bind listeners to the target attribute within the provided scope - const elements = scope.querySelectorAll(`[${this.attribute}]`); + this.bindAll(scope); + } + + // Bind event listeners to this element + bind(element) { + if(element.hasAttribute("data-bound") || !element.hasAttribute(this.attribute)) { + return false; + } + element.addEventListener("click",event => this.pointerEvent(event)); + element.setAttribute("data-bound",""); + } + + // Get all elements with the target attribute in scope + getAll(scope) { + return scope.querySelectorAll(`[${this.attribute}]`); + } + + // Bind listeners to all attributed elements within scope + bindAll(scope) { + const elements = this.getAll(scope); for(const element of elements) { this.bind(element); } } - bind(element) { - element.addEventListener("click",event => this.pointerEvent(event)); - } - // Set the page theme color (and the theme-color meta tag) setThemeColor(color) { const meta = document.head.querySelector("meta[name='theme-color']"); diff --git a/public/assets/js/script.js b/public/assets/js/script.js index b0f6106..4a3b001 100644 --- a/public/assets/js/script.js +++ b/public/assets/js/script.js @@ -23,14 +23,19 @@ const interactions = { openContactCard: () => { const module = import("./modules/Modals.mjs"); const interactions = { - hello: () => { - console.log("Hello world"); + getContact: (event) => { + const service = event.target.getAttribute("data-value"); + module.then(modals => { + event.target.closest(".modal").close(); + const card = new modals.Card(interactions); + card.openPage(service); + }); } }; module.then(modals => { const card = new modals.Card(interactions); - card.openPage("contact_card"); + card.openPage("contact"); }); } } @@ -53,4 +58,5 @@ function updateTheme() { // Set the current page theme, and listen for changes theme.addEventListener("change",updateTheme); -updateTheme(); \ No newline at end of file +updateTheme(); +window._debug.openContactsModal(); \ No newline at end of file diff --git a/public/assets/pages/contact.html b/public/assets/pages/contact.html new file mode 100644 index 0000000..b32abf4 --- /dev/null +++ b/public/assets/pages/contact.html @@ -0,0 +1,40 @@ + +
+
+ +

Signal

+
+
+

E-Mail

+
+
+

+

+
+
+
\ No newline at end of file diff --git a/public/assets/pages/contact_card.html b/public/assets/pages/contact_card.html deleted file mode 100644 index 43260e0..0000000 --- a/public/assets/pages/contact_card.html +++ /dev/null @@ -1,27 +0,0 @@ - -
-
-

Signal

-
-
-

E-Mail

-
-
-

-

-
-
-
\ No newline at end of file diff --git a/public/assets/pages/contact_signal.html b/public/assets/pages/contact_signal.html new file mode 100644 index 0000000..730f0c2 --- /dev/null +++ b/public/assets/pages/contact_signal.html @@ -0,0 +1,3 @@ + + \ No newline at end of file