about summary refs log tree commit diff
path: root/src/alf/util/useColorModeTheme.ts
blob: 49e2ec8f55f4d30fdf3bc6e456bdcc8b189bab11 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import React from 'react'
import {useColorScheme} from 'react-native'

import {useThemePrefs} from 'state/shell'
import {isWeb} from 'platform/detection'
import {ThemeName, light, dark, dim} from '#/alf/themes'
import * as SystemUI from 'expo-system-ui'

export function useColorModeTheme(): ThemeName {
  const colorScheme = useColorScheme()
  const {colorMode, darkTheme} = useThemePrefs()

  return React.useMemo(() => {
    if (
      (colorMode === 'system' && colorScheme === 'light') ||
      colorMode === 'light'
    ) {
      updateDocument('light')
      updateSystemBackground('light')
      return 'light'
    } else {
      const themeName = darkTheme ?? 'dim'
      updateDocument(themeName)
      updateSystemBackground(themeName)
      return themeName
    }
  }, [colorMode, darkTheme, colorScheme])
}

function updateDocument(theme: ThemeName) {
  // @ts-ignore web only
  if (isWeb && typeof window !== 'undefined') {
    // @ts-ignore web only
    const html = window.document.documentElement
    // remove any other color mode classes
    html.className = html.className.replace(/(theme)--\w+/g, '')

    html.classList.add(`theme--${theme}`)
  }
}

function updateSystemBackground(theme: ThemeName) {
  switch (theme) {
    case 'light':
      SystemUI.setBackgroundColorAsync(light.atoms.bg.backgroundColor)
      break
    case 'dark':
      SystemUI.setBackgroundColorAsync(dark.atoms.bg.backgroundColor)
      break
    case 'dim':
      SystemUI.setBackgroundColorAsync(dim.atoms.bg.backgroundColor)
      break
  }
}