implemented functionality

This commit is contained in:
mulan xia 2024-01-31 12:23:38 -05:00
parent 81b428cffd
commit 3da54ac860
No known key found for this signature in database
GPG Key ID: C6CE526613568D73
6 changed files with 99 additions and 68 deletions

View File

@ -24,23 +24,6 @@ export const StoryWrapper: React.FC<{ children: React.ReactNode }> = ({ children
useEffect(() => {
store.dispatch(setAppTheme(theme));
store.dispatch(setAppColorMode(colorMode));
switch (theme) {
case AppTheme.Dark: {
document?.documentElement?.classList.remove('theme-light');
document?.documentElement?.classList.add('theme-dark');
break;
}
case AppTheme.Light: {
document?.documentElement?.classList.remove('theme-dark');
document?.documentElement?.classList.add('theme-light');
break;
}
case AppTheme.Classic: {
document?.documentElement?.classList.remove('theme-dark', 'theme-light');
break;
}
}
}, [theme, colorMode]);
useEffect(() => {

BIN
public/System.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -1,8 +1,9 @@
import { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import { ThemeProvider } from 'styled-components';
import { AppTheme, AppColorMode } from '@/state/configs';
import { getAppTheme, getAppColorMode } from '@/state/configsSelectors';
import { AppTheme, AppThemeSetting, AppColorMode, AppThemeSystemSetting } from '@/state/configs';
import { getAppThemeSetting, getAppColorMode } from '@/state/configsSelectors';
import { Themes } from '@/styles/themes';
@ -11,8 +12,37 @@ export const AppThemeAndColorModeProvider = ({ ...props }) => {
};
export const useAppThemeAndColorModeContext = () => {
const theme: AppTheme = useSelector(getAppTheme);
const themeSetting: AppThemeSetting = useSelector(getAppThemeSetting);
const colorMode: AppColorMode = useSelector(getAppColorMode);
return Themes[theme][colorMode];
const darkModePref = globalThis.matchMedia('(prefers-color-scheme: dark)');
const [systemPreference, setSystemPreference] = useState(
darkModePref.matches ? AppTheme.Dark : AppTheme.Light
);
useEffect(() => {
const handler = (e) => {
if (e.matches) {
setSystemPreference(AppTheme.Dark);
} else {
setSystemPreference(AppTheme.Light);
}
};
darkModePref.addEventListener('change', handler);
return () => darkModePref.removeEventListener('change', handler);
}, []);
const getThemeFromSetting = (): AppTheme => {
switch (themeSetting) {
case AppThemeSystemSetting.System:
return systemPreference;
case AppTheme.Classic:
case AppTheme.Dark:
case AppTheme.Light:
return themeSetting;
}
};
return Themes[getThemeFromSetting()][colorMode];
};

View File

@ -12,13 +12,19 @@ export enum AppTheme {
Light = 'Light',
}
export enum AppThemeSystemSetting {
System = 'System',
}
export type AppThemeSetting = AppTheme | AppThemeSystemSetting;
export enum AppColorMode {
GreenUp = 'GreenUp',
RedUp = 'RedUp',
}
export interface ConfigsState {
appTheme: AppTheme;
appTheme: AppThemeSetting;
appColorMode: AppColorMode;
feeTiers?: kollections.List<FeeTier>;
feeDiscounts?: FeeDiscount[];
@ -26,22 +32,6 @@ export interface ConfigsState {
hasSeenLaunchIncentives: boolean;
}
const DOCUMENT_THEME_MAP = {
[AppTheme.Classic]: () => {
document?.documentElement?.classList.remove('theme-dark', 'theme-light');
},
[AppTheme.Dark]: () => {
document?.documentElement?.classList.remove('theme-light');
document?.documentElement?.classList.add('theme-dark');
},
[AppTheme.Light]: () => {
document?.documentElement?.classList.remove('theme-dark');
document?.documentElement?.classList.add('theme-light');
},
};
export const changeTheme = (theme: AppTheme) => DOCUMENT_THEME_MAP[theme]();
const initialState: ConfigsState = {
appTheme: getLocalStorage({
key: LocalStorageKey.SelectedTheme,
@ -60,15 +50,12 @@ const initialState: ConfigsState = {
}),
};
changeTheme(initialState.appTheme);
export const configsSlice = createSlice({
name: 'Inputs',
initialState,
reducers: {
setAppTheme: (state: ConfigsState, { payload }: PayloadAction<AppTheme>) => {
setAppTheme: (state: ConfigsState, { payload }: PayloadAction<AppThemeSetting>) => {
setLocalStorage({ key: LocalStorageKey.SelectedTheme, value: payload });
changeTheme(payload);
state.appTheme = payload;
},
setAppColorMode: (state: ConfigsState, { payload }: PayloadAction<AppColorMode>) => {

View File

@ -1,6 +1,18 @@
import type { RootState } from './_store';
import { AppTheme, AppThemeSystemSetting, AppThemeSetting } from './configs';
export const getAppTheme = (state: RootState) => state.configs.appTheme;
export const getAppThemeSetting = (state: RootState): AppThemeSetting => state.configs.appTheme;
export const getAppTheme = (state: RootState): AppTheme => {
switch (state.configs.appTheme) {
case AppThemeSystemSetting.System:
return globalThis.matchMedia('(prefers-color-scheme: dark)').matches
? AppTheme.Dark
: AppTheme.Light;
default:
return state.configs.appTheme;
}
};
export const getAppColorMode = (state: RootState) => state.configs.appColorMode;

View File

@ -5,8 +5,14 @@ import { Root, Item, Indicator } from '@radix-ui/react-radio-group';
import { useStringGetter } from '@/hooks';
import { AppTheme, AppColorMode, setAppTheme, setAppColorMode } from '@/state/configs';
import { getAppTheme, getAppColorMode } from '@/state/configsSelectors';
import {
AppTheme,
AppThemeSystemSetting,
AppColorMode,
setAppTheme,
setAppColorMode,
} from '@/state/configs';
import { getAppTheme, getAppThemeSetting, getAppColorMode } from '@/state/configsSelectors';
import { layoutMixins } from '@/styles/layoutMixins';
import { Themes } from '@/styles/themes';
@ -27,7 +33,7 @@ export const DisplaySettingsDialog = ({ setIsOpen }: ElementProps) => {
const dispatch = useDispatch();
const stringGetter = useStringGetter();
const currentTheme: AppTheme = useSelector(getAppTheme);
const currentTheme: AppTheme = useSelector(getAppThemeSetting);
const currentColorMode: AppColorMode = useSelector(getAppColorMode);
const sectionHeader = (heading: string) => {
@ -45,36 +51,49 @@ export const DisplaySettingsDialog = ({ setIsOpen }: ElementProps) => {
<Styled.AppThemeRoot value={currentTheme}>
{[
{
theme: AppTheme.Classic,
themeSetting: AppTheme.Classic,
label: STRING_KEYS.CLASSIC_DARK,
},
{
theme: AppTheme.Dark,
themeSetting: AppThemeSystemSetting.System,
label: STRING_KEYS.SYSTEM,
},
{
themeSetting: AppTheme.Dark,
label: STRING_KEYS.DARK,
},
{
theme: AppTheme.Light,
themeSetting: AppTheme.Light,
label: STRING_KEYS.LIGHT,
},
].map(({ theme, label }) => (
<Styled.AppThemeItem
key={theme}
value={theme}
backgroundcolor={Themes[theme][currentColorMode].layer2}
gridcolor={Themes[theme][currentColorMode].borderDefault}
onClick={() => {
dispatch(setAppTheme(theme));
}}
>
<Styled.AppThemeHeader textcolor={Themes[theme][currentColorMode].textPrimary}>
{stringGetter({ key: label })}
</Styled.AppThemeHeader>
<Styled.Image src="/chart-bars.svg" />
<Styled.CheckIndicator>
<Styled.CheckIcon iconName={IconName.Check} />
</Styled.CheckIndicator>
</Styled.AppThemeItem>
))}
].map(({ themeSetting, label }) => {
const theme =
themeSetting === AppThemeSystemSetting.System ? AppTheme.Dark : themeSetting;
const backgroundColor = Themes[theme][currentColorMode].layer2;
const gridColor = Themes[theme][currentColorMode].borderDefault;
const textColor = Themes[theme][currentColorMode].textPrimary;
return (
<Styled.AppThemeItem
key={themeSetting}
value={themeSetting}
backgroundcolor={backgroundColor}
gridcolor={gridColor}
onClick={() => {
dispatch(setAppTheme(themeSetting));
}}
>
<Styled.AppThemeHeader textcolor={textColor}>
{stringGetter({ key: label })}
</Styled.AppThemeHeader>
<Styled.Image src="/chart-bars.svg" />
<Styled.CheckIndicator>
<Styled.CheckIcon iconName={IconName.Check} />
</Styled.CheckIndicator>
</Styled.AppThemeItem>
);
})}
</Styled.AppThemeRoot>
);
};