Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use theme overrides with nested elements?

Tags:

material-ui

If I adjust the size of a button in the theme, like this:

const theme = createMuiTheme({
    overrides: {
        MuiButton: {
            fab: {
                width: 36,
                height: 36,
            },
        },
        MuiSvgIcon: {
            root: {
                width: 16,
            },
        },
    },
};

Then the button and the icon appear at the size I want. However this affects all icons, whether they're inside a button or not!

How can I say that I only want the MuiSvgIcon properties to apply when the element is found inside a MuiButton element?

like image 578
Malvineous Avatar asked Mar 07 '23 07:03

Malvineous


2 Answers

Well I've worked out one way to do it, but it's not ideal because it relies on the internal structure of the MuiSvgIcon. But it might serve as a starting point for someone else. Better answers are most welcome.

const theme = createMuiTheme({
    overrides: {
        MuiButton: {
            fab: {
                width: 36,
                height: 36,
                '& svg': {
                    width: 16,
                },
            },
        },
    },
};

It works by applying a style to the <svg> DOM element inside the JSX <Button variant="fab"> element.

like image 168
Malvineous Avatar answered Apr 09 '23 20:04

Malvineous


It's not documented anywhere unfortunately, but you can use any sort of CSS selectors to help. Use the "attribute contains" pattern with the class attribute itself to target descendants:

const theme = createMuiTheme({
    overrides: {
        MuiButton: {
            root: {
                // Targets MuiSvgIcon elements that appear as descendants of MuiButton
                '& [class*="MuiSvgIcon-root"]': {
                    width: 16
                }
            },
        },
    },
};

Note 1: Caution! Material UI minifies these classnames in prod builds by default. If you want to preserve these classnames for prod, you will need to tweak the class generator function: https://material-ui.com/customization/css-in-js/ (see dangerouslyUseGlobalCSS)

Note 2: with this pattern, occasionally you end having to use !important if there's already a competing inline style that you want to override. If you're using styled-components, you can increase the specificity by using && (see the Material UI docs).

like image 38
David Calhoun Avatar answered Apr 09 '23 21:04

David Calhoun