dev21w36b

This commit is contained in:
Victor Westerlund 2021-09-07 07:39:45 -04:00
parent ff474e1786
commit 62cdb7aae5
8 changed files with 176 additions and 24 deletions

View file

@ -23,7 +23,7 @@ body.modalActive main .screen {
top: 0; top: 0;
left: 0; left: 0;
width: 100vw; width: 100vw;
height: 100vh; height: 100%;
z-index: 1; z-index: 1;
pointer-events: none; pointer-events: none;
box-sizing: border-box; box-sizing: border-box;
@ -31,13 +31,46 @@ body.modalActive main .screen {
padding: var(--padding); padding: var(--padding);
} }
.modal + .modal {
transition: var(--transition) backdrop-filter;
backdrop-filter: blur(5px);
}
.modal.active { .modal.active {
pointer-events: all; pointer-events: all;
background-color: rgba(var(--comp-inverted),.4); background-color: rgba(var(--comp-inverted),.4);
} }
.modal .button { .modal .button {
background-color: rgba(var(--comp-inverted),.3); background-color: rgba(var(--comp-inverted),.05);
}
.modal .button p {
color: var(--color-inverted);
}
.spinner.logo {
--size: 10vw;
--anim-speed: 1s;
align-self: center;
margin-top: var(--padding);
margin-left: calc((var(--size) / 2) * -1);
animation: logoSpinner var(--anim-speed) infinite alternate linear;
}
.error {
text-align: center;
font-size: 20px;
}
.error:first-line {
font-size: 15vw;
}
@keyframes logoSpinner {
to {
opacity: .1;
}
} }
/* -- Cards -- */ /* -- Cards -- */
@ -45,18 +78,25 @@ body.modalActive main .screen {
.modal.card .inner { .modal.card .inner {
transition: var(--transition) transform, var(--transition) opacity; transition: var(--transition) transform, var(--transition) opacity;
position: relative; position: relative;
background-color: var(--color-contrast); background-color: var(--color-background);
width: calc(100vw - var(--padding)); width: calc(100vw - var(--padding));
max-width: 600px; max-width: 500px;
align-self: flex-end; align-self: flex-end;
box-sizing: border-box; box-sizing: border-box;
padding: var(--padding); padding: var(--padding);
transform: translateY(1vh); transform: translateY(1vh);
border-radius: var(--border-radius); border-radius: var(--border-radius);
opacity: 0; opacity: 0;
display: flex;
flex-direction: column;
gap: var(--padding);
} }
.modal.card.active .inner { .modal.card.active .inner {
transform: translateY(0); transform: translateY(0);
opacity: 1; opacity: 1;
} }
.modal.card .button[data-action="close"] {
margin-top: auto;
}

View file

@ -8,15 +8,36 @@ class Debug {
list() { list() {
const functions = [ const functions = [
"list", "list",
"toggleMenu",
"openContactsModal" "openContactsModal"
]; ];
console.log("Available functions:",functions.map(f => `window._debug.${f}();`)); console.log("Available functions:",functions.map(f => `window._debug.${f}();`));
} }
toggleMenu() {
document.getElementsByClassName("hamburger")[0].click();
}
openContactsModal() { openContactsModal() {
document.getElementsByClassName("hamburger")[0].click(); document.getElementsByClassName("hamburger")[0].click();
document.querySelector("div[data-action='openContactCard']").click(); document.querySelector("div[data-action='openContactCard']").click();
} }
demoCard() {
const module = import("./Modals.mjs");
const interactions = {
hello: () => {
console.log("Hello world");
}
};
module.then(modals => {
const card = new modals.Card(interactions);
card.inner.style.height = "80vh";
card.inner.insertAdjacentHTML("afterbegin","<p>Hello world</p>");
card.open();
});
}
} }
export default window._debug = new Debug(); export default window._debug = new Debug();

View file

