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;
left: 0;
width: 100vw;
height: 100vh;
height: 100%;
z-index: 1;
pointer-events: none;
box-sizing: border-box;
@ -31,13 +31,46 @@ 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);
}
.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 -- */
@ -45,18 +78,25 @@ body.modalActive main .screen {
.modal.card .inner {
transition: var(--transition) transform, var(--transition) opacity;
position: relative;
background-color: var(--color-contrast);
background-color: var(--color-background);
width: calc(100vw - var(--padding));
max-width: 600px;
max-width: 500px;
align-self: flex-end;
box-sizing: border-box;
padding: var(--padding);
transform: translateY(1vh);
border-radius: var(--border-radius);
opacity: 0;
display: flex;
flex-direction: column;
gap: var(--padding);
}
.modal.card.active .inner {
transform: translateY(0);
opacity: 1;
}
.modal.card .button[data-action="close"] {
margin-top: auto;
}

View file

@ -8,15 +8,36 @@ class Debug {
list() {
const functions = [
"list",
"toggleMenu",
"openContactsModal"
];
console.log("Available functions:",functions.map(f => `window._debug.${f}();`));
}
toggleMenu() {
document.getElementsByClassName("hamburger")[0].click();
}
openContactsModal() {
document.getElementsByClassName("hamburger")[0].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();

View file

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