Skip to content

Commit

Permalink
refactor: update toggle theme function for better structure and a11y
Browse files Browse the repository at this point in the history
Move theme switch js codes in Layout.astro file to external js file (toggle-theme.js). Update
.prettierignore to exclude the new toggle-theme.js file.  Update base.css for new data-theme
attribute.
  • Loading branch information
satnaing committed Nov 26, 2022
1 parent 5a67afc commit 0eeed8e
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 44 deletions.
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

# Except these files & folders
!/src
!/public
!/.github
!tsconfig.json
!astro.config.mjs
Expand Down
52 changes: 52 additions & 0 deletions public/toggle-theme.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
const primaryColorScheme = ""; // "light" | "dark"

// Get theme data from local storage
const currentTheme = localStorage.getItem("theme");

function getPreferTheme() {
// return theme value in local storage if it is set
if (currentTheme) return currentTheme;

// return primary color scheme if it is set
if (primaryColorScheme) return primaryColorScheme;

// return user device's prefer color scheme
return window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "light";
}

let themeValue = getPreferTheme();

function setPreference() {
localStorage.setItem("theme", themeValue);
reflectPreference();
}

function reflectPreference() {
document.firstElementChild.setAttribute("data-theme", themeValue);

document.querySelector("#theme-btn")?.setAttribute("aria-label", themeValue);
}

// set early so no page flashes / CSS is made aware
reflectPreference();

window.onload = () => {
// set on load so screen readers can get the latest value on the button
reflectPreference();

// now this script can find and listen for clicks on the control
document.querySelector("#theme-btn").addEventListener("click", () => {
themeValue = themeValue === "light" ? "dark" : "light";
setPreference();
});
};

// sync with system changes
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", ({ matches: isDark }) => {
themeValue = isDark ? "dark" : "light";
setPreference();
});
40 changes: 1 addition & 39 deletions src/layouts/Layout.astro
Original file line number Diff line number Diff line change
Expand Up @@ -61,45 +61,7 @@ const socialImageURL = new URL(
onload="this.onload=null;this.rel='stylesheet'"
/>

<script is:inline>
const primaryColorScheme = "none"; // "light" | "dark" | "none"

const darkModeMediaQuery = window.matchMedia(
"(prefers-color-scheme: dark)"
).matches;

// Get theme data from local storage
const currentTheme = localStorage.getItem("theme");

let theme;

// Set theme to 'theme-dark' if currentTheme is 'dark'
if (currentTheme) {
theme = currentTheme === "dark" ? "theme-dark" : "";
} else {
// If primary color scheme is dark
// or primary color scheme is not set and prefers-color-scheme is dark
// choose dark mode
if (
primaryColorScheme === "dark" ||
(primaryColorScheme === "none" && darkModeMediaQuery)
) {
theme = "theme-dark";
}
// If primary color scheme is light
// choose light mode
else if (primaryColorScheme === "light") {
theme = "";
}
// fallback to prefers-color-scheme
else {
theme = darkModeMediaQuery ? "theme-dark" : "";
}
}

// Put dark class on html tag to enable dark mode
document.querySelector("html").className = theme;
</script>
<script is:inline src="/toggle-theme.js"></script>
</head>
<body>
<slot />
Expand Down
12 changes: 7 additions & 5 deletions src/styles/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@
@tailwind utilities;

@layer base {
:root {
:root,
html[data-theme="light"] {
--color-fill: 251, 254, 251;
--color-text-base: 40, 39, 40;
--color-accent: 0, 108, 172;
--color-card: 230, 230, 230;
--color-card-muted: 205, 205, 205;
--color-border: 236, 233, 233;
}
.theme-dark {
html[data-theme="dark"] {
--color-fill: 47, 55, 65;
--color-text-base: 230, 230, 230;
--color-accent: 26, 217, 217;
Expand All @@ -20,11 +21,11 @@
--color-border: 59, 70, 85;
}
#sun-svg,
.theme-dark #moon-svg {
html[data-theme="dark"] #moon-svg {
display: none;
}
#moon-svg,
.theme-dark #sun-svg {
html[data-theme="dark"] #sun-svg {
display: block;
}
body {
Expand All @@ -36,7 +37,8 @@
@apply max-w-3xl mx-auto px-4;
}
a {
@apply outline-offset-1 outline-skin-fill outline-2 focus-visible:outline-dashed focus-visible:no-underline;
@apply outline-offset-1 outline-skin-fill outline-2
focus-visible:outline-dashed focus-visible:no-underline;
}
svg {
@apply w-6 h-6 inline-block fill-skin-base group-hover:fill-skin-accent;
Expand Down

0 comments on commit 0eeed8e

Please sign in to comment.