Viel neues
This commit is contained in:
138
styleguide/assets/js/app.js
Normal file
138
styleguide/assets/js/app.js
Normal file
@@ -0,0 +1,138 @@
|
||||
const $ = (selector, root = document) => root.querySelector(selector);
|
||||
const $$ = (selector, root = document) => [...root.querySelectorAll(selector)];
|
||||
|
||||
const THEME_KEY = "obyte-theme";
|
||||
const themeToggle = $("#themeToggle");
|
||||
const toast = $("#toast");
|
||||
let toastTimer = null;
|
||||
|
||||
function showToast(message) {
|
||||
if (!toast) return;
|
||||
toast.textContent = message;
|
||||
toast.classList.add("is-on");
|
||||
clearTimeout(toastTimer);
|
||||
toastTimer = setTimeout(() => toast.classList.remove("is-on"), 1400);
|
||||
}
|
||||
|
||||
async function copyText(value) {
|
||||
try {
|
||||
await navigator.clipboard.writeText(value);
|
||||
showToast("Kopiert: " + value);
|
||||
} catch {
|
||||
const fallback = document.createElement("textarea");
|
||||
fallback.value = value;
|
||||
fallback.style.position = "fixed";
|
||||
fallback.style.left = "-9999px";
|
||||
document.body.appendChild(fallback);
|
||||
fallback.select();
|
||||
document.execCommand("copy");
|
||||
fallback.remove();
|
||||
showToast("Kopiert: " + value);
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("click", (event) => {
|
||||
const trigger = event.target.closest("[data-copy-value],[data-copy-block]");
|
||||
if (!trigger) return;
|
||||
|
||||
const directValue = trigger.getAttribute("data-copy-value");
|
||||
const blockSelector = trigger.getAttribute("data-copy-block");
|
||||
|
||||
if (directValue) {
|
||||
copyText(directValue);
|
||||
return;
|
||||
}
|
||||
|
||||
if (blockSelector) {
|
||||
const block = $(blockSelector);
|
||||
if (block) {
|
||||
copyText(block.innerText.trim());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function applyTheme(theme) {
|
||||
const isDark = theme === "dark";
|
||||
document.documentElement.setAttribute("data-theme", isDark ? "dark" : "light");
|
||||
|
||||
if (themeToggle) {
|
||||
themeToggle.setAttribute("aria-pressed", String(isDark));
|
||||
themeToggle.textContent = isDark ? "Hell" : "Dunkel";
|
||||
}
|
||||
}
|
||||
|
||||
function loadInitialTheme() {
|
||||
let savedTheme = null;
|
||||
|
||||
try {
|
||||
savedTheme = localStorage.getItem(THEME_KEY);
|
||||
} catch {
|
||||
savedTheme = null;
|
||||
}
|
||||
|
||||
if (savedTheme === "light" || savedTheme === "dark") {
|
||||
applyTheme(savedTheme);
|
||||
return;
|
||||
}
|
||||
|
||||
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
|
||||
applyTheme(prefersDark ? "dark" : "light");
|
||||
}
|
||||
|
||||
themeToggle?.addEventListener("click", () => {
|
||||
const currentTheme = document.documentElement.getAttribute("data-theme");
|
||||
const nextTheme = currentTheme === "dark" ? "light" : "dark";
|
||||
|
||||
applyTheme(nextTheme);
|
||||
|
||||
try {
|
||||
localStorage.setItem(THEME_KEY, nextTheme);
|
||||
} catch {
|
||||
// Ignore storage errors in restrictive browser contexts.
|
||||
}
|
||||
});
|
||||
|
||||
loadInitialTheme();
|
||||
|
||||
const navToggle = $("#navToggle");
|
||||
const navLinks = $("#navLinks");
|
||||
|
||||
navToggle?.addEventListener("click", () => {
|
||||
const open = navLinks?.classList.toggle("is-open");
|
||||
navToggle.setAttribute("aria-expanded", String(open));
|
||||
});
|
||||
|
||||
$$(".navlink").forEach((link) => {
|
||||
link.addEventListener("click", () => {
|
||||
if (window.matchMedia("(max-width: 980px)").matches) {
|
||||
navLinks?.classList.remove("is-open");
|
||||
navToggle?.setAttribute("aria-expanded", "false");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const sections = $$(".section");
|
||||
const links = $$(".navlink");
|
||||
|
||||
function setActive(id) {
|
||||
links.forEach((link) => {
|
||||
link.classList.toggle("is-active", link.getAttribute("href") === "#" + id);
|
||||
});
|
||||
}
|
||||
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting && entry.target.id) {
|
||||
setActive(entry.target.id);
|
||||
}
|
||||
});
|
||||
},
|
||||
{ threshold: 0.28 }
|
||||
);
|
||||
|
||||
sections.forEach((section) => observer.observe(section));
|
||||
|
||||
if (location.hash) {
|
||||
setActive(location.hash.replace("#", ""));
|
||||
}
|
||||
Reference in New Issue
Block a user