Implementation — Part II

🌈  Setting up a centralized theme

notion image
notion image
 
💡 Why a centralized theme?
 
➡️  Design System References
 

Configuring the Typography System

To set up the Typography System, navigate to the src folder and create a new folder named theme. Inside this folder, create a new file named typography.js, so the path would be src/theme/typography.js. Below are the contents of this file:
 
export default { fontFamily: ["Roboto", "Helvetica", "Arial", "sans-serif"].join(","), fontSize: 14, h1: { fontSize: "6rem", fontWeight: 300, }, h2: { fontSize: "3.75rem", }, h3: { fontSize: "3rem", fontWeight: "400", }, h4: { fontSize: "2.125rem", fontWeight: "normal", }, h5: { fontSize: "2rem", fontWeight: "normal", }, h6: { fontSize: "1.5rem", fontWeight: "normal", }, body1: { fontWeight: "normal", }, body2: {}, button: { fontSize: "1rem", fontWeight: 700, textTransform: "capitalize", }, subtitle1: {}, subtitle2: {}, caption: {}, overline: { fontWeight: 600, }, };
 

Configuring the Color System

Similarly, within the src/theme directory, create a new file named palette.js, resulting in the path src/theme/palette.js. Below are the contents of this file:
const white = "#fff"; const black = "#000"; const primaryColor = "#ff1b6b"; const primaryLight = "#ffbed4"; const primaryDark = "#9d0159"; const secondaryColor = "#2d2f3c"; const secondaryLight = "#eaecfe"; const secondaryDark = "#0D0F1C"; const RED_PALETTE_KEY = "red"; const BLACK_PALETTE_KEY = "black"; export const PALETTE_KEYS = [RED_PALETTE_KEY, BLACK_PALETTE_KEY]; const redPalette = { [`${RED_PALETTE_KEY}50`]: "#ffe5ee", [`${RED_PALETTE_KEY}100`]: primaryLight, [`${RED_PALETTE_KEY}200`]: "#ff93b7", [`${RED_PALETTE_KEY}300`]: "#ff659a", [`${RED_PALETTE_KEY}400`]: "#ff4282", [`${RED_PALETTE_KEY}500`]: primaryColor, [`${RED_PALETTE_KEY}600`]: "#ed1768", [`${RED_PALETTE_KEY}700`]: "#d71363", [`${RED_PALETTE_KEY}800`]: "#c20c60", [`${RED_PALETTE_KEY}900`]: primaryDark, }; const blackPalette = { [`${BLACK_PALETTE_KEY}50`]: "#f4f6ff", [`${BLACK_PALETTE_KEY}100`]: secondaryLight, [`${BLACK_PALETTE_KEY}200`]: "#dee0f1", [`${BLACK_PALETTE_KEY}300`]: "#cbcdde", [`${BLACK_PALETTE_KEY}400`]: "#858796", [`${BLACK_PALETTE_KEY}500`]: "#5e606e", [`${BLACK_PALETTE_KEY}600`]: "#5e606e", [`${BLACK_PALETTE_KEY}700`]: "#4b4d5b", [`${BLACK_PALETTE_KEY}800`]: secondaryColor, [`${BLACK_PALETTE_KEY}900`]: secondaryDark, }; const warnings = { success: "#72CEC1", caution: "#e9d587", error: "#B00020", danger: "#E52B20", }; export default { primary: { contrastText: white, main: primaryColor, light: primaryLight, dark: primaryDark, }, secondary: { contrastText: white, dark: secondaryDark, main: secondaryColor, light: secondaryLight, }, text: { primary: black, secondary: blackPalette.black500, link: redPalette.red600, info: primaryLight, }, background: { default: white, }, error: { contrastText: white, dark: warnings.danger, main: warnings.error, light: warnings.caution, }, disabled: { contrastText: white, dark: blackPalette.black700, main: blackPalette.black50, }, ...redPalette, ...blackPalette, };
 

Consolidate both systems

Finally, create an index file to consolidate both systems under src/theme. Name this file index.js and ensure it includes the following content:
 
import { createTheme } from '@mui/material' import palette from './palette' import typography from './typography' export default createTheme({ palette, typography, })
 

Adding a New Theme in Storybook

Navigate to src/.storybook/preview.js and replace its contents with the following:
import CssBaseline from "@mui/material/CssBaseline"; import { ThemeProvider } from "@mui/material/styles"; import theme from "theme"; const preview = { parameters: { controls: { matchers: { color: /(background|color)$/i, date: /Date$/, }, }, }, decorators: [ (Story) => ( <ThemeProvider theme={theme}> <CssBaseline /> <Story /> </ThemeProvider> ), ], }; export default preview;
 

Creating Stories for Your New Systems

To simplify this process, download and extract the contents of the provided folder into your src/stories directory. After restarting Storybook, you will be able to view the changes.
 
Typography Story
notion image
 
Colors Story
notion image
 

Updating the Button Component

With the theme injected, styling the Button component becomes much simpler.
First, replace the contents of the Button.styles.js file with the following:
export default { button: { borderRadius: "3rem", }, };
👉 We've removed 50 lines of logic. Give yourself a pat on the back!
 
Next, make these two tweaks in the Button.jsx component:
... }) => ( <MuiButton disableElevation={disableElevation} disableFocusRipple={disableFocusRipple} disabled={disabled} fullWidth={fullWidth} variant={variant} size={size} color={color} // 👈 1st change: Add this line sx={styles.button} // 👈 2nd change: Replace the `sx` value with this line {...props} > {children} </MuiButton> ) ...
 
Now, our <Button> utilizes the theme directly for all color variations. Try testing its behavior by adjusting the color property.
notion image
 
 

 

⬇️  Download code [ 🔗 Link ]