forked from sombochea/verdaccio-ui
feat(style): added dark mode (#446)
This commit is contained in:
committed by
GitHub
parent
91434cc814
commit
cdad5cf70d
10
src/design-tokens/ThemeContext.ts
Normal file
10
src/design-tokens/ThemeContext.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { createContext } from 'react';
|
||||
|
||||
interface Props {
|
||||
isDarkMode: boolean;
|
||||
setIsDarkMode: (isDarkMode: boolean) => void;
|
||||
}
|
||||
|
||||
const ThemeContext = createContext<undefined | Props>(undefined);
|
||||
|
||||
export default ThemeContext;
|
||||
@@ -2,12 +2,23 @@ import React from 'react';
|
||||
import { ThemeProvider as MuiThemeProvider } from '@material-ui/core/styles';
|
||||
import { ThemeProvider as EmotionThemeProvider } from 'emotion-theming';
|
||||
|
||||
import theme from './theme';
|
||||
import ThemeContext from './ThemeContext';
|
||||
import { getTheme, ThemeMode } from './theme';
|
||||
import useLocalStorage from './useLocalStorage';
|
||||
|
||||
const ThemeProvider: React.FC = ({ children }) => (
|
||||
<EmotionThemeProvider theme={theme}>
|
||||
<MuiThemeProvider theme={theme}>{children}</MuiThemeProvider>
|
||||
</EmotionThemeProvider>
|
||||
);
|
||||
const ThemeProvider: React.FC = ({ children }) => {
|
||||
const isDarkModeDefault = window?.__VERDACCIO_BASENAME_UI_OPTIONS?.darkMode;
|
||||
const [isDarkMode, setIsDarkMode] = useLocalStorage('darkMode', !!isDarkModeDefault);
|
||||
|
||||
const themeMode: ThemeMode = isDarkMode ? 'dark' : 'light';
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={{ isDarkMode, setIsDarkMode }}>
|
||||
<EmotionThemeProvider theme={getTheme(themeMode)}>
|
||||
<MuiThemeProvider theme={getTheme(themeMode)}>{children}</MuiThemeProvider>
|
||||
</EmotionThemeProvider>
|
||||
</ThemeContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export default ThemeProvider;
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import createMuiTheme from '@material-ui/core/styles/createMuiTheme';
|
||||
|
||||
// Main colors
|
||||
// -------------------------
|
||||
const colors = {
|
||||
black: '#000',
|
||||
white: '#fff',
|
||||
@@ -25,9 +23,23 @@ const colors = {
|
||||
nobel02: '#9f9f9f',
|
||||
primary: window.VERDACCIO_PRIMARY_COLOR || '#4b5e40',
|
||||
secondary: '#20232a',
|
||||
background: '#fff',
|
||||
dodgerBlue: '#1ba1f2',
|
||||
};
|
||||
|
||||
export type Colors = keyof typeof colors;
|
||||
const themeModes = {
|
||||
light: {
|
||||
...colors,
|
||||
},
|
||||
dark: {
|
||||
...colors,
|
||||
primary: '#253341',
|
||||
secondary: '#20232a',
|
||||
background: '#1A202C',
|
||||
},
|
||||
};
|
||||
|
||||
export type ThemeMode = keyof typeof themeModes;
|
||||
|
||||
const fontSize = {
|
||||
xxl: 26,
|
||||
@@ -67,20 +79,27 @@ const customizedTheme = {
|
||||
|
||||
type CustomizedTheme = typeof customizedTheme;
|
||||
|
||||
export const theme = createMuiTheme({
|
||||
typography: {
|
||||
fontFamily: 'inherit',
|
||||
},
|
||||
palette: {
|
||||
...colors,
|
||||
primary: { main: colors.primary },
|
||||
secondary: { main: colors.secondary },
|
||||
error: { main: colors.red },
|
||||
},
|
||||
...customizedTheme,
|
||||
});
|
||||
export const getTheme = (themeMode: ThemeMode) => {
|
||||
const palette = themeModes[themeMode];
|
||||
return createMuiTheme({
|
||||
typography: {
|
||||
fontFamily: 'inherit',
|
||||
},
|
||||
palette: {
|
||||
type: themeMode,
|
||||
...palette,
|
||||
primary: { main: palette.primary },
|
||||
secondary: { main: palette.secondary },
|
||||
error: { main: palette.red },
|
||||
background: {
|
||||
default: palette.background,
|
||||
},
|
||||
},
|
||||
...customizedTheme,
|
||||
});
|
||||
};
|
||||
|
||||
export type Theme = typeof theme;
|
||||
export type Theme = ReturnType<typeof getTheme>;
|
||||
|
||||
declare module '@material-ui/core/styles/createMuiTheme' {
|
||||
/* eslint-disable-next-line @typescript-eslint/no-empty-interface */
|
||||
@@ -111,6 +130,8 @@ declare module '@material-ui/core/styles/createPalette' {
|
||||
love: string;
|
||||
nobel01: string;
|
||||
nobel02: string;
|
||||
background: string;
|
||||
dodgerBlue: string;
|
||||
}
|
||||
|
||||
/* eslint-disable-next-line @typescript-eslint/no-empty-interface */
|
||||
@@ -118,5 +139,3 @@ declare module '@material-ui/core/styles/createPalette' {
|
||||
/* eslint-disable-next-line @typescript-eslint/no-empty-interface */
|
||||
interface PaletteOptions extends Partial<CustomPalette> {}
|
||||
}
|
||||
|
||||
export default { ...theme };
|
||||
|
||||
38
src/design-tokens/useLocalStorage.ts
Normal file
38
src/design-tokens/useLocalStorage.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
// based on https://usehooks.com/useLocalStorage/
|
||||
const useLocalStorage = <V>(key: string, initialValue: V) => {
|
||||
// State to store our value
|
||||
// Pass initial state function to useState so logic is only executed once
|
||||
const [storedValue, setStoredValue] = useState(() => {
|
||||
try {
|
||||
// Get from local storage by key
|
||||
const item = window.localStorage.getItem(key);
|
||||
// Parse stored json or if none return initialValue
|
||||
return item ? JSON.parse(item) : initialValue;
|
||||
} catch (error) {
|
||||
// If error also return initialValue
|
||||
console.error('An error occurred getting a sessionStorage key', error);
|
||||
return initialValue;
|
||||
}
|
||||
});
|
||||
|
||||
// Return a wrapped version of useState's setter function that ...
|
||||
// ... persists the new value to localStorage.
|
||||
const setValue = (value: V) => {
|
||||
try {
|
||||
// Allow value to be a function so we have same API as useState
|
||||
const valueToStore = value instanceof Function ? value(storedValue) : value;
|
||||
// Save state
|
||||
setStoredValue(valueToStore);
|
||||
// Save to local storage
|
||||
window.localStorage.setItem(key, JSON.stringify(valueToStore));
|
||||
} catch (error) {
|
||||
console.error('An error occurred writing to sessionStorage', error);
|
||||
}
|
||||
};
|
||||
|
||||
return [storedValue, setValue];
|
||||
};
|
||||
|
||||
export default useLocalStorage;
|
||||
7
src/design-tokens/useTheme.ts
Normal file
7
src/design-tokens/useTheme.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { useTheme as muiUseTheme } from '@material-ui/styles';
|
||||
|
||||
import { Theme } from './theme';
|
||||
|
||||
const useTheme = () => muiUseTheme<Theme>();
|
||||
|
||||
export default useTheme;
|
||||
Reference in New Issue
Block a user