mirror of
				https://github.com/reduxjs/redux-devtools.git
				synced 2025-11-04 09:57:26 +03:00 
			
		
		
		
	Integrate color scheme preference into ui library (#950)
This commit is contained in:
		
							parent
							
								
									a8883f287d
								
							
						
					
					
						commit
						1de7e11a0a
					
				| 
						 | 
				
			
			@ -12,6 +12,7 @@
 | 
			
		|||
    "plugin:@typescript-eslint/recommended",
 | 
			
		||||
    "plugin:@typescript-eslint/recommended-requiring-type-checking",
 | 
			
		||||
    "plugin:react/recommended",
 | 
			
		||||
    "plugin:react-hooks/recommended",
 | 
			
		||||
    "prettier"
 | 
			
		||||
  ],
 | 
			
		||||
  "settings": {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,7 @@
 | 
			
		|||
    "plugin:@typescript-eslint/recommended",
 | 
			
		||||
    "plugin:@typescript-eslint/recommended-requiring-type-checking",
 | 
			
		||||
    "plugin:react/recommended",
 | 
			
		||||
    "plugin:react-hooks/recommended",
 | 
			
		||||
    "plugin:jest/recommended",
 | 
			
		||||
    "plugin:jest/style",
 | 
			
		||||
    "prettier"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -62,12 +62,10 @@ class App extends Component<Props> {
 | 
			
		|||
function mapStateToProps(state: StoreState) {
 | 
			
		||||
  const instances = state.instances;
 | 
			
		||||
  const id = getActiveInstance(instances);
 | 
			
		||||
  const { themeColorPreference, ...themeData } = state.theme;
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    options: instances.options[id],
 | 
			
		||||
    section: state.section,
 | 
			
		||||
    theme: themeData,
 | 
			
		||||
    theme: state.theme,
 | 
			
		||||
    notification: state.notification,
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,10 +8,7 @@ import configureStore from '../../../app/stores/panelStore';
 | 
			
		|||
 | 
			
		||||
import '../../views/devpanel.pug';
 | 
			
		||||
import { Action, Store } from 'redux';
 | 
			
		||||
import {
 | 
			
		||||
  applyMediaFeaturesPreferences,
 | 
			
		||||
  StoreAction,
 | 
			
		||||
} from '@redux-devtools/app/lib/actions';
 | 
			
		||||
import { StoreAction } from '@redux-devtools/app/lib/actions';
 | 
			
		||||
import { PanelMessage } from '../../../app/middlewares/api';
 | 
			
		||||
import { StoreStateWithoutSocket } from '../../../app/reducers/panel';
 | 
			
		||||
import { PersistGate } from 'redux-persist/integration/react';
 | 
			
		||||
| 
						 | 
				
			
			@ -36,20 +33,9 @@ function renderDevTools() {
 | 
			
		|||
  unmountComponentAtNode(node!);
 | 
			
		||||
  clearTimeout(naTimeout);
 | 
			
		||||
  ({ store, persistor } = configureStore(position, bgConnection));
 | 
			
		||||
 | 
			
		||||
  const onBeforeLift = () => {
 | 
			
		||||
    if (store) {
 | 
			
		||||
      store.dispatch(applyMediaFeaturesPreferences());
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  render(
 | 
			
		||||
    <Provider store={store}>
 | 
			
		||||
      <PersistGate
 | 
			
		||||
        loading={null}
 | 
			
		||||
        persistor={persistor}
 | 
			
		||||
        onBeforeLift={onBeforeLift}
 | 
			
		||||
      >
 | 
			
		||||
      <PersistGate loading={null} persistor={persistor}>
 | 
			
		||||
        <App position={position} />
 | 
			
		||||
      </PersistGate>
 | 
			
		||||
    </Provider>,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,6 @@ import configureStore from '../../../app/stores/windowStore';
 | 
			
		|||
import { MonitorMessage } from '../../../app/middlewares/api';
 | 
			
		||||
 | 
			
		||||
import '../../views/window.pug';
 | 
			
		||||
import { applyMediaFeaturesPreferences } from '@redux-devtools/app/lib/actions';
 | 
			
		||||
 | 
			
		||||
const position = location.hash;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -26,17 +25,9 @@ chrome.runtime.getBackgroundPage((window) => {
 | 
			
		|||
  bg.onMessage.addListener(update);
 | 
			
		||||
  update();
 | 
			
		||||
 | 
			
		||||
  const onBeforeLift = () => {
 | 
			
		||||
    localStore.dispatch(applyMediaFeaturesPreferences());
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  render(
 | 
			
		||||
    <Provider store={localStore}>
 | 
			
		||||
      <PersistGate
 | 
			
		||||
        loading={null}
 | 
			
		||||
        persistor={persistor}
 | 
			
		||||
        onBeforeLift={onBeforeLift}
 | 
			
		||||
      >
 | 
			
		||||
      <PersistGate loading={null} persistor={persistor}>
 | 
			
		||||
        <App position={position} />
 | 
			
		||||
      </PersistGate>
 | 
			
		||||
    </Provider>,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,20 @@ import { Provider } from 'react-redux';
 | 
			
		|||
import configureStore from '../../../src/app/stores/windowStore';
 | 
			
		||||
import App from '../../../src/app/containers/App';
 | 
			
		||||
 | 
			
		||||
Object.defineProperty(window, 'matchMedia', {
 | 
			
		||||
  writable: true,
 | 
			
		||||
  value: jest.fn().mockImplementation((query) => ({
 | 
			
		||||
    matches: false,
 | 
			
		||||
    media: query,
 | 
			
		||||
    onchange: null,
 | 
			
		||||
    addListener: jest.fn(), // deprecated
 | 
			
		||||
    removeListener: jest.fn(), // deprecated
 | 
			
		||||
    addEventListener: jest.fn(),
 | 
			
		||||
    removeEventListener: jest.fn(),
 | 
			
		||||
    dispatchEvent: jest.fn(),
 | 
			
		||||
  })),
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const { store } = configureStore(store);
 | 
			
		||||
 | 
			
		||||
describe('App container', () => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@
 | 
			
		|||
    "eslint-config-prettier": "^8.3.0",
 | 
			
		||||
    "eslint-plugin-jest": "^25.2.2",
 | 
			
		||||
    "eslint-plugin-react": "^7.26.1",
 | 
			
		||||
    "eslint-plugin-react-hooks": "^4.2.0",
 | 
			
		||||
    "jest": "^27.3.1",
 | 
			
		||||
    "lerna": "^4.0.0",
 | 
			
		||||
    "prettier": "2.4.1",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,6 +35,7 @@
 | 
			
		|||
    "eslint": "^7.32.0",
 | 
			
		||||
    "eslint-config-prettier": "^8.3.0",
 | 
			
		||||
    "eslint-plugin-react": "^7.26.1",
 | 
			
		||||
    "eslint-plugin-react-hooks": "^4.2.0",
 | 
			
		||||
    "fork-ts-checker-webpack-plugin": "^6.4.0",
 | 
			
		||||
    "html-webpack-plugin": "^5.5.0",
 | 
			
		||||
    "ts-node": "^10.4.0",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,6 +57,7 @@
 | 
			
		|||
    "eslint-config-prettier": "^8.3.0",
 | 
			
		||||
    "eslint-plugin-jest": "^25.2.2",
 | 
			
		||||
    "eslint-plugin-react": "^7.26.1",
 | 
			
		||||
    "eslint-plugin-react-hooks": "^4.2.0",
 | 
			
		||||
    "jest": "^27.3.1",
 | 
			
		||||
    "react": "^17.0.2",
 | 
			
		||||
    "react-test-renderer": "^17.0.2",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,6 +41,7 @@
 | 
			
		|||
    "eslint": "^7.32.0",
 | 
			
		||||
    "eslint-config-prettier": "^8.3.0",
 | 
			
		||||
    "eslint-plugin-react": "^7.26.1",
 | 
			
		||||
    "eslint-plugin-react-hooks": "^4.2.0",
 | 
			
		||||
    "fork-ts-checker-webpack-plugin": "^6.4.0",
 | 
			
		||||
    "html-webpack-plugin": "^5.5.0",
 | 
			
		||||
    "ts-node": "^10.4.0",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -65,6 +65,7 @@
 | 
			
		|||
    "eslint-config-prettier": "^8.3.0",
 | 
			
		||||
    "eslint-plugin-jest": "^25.2.2",
 | 
			
		||||
    "eslint-plugin-react": "^7.26.1",
 | 
			
		||||
    "eslint-plugin-react-hooks": "^4.2.0",
 | 
			
		||||
    "jest": "^27.3.1",
 | 
			
		||||
    "react": "^17.0.2",
 | 
			
		||||
    "react-test-renderer": "^17.0.2",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,6 @@ module.exports = {
 | 
			
		|||
  setupFilesAfterEnv: ['<rootDir>/test/setup.ts'],
 | 
			
		||||
  testEnvironment: 'jsdom',
 | 
			
		||||
  moduleNameMapper: {
 | 
			
		||||
    '\\.css$': '<rootDir>/test/__mocks__/styleMock.js',
 | 
			
		||||
    '\\.css$': '<rootDir>/test/__mocks__/styleMock.ts',
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -91,6 +91,7 @@
 | 
			
		|||
    "eslint-config-prettier": "^8.3.0",
 | 
			
		||||
    "eslint-plugin-jest": "^25.2.2",
 | 
			
		||||
    "eslint-plugin-react": "^7.26.1",
 | 
			
		||||
    "eslint-plugin-react-hooks": "^4.2.0",
 | 
			
		||||
    "file-loader": "^6.2.0",
 | 
			
		||||
    "fork-ts-checker-webpack-plugin": "^6.4.0",
 | 
			
		||||
    "html-loader": "^3.0.0",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@ import { AuthStates, States } from 'socketcluster-client/lib/scclientsocket';
 | 
			
		|||
import {
 | 
			
		||||
  CHANGE_SECTION,
 | 
			
		||||
  CHANGE_THEME,
 | 
			
		||||
  APPLY_MEDIA_FEATURES_PREFERENCES,
 | 
			
		||||
  SELECT_INSTANCE,
 | 
			
		||||
  SELECT_MONITOR,
 | 
			
		||||
  UPDATE_MONITOR_STATE,
 | 
			
		||||
| 
						 | 
				
			
			@ -45,10 +44,9 @@ import {
 | 
			
		|||
import { Action } from 'redux';
 | 
			
		||||
import { Features, State } from '../reducers/instances';
 | 
			
		||||
import { MonitorStateMonitorState } from '../reducers/monitor';
 | 
			
		||||
import { LiftedAction, LiftedState } from '@redux-devtools/core';
 | 
			
		||||
import { LiftedAction } from '@redux-devtools/core';
 | 
			
		||||
import { Data } from '../reducers/reports';
 | 
			
		||||
import { prefersDarkColorScheme } from '../utils/media-queries';
 | 
			
		||||
import { ThemeColorPreference } from '../reducers/theme';
 | 
			
		||||
import { LiftedState } from '@redux-devtools/core';
 | 
			
		||||
 | 
			
		||||
let monitorReducer: (
 | 
			
		||||
  monitorProps: unknown,
 | 
			
		||||
| 
						 | 
				
			
			@ -68,53 +66,19 @@ export function changeSection(section: string): ChangeSectionAction {
 | 
			
		|||
interface ChangeThemeFormData {
 | 
			
		||||
  readonly theme: Theme;
 | 
			
		||||
  readonly scheme: Scheme;
 | 
			
		||||
  readonly themeColorPreference: ThemeColorPreference;
 | 
			
		||||
  readonly colorPreference: 'auto' | 'light' | 'dark';
 | 
			
		||||
}
 | 
			
		||||
export interface ChangeThemeData {
 | 
			
		||||
interface ChangeThemeData {
 | 
			
		||||
  readonly formData: ChangeThemeFormData;
 | 
			
		||||
}
 | 
			
		||||
export interface ChangeThemeAction {
 | 
			
		||||
  readonly type: typeof CHANGE_THEME;
 | 
			
		||||
  readonly theme: Theme;
 | 
			
		||||
  readonly scheme: Scheme;
 | 
			
		||||
  readonly dark: boolean;
 | 
			
		||||
  readonly themeColorPreference: ThemeColorPreference;
 | 
			
		||||
  readonly colorPreference: 'auto' | 'light' | 'dark';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ApplyMediaFeaturesPreferencesAction {
 | 
			
		||||
  readonly type: typeof APPLY_MEDIA_FEATURES_PREFERENCES;
 | 
			
		||||
  readonly prefersDarkColorScheme: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function changeTheme(data: ChangeThemeData): ChangeThemeAction {
 | 
			
		||||
  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 };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @see https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries#media_features
 | 
			
		||||
 */
 | 
			
		||||
export function applyMediaFeaturesPreferences(
 | 
			
		||||
  payload?: Partial<Omit<ApplyMediaFeaturesPreferencesAction, 'type'>>
 | 
			
		||||
): ApplyMediaFeaturesPreferencesAction {
 | 
			
		||||
  return {
 | 
			
		||||
    prefersDarkColorScheme: prefersDarkColorScheme(),
 | 
			
		||||
    ...payload,
 | 
			
		||||
    type: APPLY_MEDIA_FEATURES_PREFERENCES,
 | 
			
		||||
  };
 | 
			
		||||
  return { type: CHANGE_THEME, ...data.formData };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface InitMonitorAction {
 | 
			
		||||
| 
						 | 
				
			
			@ -600,7 +564,6 @@ export interface ErrorAction {
 | 
			
		|||
export type StoreActionWithoutUpdateStateOrLiftedAction =
 | 
			
		||||
  | ChangeSectionAction
 | 
			
		||||
  | ChangeThemeAction
 | 
			
		||||
  | ApplyMediaFeaturesPreferencesAction
 | 
			
		||||
  | MonitorActionAction
 | 
			
		||||
  | SelectInstanceAction
 | 
			
		||||
  | SelectMonitorAction
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,10 +4,6 @@ import { Container, Form } from '@redux-devtools/ui';
 | 
			
		|||
import { listSchemes, listThemes } from '@redux-devtools/ui/lib/utils/theme';
 | 
			
		||||
import { changeTheme } from '../../actions';
 | 
			
		||||
import { StoreState } from '../../reducers';
 | 
			
		||||
import {
 | 
			
		||||
  defaultThemeColorPreference,
 | 
			
		||||
  themeColorPreferences,
 | 
			
		||||
} from '../../reducers/theme';
 | 
			
		||||
 | 
			
		||||
type StateProps = ReturnType<typeof mapStateToProps>;
 | 
			
		||||
type DispatchProps = ResolveThunks<typeof actionCreators>;
 | 
			
		||||
| 
						 | 
				
			
			@ -19,8 +15,7 @@ export class Themes extends Component<Props> {
 | 
			
		|||
    const formData = {
 | 
			
		||||
      theme: theme.theme,
 | 
			
		||||
      scheme: theme.scheme,
 | 
			
		||||
      themeColorPreference:
 | 
			
		||||
        theme.themeColorPreference ?? defaultThemeColorPreference,
 | 
			
		||||
      colorPreference: theme.colorPreference,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
| 
						 | 
				
			
			@ -38,10 +33,10 @@ export class Themes extends Component<Props> {
 | 
			
		|||
                type: 'string',
 | 
			
		||||
                enum: listSchemes(),
 | 
			
		||||
              },
 | 
			
		||||
              themeColorPreference: {
 | 
			
		||||
              colorPreference: {
 | 
			
		||||
                title: 'theme color',
 | 
			
		||||
                type: 'string',
 | 
			
		||||
                enum: themeColorPreferences as unknown as string[],
 | 
			
		||||
                enum: ['auto', 'light', 'dark'],
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
          }}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,5 @@
 | 
			
		|||
export const CHANGE_SECTION = 'main/CHANGE_SECTION';
 | 
			
		||||
export const CHANGE_THEME = 'main/CHANGE_THEME';
 | 
			
		||||
export const APPLY_MEDIA_FEATURES_PREFERENCES =
 | 
			
		||||
  'main/APPLY_MEDIA_FEATURES_PREFERENCES';
 | 
			
		||||
 | 
			
		||||
export const UPDATE_STATE = 'devTools/UPDATE_STATE';
 | 
			
		||||
export const SET_STATE = 'devTools/SET_STATE';
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,7 +7,7 @@ import configureStore from './store/configureStore';
 | 
			
		|||
import { CONNECT_REQUEST } from './constants/socketActionTypes';
 | 
			
		||||
import App from './containers/App';
 | 
			
		||||
import { StoreState } from './reducers';
 | 
			
		||||
import { StoreAction, applyMediaFeaturesPreferences } from './actions';
 | 
			
		||||
import { StoreAction } from './actions';
 | 
			
		||||
 | 
			
		||||
class Root extends Component {
 | 
			
		||||
  store?: Store<StoreState, StoreAction>;
 | 
			
		||||
| 
						 | 
				
			
			@ -27,26 +27,11 @@ class Root extends Component {
 | 
			
		|||
    this.persistor = persistor;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @hidden
 | 
			
		||||
   * @private
 | 
			
		||||
   */
 | 
			
		||||
  private _checkMediaFeaturesPreferences = () => {
 | 
			
		||||
    if (this.store) {
 | 
			
		||||
      this.store.dispatch(applyMediaFeaturesPreferences());
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  render() {
 | 
			
		||||
    if (!this.store) return null;
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
      <Provider store={this.store}>
 | 
			
		||||
        <PersistGate
 | 
			
		||||
          loading={null}
 | 
			
		||||
          persistor={this.persistor!}
 | 
			
		||||
          onBeforeLift={this._checkMediaFeaturesPreferences}
 | 
			
		||||
        >
 | 
			
		||||
        <PersistGate loading={null} persistor={this.persistor!}>
 | 
			
		||||
          <App />
 | 
			
		||||
        </PersistGate>
 | 
			
		||||
      </Provider>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,33 +1,18 @@
 | 
			
		|||
import { Theme, Scheme } from '@redux-devtools/ui';
 | 
			
		||||
import {
 | 
			
		||||
  CHANGE_THEME,
 | 
			
		||||
  APPLY_MEDIA_FEATURES_PREFERENCES,
 | 
			
		||||
} from '../constants/actionTypes';
 | 
			
		||||
import { Scheme, Theme } from '@redux-devtools/ui';
 | 
			
		||||
import { CHANGE_THEME } from '../constants/actionTypes';
 | 
			
		||||
import { StoreAction } from '../actions';
 | 
			
		||||
 | 
			
		||||
export const defaultThemeColorPreference = 'auto';
 | 
			
		||||
 | 
			
		||||
export const themeColorPreferences = [
 | 
			
		||||
  defaultThemeColorPreference,
 | 
			
		||||
  'light',
 | 
			
		||||
  'dark',
 | 
			
		||||
] as const;
 | 
			
		||||
 | 
			
		||||
export type ThemeColorPreference = typeof themeColorPreferences[number];
 | 
			
		||||
 | 
			
		||||
export interface ThemeState {
 | 
			
		||||
  readonly theme: Theme;
 | 
			
		||||
  readonly scheme: Scheme;
 | 
			
		||||
  readonly light: boolean;
 | 
			
		||||
  readonly themeColorPreference?: ThemeColorPreference;
 | 
			
		||||
  readonly colorPreference: 'auto' | 'light' | 'dark';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default function theme(
 | 
			
		||||
  state: ThemeState = {
 | 
			
		||||
    theme: 'default' as const,
 | 
			
		||||
    scheme: 'default' as const,
 | 
			
		||||
    light: true,
 | 
			
		||||
    themeColorPreference: defaultThemeColorPreference,
 | 
			
		||||
    theme: 'default',
 | 
			
		||||
    scheme: 'default',
 | 
			
		||||
    colorPreference: 'auto',
 | 
			
		||||
  },
 | 
			
		||||
  action: StoreAction
 | 
			
		||||
) {
 | 
			
		||||
| 
						 | 
				
			
			@ -35,23 +20,8 @@ export default function theme(
 | 
			
		|||
    return {
 | 
			
		||||
      theme: action.theme,
 | 
			
		||||
      scheme: action.scheme,
 | 
			
		||||
      light: !action.dark,
 | 
			
		||||
      themeColorPreference: action.themeColorPreference,
 | 
			
		||||
      colorPreference: action.colorPreference,
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (
 | 
			
		||||
    action.type === APPLY_MEDIA_FEATURES_PREFERENCES &&
 | 
			
		||||
    (!state.themeColorPreference ||
 | 
			
		||||
      state.themeColorPreference === defaultThemeColorPreference)
 | 
			
		||||
  ) {
 | 
			
		||||
    return {
 | 
			
		||||
      ...state,
 | 
			
		||||
      themeColorPreference:
 | 
			
		||||
        state.themeColorPreference ?? defaultThemeColorPreference,
 | 
			
		||||
      light: !action.prefersDarkColorScheme,
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return state;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,13 +0,0 @@
 | 
			
		|||
/**
 | 
			
		||||
 * @see https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme
 | 
			
		||||
 */
 | 
			
		||||
export function prefersDarkColorScheme(): boolean {
 | 
			
		||||
  if (
 | 
			
		||||
    typeof window !== 'undefined' &&
 | 
			
		||||
    typeof window.matchMedia === 'function'
 | 
			
		||||
  ) {
 | 
			
		||||
    return window.matchMedia('(prefers-color-scheme: dark)').matches;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
module.exports = {};
 | 
			
		||||
							
								
								
									
										1
									
								
								packages/redux-devtools-app/test/__mocks__/styleMock.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								packages/redux-devtools-app/test/__mocks__/styleMock.ts
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
export default {};
 | 
			
		||||
| 
						 | 
				
			
			@ -9,6 +9,20 @@ import rootReducer from '../src/reducers';
 | 
			
		|||
import { DATA_TYPE_KEY } from '../src/constants/dataTypes';
 | 
			
		||||
import stringifyJSON from '../src/utils/stringifyJSON';
 | 
			
		||||
 | 
			
		||||
Object.defineProperty(window, 'matchMedia', {
 | 
			
		||||
  writable: true,
 | 
			
		||||
  value: jest.fn().mockImplementation((query) => ({
 | 
			
		||||
    matches: false,
 | 
			
		||||
    media: query,
 | 
			
		||||
    onchange: null,
 | 
			
		||||
    addListener: jest.fn(), // deprecated
 | 
			
		||||
    removeListener: jest.fn(), // deprecated
 | 
			
		||||
    addEventListener: jest.fn(),
 | 
			
		||||
    removeEventListener: jest.fn(),
 | 
			
		||||
    dispatchEvent: jest.fn(),
 | 
			
		||||
  })),
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const store = createStore(rootReducer, applyMiddleware(exportState, api));
 | 
			
		||||
 | 
			
		||||
describe('App container', () => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,6 +56,7 @@
 | 
			
		|||
    "eslint": "^7.32.0",
 | 
			
		||||
    "eslint-config-prettier": "^8.3.0",
 | 
			
		||||
    "eslint-plugin-react": "^7.26.1",
 | 
			
		||||
    "eslint-plugin-react-hooks": "^4.2.0",
 | 
			
		||||
    "react": "^17.0.2",
 | 
			
		||||
    "redux": "^4.1.2",
 | 
			
		||||
    "rimraf": "^3.0.2",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,6 +57,7 @@
 | 
			
		|||
    "eslint": "^7.32.0",
 | 
			
		||||
    "eslint-config-prettier": "^8.3.0",
 | 
			
		||||
    "eslint-plugin-react": "^7.26.1",
 | 
			
		||||
    "eslint-plugin-react-hooks": "^4.2.0",
 | 
			
		||||
    "react": "^17.0.2",
 | 
			
		||||
    "redux": "^4.1.2",
 | 
			
		||||
    "rimraf": "^3.0.2",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,6 +48,7 @@
 | 
			
		|||
    "eslint": "^7.32.0",
 | 
			
		||||
    "eslint-config-prettier": "^8.3.0",
 | 
			
		||||
    "eslint-plugin-react": "^7.26.1",
 | 
			
		||||
    "eslint-plugin-react-hooks": "^4.2.0",
 | 
			
		||||
    "fork-ts-checker-webpack-plugin": "^6.4.0",
 | 
			
		||||
    "html-webpack-plugin": "^5.5.0",
 | 
			
		||||
    "style-loader": "^3.3.1",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,7 +58,11 @@ render(
 | 
			
		|||
  <Provider store={store}>
 | 
			
		||||
    <ConnectedRouter history={history}>
 | 
			
		||||
      <Container
 | 
			
		||||
        themeData={{ theme: 'default', scheme: 'default', light: true }}
 | 
			
		||||
        themeData={{
 | 
			
		||||
          theme: 'default',
 | 
			
		||||
          scheme: 'default',
 | 
			
		||||
          colorPreference: 'auto',
 | 
			
		||||
        }}
 | 
			
		||||
      >
 | 
			
		||||
        <Route path={ROOT}>
 | 
			
		||||
          <DemoApp />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,6 +73,7 @@
 | 
			
		|||
    "eslint-config-prettier": "^8.3.0",
 | 
			
		||||
    "eslint-plugin-jest": "^25.2.2",
 | 
			
		||||
    "eslint-plugin-react": "^7.26.1",
 | 
			
		||||
    "eslint-plugin-react-hooks": "^4.2.0",
 | 
			
		||||
    "jest": "^27.3.1",
 | 
			
		||||
    "react": "^17.0.2",
 | 
			
		||||
    "react-dom": "^17.0.2",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,6 +57,7 @@
 | 
			
		|||
    "eslint-config-prettier": "^8.3.0",
 | 
			
		||||
    "eslint-plugin-jest": "^25.2.2",
 | 
			
		||||
    "eslint-plugin-react": "^7.26.1",
 | 
			
		||||
    "eslint-plugin-react-hooks": "^4.2.0",
 | 
			
		||||
    "jest": "^27.3.1",
 | 
			
		||||
    "react": "^17.0.2",
 | 
			
		||||
    "react-dom": "^17.0.2",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,6 +48,7 @@
 | 
			
		|||
    "eslint": "^7.32.0",
 | 
			
		||||
    "eslint-config-prettier": "^8.3.0",
 | 
			
		||||
    "eslint-plugin-react": "^7.26.1",
 | 
			
		||||
    "eslint-plugin-react-hooks": "^4.2.0",
 | 
			
		||||
    "fork-ts-checker-webpack-plugin": "^6.4.0",
 | 
			
		||||
    "html-webpack-plugin": "^5.5.0",
 | 
			
		||||
    "ts-node": "^10.4.0",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -70,6 +70,7 @@
 | 
			
		|||
    "eslint": "^7.32.0",
 | 
			
		||||
    "eslint-config-prettier": "^8.3.0",
 | 
			
		||||
    "eslint-plugin-react": "^7.26.1",
 | 
			
		||||
    "eslint-plugin-react-hooks": "^4.2.0",
 | 
			
		||||
    "react": "^17.0.2",
 | 
			
		||||
    "redux": "^4.1.2",
 | 
			
		||||
    "rimraf": "^3.0.2",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -59,6 +59,7 @@
 | 
			
		|||
    "eslint": "^7.32.0",
 | 
			
		||||
    "eslint-config-prettier": "^8.3.0",
 | 
			
		||||
    "eslint-plugin-react": "^7.26.1",
 | 
			
		||||
    "eslint-plugin-react-hooks": "^4.2.0",
 | 
			
		||||
    "react": "^17.0.2",
 | 
			
		||||
    "redux": "^4.1.2",
 | 
			
		||||
    "rimraf": "^3.0.2",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,7 +57,6 @@
 | 
			
		|||
    "@typescript-eslint/parser": "^5.2.0",
 | 
			
		||||
    "eslint": "^7.32.0",
 | 
			
		||||
    "eslint-config-prettier": "^8.3.0",
 | 
			
		||||
    "eslint-plugin-react": "^7.26.1",
 | 
			
		||||
    "redux": "^4.1.2",
 | 
			
		||||
    "rimraf": "^3.0.2",
 | 
			
		||||
    "typescript": "~4.4.4"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,6 +49,7 @@
 | 
			
		|||
    "eslint": "^7.32.0",
 | 
			
		||||
    "eslint-config-prettier": "^8.3.0",
 | 
			
		||||
    "eslint-plugin-react": "^7.26.1",
 | 
			
		||||
    "eslint-plugin-react-hooks": "^4.2.0",
 | 
			
		||||
    "fork-ts-checker-webpack-plugin": "^6.4.0",
 | 
			
		||||
    "html-webpack-plugin": "^5.5.0",
 | 
			
		||||
    "style-loader": "^3.3.1",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -69,6 +69,7 @@
 | 
			
		|||
    "eslint": "^7.32.0",
 | 
			
		||||
    "eslint-config-prettier": "^8.3.0",
 | 
			
		||||
    "eslint-plugin-react": "^7.26.1",
 | 
			
		||||
    "eslint-plugin-react-hooks": "^4.2.0",
 | 
			
		||||
    "react": "^17.0.2",
 | 
			
		||||
    "redux": "^4.1.2",
 | 
			
		||||
    "rimraf": "^3.0.2",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,6 +47,7 @@
 | 
			
		|||
    "eslint": "^7.32.0",
 | 
			
		||||
    "eslint-config-prettier": "^8.3.0",
 | 
			
		||||
    "eslint-plugin-react": "^7.26.1",
 | 
			
		||||
    "eslint-plugin-react-hooks": "^4.2.0",
 | 
			
		||||
    "fork-ts-checker-webpack-plugin": "^6.4.0",
 | 
			
		||||
    "html-webpack-plugin": "^5.5.0",
 | 
			
		||||
    "style-loader": "^3.3.1",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,6 +48,7 @@
 | 
			
		|||
    "eslint": "^7.32.0",
 | 
			
		||||
    "eslint-config-prettier": "^8.3.0",
 | 
			
		||||
    "eslint-plugin-react": "^7.26.1",
 | 
			
		||||
    "eslint-plugin-react-hooks": "^4.2.0",
 | 
			
		||||
    "react": "^17.0.2",
 | 
			
		||||
    "redux": "^4.1.2",
 | 
			
		||||
    "rimraf": "^3.0.2",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,6 +13,7 @@ export const globalTypes = {
 | 
			
		|||
    defaultValue: 'default',
 | 
			
		||||
    toolbar: {
 | 
			
		||||
      items: listThemes(),
 | 
			
		||||
      showName: true,
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  scheme: {
 | 
			
		||||
| 
						 | 
				
			
			@ -21,6 +22,7 @@ export const globalTypes = {
 | 
			
		|||
    defaultValue: 'default',
 | 
			
		||||
    toolbar: {
 | 
			
		||||
      items: listSchemes(),
 | 
			
		||||
      showName: true,
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  color: {
 | 
			
		||||
| 
						 | 
				
			
			@ -28,7 +30,8 @@ export const globalTypes = {
 | 
			
		|||
    description: 'Global color for components',
 | 
			
		||||
    defaultValue: 'light',
 | 
			
		||||
    toolbar: {
 | 
			
		||||
      items: ['light', 'dark'],
 | 
			
		||||
      items: ['auto', 'light', 'dark'],
 | 
			
		||||
      showName: true,
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -38,7 +41,7 @@ const withThemeProvider = (Story, context) => (
 | 
			
		|||
    themeData={{
 | 
			
		||||
      theme: context.globals.theme,
 | 
			
		||||
      scheme: context.globals.scheme,
 | 
			
		||||
      light: context.globals.color === 'light',
 | 
			
		||||
      colorPreference: context.globals.color,
 | 
			
		||||
    }}
 | 
			
		||||
  >
 | 
			
		||||
    <Story {...context} />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,6 +73,7 @@
 | 
			
		|||
    "eslint-config-prettier": "^8.3.0",
 | 
			
		||||
    "eslint-plugin-jest": "^25.2.2",
 | 
			
		||||
    "eslint-plugin-react": "^7.26.1",
 | 
			
		||||
    "eslint-plugin-react-hooks": "^4.2.0",
 | 
			
		||||
    "jest": "^27.3.1",
 | 
			
		||||
    "react": "^17.0.2",
 | 
			
		||||
    "react-dom": "^17.0.2",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,10 +1,28 @@
 | 
			
		|||
import React from 'react';
 | 
			
		||||
import PropTypes from 'prop-types';
 | 
			
		||||
import { ThemeProvider } from 'styled-components';
 | 
			
		||||
import { getTheme, ThemeData } from '../utils/theme';
 | 
			
		||||
import { useTheme, ThemeData } from '../utils/theme';
 | 
			
		||||
import { MainContainerWrapper, ContainerWrapper } from './styles';
 | 
			
		||||
import { Theme } from '../themes/default';
 | 
			
		||||
 | 
			
		||||
interface ContainerFromThemeDataProps {
 | 
			
		||||
  children?: React.ReactNode;
 | 
			
		||||
  themeData: ThemeData;
 | 
			
		||||
  className?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const ContainerFromThemeData: React.FunctionComponent<ContainerFromThemeDataProps> =
 | 
			
		||||
  ({ themeData, className, children }) => {
 | 
			
		||||
    const theme = useTheme(themeData);
 | 
			
		||||
    return (
 | 
			
		||||
      <ThemeProvider theme={theme}>
 | 
			
		||||
        <MainContainerWrapper className={className}>
 | 
			
		||||
          {children}
 | 
			
		||||
        </MainContainerWrapper>
 | 
			
		||||
      </ThemeProvider>
 | 
			
		||||
    );
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
interface Props {
 | 
			
		||||
  children?: React.ReactNode;
 | 
			
		||||
  themeData?: ThemeData;
 | 
			
		||||
| 
						 | 
				
			
			@ -27,11 +45,9 @@ const Container: React.FunctionComponent<Props> = ({
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <ThemeProvider theme={getTheme(themeData)}>
 | 
			
		||||
      <MainContainerWrapper className={className}>
 | 
			
		||||
        {children}
 | 
			
		||||
      </MainContainerWrapper>
 | 
			
		||||
    </ThemeProvider>
 | 
			
		||||
    <ContainerFromThemeData themeData={themeData} className={className}>
 | 
			
		||||
      {children}
 | 
			
		||||
    </ContainerFromThemeData>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,4 @@
 | 
			
		|||
import { useEffect, useMemo, useState } from 'react';
 | 
			
		||||
import * as themes from '../themes';
 | 
			
		||||
import { nicinabox as defaultDarkScheme } from 'redux-devtools-themes';
 | 
			
		||||
import * as baseSchemes from 'base16';
 | 
			
		||||
| 
						 | 
				
			
			@ -15,7 +16,7 @@ export type Scheme = keyof typeof schemes;
 | 
			
		|||
export interface ThemeData {
 | 
			
		||||
  theme: keyof typeof themes;
 | 
			
		||||
  scheme: keyof typeof schemes;
 | 
			
		||||
  light: boolean;
 | 
			
		||||
  colorPreference: 'auto' | 'light' | 'dark';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ThemeFromProvider extends ThemeBase {
 | 
			
		||||
| 
						 | 
				
			
			@ -23,11 +24,11 @@ export interface ThemeFromProvider extends ThemeBase {
 | 
			
		|||
  light: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const getTheme = ({
 | 
			
		||||
  theme: type,
 | 
			
		||||
  scheme,
 | 
			
		||||
  light,
 | 
			
		||||
}: ThemeData): ThemeFromProvider => {
 | 
			
		||||
const getTheme = (
 | 
			
		||||
  type: keyof typeof themes,
 | 
			
		||||
  scheme: keyof typeof schemes,
 | 
			
		||||
  light: boolean
 | 
			
		||||
): ThemeFromProvider => {
 | 
			
		||||
  let colors;
 | 
			
		||||
  if (scheme === 'default') {
 | 
			
		||||
    colors = light ? schemes.default : defaultDarkScheme;
 | 
			
		||||
| 
						 | 
				
			
			@ -47,3 +48,40 @@ export const getTheme = ({
 | 
			
		|||
 | 
			
		||||
  return theme;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const useTheme = ({
 | 
			
		||||
  theme: type,
 | 
			
		||||
  scheme,
 | 
			
		||||
  colorPreference,
 | 
			
		||||
}: ThemeData): ThemeFromProvider => {
 | 
			
		||||
  const [prefersDarkColorScheme, setPrefersDarkColorScheme] = useState(
 | 
			
		||||
    window.matchMedia('(prefers-color-scheme: dark)').matches
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
 | 
			
		||||
 | 
			
		||||
    const handleChange = ({ matches }: MediaQueryListEvent) => {
 | 
			
		||||
      if (matches && !prefersDarkColorScheme) {
 | 
			
		||||
        setPrefersDarkColorScheme(true);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (!matches && prefersDarkColorScheme) {
 | 
			
		||||
        setPrefersDarkColorScheme(false);
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    mediaQuery.addEventListener('change', handleChange);
 | 
			
		||||
    return () => mediaQuery.removeEventListener('change', handleChange);
 | 
			
		||||
  }, [prefersDarkColorScheme]);
 | 
			
		||||
 | 
			
		||||
  const light = useMemo(
 | 
			
		||||
    () =>
 | 
			
		||||
      colorPreference === 'auto'
 | 
			
		||||
        ? !prefersDarkColorScheme
 | 
			
		||||
        : colorPreference === 'light',
 | 
			
		||||
    [colorPreference, prefersDarkColorScheme]
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  return getTheme(type, scheme, light);
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,11 +2,29 @@ import React from 'react';
 | 
			
		|||
import { render } from '@testing-library/react';
 | 
			
		||||
import { Container } from '../src';
 | 
			
		||||
 | 
			
		||||
Object.defineProperty(window, 'matchMedia', {
 | 
			
		||||
  writable: true,
 | 
			
		||||
  value: jest.fn().mockImplementation((query) => ({
 | 
			
		||||
    matches: false,
 | 
			
		||||
    media: query,
 | 
			
		||||
    onchange: null,
 | 
			
		||||
    addListener: jest.fn(), // deprecated
 | 
			
		||||
    removeListener: jest.fn(), // deprecated
 | 
			
		||||
    addEventListener: jest.fn(),
 | 
			
		||||
    removeEventListener: jest.fn(),
 | 
			
		||||
    dispatchEvent: jest.fn(),
 | 
			
		||||
  })),
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
describe('Container', function () {
 | 
			
		||||
  it('renders correctly', () => {
 | 
			
		||||
    const { container } = render(
 | 
			
		||||
      <Container
 | 
			
		||||
        themeData={{ theme: 'default', scheme: 'default', light: false }}
 | 
			
		||||
        themeData={{
 | 
			
		||||
          theme: 'default',
 | 
			
		||||
          scheme: 'default',
 | 
			
		||||
          colorPreference: 'auto',
 | 
			
		||||
        }}
 | 
			
		||||
      >
 | 
			
		||||
        Text
 | 
			
		||||
      </Container>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
 | 
			
		||||
exports[`Container renders correctly 1`] = `
 | 
			
		||||
<div
 | 
			
		||||
  class="sc-bdvvtL gyKeHC"
 | 
			
		||||
  class="sc-bdvvtL bKcxHw"
 | 
			
		||||
>
 | 
			
		||||
  Text
 | 
			
		||||
</div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,6 +48,7 @@
 | 
			
		|||
    "eslint": "^7.32.0",
 | 
			
		||||
    "eslint-config-prettier": "^8.3.0",
 | 
			
		||||
    "eslint-plugin-react": "^7.26.1",
 | 
			
		||||
    "eslint-plugin-react-hooks": "^4.2.0",
 | 
			
		||||
    "fork-ts-checker-webpack-plugin": "^6.4.0",
 | 
			
		||||
    "html-webpack-plugin": "^5.5.0",
 | 
			
		||||
    "ts-node": "^10.4.0",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -62,6 +62,7 @@
 | 
			
		|||
    "eslint": "^7.32.0",
 | 
			
		||||
    "eslint-config-prettier": "^8.3.0",
 | 
			
		||||
    "eslint-plugin-react": "^7.26.1",
 | 
			
		||||
    "eslint-plugin-react-hooks": "^4.2.0",
 | 
			
		||||
    "fork-ts-checker-webpack-plugin": "^6.4.0",
 | 
			
		||||
    "html-webpack-plugin": "^5.5.0",
 | 
			
		||||
    "style-loader": "^3.3.1",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,6 +60,7 @@
 | 
			
		|||
    "eslint-config-prettier": "^8.3.0",
 | 
			
		||||
    "eslint-plugin-jest": "^25.2.2",
 | 
			
		||||
    "eslint-plugin-react": "^7.26.1",
 | 
			
		||||
    "eslint-plugin-react-hooks": "^4.2.0",
 | 
			
		||||
    "jest": "^27.3.1",
 | 
			
		||||
    "react": "^17.0.2",
 | 
			
		||||
    "react-dom": "^17.0.2",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										23
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								yarn.lock
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -4576,6 +4576,7 @@ __metadata:
 | 
			
		|||
    eslint-config-prettier: ^8.3.0
 | 
			
		||||
    eslint-plugin-jest: ^25.2.2
 | 
			
		||||
    eslint-plugin-react: ^7.26.1
 | 
			
		||||
    eslint-plugin-react-hooks: ^4.2.0
 | 
			
		||||
    file-loader: ^6.2.0
 | 
			
		||||
    fork-ts-checker-webpack-plugin: ^6.4.0
 | 
			
		||||
    html-loader: ^3.0.0
 | 
			
		||||
| 
						 | 
				
			
			@ -4634,6 +4635,7 @@ __metadata:
 | 
			
		|||
    eslint: ^7.32.0
 | 
			
		||||
    eslint-config-prettier: ^8.3.0
 | 
			
		||||
    eslint-plugin-react: ^7.26.1
 | 
			
		||||
    eslint-plugin-react-hooks: ^4.2.0
 | 
			
		||||
    prop-types: ^15.7.2
 | 
			
		||||
    react: ^17.0.2
 | 
			
		||||
    redux: ^4.1.2
 | 
			
		||||
| 
						 | 
				
			
			@ -4730,6 +4732,7 @@ __metadata:
 | 
			
		|||
    eslint-config-prettier: ^8.3.0
 | 
			
		||||
    eslint-plugin-jest: ^25.2.2
 | 
			
		||||
    eslint-plugin-react: ^7.26.1
 | 
			
		||||
    eslint-plugin-react-hooks: ^4.2.0
 | 
			
		||||
    jest: ^27.3.1
 | 
			
		||||
    lodash: ^4.17.21
 | 
			
		||||
    prop-types: ^15.7.2
 | 
			
		||||
| 
						 | 
				
			
			@ -4765,6 +4768,7 @@ __metadata:
 | 
			
		|||
    eslint: ^7.32.0
 | 
			
		||||
    eslint-config-prettier: ^8.3.0
 | 
			
		||||
    eslint-plugin-react: ^7.26.1
 | 
			
		||||
    eslint-plugin-react-hooks: ^4.2.0
 | 
			
		||||
    parse-key: ^0.2.1
 | 
			
		||||
    prop-types: ^15.7.2
 | 
			
		||||
    react: ^17.0.2
 | 
			
		||||
| 
						 | 
				
			
			@ -4829,6 +4833,7 @@ __metadata:
 | 
			
		|||
    eslint-config-prettier: ^8.3.0
 | 
			
		||||
    eslint-plugin-jest: ^25.2.2
 | 
			
		||||
    eslint-plugin-react: ^7.26.1
 | 
			
		||||
    eslint-plugin-react-hooks: ^4.2.0
 | 
			
		||||
    javascript-stringify: ^2.1.0
 | 
			
		||||
    jest: ^27.3.1
 | 
			
		||||
    jsan: ^3.1.13
 | 
			
		||||
| 
						 | 
				
			
			@ -4879,6 +4884,7 @@ __metadata:
 | 
			
		|||
    eslint-config-prettier: ^8.3.0
 | 
			
		||||
    eslint-plugin-jest: ^25.2.2
 | 
			
		||||
    eslint-plugin-react: ^7.26.1
 | 
			
		||||
    eslint-plugin-react-hooks: ^4.2.0
 | 
			
		||||
    html-entities: ^2.3.2
 | 
			
		||||
    jest: ^27.3.1
 | 
			
		||||
    path-browserify: ^1.0.1
 | 
			
		||||
| 
						 | 
				
			
			@ -4927,6 +4933,7 @@ __metadata:
 | 
			
		|||
    eslint: ^7.32.0
 | 
			
		||||
    eslint-config-prettier: ^8.3.0
 | 
			
		||||
    eslint-plugin-react: ^7.26.1
 | 
			
		||||
    eslint-plugin-react-hooks: ^4.2.0
 | 
			
		||||
    hex-rgba: ^1.0.2
 | 
			
		||||
    immutable: ^4.0.0
 | 
			
		||||
    javascript-stringify: ^2.1.0
 | 
			
		||||
| 
						 | 
				
			
			@ -4998,6 +5005,7 @@ __metadata:
 | 
			
		|||
    eslint: ^7.32.0
 | 
			
		||||
    eslint-config-prettier: ^8.3.0
 | 
			
		||||
    eslint-plugin-react: ^7.26.1
 | 
			
		||||
    eslint-plugin-react-hooks: ^4.2.0
 | 
			
		||||
    lodash.debounce: ^4.0.8
 | 
			
		||||
    prop-types: ^15.7.2
 | 
			
		||||
    react: ^17.0.2
 | 
			
		||||
| 
						 | 
				
			
			@ -5030,7 +5038,6 @@ __metadata:
 | 
			
		|||
    "@typescript-eslint/parser": ^5.2.0
 | 
			
		||||
    eslint: ^7.32.0
 | 
			
		||||
    eslint-config-prettier: ^8.3.0
 | 
			
		||||
    eslint-plugin-react: ^7.26.1
 | 
			
		||||
    jsan: ^3.1.13
 | 
			
		||||
    querystring: ^0.2.1
 | 
			
		||||
    redux: ^4.1.2
 | 
			
		||||
| 
						 | 
				
			
			@ -5065,6 +5072,7 @@ __metadata:
 | 
			
		|||
    eslint: ^7.32.0
 | 
			
		||||
    eslint-config-prettier: ^8.3.0
 | 
			
		||||
    eslint-plugin-react: ^7.26.1
 | 
			
		||||
    eslint-plugin-react-hooks: ^4.2.0
 | 
			
		||||
    hex-rgba: ^1.0.2
 | 
			
		||||
    immutable: ^4.0.0
 | 
			
		||||
    jss: ^10.8.2
 | 
			
		||||
| 
						 | 
				
			
			@ -5132,6 +5140,7 @@ __metadata:
 | 
			
		|||
    eslint: ^7.32.0
 | 
			
		||||
    eslint-config-prettier: ^8.3.0
 | 
			
		||||
    eslint-plugin-react: ^7.26.1
 | 
			
		||||
    eslint-plugin-react-hooks: ^4.2.0
 | 
			
		||||
    prop-types: ^15.7.2
 | 
			
		||||
    react: ^17.0.2
 | 
			
		||||
    redux: ^4.1.2
 | 
			
		||||
| 
						 | 
				
			
			@ -5182,6 +5191,7 @@ __metadata:
 | 
			
		|||
    eslint-config-prettier: ^8.3.0
 | 
			
		||||
    eslint-plugin-jest: ^25.2.2
 | 
			
		||||
    eslint-plugin-react: ^7.26.1
 | 
			
		||||
    eslint-plugin-react-hooks: ^4.2.0
 | 
			
		||||
    jest: ^27.3.1
 | 
			
		||||
    prop-types: ^15.7.2
 | 
			
		||||
    react: ^17.0.2
 | 
			
		||||
| 
						 | 
				
			
			@ -11807,6 +11817,7 @@ __metadata:
 | 
			
		|||
    eslint: ^7.32.0
 | 
			
		||||
    eslint-config-prettier: ^8.3.0
 | 
			
		||||
    eslint-plugin-react: ^7.26.1
 | 
			
		||||
    eslint-plugin-react-hooks: ^4.2.0
 | 
			
		||||
    fork-ts-checker-webpack-plugin: ^6.4.0
 | 
			
		||||
    html-webpack-plugin: ^5.5.0
 | 
			
		||||
    prop-types: ^15.7.2
 | 
			
		||||
| 
						 | 
				
			
			@ -16700,6 +16711,7 @@ fsevents@^1.2.7:
 | 
			
		|||
    eslint: ^7.32.0
 | 
			
		||||
    eslint-config-prettier: ^8.3.0
 | 
			
		||||
    eslint-plugin-react: ^7.26.1
 | 
			
		||||
    eslint-plugin-react-hooks: ^4.2.0
 | 
			
		||||
    fork-ts-checker-webpack-plugin: ^6.4.0
 | 
			
		||||
    history: ^4.10.1
 | 
			
		||||
    html-webpack-plugin: ^5.5.0
 | 
			
		||||
| 
						 | 
				
			
			@ -23744,6 +23756,7 @@ fsevents@^1.2.7:
 | 
			
		|||
    eslint: ^7.32.0
 | 
			
		||||
    eslint-config-prettier: ^8.3.0
 | 
			
		||||
    eslint-plugin-react: ^7.26.1
 | 
			
		||||
    eslint-plugin-react-hooks: ^4.2.0
 | 
			
		||||
    fork-ts-checker-webpack-plugin: ^6.4.0
 | 
			
		||||
    html-webpack-plugin: ^5.5.0
 | 
			
		||||
    react: ^17.0.2
 | 
			
		||||
| 
						 | 
				
			
			@ -23782,6 +23795,7 @@ fsevents@^1.2.7:
 | 
			
		|||
    eslint-config-prettier: ^8.3.0
 | 
			
		||||
    eslint-plugin-jest: ^25.2.2
 | 
			
		||||
    eslint-plugin-react: ^7.26.1
 | 
			
		||||
    eslint-plugin-react-hooks: ^4.2.0
 | 
			
		||||
    jest: ^27.3.1
 | 
			
		||||
    lodash.debounce: ^4.0.8
 | 
			
		||||
    prop-types: ^15.7.2
 | 
			
		||||
| 
						 | 
				
			
			@ -23947,6 +23961,7 @@ fsevents@^1.2.7:
 | 
			
		|||
    eslint: ^7.32.0
 | 
			
		||||
    eslint-config-prettier: ^8.3.0
 | 
			
		||||
    eslint-plugin-react: ^7.26.1
 | 
			
		||||
    eslint-plugin-react-hooks: ^4.2.0
 | 
			
		||||
    fork-ts-checker-webpack-plugin: ^6.4.0
 | 
			
		||||
    html-webpack-plugin: ^5.5.0
 | 
			
		||||
    immutable: ^4.0.0
 | 
			
		||||
| 
						 | 
				
			
			@ -23984,6 +23999,7 @@ fsevents@^1.2.7:
 | 
			
		|||
    eslint-config-prettier: ^8.3.0
 | 
			
		||||
    eslint-plugin-jest: ^25.2.2
 | 
			
		||||
    eslint-plugin-react: ^7.26.1
 | 
			
		||||
    eslint-plugin-react-hooks: ^4.2.0
 | 
			
		||||
    jest: ^27.3.1
 | 
			
		||||
    prop-types: ^15.7.2
 | 
			
		||||
    react: ^17.0.2
 | 
			
		||||
| 
						 | 
				
			
			@ -25352,6 +25368,7 @@ resolve@^2.0.0-next.3:
 | 
			
		|||
    eslint-config-prettier: ^8.3.0
 | 
			
		||||
    eslint-plugin-jest: ^25.2.2
 | 
			
		||||
    eslint-plugin-react: ^7.26.1
 | 
			
		||||
    eslint-plugin-react-hooks: ^4.2.0
 | 
			
		||||
    jest: ^27.3.1
 | 
			
		||||
    lerna: ^4.0.0
 | 
			
		||||
    prettier: 2.4.1
 | 
			
		||||
| 
						 | 
				
			
			@ -25400,6 +25417,7 @@ resolve@^2.0.0-next.3:
 | 
			
		|||
    eslint: ^7.32.0
 | 
			
		||||
    eslint-config-prettier: ^8.3.0
 | 
			
		||||
    eslint-plugin-react: ^7.26.1
 | 
			
		||||
    eslint-plugin-react-hooks: ^4.2.0
 | 
			
		||||
    fork-ts-checker-webpack-plugin: ^6.4.0
 | 
			
		||||
    framer-motion: ^4.1.17
 | 
			
		||||
    html-webpack-plugin: ^5.5.0
 | 
			
		||||
| 
						 | 
				
			
			@ -26171,6 +26189,7 @@ resolve@^2.0.0-next.3:
 | 
			
		|||
    eslint: ^7.32.0
 | 
			
		||||
    eslint-config-prettier: ^8.3.0
 | 
			
		||||
    eslint-plugin-react: ^7.26.1
 | 
			
		||||
    eslint-plugin-react-hooks: ^4.2.0
 | 
			
		||||
    fork-ts-checker-webpack-plugin: ^6.4.0
 | 
			
		||||
    html-webpack-plugin: ^5.5.0
 | 
			
		||||
    prop-types: ^15.7.2
 | 
			
		||||
| 
						 | 
				
			
			@ -27670,6 +27689,7 @@ resolve@^2.0.0-next.3:
 | 
			
		|||
    eslint: ^7.32.0
 | 
			
		||||
    eslint-config-prettier: ^8.3.0
 | 
			
		||||
    eslint-plugin-react: ^7.26.1
 | 
			
		||||
    eslint-plugin-react-hooks: ^4.2.0
 | 
			
		||||
    fork-ts-checker-webpack-plugin: ^6.4.0
 | 
			
		||||
    history: ^4.10.1
 | 
			
		||||
    html-webpack-plugin: ^5.5.0
 | 
			
		||||
| 
						 | 
				
			
			@ -27949,6 +27969,7 @@ resolve@^2.0.0-next.3:
 | 
			
		|||
    eslint: ^7.32.0
 | 
			
		||||
    eslint-config-prettier: ^8.3.0
 | 
			
		||||
    eslint-plugin-react: ^7.26.1
 | 
			
		||||
    eslint-plugin-react-hooks: ^4.2.0
 | 
			
		||||
    fork-ts-checker-webpack-plugin: ^6.4.0
 | 
			
		||||
    html-webpack-plugin: ^5.5.0
 | 
			
		||||
    prop-types: ^15.7.2
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user