Archived
docs: add automatic theme state
This commit is contained in:
+33
-12
@@ -2,9 +2,9 @@ const themeButtons = document.querySelectorAll("[data-theme-toggle]");
|
|||||||
const themeStorageKey = "pi-web-theme";
|
const themeStorageKey = "pi-web-theme";
|
||||||
const systemPrefersLight = window.matchMedia("(prefers-color-scheme: light)");
|
const systemPrefersLight = window.matchMedia("(prefers-color-scheme: light)");
|
||||||
|
|
||||||
function storedTheme() {
|
function storedThemeMode() {
|
||||||
const theme = window.localStorage.getItem(themeStorageKey);
|
const theme = window.localStorage.getItem(themeStorageKey);
|
||||||
return theme === "light" || theme === "dark" ? theme : undefined;
|
return theme === "light" || theme === "dark" || theme === "auto" ? theme : "auto";
|
||||||
}
|
}
|
||||||
|
|
||||||
function activeTheme() {
|
function activeTheme() {
|
||||||
@@ -15,28 +15,49 @@ function activeTheme() {
|
|||||||
: "dark";
|
: "dark";
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateThemeButtons(theme = activeTheme()) {
|
function applyThemeMode(mode) {
|
||||||
|
if (mode === "light" || mode === "dark") {
|
||||||
|
document.documentElement.dataset.theme = mode;
|
||||||
|
} else {
|
||||||
|
delete document.documentElement.dataset.theme;
|
||||||
|
}
|
||||||
|
window.localStorage.setItem(themeStorageKey, mode);
|
||||||
|
updateThemeButtons(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateThemeButtons(mode = storedThemeMode()) {
|
||||||
|
const active = activeTheme();
|
||||||
for (const button of themeButtons) {
|
for (const button of themeButtons) {
|
||||||
button.dataset.theme = theme;
|
button.dataset.theme = mode;
|
||||||
button.setAttribute("aria-pressed", theme === "light" ? "true" : "false");
|
button.dataset.activeTheme = active;
|
||||||
const icon = button.querySelector("[data-theme-icon]");
|
const icon = button.querySelector("[data-theme-icon]");
|
||||||
const label = button.querySelector("[data-theme-label]");
|
const label = button.querySelector("[data-theme-label]");
|
||||||
if (icon !== null) icon.textContent = theme === "light" ? "☀" : "☾";
|
if (mode === "auto") {
|
||||||
if (label !== null) label.textContent = theme === "light" ? "Light" : "Dark";
|
button.setAttribute("aria-label", `Theme: Auto (${active}). Click to use dark theme.`);
|
||||||
|
if (icon !== null) icon.textContent = "◐";
|
||||||
|
if (label !== null) label.textContent = "Auto";
|
||||||
|
} else if (mode === "light") {
|
||||||
|
button.setAttribute("aria-label", "Theme: Light. Click to use automatic theme.");
|
||||||
|
if (icon !== null) icon.textContent = "☀";
|
||||||
|
if (label !== null) label.textContent = "Light";
|
||||||
|
} else {
|
||||||
|
button.setAttribute("aria-label", "Theme: Dark. Click to use light theme.");
|
||||||
|
if (icon !== null) icon.textContent = "☾";
|
||||||
|
if (label !== null) label.textContent = "Dark";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateThemeButtons();
|
updateThemeButtons();
|
||||||
systemPrefersLight.addEventListener("change", () => {
|
systemPrefersLight.addEventListener("change", () => {
|
||||||
if (storedTheme() === undefined) updateThemeButtons();
|
if (storedThemeMode() === "auto") updateThemeButtons("auto");
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const button of themeButtons) {
|
for (const button of themeButtons) {
|
||||||
button.addEventListener("click", () => {
|
button.addEventListener("click", () => {
|
||||||
const nextTheme = activeTheme() === "light" ? "dark" : "light";
|
const currentMode = storedThemeMode();
|
||||||
document.documentElement.dataset.theme = nextTheme;
|
const nextTheme = currentMode === "auto" ? "dark" : currentMode === "dark" ? "light" : "auto";
|
||||||
window.localStorage.setItem(themeStorageKey, nextTheme);
|
applyThemeMode(nextTheme);
|
||||||
updateThemeButtons(nextTheme);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-7
@@ -65,7 +65,7 @@ body::after {
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(-42vh);
|
transform: translateY(-42vh);
|
||||||
animation: word-drop 640ms cubic-bezier(0.18, 0.88, 0.22, 1.08) forwards;
|
animation: word-drop 520ms cubic-bezier(0.34, 0, 0.2, 1) forwards;
|
||||||
animation-delay: calc(140ms + (var(--i) * 190ms));
|
animation-delay: calc(140ms + (var(--i) * 190ms));
|
||||||
color: var(--intro-color, var(--text));
|
color: var(--intro-color, var(--text));
|
||||||
}
|
}
|
||||||
@@ -96,11 +96,6 @@ body::after {
|
|||||||
transform: translateY(-42vh);
|
transform: translateY(-42vh);
|
||||||
}
|
}
|
||||||
|
|
||||||
72% {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translateY(0.08em);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
@@ -199,7 +194,8 @@ video {
|
|||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
padding: 10px 12px;
|
min-height: 42px;
|
||||||
|
padding: 0 12px;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,12 +214,26 @@ video {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.theme-toggle {
|
.theme-toggle {
|
||||||
|
width: 92px;
|
||||||
|
justify-content: center;
|
||||||
|
appearance: none;
|
||||||
|
line-height: 1;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: var(--muted);
|
color: var(--muted);
|
||||||
font: inherit;
|
font: inherit;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.theme-toggle [data-theme-icon],
|
||||||
|
.theme-toggle [data-theme-label] {
|
||||||
|
display: inline-block;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-toggle[data-theme="auto"] [data-theme-icon] {
|
||||||
|
color: var(--brand);
|
||||||
|
}
|
||||||
|
|
||||||
.theme-toggle[data-theme="dark"] [data-theme-icon] {
|
.theme-toggle[data-theme="dark"] [data-theme-icon] {
|
||||||
color: var(--brand-2);
|
color: var(--brand-2);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user