Simple, flexible, reactive mobx theme detector and switcher
mobx-theme
Simple, flexible, reactive mobx theme detector and switcher.
Features
- Uses prefers-color-schemeto detect initial theme
- Saves selected theme to local storage for the next page load.
- Updates theme between tabs (this is a feature of mobx-localstorage)
- Updates theme when preferred color scheme changes (this is a feature of mobx-matchmedia)
- You can add more themes in addition to 'light'and'dark'
Example
This example uses Webpack style-loader with lazyStyleTag. You can see the complete folder in the demo dir.
import { Theme } from 'mobx-theme'
import light from './light.lazy.css'
import dark from './dark.lazy.css'
import { autorunCleanup } from 'mobx-autorun-cleanup'
import { render } from 'react-dom'
import { observer } from 'mobx-react-lite'
const themes = { dark, light }
const theme = new Theme()
autorunCleanup(() => {
  const currentTheme = theme.theme
  themes[currentTheme].use()
  console.log('Loaded theme', currentTheme)
  return () => {
    themes[currentTheme].unuse()
    console.log('Unloaded theme', currentTheme)
  }
})
const Component = observer(() => (
  <select
    value={theme.selectedTheme ?? 'system'}
    onChange={({ target: { value } }) => {
      theme.selectedTheme = value === 'system' ? undefined : value
    }}
  >
    <option value='dark'>Dark</option>
    <option value='light'>Light</option>
    <option value='system'>System</option>
  </select>
))
render(<Component />, document.getElementById('app'))