If you are already familiar with styled components, you might want to use that along with the MUI. To use styled-component with MUI, there is styled() utility. The official documentation of MUI doesn't have enough examples with the styled() utility. This article's purpose is to provide enough examples of styled() utility with both Javascript object syntax & CSS like syntax.

 

📑Table of Contents

  • Basic
  • MUI Theme in the styled() Utility
  • Child Component and Child Element
  • Pseudo classes
  • Sibling Component
  • Props

 

Basic

 

Import
 

// You must import 'styled' utility form mui
import { styled } from '@mui/material/styles';

// Also, you must import the components which you are gonna use with the styled utility
import Box from '@mui/material/Box';
Enter fullscreen mode Exit fullscreen mode

 

JavaScript Object Syntax

 

Let's create a component with styled() utility by using JavaScript object syntax:

const Basic = styled(Box)({

  backgroundColor: 'aliceblue',
  color: 'darkslategray',
  padding: '2rem',
  textAlign:'center'

})
Enter fullscreen mode Exit fullscreen mode

Note:

  • Here, we are using the Box component but instead of the Box component, we can use any other MUI component. We just need to import that component.
  • Instead of a component we can also use an HTML tag. To use HTML tag, we have to put the HTML tag inside quote, styled('div').
  • Here, the variable name is Basic. Always make sure that the first letter of the variable is capital because it will work like a component and a component name has to start with a capital letter.

 

CSS Like Syntax

 

Instead of JavaScript object syntax, we can also have CSS-like syntax:

const Basic = styled(Box)`
  background-color: aliceblue;
  color: darkslategray;
  padding: 2rem;
  text-align: center;
`;
Enter fullscreen mode Exit fullscreen mode

Note:

  • Don't forget the backticks

  • Semicolon after ending backtick is optional.

 

MUI Theme in the styled() Utility

 

Take a look at the default theme of MUI.

 

JavaScript Object Syntax

 

const UsingTheme = styled(Box)(
  ({ theme }) => ({
    backgroundColor: theme.palette.primary.light,
    color: theme.palette.grey[900],
    padding: theme.spacing(2),
    textAlign: 'center',
    ...theme.typography.h6,
  })
)

Enter fullscreen mode Exit fullscreen mode

The following picture is showing the MUI default theme. In the picture, we can see that the h6 is an object. It has fontFamily, fontWeight, fontSize, lineHeight & letterSpacing properties. We want all of them. So, we are destructuring it (...theme.typography.h6,).

Image description

 

CSS Like Syntax

 

const UsingTheme = styled(Box)(
  ({ theme }) => `
  background-color: ${theme.palette.primary.light};
  color: ${theme.palette.grey[900]};
  padding: ${theme.spacing(2)};
  text-align: center;


  ${ /* here, we can't destructure like javascript object syntax. So, we need to manually access all the properties of 'h6'  */'' }

  font-size: ${theme.typography.h6.fontSize};
  font-weight: ${theme.typography.h6.fontWeight};
  font-family: ${theme.typography.h6.fontFamily};
  line-height: ${theme.typography.h6.lineHeight};
  letter-spacing: ${theme.typography.h6.letterSpacing};
 `,
)

Enter fullscreen mode Exit fullscreen mode

 

Child Component and Child Element

 

JSX

 

Suppose, we want the following JSX:

<ParentComponent>

      <div>Hi</div>

     <Box className='childComponent'> Hello </Box>

</ParentComponent>

Enter fullscreen mode Exit fullscreen mode

So, we need to create the ParentComponent component and also need to style the child element div and child component Box.

 

JavaScript Object Syntax

 


const ParentComponent = styled(Box)(

  ({ theme }) => ({

    backgroundColor: theme.palette.primary.light,
    color: theme.palette.grey[900],
    padding: theme.spacing(2),
    textAlign: 'center',


    // Child element
    "> div": {
      backgroundColor: theme.palette.error.dark,
      color: theme.palette.grey[100]
    },


    // Child Component (We need to select the class or id which is used in the child component)
    "> .childComponent": {
      backgroundColor: theme.palette.success.dark,
      color: theme.palette.grey[100]
    },

  })
)

