mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2025-07-25 23:49:46 +03:00
feat(app): add theme color dropdown
This commit is contained in:
parent
fb1ec166d3
commit
482674b83b
|
@ -62,10 +62,12 @@ class App extends Component<Props> {
|
||||||
function mapStateToProps(state: StoreState) {
|
function mapStateToProps(state: StoreState) {
|
||||||
const instances = state.instances;
|
const instances = state.instances;
|
||||||
const id = getActiveInstance(instances);
|
const id = getActiveInstance(instances);
|
||||||
|
const { themeColorPreference, ...themeData } = state.theme;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
options: instances.options[id],
|
options: instances.options[id],
|
||||||
section: state.section,
|
section: state.section,
|
||||||
theme: state.theme,
|
theme: themeData,
|
||||||
notification: state.notification,
|
notification: state.notification,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ import { MonitorStateMonitorState } from '../reducers/monitor';
|
||||||
import { LiftedAction, LiftedState } from '@redux-devtools/core';
|
import { LiftedAction, LiftedState } from '@redux-devtools/core';
|
||||||
import { Data } from '../reducers/reports';
|
import { Data } from '../reducers/reports';
|
||||||
import { prefersDarkColorScheme } from '../utils/media-queries';
|
import { prefersDarkColorScheme } from '../utils/media-queries';
|
||||||
|
import { ThemeColorPreference } from '../reducers/theme';
|
||||||
|
|
||||||
let monitorReducer: (
|
let monitorReducer: (
|
||||||
monitorProps: unknown,
|
monitorProps: unknown,
|
||||||
|
@ -67,9 +68,9 @@ export function changeSection(section: string): ChangeSectionAction {
|
||||||
interface ChangeThemeFormData {
|
interface ChangeThemeFormData {
|
||||||
readonly theme: Theme;
|
readonly theme: Theme;
|
||||||
readonly scheme: Scheme;
|
readonly scheme: Scheme;
|
||||||
readonly dark: boolean;
|
readonly themeColorPreference: ThemeColorPreference;
|
||||||
}
|
}
|
||||||
interface ChangeThemeData {
|
export interface ChangeThemeData {
|
||||||
readonly formData: ChangeThemeFormData;
|
readonly formData: ChangeThemeFormData;
|
||||||
}
|
}
|
||||||
export interface ChangeThemeAction {
|
export interface ChangeThemeAction {
|
||||||
|
@ -77,6 +78,7 @@ export interface ChangeThemeAction {
|
||||||
readonly theme: Theme;
|
readonly theme: Theme;
|
||||||
readonly scheme: Scheme;
|
readonly scheme: Scheme;
|
||||||
readonly dark: boolean;
|
readonly dark: boolean;
|
||||||
|
readonly themeColorPreference: ThemeColorPreference;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ApplyMediaFeaturesPreferencesAction {
|
export interface ApplyMediaFeaturesPreferencesAction {
|
||||||
|
@ -85,7 +87,21 @@ export interface ApplyMediaFeaturesPreferencesAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function changeTheme(data: ChangeThemeData): ChangeThemeAction {
|
export function changeTheme(data: ChangeThemeData): ChangeThemeAction {
|
||||||
return { type: CHANGE_THEME, ...data.formData };
|
const { themeColorPreference } = data.formData;
|
||||||
|
let dark: boolean;
|
||||||
|
|
||||||
|
switch (themeColorPreference) {
|
||||||
|
case 'light':
|
||||||
|
dark = false;
|
||||||
|
break;
|
||||||
|
case 'dark':
|
||||||
|
dark = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dark = prefersDarkColorScheme();
|
||||||
|
}
|
||||||
|
|
||||||
|
return { type: CHANGE_THEME, ...data.formData, dark };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,6 +4,10 @@ import { Container, Form } from '@redux-devtools/ui';
|
||||||
import { listSchemes, listThemes } from '@redux-devtools/ui/lib/utils/theme';
|
import { listSchemes, listThemes } from '@redux-devtools/ui/lib/utils/theme';
|
||||||
import { changeTheme } from '../../actions';
|
import { changeTheme } from '../../actions';
|
||||||
import { StoreState } from '../../reducers';
|
import { StoreState } from '../../reducers';
|
||||||
|
import {
|
||||||
|
defaultThemeColorPreference,
|
||||||
|
themeColorPreferences,
|
||||||
|
} from '../../reducers/theme';
|
||||||
|
|
||||||
type StateProps = ReturnType<typeof mapStateToProps>;
|
type StateProps = ReturnType<typeof mapStateToProps>;
|
||||||
type DispatchProps = ResolveThunks<typeof actionCreators>;
|
type DispatchProps = ResolveThunks<typeof actionCreators>;
|
||||||
|
@ -15,7 +19,8 @@ export class Themes extends Component<Props> {
|
||||||
const formData = {
|
const formData = {
|
||||||
theme: theme.theme,
|
theme: theme.theme,
|
||||||
scheme: theme.scheme,
|
scheme: theme.scheme,
|
||||||
dark: !theme.light,
|
themeColorPreference:
|
||||||
|
theme.themeColorPreference ?? defaultThemeColorPreference,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -33,8 +38,10 @@ export class Themes extends Component<Props> {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
enum: listSchemes(),
|
enum: listSchemes(),
|
||||||
},
|
},
|
||||||
dark: {
|
themeColorPreference: {
|
||||||
type: 'boolean',
|
title: 'theme color',
|
||||||
|
type: 'string',
|
||||||
|
enum: themeColorPreferences as unknown as string[],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -1,15 +1,25 @@
|
||||||
import { Scheme, Theme } from '@redux-devtools/ui';
|
import { Theme, Scheme } from '@redux-devtools/ui';
|
||||||
import {
|
import {
|
||||||
CHANGE_THEME,
|
CHANGE_THEME,
|
||||||
APPLY_MEDIA_FEATURES_PREFERENCES,
|
APPLY_MEDIA_FEATURES_PREFERENCES,
|
||||||
} from '../constants/actionTypes';
|
} from '../constants/actionTypes';
|
||||||
import { StoreAction } from '../actions';
|
import { StoreAction } from '../actions';
|
||||||
|
|
||||||
|
export const defaultThemeColorPreference = 'default';
|
||||||
|
|
||||||
|
export const themeColorPreferences = [
|
||||||
|
defaultThemeColorPreference,
|
||||||
|
'light',
|
||||||
|
'dark',
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
export type ThemeColorPreference = typeof themeColorPreferences[number];
|
||||||
|
|
||||||
export interface ThemeState {
|
export interface ThemeState {
|
||||||
readonly theme: Theme;
|
readonly theme: Theme;
|
||||||
readonly scheme: Scheme;
|
readonly scheme: Scheme;
|
||||||
readonly light: boolean;
|
readonly light: boolean;
|
||||||
readonly latestChangeBy?: string;
|
readonly themeColorPreference?: ThemeColorPreference;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function theme(
|
export default function theme(
|
||||||
|
@ -17,6 +27,7 @@ export default function theme(
|
||||||
theme: 'default' as const,
|
theme: 'default' as const,
|
||||||
scheme: 'default' as const,
|
scheme: 'default' as const,
|
||||||
light: true,
|
light: true,
|
||||||
|
themeColorPreference: defaultThemeColorPreference,
|
||||||
},
|
},
|
||||||
action: StoreAction
|
action: StoreAction
|
||||||
) {
|
) {
|
||||||
|
@ -25,18 +36,20 @@ export default function theme(
|
||||||
theme: action.theme,
|
theme: action.theme,
|
||||||
scheme: action.scheme,
|
scheme: action.scheme,
|
||||||
light: !action.dark,
|
light: !action.dark,
|
||||||
latestChangeBy: CHANGE_THEME,
|
themeColorPreference: action.themeColorPreference,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
action.type === APPLY_MEDIA_FEATURES_PREFERENCES &&
|
action.type === APPLY_MEDIA_FEATURES_PREFERENCES &&
|
||||||
state.latestChangeBy !== CHANGE_THEME
|
(!state.themeColorPreference ||
|
||||||
|
state.themeColorPreference === defaultThemeColorPreference)
|
||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
themeColorPreference:
|
||||||
|
state.themeColorPreference ?? defaultThemeColorPreference,
|
||||||
light: !action.prefersDarkColorScheme,
|
light: !action.prefersDarkColorScheme,
|
||||||
latestChangeBy: APPLY_MEDIA_FEATURES_PREFERENCES,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user