The Ultimate Material-UI Custom Button Example (MUI v5)

The Material-UI (MUI) Button component merits a detailed exploration of all of its functionality. Its broad use across many UIs makes a deep knowledge of it’s props highly valuable.

In this MUI Button demo I will create a new button variant (a great new feature in v5!), enable all props on it, and use it as a link. I will also examine how to use new styling APIs with the Button.

There is a Code Sandbox with full React code in the Resources section.

Custom Button Variant

The foundation of our Material-UI Button is the custom variant that we’ll create.

I named my variant “bold” and gave it a simple styling of a relatively thick border and bold font. It’s nothing fancy:

MUI Custom Button Variant

However, I noticed something unexpected when I created the new variant. The default color is no longer applied. I specified the black border, but text color should be whatever the theme or default palette.primary color is.

I attempted to add color using the color prop but was not successful. Because of this, I added a color to the variant.

const CustomTheme = createTheme({
  components: {
    MuiButton: {
      variants: [
        {
          props: { variant: "bold" },
          style: {
            fontWeight: "bold",
            border: `4px solid black`,
            color: "orange"
          }
        }
      ]      
    }
  }
});

All other default props seemed unaffected. I tested ripple, focus, and disabled and they worked great.

Regardless, the variant functionality in MUI v5 gives a great way to package up Button styling.

Custom Default Props

Another great new feature in MUI v5 is the ability to override the default values of props for a component across your theme. The defaultProps syntax is similar to variants and styleOverrides. It ‘lives’ inside theme.component.[component]:

const CustomTheme = createTheme({
  components: {
    MuiButton: {
      defaultProps: {
        disableElevation: true,
        disableFocusRipple: true,
        disableRipple: true,
        endIcon: <Icon>star</Icon>
      }
    }
  }
});

I disabled the elevation and ripple props. I also added an endIcon simply to show it could be done as a default prop. Now all buttons using customTheme will have a star icon after their text:

MUI Button Default Props

Here’s the docs link if you want to learn more about default props.

All Button Props Enabled

We have set some styling and props with the custom button variant and default props. Now I will enable the remaining props except for a few that conflict.

These are the props I enabled:

size="medium"
startIcon={<Icon>star</Icon>}
sx={{ mt: 2, ml: 2 }}
variant="bold"
href="smartdevpreneur.com"
  • size – values can be “small”, “medium”, and “large” (plus custom string values according to the docs)
  • startIcon – similar to endIcon, but this injects an icon before the Button text
  • sx – this is a new styling prop in MUI 5. It accepts all CSS values plus additional styling MUI “system” values.
  • variant – this enables an existing or custom variant. I enabled our “bold” variant.
  • href – this accepts a string value that is expected to be a url. When enabled, it turns buttons into links. It also sets the root element to an anchor tag.

At this point our button is finished.

MUI Button with all props

Here are the props I didn’t enable:

  • color – this didn’t play well with our custom variant so I set a value directly in the variant
  • classes – the sx prop essentially replaced this in Material-UI 5.
  • component – I could have used this to change the root component/element for Button, but the href prop was already setting the root to <a>. I checked just to be sure and it turns out the component prop will override the href prop.
  • disabled – this disables the button and I simply didn’t want to do that.
  • fullWidth – this conflicts with the size prop.

ButtonUnstyled Component

Instead of creating a variant and removing default props, we could simply have started with a ButtonUnstyled component. It looks like this:

MUI ButtonUnstyled

It is simply an HTML button element. We can set some props, like disabled, but not others, like size. Ripples are not toggled via prop either.

Use the new styled API for styling UnstyledButton components. It is an MUI adaptation of the styled-components library.

Resources

Code Sandbox link

Read how to align buttons here.

Button docs

Button API

Share this post:

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.