const themeToggle = document.createElement('template');
themeToggle.innerHTML = `
`;
class ThemeToggle extends HTMLElement {
constructor() {
super();
this.attachShadow({
mode: 'open'
}).append(themeToggle.content.cloneNode(true));
this.isChecked = false;
this.hasTheme = 'light';
this.toggleState = this.toggleState.bind(this);
this.fireEvent = this.fireEvent.bind(this);
this.handleThemeChange = this.handleThemeChange.bind(this);
}
static get observedAttributes() {
return ['checked'];
}
daylight() {
this.hasTheme = 'light';
document.body.dataset.theme = 'light';
this.setAttribute('aria-checked', 'false');
}
nightlight() {
this.hasTheme = 'dark';
document.body.dataset.theme = 'dark';
this.setAttribute('aria-checked', 'true');
}
toggleState() {
this.toggleAttribute('checked');
this.fireEvent();
}
handleKeyDown(e) {
if (e.key === ' ') {
this.toggleState();
}
}
handleThemeChange(e) {
if (e.detail.theme !== this.hasTheme) {
if (e.detail.theme === 'dark') {
this.setAttribute('checked', '');
}
else {
this.removeAttribute('checked');
}
}
}
fireEvent() {
this.dispatchEvent(
new CustomEvent('themechange', {
bubbles: true,
composed: true,
detail: {
theme: this.hasTheme
}
})
);
}
connectedCallback() {
this.setAttribute('role', 'switch');
this.setAttribute('aria-label', 'theme toggle');
if (localStorage.getItem(`${window.location.hostname}-theme`) === "dark") {
this.nightlight();
this.setAttribute('checked', '');
} else if (localStorage.getItem(`${window.location.hostname}-theme`) === "light") {
this.daylight();
this.removeAttribute('checked');
}
else {
if (window.matchMedia(`(prefers-color-scheme: dark)`).matches) {
this.nightlight();
this.setAttribute('checked', '');
} else {
this.daylight();
this.removeAttribute('checked');
}
}
this.addEventListener("click", this.toggleState);
this.addEventListener("keydown", this.handleKeyDown);
document.addEventListener('themechange', this.handleThemeChange);
}
disconnectedCallback() {
this.removeEventListener("click", this.toggleState);
this.removeEventListener("keydown", this.handleKeyDown);
document.removeEventListener('themechange', this.handleThemeChange);
}
attributeChangedCallback(name, oldVal, newVal) {
if (name === 'checked') {
if (this.hasAttribute('checked')) {
this.nightlight();
localStorage.setItem(`${window.location.hostname}-theme`, "dark");
} else {
this.daylight();
localStorage.setItem(`${window.location.hostname}-theme`, "light");
}
}
}
}
window.customElements.define('theme-toggle', ThemeToggle);