feat(theme-switcher): add theme reset button (#198)

main
Óscar Fernández 1 year ago committed by GitHub
parent c7bd9b36ce
commit afbf4017e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,7 +1,7 @@
+++
title = "Sense JavaScript obligatori"
date = 2023-01-06
updated = 2023-09-01
updated = 2023-10-06
description = "JavaScript només s'utilitza quan HTML i CSS no són suficients."
[taxonomies]
@ -16,8 +16,8 @@ Aquest tema no requereix JavaScript obligatori. Opcionalment, pot carregar una q
## Opcions habilitades globalment
- L'**interruptor de mode clar/fosc** es pot habilitar configurant `theme_switcher = true` a la secció `[extra]` del teu `config.toml` (~900 bytes de JavaScript).
- L'**interruptor de mode clar/fosc** es pot habilitar configurant `theme_switcher = true` a la secció `[extra]` del teu `config.toml` (~1KB de JavaScript).
- **Decodificació de correu electrònic** (~400 bytes). Per protegir contra robots de correu brossa, pots configurar `encode_plaintext_email = true`. Si el teu lloc web està en un repositori públic, considera utilitzar el teu `email` com una cadena codificada en base64[^1].
## Opcions que es poden sobreescriure de forma jeràrquica

@ -1,7 +1,7 @@
+++
title = "Sin JavaScript obligatorio"
date = 2023-01-06
updated = 2023-09-01
updated = 2023-10-06
description = "JavaScript solo se utiliza cuando HTML y CSS no son suficientes."
[taxonomies]
@ -16,8 +16,8 @@ Este tema no requiere JavaScript de manera obligatoria. Opcionalmente, puede car
## Opciones habilitadas globalmente
- El **interruptor de modo claro/oscuro** puede habilitarse configurando `theme_switcher = true` en la sección `[extra]` de tu `config.toml` (~900 bytes de JavaScript).
- El **interruptor de modo claro/oscuro** puede habilitarse configurando `theme_switcher = true` en la sección `[extra]` de tu `config.toml` (~1KB de JavaScript).
- **Descodificación de correo electrónico** (~400 bytes). Para proteger contra bots que recopilan correos electrónicos desde tu sitio web, puedes configurar `encode_plaintext_email = true`. Si tu sitio está en un repositorio público, para mayor protección, considera configurar tu `email` como una cadena codificada en base64[^1].
## Opciones que se pueden sobreescribir de forma jerárquica

@ -1,7 +1,7 @@
+++
title = "No mandatory JavaScript"
date = 2023-01-06
updated = 2023-09-01
updated = 2023-10-06
description = "JavaScript is only used when HTML and CSS aren't enough."
[taxonomies]
@ -16,7 +16,7 @@ This theme has no mandatory JavaScript. Optionally, it can load a minimal amount
## Globally enabled settings
- The **light/dark mode switch** can be enabled by setting `theme_switcher = true` in the `[extra]` section of your `config.toml` (~900 bytes of JavaScript).
- The **light/dark mode switch** can be enabled by setting `theme_switcher = true` in the `[extra]` section of your `config.toml` (~1KB of JavaScript).
- **E-mail decoding** (~400 bytes). To protect against spambots scraping your e-mail from your website, you can set `encode_plaintext_email = true`. If your site is on a public repository, for extra protection, consider setting your `email` as a base64-encoded string[^1] directly.

@ -26,6 +26,7 @@ language_selection = "Selecció d'idioma"
toggle_mode = "Canvia el mode $MODE" # $MODE will be replaced by a value (or both) below.
dark = "obscur"
light = "clar"
reset_mode = "Restableix el mode als valors predeterminats del sistema"
# Post metadata.
draft = "ESBORRANY"

@ -30,6 +30,7 @@ language_selection = "Sprachauswahl"
toggle_mode = "Wechsle in den $MODE Modus" # $MODE will be replaced by a value (or both) below.
dark = "dunkel"
light = "hell"
reset_mode = "Modus auf Betriebssystemstandard zurücksetzen"
# Post metadata.
draft = "ENTWURF"

@ -26,6 +26,7 @@ language_selection = "Language selection"
toggle_mode = "Toggle $MODE mode" # $MODE will be replaced by a value (or both) below.
dark = "dark"
light = "light"
reset_mode = "Reset mode to OS default"
# Post metadata.
draft = "DRAFT"

@ -26,6 +26,7 @@ language_selection = "Selección de idioma"
toggle_mode = "Cambiar a modo $MODE" # $MODE will be replaced by a value (or both) below.
dark = "oscuro"
light = "claro"
reset_mode = "Restablecer modo a configuración predeterminada del SO"
# Post metadata.
draft = "BORRADOR"

@ -30,6 +30,7 @@ language_selection = "Sélection de la langue"
toggle_mode = "Basculer en mode $MODE" # $MODE will be replaced by a value (or both) below.
dark = "sombre"
light = "clair"
reset_mode = "Réinitialiser le mode aux paramètres par défaut du système"
# Post metadata.
draft = "BROUILLON"

@ -28,6 +28,7 @@ language_selection = "भाषा चयन"
toggle_mode = "$MODE मोड में टॉगल करें" # $MODE will be replaced by a value (or both) below.
dark = "अंधेरा"
light = "रोशनी"
reset_mode = "मोड को ओएस डिफ़ॉल्ट पर रीसेट करें"
# Post metadata.
draft = "मसौदा"

@ -26,6 +26,7 @@ language_selection = "Selezione della lingua"
toggle_mode = "Passa alla modalità $MODE" # $MODE will be replaced by a value (or both) below.
dark = "scuro"
light = "chiaro"
reset_mode = "Reimposta la modalità alle impostazioni predefinite del sistema operativo"
# Post metadata.
draft = "BOZZA"

@ -30,6 +30,7 @@ language_selection = "言語選択"
toggle_mode = "$MODE モードに切り替え" # $MODE will be replaced by a value (or both) below.
dark = "暗い"
light = "明るい"
reset_mode = "モードをOSデフォルトにリセット"
# Post metadata.
draft = "ドラフト"

@ -30,6 +30,7 @@ language_selection = "언어 선택"
toggle_mode = "$MODE 모드로 전환" # $MODE will be replaced by a value (or both) below.
dark = "어두운"
light = "밝은"
reset_mode = "모드를 OS 기본값으로 재설정"
# Post metadata.
draft = "임시 저장"

@ -26,6 +26,7 @@ language_selection = "Seleção de idioma"
toggle_mode = "Alternar para o modo $MODE" # $MODE will be replaced by a value (or both) below.
dark = "escuro"
light = "claro"
reset_mode = "Repor o modo para o padrão do SO"
# Post metadata.
draft = "RASCUNHO"

@ -26,6 +26,7 @@ language_selection = "Выбор языка"
toggle_mode = "Переключить на режим $MODE" # $MODE will be replaced by a value (or both) below.
dark = "тёмный"
light = "светлый"
reset_mode = "Сбросить режим к настройкам ОС по умолчанию"
# Post metadata.
draft = "ЧЕРНОВИК"

@ -30,6 +30,7 @@ language_selection = "Вибір мови"
toggle_mode = "Перемкнути в режим $MODE" # $MODE will be replaced by a value (or both) below.
dark = "темний"
light = "світлий"
reset_mode = "Скинути режим до типових параметрів ОС"
# Post metadata.
draft = "ЧЕРНЕТКА"

@ -24,8 +24,9 @@ all_posts = "所有文章"
all_tags = "所有标签"
language_selection = "语言选择" # Machine translated.
toggle_mode = "切换到$MODE模式" # $MODE will be replaced by a value (or both) below. Machine translated.
dark = "暗" # Machine translated.
dark = "暗" # Machine translated.
light = "亮" # Machine translated.
reset_mode = "重置为操作系统默认模式" # Machine translated.
# Post metadata.
draft = "草稿"

@ -26,6 +26,7 @@ language_selection = "語言選擇" # Machine translated.
toggle_mode = "切換到$MODE模式" # $MODE will be replaced by a value (or both) below. Machine translated.
dark = "暗" # Machine translated.
light = "亮" # Machine translated.
reset_mode = "重置為操作系統預設模式" # Machine translated.
# Post metadata.
draft = "草稿"

@ -11,3 +11,32 @@
background: var(--meta-color);
}
}
.theme-switcher-wrapper {
position: relative;
}
.theme-resetter {
-webkit-mask: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" %3E%3Cpath d="M295.87-193.869v-78.001h291.152q43.63 0 72.369-33.424 28.739-33.423 28.739-79.271t-28.739-79.391Q630.652-497.5 587.022-497.5H343.913l87.478 87.478-55.652 55.153L193.869-536.5l181.87-181.631 55.652 55.653-87.478 86.978h243.109q75.435 0 127.272 56.522 51.837 56.521 51.837 134.174 0 77.652-51.837 134.293-51.837 56.642-127.272 56.642H295.87Z"/%3E%3C/svg%3E');
position: absolute;
top: -0.6rem;
right: -0.6rem;
visibility: hidden;
opacity: 0;
transition: opacity 0.3s ease, visibility 0.3s ease;
transition-delay: 0.5s;
cursor: pointer;
background: var(--text-color);
width: 0.8rem;
height: 0.8rem;
}
.theme-switcher-wrapper:hover .theme-resetter.has-custom-theme {
visibility: visible;
opacity: 1;
transition: opacity 0.1s ease, visibility 0.1s ease;
transition-delay: 0s;
&:hover {
background: var(--meta-color);
}
}

