main
ts 64 lines 2.46 KB
Raw
1 // This file is part of HFS - Copyright 2021-2023, Massimo Melina <a@rejetto.com> - License https://www.gnu.org/licenses/gpl-3.0.txt
2
3 import { createTheme, useMediaQuery } from '@mui/material'
4 import { createElement as h, useMemo } from 'react'
5 import { state, useSnapState } from './state'
6 import { Btn, BtnProps } from './mui'
7 import { Brightness4, Brightness7 } from '@mui/icons-material'
8
9 export function useDark() {
10 return useMediaQuery('(prefers-color-scheme: dark)')
11 }
12
13 const EMPTY = {}
14 export function useMyTheme() {
15 const { darkTheme } = useSnapState()
16 const detected = useDark()
17 const lightMode = (darkTheme ?? detected) ? null : EMPTY
18 return useMemo(() => createTheme({
19 palette: lightMode || {
20 mode: 'dark',
21 text: { primary: '#bbb', secondary: '#fff6' },
22 primary: { main: '#469', light: '#68c' },
23 secondary: { main: '#969' },
24 },
25 typography: {
26 fontFamily: 'Roboto, "Noto sans", "Segoe UI", "San Francisco", "Helvetica Neue", Arial, sans-serif'
27 },
28 components: {
29 MuiLink: {
30 defaultProps: lightMode || { color: 'primary.light' }, // primary.main too dark for dark theme
31 },
32 MuiTextField: {
33 defaultProps: { variant: 'filled' },
34 styleOverrides: lightMode || {
35 root: { '& label.Mui-focused': { color: '#ccc' } } // our primary.main is too dark for mui's dark theme, and when input element is :-webkit-autofill it will make not enough contrast
36 }
37 },
38 MuiButton: {
39 defaultProps: { variant: 'outlined' },
40 styleOverrides: lightMode || {
41 root({ ownerState }) {
42 return ownerState.color === 'primary' && {
43 color: ownerState.variant === 'contained' ? '#ddd' : '#68c'
44 }
45 }
46 }
47 }
48 }
49 }), [lightMode])
50 }
51
52 export function SwitchThemeBtn(props: BtnProps) {
53 const { darkTheme } = useSnapState()
54 const darkDetected = useDark()
55 const currentlyDark = darkTheme ?? darkDetected
56 return h(Btn, {
57 icon: currentlyDark ? Brightness7 : Brightness4,
58 onClick: () => {
59 const v = !currentlyDark
60 return state.darkTheme = darkDetected === v ? undefined : v
61 },
62 ...props,
63 }, currentlyDark ? "Light theme" : "Dark theme")
64 }