Lab - Theming

Plan: B2B Developer

Lesson 15 of 25 · 20 min

Introduction

In this exercise, we’ll pick up where we left off with our Overview UI, exploring available options for global theming of Material UI components.

In this lab, you will:

  • Create custom configuration pulled into the Material UI theme
  • Apply a custom font
  • Modify various component styles

Setup

This exercise continues where you left off previously. Make sure the dev server is started in your Buyer Portal project:

yarn dev

If you need a fresh start, you can follow the instructions below to set up a new project complete with previous exercise code.

  1. Copy the project with the appropriate tag.
degit https://github.com/bigcommerce-edu/lab-b2b-buyer-portal.git#e-theme-pre <directory-name>
  1. Install dependencies.
cd <directory-name>
yarn install
  1. Run the dev server.
yarn dev

Remember!

Script Manager in your store control panel must contain appropriate header/footer scripts to load the Buyer Portal from your local environment on the appropriate port.

Revisit the initial setup lab for full details on setting up your environment.

Exercise Reference Copy

If it’s helpful to compare your own code as you go, you can clone or download the completed version of this labs as a reference.

Theming Lab Snapshot

The Material UI Theme

Remember, all file paths referenced in these exercises are relative to apps/storefront/src in your Buyer Portal project.

The Material UI default theme we’ve previously seen controls styles for all Material UI components in your application. We’ve already seen how theme values from this schema can be applied in a specific context. When these values are changed in the theme, all relevant components are affected.

Overriding the default theme with your own values involves the use of createTheme and a ThemeProvider as described in the documentation.

The Buyer Portal already implements just such a provider in theme.tsx, to faciliate the custom primary palette color and default background color. In this exercise, we’ll update this code to merge in config from a separate file, where we can cleanly implement any custom theme values we wish to apply.

Step 1: Apply Custom Theme Config and a Font

Our boilerplate code already includes a file with a getThemeConfig function, which we’ll flesh out in this step. First, we need to update the Buyer Portal’s Material UI theme config to include this output.

  1. Open theme.tsx and add an import for the getThemeConfig function.
theme.tsx
import { getThemeConfig } from './theme-config';
  1. Update the theme function that returns the Material UI theme. Our goal is to run createTheme twice now, once with the values the Buyer Portal already provides and another with our custom config.
theme.tsx
const theme = (lang: string) => {
let t = createTheme(
{
palette: {
background: {
default: backgroundColor,
},
primary: {
main: primaryColor || '#1976d2',
},
},
},
(materialMultiLanguages as MaterialMultiLanguagesType)[MUI_LANG_MAP[lang] || 'enUS'],
);
t = createTheme(
getThemeConfig(t),
(materialMultiLanguages as MaterialMultiLanguagesType)[MUI_LANG_MAP[lang] || 'enUS'],
);
return t;
};

Don’t forget to include the explicit opening and closing curly braces we’re introducing to the function.

  1. Open theme-config.ts and add a return value as shown.
theme-config.ts
export const getThemeConfig = (theme: Theme) => {
return {
palette: {
background: {
default: theme.palette.background.default,
},
primary: {
main: theme.palette.primary.main,
},
},
} as ThemeOptions;
}

We’re accepting the initial theme configuration as an argument and using it to set the same palette values already provided, preserving the Buyer Portal’s native functionality.

Changing the Font

Let’s utilize the Material UI theme to change the default font used throughout components. We’ll use the Google Font Montserrat, which is the default font of the Cornerstone theme.

First, we need to make sure the font is being loaded. There’s a constant for this primary font URL in App.tsx.

  1. Open App.tsx and update FONT_URL.
App.tsx
const FONT_URL = 'https://fonts.googleapis.com/css?family=Montserrat:700,500,400&display=block';
export default function App() {
...
}
  1. Open theme-config.ts and add the appropriate typography configuration.
theme-config.ts
export const getThemeConfig = (theme: Theme) => {
return {
palette: {
...
},
typography: {
fontFamily: 'Montserrat, Arial, sans-serif',
},
} as ThemeOptions;
}

Navigate to the Buyer Portal in your storefront and verify that the new font is applied throughout the UI.

Step 2: Expand Theme Config

Now that there’s a clean configuration for overriding Material UI theme values, let’s try modifying a few more color and typography styles.

  1. Open theme-config.ts and add values as shown.
theme-config.ts
export const getThemeConfig = (theme: Theme) => {
return {
palette: {
...,
secondary: {
main: '#f2a579',
},
},
typography: {
fontFamily: 'Montserrat, Arial, sans-serif',
body1: {
fontSize: '1.25rem',
},
body2: {
fontSize: '1rem',
},
h3: {
fontSize: '1.5rem',
fontWeight: 'bold',
},
button: {
fontSize: '1rem',
},
},
} as ThemeOptions;
}

Recall that the “secondary” color in the Material UI palette is the color we applied to the background of the “Identity” cards. These should now reflect our new value. The typography changes should be evident in headings, body text, and buttons throughout the Buyer Portal.

Before:

Overview before theme config

After:

Overview after theme config

Feel free to experiment with other values for the theme config.

Step 3: Apply Component Theming

As you can see, the Material UI theme schema consists of broadly applicable values, like a general color palette and generic font sizes/weights.

This broad config is very valuable for ensuring that there’s a consistent look and feel across components. However, the theme configuration also allows us to get much more granular, making it possible to declare things like “what a ‘contained’ button looks like” in the theme itself.

In this step, we’ll apply this kind of component-specific theming in a few areas.

  1. Open theme-config.ts and add values as shown.
theme-config.ts
export const getThemeConfig = (theme: Theme) => {
return {
palette: {
...
},
typography: {
...
},
components: {
MuiAccordion: {
styleOverrides: {
root: {
backgroundColor: theme.palette.primary.light,
},
},
},
MuiButton: {
defaultProps: {
variant: 'contained',
},
styleOverrides: {
root: {
margin: '5px',
},
},
},
MuiIconButton: {
styleOverrides: {
root: {
color: theme.palette.primary.main,
},
},
},
},
} as ThemeOptions;
}

We’re declaring theme values for Accordion, Button and IconButton components. The keys used to identify each component (such as MuiButton) are detailed in the Component API documentation (such as this example for Button).

The code above demonstrates two aspects of component theming:

  • defaultProps can be used to set the default value of any prop the component accepts. See the “Props” section of the component API documentation.
  • styleOverrides sets CSS styles for the component. Note the sub-key root in the MuiButton config. This corresponds the .MuiButton-root class that styles the root element. Components consist of multiple parts and variations, and other keys can be used in the same way to target these. For example, the contained key can be used to provide styles corresponding with the .MuiButton-contained class. See “CSS classes” in the component API documentation.

Revisit your Overview page to see the effects on the Accordion and Button components.

The IconButton component can be seen in action on the “User management” page, where “edit” and “delete” icons appear for each user.

Full Exercise Code

Taking It Further

  • Explore the Material UI theme configuration and expand theme-config.ts with additional values.
  • In the Component API documentation, review the available CSS classes for other components in the Buyer Portal, such as Box, Card, Grid, and Table. Incorporate component-specific styles into your theme config.
  • Review the documentation for creating themed components and try building your own component that can be styled with theme configuration.

Resources