@@ -3,13 +3,15 @@ import { DOCUMENT } from '@angular/common';
33import { MediaMatcher } from '@angular/cdk/layout' ;
44import { StorageService } from '../../services/storage.service' ;
55
6+ type Theme = 'light' | 'dark' ;
7+
68@Component ( {
79 selector : 'app-theme-mode-toggle' ,
810 templateUrl : './theme-mode-toggle.component.html' ,
911 styleUrls : [ './theme-mode-toggle.component.scss' ] ,
1012} )
1113export class ThemeModeToggleComponent implements OnInit {
12- isDarkMode : boolean ;
14+ theme : Theme ;
1315
1416 constructor (
1517 @Inject ( DOCUMENT )
@@ -19,31 +21,35 @@ export class ThemeModeToggleComponent implements OnInit {
1921 ) { }
2022
2123 ngOnInit ( ) {
22- // This is commented out because by default the theme mode is set to light (at least for now)
23- // const userPrefersTheme =
24- // this.mediaMatcher.matchMedia &&
25- // this.mediaMatcher.matchMedia('(prefers-color-scheme: light)').matches;
26- // this.setThemeMode(this.getUserSettingsIsDarkMode() || userPrefersTheme);
27-
28- const isDarkMode = this . getUserSettingsIsDarkMode ( ) ;
29- this . setThemeMode ( isDarkMode ) ;
24+ const preferredScheme = this . mediaMatcher . matchMedia (
25+ '(prefers-color-scheme: dark)' ,
26+ ) ;
27+
28+ preferredScheme . onchange = ( ) => {
29+ if ( ! this . getStoredTheme ( ) ) this . toggleTheme ( true ) ;
30+ } ;
31+
32+ const isDarkSchemePreferred = preferredScheme . matches ;
33+ const storedTheme = this . getStoredTheme ( ) ;
34+
35+ this . theme = storedTheme ?? ( isDarkSchemePreferred ? 'dark' : 'light' ) ;
36+ this . setTheme ( this . theme ) ;
3037 }
3138
32- toggleThemeMode ( ) {
33- const isDarkMode = ! this . isDarkMode ;
34- this . storageService . set ( 'theme-mode' , isDarkMode . toString ( ) ) ;
35- this . setThemeMode ( isDarkMode ) ;
39+ toggleTheme ( skipStorage = false ) {
40+ this . theme = this . theme === 'dark' ? 'light' : 'dark' ;
41+ // NOTE: We should skip saving theme in storage when toggle is caused by matchMedia change event
42+ // Otherwise, once saved, it'll no longer correspond to the system preferences,
43+ // despite the user not touching the toggle button themselves
44+ if ( ! skipStorage ) this . storageService . set ( 'theme' , this . theme ) ;
45+ this . setTheme ( this . theme ) ;
3646 }
3747
38- private getUserSettingsIsDarkMode ( ) : boolean {
39- return this . storageService . get ( 'theme-mode ' ) === 'true' ;
48+ private getStoredTheme ( ) {
49+ return this . storageService . get ( 'theme' ) as Theme | null ;
4050 }
4151
42- private setThemeMode ( isDarkMode : boolean ) {
43- this . isDarkMode = isDarkMode ;
44- this . document . documentElement . setAttribute (
45- 'mode' ,
46- isDarkMode ? 'dark' : 'light' ,
47- ) ;
52+ private setTheme ( theme : Theme ) {
53+ this . document . documentElement . setAttribute ( 'mode' , theme ) ;
4854 }
4955}
0 commit comments