Search code examples
reactjsmaterial-ui

Can you pass custom props to Material-UI v5 `styled()` components?


For example, in styled-components you can do the following:

const Div = styled.div`
  background: ${props => props.primary ? "palevioletred" : "white"};
  color: ${props => props.primary ? "white" : "palevioletred"};
`;

render(
  <section>
    <Div>Normal</Div>
    <Div primary>Primary</Div>
  </section>
);

Can you get the same result with Material-UI v5 styled utility without adding overrides to the global theme object like the example in the styled() docs?


Solution

  • Yes!

    The most basic example of the above would look like this in MUI v5:

    const Div = styled("div")(({ primary }) => ({
      backgroundColor: primary ? "palevioletred" : "white",
      color: primary ? "white" : "palevioletred"
    }));
    
    
    render(
      <section>
        <Div>Normal</Div>
        <Div primary>Primary!</Div>
      <section>
    );
    

    However, as the React docs say:

    The unknown-prop warning will fire if you attempt to render a DOM element with a prop that is not recognized by React as a legal DOM attribute/property. You should ensure that your DOM elements do not have spurious props floating around.

    So MUI gave us the shouldForwardProp option to tell MUI whether it "should forward the prop" to the root node or not. The above example would look like this using that prop:

    const Div = styled("div", {
      shouldForwardProp: (prop) => prop !== "primary"
    })(({ primary }) => ({
      backgroundColor: primary ? "palevioletred" : "white",
      color: primary ? "white" : "palevioletred"
    }));
    
    render(
      <section>
        <Div>Normal</Div>
        <Div primary>Primary!</Div>
      <section>
    );
    

    Explanation

    The second argument to the styled function is an options object, one of the things it accepts is shouldForwardProp, which as the docs say, "Indicates whether the prop should be forwarded to the Component". So to remove the unknown prop warning from the console, we tell it not to pass our custom prop to the DOM element with shouldForwardProp: (prop) => prop !== "primary". Now we destructure this prop in the function call that returns our custom styles, and use it in those styles like we would any other function.

    If you want to use the global theme styles here as well, just destructure it along with your custom prop(s), ie ({ primary, otherProp, thirdProp, theme }).

    Working codesandbox.

    MUI v5 styled API docs