Enter fullscreen mode Exit fullscreen mode

Note:

  • I haven't found a way to select an MUI component without the class or an id that is used in that child component. If you know any way other, please write it down in the comment section.

 

CSS Like Syntax

 

const ParentComponent = styled(Box)(
  ({ theme }) => `
  background-color: ${theme.palette.primary.light};
  color: ${theme.palette.grey[900]};
  padding: ${theme.spacing(2)};
  text-align: center;


  ${ /* Child element  */'' }

  > div  {
    background-color: ${theme.palette.error.dark};
    color: ${theme.palette.grey[100]};
  };


  ${ /* Child Component (We need to select the class or id which is used in the child component)  */'' }

   > .childComponent {
    background-color: ${theme.palette.success.dark};
    color: ${theme.palette.grey[100]};
  };


 `,
)

Enter fullscreen mode Exit fullscreen mode

 

Pseudo classes

 

JSX

 

Suppose, we want the following JSX:

<PseudoClasses>

      <div>Hi</div>

     <Box className='childComponent'> Hello </Box>

</PseudoClasses>
Enter fullscreen mode Exit fullscreen mode

So, we need to create the PseudoClasses component and also need to style the child element div and child component Box with pseudo-classes.

 

JavaScript Object Syntax

 

const PseudoClasses = styled(Box)(

  ({ theme }) => ({

    backgroundColor: theme.palette.primary.light,
    color: theme.palette.grey[900],
    padding: theme.spacing(2),
    textAlign: 'center',

    ":hover": {
      backgroundColor: theme.palette.primary.dark,
      color: theme.palette.grey[100],
    },

    ":active": {
      backgroundColor: theme.palette.warning.dark,
      color: theme.palette.grey[100],
    },


    // Pseudo select child element
    ":hover > div": {
      backgroundColor: theme.palette.error.dark,
    },


    // Pseudo select child component (We need to select the class or id which is used in the child component) 
    ":hover > .childComponent": {
      backgroundColor: theme.palette.success.dark,
    },

  })
)
Enter fullscreen mode Exit fullscreen mode

 

CSS Like Syntax

 

const PseudoClasses = styled(Box)(
  ({ theme }) => `
  background-color: ${theme.palette.primary.light};
  color: ${theme.palette.grey[900]};
  padding: ${theme.spacing(2)};
  text-align: center;


  :hover {
    background-color: ${theme.palette.primary.dark};
    color: ${theme.palette.grey[100]};
  };


  :active {
    background-color: ${theme.palette.warning.dark};
    color: ${theme.palette.grey[100]};
  };


  ${ /* Pseudo select child element  */'' }

  :hover > div  {
    background-color: ${theme.palette.error.dark};
  };


  ${ /* Pseudo select child component (We need to select the class or id which is used in the child component)   */'' }

  :hover > .childComponent {
    background-color: ${theme.palette.success.dark};
  };


 `,
)
Enter fullscreen mode Exit fullscreen mode

 

Sibling Component

 

JSX

 

Suppose, we want the following JSX:

<>
  <MainComponent> Hello </MainComponent>
  <Box className='siblingComponent'> Hi </Box>
</>
Enter fullscreen mode Exit fullscreen mode

So, we need to create the MainComponent and also need to style the sibling component Box.

 

JavaScript Object Syntax

 

const MainComponent = styled(Box)(

  ({ theme }) => ({

    backgroundColor: theme.palette.primary.light,
    color: theme.palette.grey[900],

    // Adjacent Sibling Component (We need to use class or id of the Sibling component)
    "+ .siblingComponent": {
      backgroundColor: theme.palette.success.dark,
      color: theme.palette.grey[100]
    },

  })
)
Enter fullscreen mode Exit fullscreen mode

