Skip to content

Commit

Permalink
Merge pull request #1931 from oasisprotocol/mz/systemTheme
Browse files Browse the repository at this point in the history
Enable system option in theme dropdown
  • Loading branch information
buberdds committed May 14, 2024
2 parents cdc95f9 + d16307f commit 61181fe
Show file tree
Hide file tree
Showing 7 changed files with 20 additions and 15 deletions.
1 change: 1 addition & 0 deletions .changelog/1931.trivial.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Enable system option in theme dropdown
16 changes: 11 additions & 5 deletions src/app/components/ThemeSwitcher/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/
import { Moon } from 'grommet-icons/es6/icons/Moon'
import { Sun } from 'grommet-icons/es6/icons/Sun'
import { System } from 'grommet-icons/es6/icons/System'
import { memo } from 'react'
import { TFunction } from 'i18next'
import { useTranslation } from 'react-i18next'
Expand All @@ -13,12 +14,14 @@ import { themeActions } from 'styles/theme/slice'
import { selectTheme } from 'styles/theme/slice/selectors'
import { SelectWithIcon } from '../SelectWithIcon'
import { SidebarButton } from '../Sidebar'
import { getTargetTheme } from 'styles/theme/utils'

interface Props {}

const getThemesIcons = (t: TFunction) => ({
light: <Sun aria-label={t('theme.lightMode', 'Light mode')} />,
dark: <Moon aria-label={t('theme.darkMode', 'Dark mode')} />,
system: <System aria-label={t('theme.system', 'System')} />,
})

export const ThemeSwitcher = memo((props: Props) => {
Expand All @@ -36,10 +39,9 @@ export const ThemeSwitcher = memo((props: Props) => {
label: t('theme.lightMode', 'Light mode'),
},
}

const currentMode = modes[theme]
const currentMode = modes[getTargetTheme(theme)]
const switchTheme = () => {
const newTheme = theme === 'dark' ? 'light' : 'dark'
const newTheme = getTargetTheme(theme) === 'dark' ? 'light' : 'dark'
dispatch(themeActions.changeTheme(newTheme))
}

Expand All @@ -51,7 +53,7 @@ export const ThemeSelect = () => {
const theme = useSelector(selectTheme)
const dispatch = useDispatch()
const icons = getThemesIcons(t)
const themeOptions: { value: 'dark' | 'light'; label: string }[] = [
const themeOptions: { value: 'dark' | 'light' | 'system'; label: string }[] = [
{
value: 'light',
label: t('theme.lightMode', 'Light mode'),
Expand All @@ -60,14 +62,18 @@ export const ThemeSelect = () => {
value: 'dark',
label: t('theme.darkMode', 'Dark mode'),
},
{
value: 'system',
label: t('theme.system', 'System'),
},
]

return (
<SelectWithIcon
label={t('theme.title', 'Theme')}
id="theme"
name="theme"
icon={theme === 'light' ? icons.light : icons.dark}
icon={icons[theme]}
value={theme}
options={themeOptions}
onChange={option => dispatch(themeActions.changeTheme(option))}
Expand Down
1 change: 1 addition & 0 deletions src/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@
"theme": {
"darkMode": "Dark mode",
"lightMode": "Light mode",
"system": "System",
"title": "Theme"
},
"toolbar": {
Expand Down
3 changes: 2 additions & 1 deletion src/styles/theme/ThemeProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useSelector } from 'react-redux'
import { selectTheme } from './slice/selectors'
import { dataTableTheme } from './dataTableTheme'
import { css } from 'styled-components'
import { getTargetTheme } from './utils'

/**
* React-data-table by default sets its own background and text colors
Expand Down Expand Up @@ -340,7 +341,7 @@ export const ThemeProvider = (props: { children: React.ReactChild }) => {
const mode = useSelector(selectTheme)

return (
<Grommet theme={theme} themeMode={mode} style={{ minHeight: '100dvh' }}>
<Grommet theme={theme} themeMode={getTargetTheme(mode)} style={{ minHeight: '100dvh' }}>
{React.Children.only(props.children)}
</Grommet>
)
Expand Down
2 changes: 1 addition & 1 deletion src/styles/theme/slice/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const themeSlice = createSlice({
name: 'theme',
initialState: () => getInitialState(),
reducers: {
changeTheme(state, action: PayloadAction<'dark' | 'light'>) {
changeTheme(state, action: PayloadAction<'dark' | 'light' | 'system'>) {
saveTheme(action.payload)
state.selected = action.payload
},
Expand Down
9 changes: 1 addition & 8 deletions src/styles/theme/slice/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,6 @@ import { createSelector } from '@reduxjs/toolkit'

import { RootState } from 'types'
import { getInitialState } from '.'
import { isSystemDark } from '../utils'

const selectSlice = (state: RootState) => state.theme || getInitialState()
export const selectTheme = createSelector([selectSlice], theme => {
if (theme.selected === 'system') {
return isSystemDark ? 'dark' : 'light'
}

return theme.selected
})
export const selectTheme = createSelector([selectSlice], theme => theme.selected)
3 changes: 3 additions & 0 deletions src/styles/theme/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ export const isSystemDark = window?.matchMedia
? window.matchMedia('(prefers-color-scheme: dark)')?.matches
: undefined

export const getTargetTheme = (theme: 'light' | 'dark' | 'system') =>
theme === 'system' ? (isSystemDark ? 'dark' : 'light') : theme

export function saveTheme(theme: ThemeKeyType) {
window.localStorage.setItem('selectedTheme', theme)
}
Expand Down

0 comments on commit 61181fe

Please sign in to comment.