From 6ab88d7950fc4e9e7f34f5dc0e889c758274d5be Mon Sep 17 00:00:00 2001 From: Abhimanyu Rana Date: Thu, 11 May 2023 03:33:35 +0530 Subject: [PATCH] added theme switcher --- src/layouts/Layout.astro | 48 +++++++++++++++++++++++++++++++++ src/layouts/theme.js | 58 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 src/layouts/theme.js diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index 4b46f73..ce6e619 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -12,6 +12,7 @@ const { title } = Astro.props; + {title} @@ -27,7 +28,12 @@ const { title } = Astro.props; + + + diff --git a/src/layouts/theme.js b/src/layouts/theme.js new file mode 100644 index 0000000..ce9bd63 --- /dev/null +++ b/src/layouts/theme.js @@ -0,0 +1,58 @@ +const storageKey = 'theme-preference' + +const onClick = () => { + // flip current value + theme.value = theme.value === 'light' + ? 'dark' + : 'light' + + 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-new-ui-theme', theme.value) + + document + .querySelector('#theme-toggle') + ?.setAttribute('aria-label', theme.value) +} + +const theme = { + value: getColorPreference(), +} + +// set early so no page flashes / CSS is made aware +reflectPreference() + +window.onload = () => { + // set on load so screen readers can see latest value on the button + reflectPreference() + + // now this script can find and listen for clicks on the control + document + .querySelector('#theme-toggle') + .addEventListener('click', onClick) +} + +// sync with system changes +window + .matchMedia('(prefers-color-scheme: dark)') + .addEventListener('change', ({matches:isDark}) => { + theme.value = isDark ? 'dark' : 'light' + setPreference() + }) \ No newline at end of file