@ -1,10 +1,11 @@
// Get the theme switcher button element.
// Get the theme switcher button elements.
const themeSwitcher = document.querySelector(".theme-switcher");
const themeResetter = document.querySelector(".theme-resetter");
// Retrieve theme from either the localStorage or the data-theme attribute on the document element.
let currentTheme = localStorage.getItem("theme") || document.documentElement.getAttribute('data-theme');
// Function to set theme
// Function to set theme.
function setTheme(theme, saveToLocalStorage = false) {
document.documentElement.setAttribute("data-theme", theme);
currentTheme = theme;
@ -13,6 +14,12 @@ function setTheme(theme, saveToLocalStorage = false) {
if (saveToLocalStorage) {
localStorage.setItem("theme", theme);
themeResetter.classList.add("has-custom-theme");
themeResetter.setAttribute("aria-hidden", "false");
} else {
localStorage.removeItem("theme");
themeResetter.classList.remove("has-custom-theme");
themeResetter.setAttribute("aria-hidden", "true");
}
// Dispatch a custom event for comment systems.
@ -22,6 +29,12 @@ function setTheme(theme, saveToLocalStorage = false) {
window.dispatchEvent(event);
}
function resetTheme() {
const isSystemDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const defaultTheme = isSystemDark ? "dark" : "light";
setTheme(defaultTheme);
}
// Function to switch between dark and light themes.
function switchTheme() {
// Set the new theme based on the current theme.
@ -31,6 +44,8 @@ function switchTheme() {
// Initialize the theme switcher button.
themeSwitcher.addEventListener("click", switchTheme, false);
themeResetter.addEventListener("click", resetTheme, false);
themeSwitcher.setAttribute("role", "button");
let togglePressed = currentTheme === "dark" ? "true" : "false";
themeSwitcher.setAttribute("aria-pressed", togglePressed);
@ -40,3 +55,9 @@ window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", e =
const newTheme = e.matches ? "dark" : "light";
setTheme(newTheme);
});
if (localStorage.getItem("theme")) {
themeResetter.classList.add("has-custom-theme");
} else {
themeResetter.classList.remove("has-custom-theme");
}

@ -1 +1 @@
const themeSwitcher=document.querySelector(".theme-switcher");let currentTheme=localStorage.getItem("theme")||document.documentElement.getAttribute("data-theme");function setTheme(e,t=!1){document.documentElement.setAttribute("data-theme",e),currentTheme=e;let r="dark"===e?"true":"false";themeSwitcher.setAttribute("aria-pressed",r),t&&localStorage.setItem("theme",e);const h=new CustomEvent("themeChanged",{detail:{theme:e}});window.dispatchEvent(h)}function switchTheme(){setTheme("dark"===currentTheme?"light":"dark",!0)}themeSwitcher.addEventListener("click",switchTheme,!1),themeSwitcher.setAttribute("role","button");let togglePressed="dark"===currentTheme?"true":"false";themeSwitcher.setAttribute("aria-pressed",togglePressed),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",(e=>{setTheme(e.matches?"dark":"light")}));
const themeSwitcher=document.querySelector(".theme-switcher"),themeResetter=document.querySelector(".theme-resetter");let currentTheme=localStorage.getItem("theme")||document.documentElement.getAttribute("data-theme");function setTheme(e,t=!1){document.documentElement.setAttribute("data-theme",e);var r="dark"===(currentTheme=e)?"true":"false",r=(themeSwitcher.setAttribute("aria-pressed",r),t?(localStorage.setItem("theme",e),themeResetter.classList.add("has-custom-theme"),themeResetter.setAttribute("aria-hidden","false")):(localStorage.removeItem("theme"),themeResetter.classList.remove("has-custom-theme"),themeResetter.setAttribute("aria-hidden","true")),new CustomEvent("themeChanged",{detail:{theme:e}}));window.dispatchEvent(r)}function resetTheme(){setTheme(window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light")}function switchTheme(){setTheme("dark"===currentTheme?"light":"dark",!0)}themeSwitcher.addEventListener("click",switchTheme,!1),themeResetter.addEventListener("click",resetTheme,!1),themeSwitcher.setAttribute("role","button");let togglePressed="dark"===currentTheme?"true":"false";themeSwitcher.setAttribute("aria-pressed",togglePressed),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",e=>{setTheme(e.matches?"dark":"light")}),localStorage.getItem("theme")?themeResetter.classList.add("has-custom-theme"):themeResetter.classList.remove("has-custom-theme");

@ -3,16 +3,27 @@
{%- set toggle_str = macros_translate::translate(key='toggle_mode', default='Toggle $MODE mode', language_strings=language_strings) -%}
{%- set dark_str = macros_translate::translate(key='dark', default='dark', language_strings=language_strings) -%}
{%- set light_str = macros_translate::translate(key='light', default='light', language_strings=language_strings) -%}
{%- set combined_mode_str = dark_str ~ "/" ~ light_str -%}
{%- set title_label = toggle_str | replace(from="$MODE", to=combined_mode_str) -%}
{%- set aria_label = toggle_str | replace(from="$MODE", to=dark_str) -%}
<div
<div
title="{{ title_label }}"
class="theme-switcher"
role="button"
aria-label="{{ aria_label }}"
class="theme-switcher"
role="button"
aria-label="{{ aria_label }}"
aria-pressed="false">
</div>
{%- set reset_str = macros_translate::translate(key='reset_mode', default='Reset mode to OS default', language_strings=language_strings) -%}
<div
title="{{ reset_str }}"
class="theme-resetter"
role="button"
aria-hidden="true"
aria-label="{{ reset_str }}">
</div>
</li>

Loading…
Cancel
Save