victorwesterlund.com/public/assets/js/modules/UI.mjs
2021-09-06 15:33:57 +02:00

72 lines
No EOL
2.1 KiB
JavaScript

// Copyright © Victor Westerlund - No libraries! 😲
import { default as Logging } from "./Logging.mjs";
// Remove an element and its subtree
export function destroy(family) {
while(family.firstChild) {
family.removeChild(family.lastChild);
}
family.parentNode.removeChild(family);
}
// General-purpose scoped event handler
export default class Interaction extends Logging {
constructor(interactions,scope) {
super();
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}]`);
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']");
const style = getComputedStyle(document.body);
if(!meta || !color) {
return false;
}
// Dark mode will always use the background color
if(document.body.classList.contains("dark")) {
color = "background";
}
if(color[0] !== "#") {
// Get CSS variable if color isn't a HEX code
color = style.getPropertyValue(`--color-${color}`);
color = color.replaceAll(" ","");
}
document.body.style.setProperty("background-color",color);
meta.setAttribute("content",color);
}
// Handle click/touch interactions
pointerEvent(event) {
const target = event.target.closest(`[${this.attribute}]`);
const action = target?.getAttribute(this.attribute) ?? null;
if(!target || !action || !Object.keys(this.interactions).includes(action)) {
// Exit if the interaction is invalid or action doesn't exist
return false;
}
// Execute the function from the data-action attribute
this.interactions[action](event);
// The button has requested a theme-color change
if(target.hasAttribute("data-theme-color")) {
this.setThemeColor(target.getAttribute("data-theme-color"));
}
}
}