From be5ada8bdf8a2f0bebb0c33095b6f4421d27b456 Mon Sep 17 00:00:00 2001 From: madrilene Date: Fri, 9 Feb 2024 11:07:18 +0100 Subject: [PATCH] theme switch as component, fixed accessibility --- package.json | 2 +- src/_includes/components/theme-switch.njk | 16 +++++ src/_includes/partials/footer.njk | 19 +----- src/_includes/theme-toggle-inline.js | 2 +- src/assets/css/blocks/theme-switch.css | 11 +++- src/assets/scripts/theme-toggle.js | 76 ++++++++++++----------- 6 files changed, 69 insertions(+), 57 deletions(-) create mode 100644 src/_includes/components/theme-switch.njk diff --git a/package.json b/package.json index 0f16db7..2742301 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eleventy-excellent", - "version": "2.1.1", + "version": "2.1.2", "description": "Eleventy starter based on the workflow suggested by Andy Bell's buildexcellentwebsit.es.", "author": "Lene Saile", "license": "ISC", diff --git a/src/_includes/components/theme-switch.njk b/src/_includes/components/theme-switch.njk new file mode 100644 index 0000000..0e7bfc6 --- /dev/null +++ b/src/_includes/components/theme-switch.njk @@ -0,0 +1,16 @@ + diff --git a/src/_includes/partials/footer.njk b/src/_includes/partials/footer.njk index 5083b44..c939243 100644 --- a/src/_includes/partials/footer.njk +++ b/src/_includes/partials/footer.njk @@ -40,24 +40,9 @@ -
Made with {% include 'svg/heart.svg' %} diff --git a/src/_includes/theme-toggle-inline.js b/src/_includes/theme-toggle-inline.js index 3e73915..d90fdf2 100644 --- a/src/_includes/theme-toggle-inline.js +++ b/src/_includes/theme-toggle-inline.js @@ -1 +1 @@ -(()=>{var r="theme-preference",l="{{ meta.themeSwitch.light }}",o="{{ meta.themeSwitch.dark }}",h=()=>{e.value=e.value==="light"?"dark":"light",document.querySelector("[theme-toggle]").querySelector("span").innerHTML=e.value==="light"?l:o,n()},i=()=>localStorage.getItem(r)?localStorage.getItem(r):window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light",n=()=>{localStorage.setItem(r,e.value),c()},c=()=>{document.firstElementChild.setAttribute("data-theme",e.value)},e={value:i()};c();window.onload=()=>{let t=document.querySelector("[theme-toggle]"),a=document.querySelector("[data-theme-switcher]");a&&(a.removeAttribute("hidden"),c(),t.addEventListener("click",h),t.querySelector("span").innerHTML=e.value==="light"?l:o)};window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",({matches:t})=>{e.value=t?"dark":"light",n()});})(); +(()=>{var r="theme-preference",n="{{ meta.themeSwitch.light }}",d="{{ meta.themeSwitch.dark }}",t={value:s()};window.onload=()=>{let e=document.querySelector("#light-theme-toggle"),l=document.querySelector("#dark-theme-toggle"),o=document.querySelector("[data-theme-switcher]");o&&(o.removeAttribute("hidden"),a(),e.addEventListener("click",()=>c("light")),l.addEventListener("click",()=>c("dark")),e.setAttribute("aria-pressed",t.value==="light"),l.setAttribute("aria-pressed",t.value==="dark"))};window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",({matches:e})=>{t.value=e?"dark":"light",i()});function c(e){t.value=e,document.querySelector("#light-theme-toggle").setAttribute("aria-pressed",e==="light"),document.querySelector("#dark-theme-toggle").setAttribute("aria-pressed",e==="dark"),i()}function s(){return localStorage.getItem(r)?localStorage.getItem(r):window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}function i(){localStorage.setItem(r,t.value),a()}function a(){document.firstElementChild.setAttribute("data-theme",t.value),document.querySelector("#light-theme-toggle")?.setAttribute("aria-label",n),document.querySelector("#dark-theme-toggle")?.setAttribute("aria-label",d)}a();})(); diff --git a/src/assets/css/blocks/theme-switch.css b/src/assets/css/blocks/theme-switch.css index 7ff125b..e4d3ed3 100644 --- a/src/assets/css/blocks/theme-switch.css +++ b/src/assets/css/blocks/theme-switch.css @@ -6,8 +6,15 @@ .theme-switch .button { --button-border: var(--color-bg-accent-2); border-radius: var(--border-radius); - font-size: var(--size-step-min-1); - padding: 0.1rem 0; + font-size: var(--size-step-min-2); + padding: 0.1rem 0.625rem; font-weight: 600; min-block-size: 1.5em; + text-transform: uppercase; +} + +.theme-switch .button[aria-pressed='true'] { + --button-bg: var(--color-primary); + --button-text: var(--color-base-light); + --button-border: var(--color-primary); } diff --git a/src/assets/scripts/theme-toggle.js b/src/assets/scripts/theme-toggle.js index 0d44b0f..f97dc06 100644 --- a/src/assets/scripts/theme-toggle.js +++ b/src/assets/scripts/theme-toggle.js @@ -1,44 +1,14 @@ const storageKey = 'theme-preference'; - -// get labels from meta const lightLabel = '{{ meta.themeSwitch.light }}'; const darkLabel = '{{ meta.themeSwitch.dark }}'; -const onClick = () => { - // flip current value - theme.value = theme.value === 'light' ? 'dark' : 'light'; - document.querySelector('[theme-toggle]').querySelector('span').innerHTML = - theme.value === 'light' ? lightLabel : darkLabel; - setPreference(); -}; - -const getColorPreference = () => { - if (localStorage.getItem(storageKey)) return localStorage.getItem(storageKey); - else - return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; -}; - -const setPreference = () => { - localStorage.setItem(storageKey, theme.value); - reflectPreference(); -}; - -const reflectPreference = () => { - document.firstElementChild.setAttribute('data-theme', theme.value); - - // themeToggle.querySelector('span').innerHTML = - // theme.value === 'light' ? lightLabel : darkLabel; -}; - const theme = { value: getColorPreference() }; -// set early so no page flashes / CSS is made aware -reflectPreference(); - window.onload = () => { - const themeToggle = document.querySelector('[theme-toggle]'); + const lightThemeToggle = document.querySelector('#light-theme-toggle'); + const darkThemeToggle = document.querySelector('#dark-theme-toggle'); const switcher = document.querySelector('[data-theme-switcher]'); if (!switcher) { @@ -46,12 +16,13 @@ window.onload = () => { } switcher.removeAttribute('hidden'); - reflectPreference(); - themeToggle.addEventListener('click', onClick); - themeToggle.querySelector('span').innerHTML = - theme.value === 'light' ? lightLabel : darkLabel; + lightThemeToggle.addEventListener('click', () => onClick('light')); + darkThemeToggle.addEventListener('click', () => onClick('dark')); + + lightThemeToggle.setAttribute('aria-pressed', theme.value === 'light'); + darkThemeToggle.setAttribute('aria-pressed', theme.value === 'dark'); }; // sync with system changes @@ -61,3 +32,36 @@ window theme.value = isDark ? 'dark' : 'light'; setPreference(); }); + +function onClick(themeValue) { + theme.value = themeValue; + document + .querySelector('#light-theme-toggle') + .setAttribute('aria-pressed', themeValue === 'light'); + document + .querySelector('#dark-theme-toggle') + .setAttribute('aria-pressed', themeValue === 'dark'); + setPreference(); +} + +function getColorPreference() { + if (localStorage.getItem(storageKey)) { + return localStorage.getItem(storageKey); + } else { + return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; + } +} + +function setPreference() { + localStorage.setItem(storageKey, theme.value); + reflectPreference(); +} + +function reflectPreference() { + document.firstElementChild.setAttribute('data-theme', theme.value); + document.querySelector('#light-theme-toggle')?.setAttribute('aria-label', lightLabel); + document.querySelector('#dark-theme-toggle')?.setAttribute('aria-label', darkLabel); +} + +// set early so no page flashes / CSS is made aware +reflectPreference();