Material UI
If you don't have design skills then it is best to follow someone else's design system. A good one is material design as pioneered by Google as there is a great React component library that follows it. The library is called Material-UI and is installed with npm,
Run this command in frontend/
npm install --save @material-ui/core
npm install --save @material-ui/icons
which installed 4.11.1.
Styling Material-UI components
Fortunately Material-UI's components can be styled using
styled-components, but for this to work effectively the Material-UI
styles must be injected first, this is achieved by adding an outer
<StylesProvider>
wrapper to the app in frontend/src/App.tsx
,
import CssBaseline from "@material-ui/core/CssBaseline";
import { StylesProvider } from "@material-ui/core/styles";
...
const App = () => {
...
return (
<StylesProvider injectFirst>
<CssBaseline />
...
</StylesProvider>
);
}
where ... represents the existing code.
Theming
Material-UI can be themed, allowing for changes to the appearance of
the app. The theme is created by createMuiTheme
and is
styled-components compatible. This allows the following to be added to
frontend/src/theme.ts
,
import { createMuiTheme, Theme } from "@material-ui/core/styles";
const createTheme = (darkMode: boolean): Theme => {
const palette = {
type: (darkMode ? "dark" : "light") as any,
};
return createMuiTheme({ palette });
};
export default createTheme;
which allows for dark mode support based on the user's preference by
adding the following to frontend/src/App.tsx
,
import useMediaQuery from "@material-ui/core/useMediaQuery";
import { ThemeProvider as MuiThemeProvider } from "@material-ui/styles";
import { ThemeProvider } from "styled-components";
import createTheme from "src/theme";
const App = () => {
const prefersDarkMode = useMediaQuery("(prefers-color-scheme: dark)");
const theme = React.useMemo(
() => createTheme(prefersDarkMode), [prefersDarkMode]
);
return (
<ThemeProvider theme={theme}>
<MuiThemeProvider theme={theme}>
... // Existing code
</MuiThemeProvider>
</ThemeProvider>
);
};