Last active
September 2, 2024 08:54
-
-
Save perjo927/421c718b410a17c8b6f3e383e4c0babc to your computer and use it in GitHub Desktop.
dark/light mode toggle
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
:root { | |
--black: rgb(13, 13, 13); | |
--darkest-gray: rgb(24, 25, 32); | |
--dark-gray: rgb(79, 79, 79); | |
--medium-gray: rgb(130, 130, 130); | |
--gray: rgb(189, 189, 189); | |
--light-gray: rgb(224, 224, 224); | |
--lightest-gray: rgb(242, 242, 242); | |
--white: rgb(250, 250, 250); | |
--purple: rgb(101, 82, 224); | |
--gold: rgb(204, 155, 46); | |
--green: rgb(46, 204, 69); | |
--blue: rgb(46, 120, 204); | |
--light-blue: rgb(46, 196, 204); | |
--light-red: rgb(235, 86, 86); | |
--light-yellow: rgb(246, 212, 126); | |
--primary-bg-color-darkmode: var(--darkest-gray); | |
--secondary-bg-color-darkmode: var(--black); | |
--primary-text-color-darkmode: var(--white); | |
--border-color-darkmode: var(--dark-gray); | |
--primary-bg-color-lightmode: var(--light-gray); | |
--secondary-bg-color-lightmode: var(--white); | |
--primary-text-color-lightmode: var(--darkest-gray); | |
--border-color-lightmode: var(--gray); | |
--primary-bg-color: var(--primary-bg-color-lightmode); | |
--secondary-bg-color: var(--secondary-bg-color-lightmode); | |
--primary-text-color: var(--primary-text-color-lightmode); | |
--secondary-text-color: var(--medium-gray); | |
--primary-color: var(--purple); | |
--secondary-color: var(--light-blue); | |
--error-color: var(--light-red); | |
--warning-color: var(--light-yellow); | |
--link-color: var(--primary-color); | |
--border-color: var(--border-color-lightmode); | |
--border-radius: 0.25rem; | |
--base-gap: 0.75rem; | |
--container-padding: 0.75rem; | |
--z-index-bottom: 1; | |
--z-index-popup: 10; | |
--z-index-menu: 1000; | |
--primary-box-shadow: 0 0.25rem 0.375rem var(--border-color); | |
font-size: 16px; | |
font-family: 'Manrope', Helvetica, Arial, sans-serif; | |
color-scheme: dark light; | |
/* TODO: this dark-mode switch is not supported yet */ | |
/* https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/light-dark */ | |
/* | |
color: light-dark(var(--primary-text-color), var(--primary-text-color-darkmode)); | |
background-color: light-dark( | |
var(--primary-bg-color), | |
var(--primary-bg-color-darkmode) | |
); | |
*/ | |
color: var(--primary-text-color); | |
background-color: var(--primary-bg-color); | |
} | |
/* media query that listens to system preferecens */ | |
@media (prefers-color-scheme: dark) { | |
/* TODO: this can be replaced by light-dark in the future */ | |
:root { | |
--primary-bg-color: var(--primary-bg-color-darkmode); | |
--secondary-bg-color: var(--secondary-bg-color-darkmode); | |
--primary-text-color: var(--primary-text-color-darkmode); | |
--border-color: var(--border-color-darkmode); | |
} | |
} | |
/* data attributes for color scheme that are set to user preferences */ | |
[data-theme='light'] { | |
--primary-bg-color: var(--primary-bg-color-lightmode); | |
--secondary-bg-color: var(--secondary-bg-color-lightmode); | |
--primary-text-color: var(--primary-text-color-lightmode); | |
--border-color: var(--border-color-lightmode); | |
} | |
[data-theme='dark'] { | |
--primary-bg-color: var(--primary-bg-color-darkmode); | |
--secondary-bg-color: var(--secondary-bg-color-darkmode); | |
--primary-text-color: var(--primary-text-color-darkmode); | |
--border-color: var(--border-color-darkmode); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {getColorScheme, initColorScheme} from './utils/color-scheme'; | |
import {themeContext} from './data/contexts/theme-context'; | |
@customElement('app-root') | |
export class AppRootElement extends LitElement { | |
private _themeContext = new ContextProvider(this, { | |
context: themeContext, | |
initialValue: { | |
colorScheme: getColorScheme(), | |
}, | |
}); | |
#handleColorSchemeChanged = (event: Event) => { | |
const detail = (event as CustomEvent).detail; | |
this._themeContext.setValue({ | |
colorScheme: detail, | |
}); | |
}; | |
override connectedCallback(): void { | |
super.connectedCallback(); | |
initColorScheme(); | |
} | |
protected override firstUpdated(): void { | |
const mediaQueryListener = window.matchMedia('(min-width: 992px)'); | |
this.#handleMenuToggled(null, mediaQueryListener.matches); | |
const header = this.renderRoot.querySelector('header-element'); | |
header?.addEventListener( | |
HeaderElement.events.colorSchemeChanged, | |
this.#handleColorSchemeChanged | |
); | |
} | |
constructor() { | |
super(); | |
} | |
override render() { | |
return html` | |
<header> | |
Some stuff here | |
</header> | |
<aside> | |
Some other stuff here | |
</aside> | |
<main>Some more stuff here</main> | |
`; | |
} | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {ColorScheme} from '../types'; | |
export function getColorScheme(): ColorScheme { | |
const currentUserTheme = localStorage.getItem('color-scheme'); | |
if (currentUserTheme) { | |
const userTheme = currentUserTheme as ColorScheme; | |
return userTheme; | |
} | |
const darkScheme = window.matchMedia('(prefers-color-scheme: dark)'); | |
const lightScheme = window.matchMedia('(prefers-color-scheme: light)'); | |
if (darkScheme.matches) { | |
return 'dark'; | |
} | |
if (lightScheme.matches) { | |
return 'light'; | |
} | |
return 'dark'; | |
} | |
export function initColorScheme() { | |
const currentUserTheme = localStorage.getItem('color-scheme'); | |
if (currentUserTheme) { | |
const htmlElement = document.querySelector('html'); | |
htmlElement?.setAttribute('data-theme', currentUserTheme); | |
} | |
} | |
export function toggleColorScheme( | |
onToggledColorScheme: (colorScheme: ColorScheme) => void | |
) { | |
const currentTheme = getColorScheme(); | |
const htmlElement = document.querySelector('html'); | |
const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; | |
localStorage.setItem('color-scheme', newTheme); | |
htmlElement?.setAttribute('data-theme', newTheme); | |
onToggledColorScheme(newTheme); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment