Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add system theme option #586

Merged
merged 14 commits into from
Jul 24, 2024
1 change: 1 addition & 0 deletions src/_data/sites/de.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ footer:
mastodon: Mastodon
theme_switcher:
title: Themenauswahl
system: System
light: Hell
dark: Dunkel
language_switcher:
Expand Down
1 change: 1 addition & 0 deletions src/_data/sites/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ footer:
mastodon: Mastodon
theme_switcher:
title: Theme Switcher
system: System
light: Light
dark: Dark
language_switcher:
Expand Down
1 change: 1 addition & 0 deletions src/_data/sites/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ footer:
mastodon: Mastodon
theme_switcher:
title: Cambiar temas
system: Sistema
light: Claro
dark: Oscuro
language_switcher:
Expand Down
1 change: 1 addition & 0 deletions src/_data/sites/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ footer:
mastodon: Mastodon
theme_switcher:
title: Thèmes
system: Système
light: Light
dark: Dark
language_switcher:
Expand Down
1 change: 1 addition & 0 deletions src/_data/sites/hi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ footer:
mastodon: Mastodon
theme_switcher:
title: Theme Switcher
system: System
light: Light
dark: Dark
language_switcher:
Expand Down
1 change: 1 addition & 0 deletions src/_data/sites/ja.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ footer:
mastodon: Mastodon
theme_switcher:
title: 配色モード切り替え
system: システム
light: 通常
dark: ダーク
language_switcher:
Expand Down
1 change: 1 addition & 0 deletions src/_data/sites/pt-br.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ footer:
mastodon: Mastodon
theme_switcher:
title: Trocar tema
system: Sistema
light: Claro
dark: Escuro
language_switcher:
Expand Down
1 change: 1 addition & 0 deletions src/_data/sites/zh-hans.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ footer:
mastodon: Mastodon
theme_switcher:
title: 主题切换
system: 系统
light: 浅色
dark: 深色
language_switcher:
Expand Down
4 changes: 4 additions & 0 deletions src/_includes/components/theme-switcher.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ <h2 class="theme-switcher-label visually-hidden" id="theme-switcher-label">{{ si
<svg class="theme-switcher__icon" focusable="false" width="22" height="22" viewBox="0 0 100 100" aria-hidden="true"><g transform="translate(0,-952.36218)"><path d="m 50,955.36218 c 1.6568,0 3,1.3431 3,3 l 0,16 c 0,1.6569 -1.3432,3 -3,3 -1.6569,0 -3,-1.3431 -3,-3 l 0,-16 c 0,-1.6569 1.3431,-3 3,-3 z m 31.125,12.875 c 0.76777,0 1.50798,0.3205 2.09375,0.9062 1.17159,1.1717 1.17157,3.0472 0,4.2188 l -11.3125,11.3125 c -1.17157,1.1716 -3.04714,1.1716 -4.21875,0 -1.17153,-1.1715 -1.17158,-3.0472 0,-4.2187 L 79,969.14338 c 0.58579,-0.5857 1.35723,-0.9062 2.125,-0.9062 z m -62.25,0 c 0.76777,0 1.53921,0.3205 2.125,0.9062 l 11.3125,11.3126 c 1.17158,1.1715 1.17153,3.0472 0,4.2187 -1.17161,1.1716 -3.04718,1.1716 -4.21875,0 l -11.3125,-11.3125 c -1.17157,-1.1716 -1.17159,-3.0471 0,-4.2188 0.58577,-0.5857 1.32598,-0.9062 2.09375,-0.9062 z M 50,983.36218 c 10.45786,0 19,8.5422 19,19.00002 0,10.4579 -8.54214,19 -19,19 -10.45784,0 -19,-8.5421 -19,-19 0,-10.45792 8.54216,-19.00002 19,-19.00002 z m 0,6 c -7.21516,0 -13,5.7848 -13,13.00002 0,7.2152 5.78484,13 13,13 7.21518,0 13,-5.7848 13,-13 0,-7.21522 -5.78482,-13.00002 -13,-13.00002 z m 44,10 c 1.65686,0 2.99999,1.34322 3,3.00002 -1e-5,1.6569 -1.34315,3 -3,3 l -16,0 c -1.65685,0 -3,-1.3431 -3,-3 0,-1.6568 1.34316,-3.00002 3,-3.00002 l 16,0 z m -72,0 c 1.65684,0 3,1.34322 3,3.00002 0,1.6569 -1.34315,3 -3,3 l -16,0 c -1.65685,0 -2.99999,-1.3431 -3,-3 1e-5,-1.6568 1.34314,-3.00002 3,-3.00002 l 16,0 z m 47.8125,19.81252 c 0.76777,0 1.50797,0.2892 2.09375,0.875 l 11.3125,11.3125 c 1.17158,1.1716 1.17152,3.0472 0,4.2188 -1.1716,1.1715 -3.04718,1.1715 -4.21875,0 l -11.3125,-11.3126 c -1.17157,-1.1715 -1.1716,-3.0471 0,-4.2187 0.58577,-0.5858 1.35723,-0.875 2.125,-0.875 z m -39.625,0 c 0.76777,0 1.53923,0.2892 2.125,0.875 1.1716,1.1716 1.17157,3.0472 0,4.2187 L 21,1035.581 c -1.17157,1.1715 -3.04715,1.1715 -4.21875,0 -1.17152,-1.1716 -1.17158,-3.0472 0,-4.2188 l 11.3125,-11.3125 c 0.58578,-0.5858 1.32598,-0.875 2.09375,-0.875 z M 50,1027.3622 c 1.6568,0 3,1.3431 3,3 l 0,16 c 0,1.6569 -1.3432,3 -3,3 -1.6569,0 -3,-1.3431 -3,-3 l 0,-16 c 0,-1.6569 1.3431,-3 3,-3 z" fill="currentColor" fill-opacity="1" stroke="none"></path></g></svg>
<span>{{ site.footer.theme_switcher.light }}</span>
</button>
<button class="theme-switcher__button js-toggle-button" id="system-theme-toggle" data-theme="system">
<svg class="theme-switcher__icon" focusable="false" width="22" height="22" viewBox="0 0 24 24" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-monitor"><rect x="2" y="3" width="20" height="14" rx="2" ry="2"></rect><line x1="8" y1="21" x2="16" y2="21"></line><line x1="12" y1="17" x2="12" y2="21"></line></svg>
<span>{{ site.footer.theme_switcher.system }}</span>
</button>
<button class="theme-switcher__button js-toggle-button" id="dark-theme-toggle" data-theme="dark">
<svg class="theme-switcher__icon" focusable="false" width="22" height="22" viewBox="0 0 100 100" aria-hidden="true"><g transform="translate(0,-952.36218)"><path d="m 35.377874,961.36325 a 3.0003,3.0003 0 0 0 -0.9063,0.1875 c -16.1759,5.9947 -25.4686997,21.7109 -25.4686997,39.59375 0,23.2769 18.9104997,42.2187 42.1873997,42.2187 17.8829,0 33.6304,-9.324 39.625,-25.5 a 3.0003,3.0003 0 0 0 -3.9374,-3.8125 c -4.0936,1.6462 -8.5949,2.5 -13.3438,2.5 -19.5969,0 -37.7188,-18.15315 -37.7188,-37.74995 0,-4.7489 0.8226,-9.2504 2.4688,-13.3437 a 3.0003,3.0003 0 0 0 -2.9062,-4.0938 z m -4.6563,8.7188 c -0.5822,2.8241 -0.9063,5.7363 -0.9063,8.7187 0,23.21085 20.5079,43.74995 43.7188,43.74995 2.9824,0 5.8946,-0.3553 8.7188,-0.9375 -6.2657,10.0487 -17.6431,15.75 -31.0626,15.75 -20.0342,0 -36.1874,-16.1844 -36.1874,-36.2187 0,-13.42105 5.6679,-24.79725 15.7187,-31.06245 z" fill="currentColor" fill-opacity="1" stroke="none"></path></g></svg>
<span>{{ site.footer.theme_switcher.dark }}</span>
Expand Down
2 changes: 1 addition & 1 deletion src/_includes/layouts/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
<script>
(function () {
var theme = window.localStorage.getItem("theme");
if (theme) document.documentElement.setAttribute('data-theme', theme)
if (theme && theme !== "system") document.documentElement.setAttribute('data-theme', theme)
else if (window.matchMedia('(prefers-color-scheme: dark)').matches)
document.documentElement.setAttribute('data-theme', 'dark');
else document.documentElement.setAttribute('data-theme', 'light');
Expand Down
113 changes: 67 additions & 46 deletions src/assets/js/themes.js
Original file line number Diff line number Diff line change
@@ -1,57 +1,78 @@
/* theme toggle buttons */
(function () {
var enableToggle = function (btn) {
btn.setAttribute("aria-pressed", "true");
};
var disableToggle = function (btn) {
btn.setAttribute("aria-pressed", "false");

var disableToggle = function (btns) {
btns.forEach(btn => btn.setAttribute("aria-pressed", "false"));
};

var setTheme = function (theme) {
document.documentElement.setAttribute("data-theme", theme);
if (theme === "system") {
var systemTheme = window.matchMedia("(prefers-color-scheme: dark)")
.matches
? "dark"
: "light";
document.documentElement.setAttribute("data-theme", systemTheme);
} else {
document.documentElement.setAttribute("data-theme", theme);
}
window.localStorage.setItem("theme", theme);
};

var theme = document.documentElement.getAttribute("data-theme");

document.addEventListener(
"DOMContentLoaded",
function () {
var switcher = document.getElementById("js-theme-switcher");
switcher.removeAttribute("hidden");
var light_theme_toggle =
document.getElementById("light-theme-toggle"),
dark_theme_toggle =
document.getElementById("dark-theme-toggle");
if (theme) {
if (theme === "light") {
enableToggle(light_theme_toggle);
disableToggle(dark_theme_toggle);
} else if (theme === "dark") {
enableToggle(dark_theme_toggle);
disableToggle(light_theme_toggle);
var initializeThemeSwitcher = function () {
var theme = window.localStorage.getItem("theme") || "system";
var switcher = document.getElementById("js-theme-switcher");
switcher.removeAttribute("hidden");

var lightThemeToggle = document.getElementById("light-theme-toggle");
var darkThemeToggle = document.getElementById("dark-theme-toggle");
var systemThemeToggle = document.getElementById("system-theme-toggle");

var toggleButtons = [
lightThemeToggle,
darkThemeToggle,
systemThemeToggle,
];

toggleButtons.forEach(function (btn) {
btn.addEventListener("click", function () {
enableToggle(btn);
var theme = this.getAttribute("data-theme");
setTheme(theme);
if (btn === systemThemeToggle) {
disableToggle([lightThemeToggle, darkThemeToggle]);
} else if (btn === lightThemeToggle) {
disableToggle([systemThemeToggle, darkThemeToggle]);
} else if (btn === darkThemeToggle) {
disableToggle([systemThemeToggle, lightThemeToggle]);
}
}
light_theme_toggle.addEventListener(
"click",
function () {
enableToggle(light_theme_toggle);
theme = this.getAttribute("data-theme");
setTheme(theme);
disableToggle(dark_theme_toggle);
},
false,
);
dark_theme_toggle.addEventListener(
"click",
function () {
enableToggle(dark_theme_toggle);
theme = this.getAttribute("data-theme");
setTheme(theme);
disableToggle(light_theme_toggle);
},
false,
);
},
false,
);
});
});

if (theme === "system") {
enableToggle(systemThemeToggle);
disableToggle([lightThemeToggle, darkThemeToggle]);
} else if (theme === "light") {
enableToggle(lightThemeToggle);
disableToggle([systemThemeToggle, darkThemeToggle]);
} else if (theme === "dark") {
enableToggle(darkThemeToggle);
disableToggle([systemThemeToggle, lightThemeToggle]);
}

// Update theme on system preference change
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", function () {
var currentTheme = window.localStorage.getItem("theme");
if (currentTheme === "system" || !currentTheme) {
enableToggle(systemThemeToggle);
disableToggle([lightThemeToggle, darkThemeToggle]);
setTheme("system");
}
});
};

document.addEventListener("DOMContentLoaded", initializeThemeSwitcher);
})();
6 changes: 5 additions & 1 deletion src/assets/scss/components/theme-switcher.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,17 @@

.theme-switcher__button {
box-shadow: var(--shadow-xs);
padding: 0.625rem 0.875rem;
padding: 0.625rem 0.675rem;
amareshsm marked this conversation as resolved.
Show resolved Hide resolved
display: inline-flex;
align-items: center;
margin: 0;
gap: 0.25rem;
color: inherit;

@media (max-width: 1100px) {
padding: 0.625rem 0.375rem;
}
amareshsm marked this conversation as resolved.
Show resolved Hide resolved

&:first-of-type {
border-right: 0.5px solid var(--border-color);
border-inline-end: 0.5px solid var(--border-color);
Expand Down
2 changes: 1 addition & 1 deletion src/assets/scss/footer.scss
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
align-items: center;
gap: 2rem;

@media all and (min-width: 768px) {
@media all and (min-width: 800px) {
flex-direction: row;
justify-content: space-between;
}
Expand Down
77 changes: 70 additions & 7 deletions src/playground/components/ThemeSwitcher.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,44 @@
import React, { useState } from "react";
import React, { useEffect, useState } from "react";

export default function ThemeSwitcher() {
const [theme, setTheme] = useState(
document.documentElement.getAttribute("data-theme"),
);
const [theme, setTheme] = useState(window.localStorage.getItem("theme"));

const toggleTheme = newTheme => {
setTheme(newTheme);
document.documentElement.setAttribute("data-theme", newTheme);
window.localStorage.setItem("theme", newTheme);
if (newTheme === "system") {
const currentSystemTheme = window.matchMedia(
"(prefers-color-scheme: dark)",
).matches
? "dark"
: "light";

document.documentElement.setAttribute(
"data-theme",
currentSystemTheme,
);
window.localStorage.setItem("theme", "system");
setTheme("system");
} else {
document.documentElement.setAttribute("data-theme", newTheme);
window.localStorage.setItem("theme", newTheme);
setTheme(newTheme);
}
};
amareshsm marked this conversation as resolved.
Show resolved Hide resolved

useEffect(() => {
const media = window.matchMedia("(prefers-color-scheme: dark)");

function onChangeMedia() {
const currentTheme = window.localStorage.getItem("theme");

if (currentTheme === "system" || !currentTheme) {
toggleTheme("system");
}
}

media.addEventListener("change", onChangeMedia);
return () => media.removeEventListener("change", onChangeMedia);
}, []);

return (
<div
role="region"
Expand Down Expand Up @@ -52,6 +80,41 @@ export default function ThemeSwitcher() {
</svg>
<span>Light</span>
</button>
<button
className="theme-switcher__button js-toggle-button"
id="system-theme-toggle"
data-theme="system"
onClick={() => {
toggleTheme("system");
}}
aria-pressed={theme === "system"}
>
<svg
className="theme-switcher__icon"
focusable="false"
width="22"
height="22"
viewBox="0 0 24 24"
aria-hidden="true"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<rect
x="2"
y="3"
width="20"
height="14"
rx="2"
ry="2"
></rect>
<line x1="8" y1="21" x2="16" y2="21"></line>
<line x1="12" y1="17" x2="12" y2="21"></line>
</svg>
<span>System</span>
</button>
<button
className="theme-switcher__button js-toggle-button"
onClick={() => {
Expand Down
Loading