Note:

  • Instead of a sibling component, if there was a sibling HTML tag, we could have a style that too ("+ div").

  • The adjacent sibling selector (+) is used to select an element that is directly after another specific element.

 

CSS Like Syntax

 

const MainComponent= styled(Box)(

  ({ theme }) => `
  background-color: ${theme.palette.primary.light};
  color: ${theme.palette.grey[900]};


  ${ /* Adjacent Sibling Component (We need to use class or id of the Sibling component) */'' }

   + .siblingComponent {
    background-color: ${theme.palette.success.dark};
    color: ${theme.palette.grey[100]};
  };

 `,
)
Enter fullscreen mode Exit fullscreen mode

 

Props

 

 

JSX

 

Suppose, we want to have a component (TestingProp) where we can pass two props: dark & border. The value of both props is boolean & the value will of these props controls the style of the component.

   <>

   <TestingProps border={true} dark={true}>Hello
   </TestingProps>

  </>
Enter fullscreen mode Exit fullscreen mode

So, we need to create the TestingProps and also need work with the prop dark & border.

 

JavaScript Object Syntax (Without MUI Theme)

 

const TestingProps = styled(Box, {

    // Configure which props should be forwarded on DOM
   shouldForwardProp: (prop) => prop !== 'dark' && prop!== 'border'

   })

   (({ dark, border }) => ({

   backgroundColor: dark? "black" : "white",
   color: dark? "white" : "black",
   border: border? "1rem solid pink" : 'none'

   }));

Enter fullscreen mode Exit fullscreen mode

What is this shouldForwaredProp?

We may already know that MUI5 uses emotion as a default style engine. This shouldForwardProp is coming from emotion. shouldForwaredProp is used to pass prop. In an example in the official documentation, shouldForwaredProp is used, you can check the example if you want.

 

CSS Like Syntax (Without MUI Theme)

 

const TestingProps4 = styled(Box, {

  // Configure which props should be forwarded on DOM
  shouldForwardProp: prop => prop !== 'dark',

  })


  (({ dark, border }) => `

    background-color: ${dark? "black" : "white"};
    color: ${dark? "white" : "black"};
    border: ${border? "1rem solid pink" : 'none'}

  `);

Enter fullscreen mode Exit fullscreen mode

 

JavaScript Object Syntax (With MUI Theme)

 

const TestingProps = styled(Box, {

   // Configure which props should be forwarded on DOM
  shouldForwardProp: (prop) => prop !== 'dark' && prop!== 'border'

  })

  (({ dark, border, theme }) => ({

  backgroundColor: dark? theme.palette.grey[900] : theme.palette.grey[100],
  color: dark? theme.palette.grey[100] : theme.palette.grey[900],
  border: border? `1rem solid ${theme.palette.primary.main}` : 'none'

  }));

Enter fullscreen mode Exit fullscreen mode

 

CSS Like Syntax (With MUI Theme)

 

const TestingProps = styled(Box, {

   // Configure which props should be forwarded on DOM
   shouldForwardProp: (prop) => prop !== 'dark' && prop!== 'border'

  })


  (({ dark, border, theme }) => `

    background-color: ${dark? theme.palette.grey[900] : theme.palette.grey[100]};
    color: ${dark? theme.palette.grey[100] : theme.palette.grey[900]};
    border: ${border? `1rem solid ${theme.palette.primary.main}` : 'none'};

  `);

Enter fullscreen mode Exit fullscreen mode

 

Default Prop Value

 

We can also pass the default value for the props.

TestingProps.defaultProps = {
    dark: false,
    border: false
  }

Enter fullscreen mode Exit fullscreen mode

 


 

That's it. 😃 Thanks for reading. 🎉

Logo

React社区为您提供最前沿的新闻资讯和知识内容

更多推荐