1- document . addEventListener ( "DOMContentLoaded" , ( ) => {
2- const themeBtn = document . querySelector ( '#theme-toggle' ) ;
3- const root = document ?. documentElement ;
4-
5- const themeWatcher = watchColorSchemeChange ( ( colorScheme ) => {
6- if ( ! hasLocalStorage ( ) ) {
7- // If localStorage is not supported, use system preference
1+ let themeBtn ;
2+ const themeWatcher = watchColorSchemeChange ( ( colorScheme ) => {
3+ if ( ! hasLocalStorage ( ) ) {
4+ // If localStorage is not supported, use system preference
5+ document ?. addEventListener ( 'DOMContentLoaded' , ( ) => {
6+ // remove icon
7+ document . querySelector ( '#theme-toggle' ) . remove ( )
88 setTheme ( colorScheme ) ;
9- themeBtn . remove ( ) ; // Hide toggle
9+ } )
10+ } else {
11+ const localTheme = localStorage . getItem ( 'expressjs-theme' ) ;
12+ if ( localTheme === null ) {
13+ localStorage . setItem ( 'expressjs-theme' , colorScheme ) ; // store system theme as local theme
14+ setTheme ( colorScheme ) ; // use system theme
1015 } else {
11- const localTheme = localStorage . getItem ( 'local-theme' ) ;
12- if ( localTheme === null ) {
13- localStorage . setItem ( 'local-theme' , colorScheme ) ; // store system theme as local theme
14- setTheme ( colorScheme ) ; // use system theme
15- } else {
16- setTheme ( localTheme ) ; // use previous theme
17- }
16+ setTheme ( localTheme ) ; // use previous theme
17+ } ;
1818
19+ document . addEventListener ( "DOMContentLoaded" , ( ) => {
20+ const themeBtn = document . querySelector ( '#theme-toggle' ) ;
1921 // add click event on theme loggle btn
2022 themeBtn . addEventListener ( 'click' , toggleLocalStorageTheme ) ;
2123 // set accessibility on page load
2224 themeBtn . setAttribute ( 'aria-label' , colorScheme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode' ) ;
23- }
24- } ) ;
25+ } ) ;
26+ }
27+ } ) ;
2528
26- // apply given theme
27- function setTheme ( theme ) {
28- if ( theme === 'dark' ) {
29- darkModeOn ( )
30- } else {
31- lightModeOn ( )
32- }
29+ // apply given theme
30+ function setTheme ( theme ) {
31+ if ( theme === 'dark' ) {
32+ darkModeOn ( )
33+ } else {
34+ lightModeOn ( )
3335 }
34- // toggle theme btn or set a theme if none set
35- function toggleLocalStorageTheme ( ) {
36- let nextTheme ;
37- const localTheme = localStorage . getItem ( 'local-theme' ) ;
36+ }
37+ // toggle theme btn or set a theme if none set
38+ function toggleLocalStorageTheme ( ) {
39+ let nextTheme ;
40+ const localTheme = localStorage . getItem ( 'expressjs-theme' ) ;
3841
39- if ( localTheme === 'light' ) {
40- nextTheme = 'dark' ;
41- } else if ( localTheme === 'dark' ) {
42- nextTheme = 'light' ;
43- } else {
44- nextTheme = darkModeState ( ) ? 'light' : 'dark' ;
45- }
42+ if ( localTheme === 'light' ) {
43+ nextTheme = 'dark' ;
44+ } else if ( localTheme === 'dark' ) {
45+ nextTheme = 'light' ;
46+ } else {
47+ nextTheme = darkModeState ( ) ? 'light' : 'dark' ; // fallback
48+ } ;
4649
47- localStorage . setItem ( 'local-theme' , nextTheme ) ;
48- setTheme ( nextTheme ) ;
49- }
50- function darkModeOn ( ) {
51- root . classList . remove ( 'light-mode' )
52- root . classList . add ( 'dark-mode' )
53- updateThemeIcon ( 'dark' ) ;
54- }
55- function lightModeOn ( ) {
56- root . classList . remove ( 'dark-mode' )
57- root . classList . add ( 'light-mode' )
58- updateThemeIcon ( 'light' ) ;
59- }
60- function darkModeState ( ) {
61- return root . classList . contains ( 'dark-mode' )
62- }
63- function hasLocalStorage ( ) {
64- return typeof Storage !== 'undefined'
65- }
66- function watchColorSchemeChange ( callback ) {
67- // get system theme preference
68- const darkMediaQuery = window ?. matchMedia ( '(prefers-color-scheme: dark)' )
50+ localStorage . setItem ( 'local-theme' , nextTheme ) ;
51+ setTheme ( nextTheme ) ;
52+ }
53+ function darkModeOn ( ) {
54+ document ?. documentElement ? .classList . remove ( 'light-mode' )
55+ document ?. documentElement ? .classList . add ( 'dark-mode' )
56+ updateThemeIcon ( 'dark' ) ;
57+ }
58+ function lightModeOn ( ) {
59+ document ?. documentElement ? .classList . remove ( 'dark-mode' )
60+ document ?. documentElement ? .classList . add ( 'light-mode' )
61+ updateThemeIcon ( 'light' ) ;
62+ }
63+ function darkModeState ( ) {
64+ return document ?. documentElement ? .classList . contains ( 'dark-mode' )
65+ }
66+ function hasLocalStorage ( ) {
67+ return typeof Storage !== 'undefined'
68+ }
69+ function watchColorSchemeChange ( callback ) {
70+ // get system theme preference
71+ const darkMediaQuery = window ?. matchMedia ( '(prefers-color-scheme: dark)' )
6972
70- const handleChange = ( event ) => {
71- const newColorScheme = event ?. matches ? 'dark' : 'light'
72- callback ( newColorScheme )
73- }
74- darkMediaQuery . addEventListener ( 'change' , handleChange )
75- // initial call : if system theme is not dark then light mode is choosen
76- callback ( darkMediaQuery . matches ? 'dark' : 'light' )
77- // remove event from window
78- return ( ) => darkMediaQuery . removeEventListener ( 'change' , handleChange )
73+ const handleChange = ( event ) => {
74+ const newColorScheme = event ?. matches ? 'dark' : 'light'
75+ callback ( newColorScheme )
7976 }
77+ darkMediaQuery . addEventListener ( 'change' , handleChange )
78+ // initial call : if system theme is not dark then light mode is choosen
79+ callback ( darkMediaQuery . matches ? 'dark' : 'light' )
80+ // remove event from window
81+ return ( ) => darkMediaQuery . removeEventListener ( 'change' , handleChange )
82+ }
8083
81- function updateThemeIcon ( theme ) {
82- const sun = document . getElementById ( 'icon-sun' ) ;
83- const moon = document . getElementById ( 'icon-moon' ) ;
84- if ( ! sun || ! moon ) return ;
85-
86- const isDark = theme === 'dark' ;
84+ function updateThemeIcon ( theme ) {
85+ const sun = document . getElementById ( 'icon-sun' ) ;
86+ const moon = document . getElementById ( 'icon-moon' ) ;
87+ const themeBtn = document . querySelector ( '#theme-toggle' ) ;
88+ if ( ! sun || ! moon ) return ;
8789
88- // hide or show icon
89- sun . hidden = ! isDark ;
90- moon . hidden = isDark ;
91- // improve accessibility for screen readers
92- sun . setAttribute ( 'aria-hidden' , isDark ? 'false' : 'true' ) ;
93- moon . setAttribute ( 'aria-hidden' , isDark ? 'true' : 'false' ) ;
94- // change label on btn click
95- themeBtn . setAttribute ( 'aria-label' , isDark ? 'Switch to light mode' : 'Switch to dark mode' ) ;
96- } ;
97- } ) ;
90+ const isDark = theme === 'dark' ;
91+
92+ // hide or show icon
93+ sun . hidden = ! isDark ;
94+ moon . hidden = isDark ;
95+ // improve accessibility for screen readers
96+ sun . setAttribute ( 'aria-hidden' , isDark ? 'false' : 'true' ) ;
97+ moon . setAttribute ( 'aria-hidden' , isDark ? 'true' : 'false' ) ;
98+ // change label on btn click
99+ themeBtn . setAttribute ( 'aria-label' , isDark ? 'Switch to light mode' : 'Switch to dark mode' ) ;
100+ } ;
0 commit comments