@ -17,25 +17,25 @@ class Modal extends Interaction {
super(interactions,element); super(interactions,element);
this.element = this.applyTemplate(element); this.element = this.applyTemplate(element);
this.importStyleSheet();
document.body.appendChild(this.element); document.body.appendChild(this.element);
} }
// Import the companion CSS rules // Fetch page html from "assets/pages"
importStyleSheet() { async getPage(page) {
let sheet = "assets/css/modal.css"; const url = `assets/pages/${page}.html`;
const element = document.createElement("link"); const response = await fetch(url);
if(!response.ok) {
// Exit if the stylesheet has already been imported throw new Error(`Modal: Failed to fetch page "${page}"`);
if(document.head.querySelector("link[data-async-modalcss]")) { }
return false; return response.text();
} }
// Import the stylesheet with a link tag insertHTML(element) {
element.setAttribute("rel","stylesheet"); this.inner.insertAdjacentHTML("afterbegin",element);
element.setAttribute("href",sheet); }
element.setAttribute("data-async-modalcss","");
document.head.appendChild(element); insertElement(element) {
this.inner.insertAdjacentElement("afterbegin",element);
} }
// Apply a modal template to the provided element // Apply a modal template to the provided element
@ -83,10 +83,6 @@ export class Card extends Modal {
this.init(); this.init();
} }
setContent(content) {
this.element.insertAdjacentHTML("beforeend",content);
}
init(slim) { init(slim) {
this.element.classList.add("card"); this.element.classList.add("card");
this.element.classList.add("center"); this.element.classList.add("center");
@ -100,7 +96,22 @@ export class Card extends Modal {
this.inner.appendChild(closeButtonElement); this.inner.appendChild(closeButtonElement);
} }
// Open page from "assets/pages"
openPage(page) { openPage(page) {
// Show a spinner while fetching
const spinner = document.createElement("div");
spinner.classList = "logo spinner";
this.insertElement(spinner);
this.open(); this.open();
// 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));
} }
} }

View file

@ -0,0 +1,42 @@
// Copyright © Victor Westerlund - No libraries! 😲
// Load assets for later use on this page.
// This implements a hybrid of the link types "preload" and "prefetch"
export default class Preload {
constructor(assets) {
this.scripts = [];
this.stylesheets = [];
// Get the type of asset from the file extension
assets.forEach(asset => {
const components = asset.split(".");
const extension = components[components.length - 1];
switch(extension) {
case "mjs":
this.scripts.push(asset);
break;
case "css":
this.stylesheets.push(asset);
break;
}
});
// Append tags when DOM is ready
window.addEventListener("DOMContentLoaded",() => this.import());
}
import() {
this.scripts.forEach(script => {
const element = document.createElement("script");
element.setAttribute("type","module");
element.src = "assets/js/" + script;
document.body.appendChild(element);
});
this.stylesheets.forEach(sheet => {
const element = document.createElement("link");
element.setAttribute("rel","stylesheet");
element.href = "assets/css/" + sheet;
document.head.appendChild(element);
});
}
}

View file

@ -1,7 +1,15 @@
// Copyright © Victor Westerlund - No libraries! 😲 // Copyright © Victor Westerlund - No libraries! 😲
import { default as Preload } from "./modules/Preload.mjs";
import { default as Interaction } from "./modules/UI.mjs"; import { default as Interaction } from "./modules/UI.mjs";
import { default as Debug } from "./modules/Debugging.mjs"; import { default as Debug } from "./modules/Debugging.mjs";
// Load these assets when the DOM is ready (not needed right away)
const preload = new Preload([
"modules/Modals.mjs",
"modules/Components.mjs",
"modal.css"
]);
// All default interactions // All default interactions
const interactions = { const interactions = {
toggleMenu: () => { toggleMenu: () => {

View file

@ -0,0 +1,27 @@
<style>
.contact {
display: grid;
grid-template-rows: repeat(2, 1fr);
grid-template-columns: repeat(2, 1fr);
gap: var(--padding);
}
.contact .item {
height: 140px;
border-radius: var(--border-radius);
background-color: rgba(var(--comp-inverted),.05);
}
</style>
<div class="contact">
<div class="item" data-action="hello" data-value="signal">
<p>Signal</p>
</div>
<div class="item" data-action="getContact" data-value="email">
<p>E-Mail</p>
</div>
<div class="item">
<p>
</div>
<div class="item">
</div>
</div>

View file

@ -3,12 +3,15 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Victor Westerlund</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Full-stack web developer from Stockholm, Sweden."> <meta name="description" content="Full-stack web developer from Stockholm, Sweden.">
<meta name="theme-color" content=""> <meta name="theme-color" content="red">
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#212121">
<link href="assets/img/favicon.png" rel="icon"> <link href="assets/img/favicon.png" rel="icon">
<link href="assets/css/style.css" rel="stylesheet"> <link href="assets/css/style.css" rel="stylesheet">
<title>Victor Westerlund</title>
</head> </head>
<body> <body>
<main> <main>