chore: theme toggle web component
This commit is contained in:
parent
5e8154dccd
commit
434346dc36
6 changed files with 76 additions and 122 deletions
|
@ -1,60 +0,0 @@
|
|||
const themeToggleTemplate = document.createElement('template')
|
||||
|
||||
themeToggleTemplate.innerHTML = `
|
||||
<button class="theme__toggle">
|
||||
<span class="light"></span>
|
||||
<span class="dark"></span>
|
||||
</button>
|
||||
`
|
||||
|
||||
themeToggleTemplate.id = "theme-toggle-template"
|
||||
|
||||
if (!document.getElementById(themeToggleTemplate.id)) document.body.appendChild(themeToggleTemplate)
|
||||
|
||||
class ThemeToggle extends HTMLElement {
|
||||
static register(tagName) {
|
||||
if ("customElements" in window) customElements.define(tagName || "theme-toggle", ThemeToggle)
|
||||
}
|
||||
|
||||
async connectedCallback() {
|
||||
this.append(this.template)
|
||||
const btn = this.querySelector('.theme__toggle')
|
||||
const setTheme = (isOnLoad) => {
|
||||
const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
const currentTheme = localStorage?.getItem('theme')
|
||||
let theme
|
||||
if (!currentTheme) localStorage?.setItem('theme', (prefersDarkScheme ? 'dark' : 'light'))
|
||||
if (isOnLoad) {
|
||||
if (currentTheme === 'dark') {
|
||||
document.body.classList.add('theme__dark')
|
||||
} else if (currentTheme === 'light') {
|
||||
document.body.classList.add('theme__light')
|
||||
} else if (prefersDarkScheme) {
|
||||
document.body.classList.add('theme__dark')
|
||||
} else if (!prefersDarkScheme) {
|
||||
document.body.classList.add('theme__light')
|
||||
}
|
||||
}
|
||||
if (prefersDarkScheme) {
|
||||
theme = document.body.classList.contains('theme__light') ? 'light' : 'dark'
|
||||
} else {
|
||||
theme = document.body.classList.contains('theme__dark') ? 'dark' : 'light'
|
||||
}
|
||||
localStorage?.setItem('theme', theme)
|
||||
}
|
||||
|
||||
setTheme(true);
|
||||
|
||||
btn.addEventListener('click', () => {
|
||||
document.body.classList.toggle('theme__light')
|
||||
document.body.classList.toggle('theme__dark')
|
||||
setTheme()
|
||||
})
|
||||
}
|
||||
|
||||
get template() {
|
||||
return document.getElementById(themeToggleTemplate.id).content.cloneNode(true)
|
||||
}
|
||||
}
|
||||
|
||||
ThemeToggle.register()
|
|
@ -31,7 +31,7 @@
|
|||
--gray-lighter: var(--gray-50);
|
||||
--gray-dark: var(--gray-700);
|
||||
|
||||
/* theme */
|
||||
/* base theme */
|
||||
--color-lightest: var(--white);
|
||||
--color-darkest: var(--black);
|
||||
--text-color: var(--color-darkest);
|
||||
|
@ -116,6 +116,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
/* light theme */
|
||||
:root body.theme__light {
|
||||
--text-color: var(--color-darkest);
|
||||
--background-color: var(--color-lightest);
|
||||
|
@ -130,6 +131,7 @@
|
|||
--brand-github: #333;
|
||||
}
|
||||
|
||||
/* dark theme */
|
||||
:root body.theme__dark {
|
||||
--text-color: var(--color-lightest);
|
||||
--background-color: var(--color-darkest);
|
||||
|
|
|
@ -140,4 +140,6 @@ The final template that leverages the component looks like this:
|
|||
|
||||
I load the web component script, embed my styles, define the template such that preferred icons are included using [Eleventy](https://www.11ty.dev/) shortcodes and the result is wrapped in an `li` to match the rest of my menu items, with `.client-side` added to hide the component should JavaScript be disabled.
|
||||
|
||||
[The complete JavaScript can be viewed in the source for my site.](https://github.com/cdransf/coryd.dev/blob/main/src/assets/scripts/components/theme-toggle.js)
|
||||
[The complete JavaScript can be viewed in the source for my site.](https://github.com/cdransf/coryd.dev/blob/main/src/assets/scripts/components/theme-toggle.js)
|
||||
|
||||
You can also install the component via npm using `npm i @cdransf/theme-toggle`.
|
Reference in a new issue