How to pass custom props to styled components using Material UI and TypeScript?
Asked Answered
V

2

6

I am using TypeScript(v4.2.3) and Material UI(v4.11.3), and trying to pass the custom props to styled component.

import React from 'react';
import {
  IconButton,
  styled,
} from '@material-ui/core';

const NavListButton = styled(IconButton)(
 ({ theme, panelOpen }: { theme: Theme; panelOpen: boolean }) => ({
   display: 'inline-block',
   width: 48,
   height: 48,
   borderRadius: 24,
   margin: theme.spacing(1),
   backgroundColor: panelOpen ? theme.palette.secondary.dark : 'transparent',
 }),
);

...

const Component: React.FC<Props> = () => {
  return (
    <NavListButton panelOpen={true} />
  );
};

This works fine, but if I check the console, it faces an error.

Warning: React does not recognize the `panelOpen` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `panelopen` instead. If you accidentally passed it from a parent component, remove it from the DOM element.
    at button
    at ButtonBase ...

How to get rid of this without using styled-components module, need to use styled from Material UI?

And also this is another similar question.

I wanted to add media queries to styled components, it says TypeError: Cannot read property 'addRule' of null.

const PrintableTableContainer = styled(TableContainer)(() => ({
  '@media print': {
    '@page': { size: 'landscape' },
  },
}));

enter image description here

I also tried this.

const PrintableTableContainer = styled(TableContainer)`
  @media print {
    @page { size: landscape }
  }
`;

But it also says

Argument of type 'TemplateStringsArray' is not assignable to parameter of type 'CreateCSSProperties<(value: string, index: number, array: readonly string[]) => unknown> | ((props: { theme: Theme; } & ((value: string, index: number, array: readonly string[]) => unknown)) => CreateCSSProperties<...>)'.
  Type 'TemplateStringsArray' is not assignable to type 'CreateCSSProperties<(value: string, index: number, array: readonly string[]) => unknown>'.
    Types of property 'filter' are incompatible.
...
Villeneuve answered 29/6, 2021 at 3:19 Comment(1)
Not possible to get rid of this?Villeneuve
C
2

Just my 2 cents, hope the solution I provide can help you.

The main cause is the material-ui version, your project may mix up with version 4 and version 5.

1st: Install material-ui v5

  • @next version = v5
  • install material-ui and styled-engine to use styled-components
// npm
npm install @material-ui/core@next @material-ui/styled-engine-sc@next styled-components
npm install --save-dev @types/styled-components


// yarn 
yarn add @material-ui/core@next @material-ui/styled-engine-sc@next styled-components
yarn add --dev @types/styled-components

2nd: Install react-app-rewired

the default material-ui styled-engine is pointing to emotion, so we need to override the webpack config to refer to styled-components.

The Official Doc explains how to use styled-components in material-ui:

For create-react-app, install react-app-rewired

// npm 
npm install --save-dev react-app-rewired customize-cra

// yarn
yarn add --dev react-app-rewired customize-cra

3rd: Override webpack config

The Offical example: https://github.com/mui-org/material-ui/tree/next/examples/create-react-app-with-styled-components-typescript

  • create config-overrides.js
  • override styled-engine path to point to styled-engine-sc path
// config-overrides.js
const { addWebpackAlias, override } = require('customize-cra');

module.exports = override(
  addWebpackAlias({
    '@material-ui/styled-engine': '@material-ui/styled-engine-sc',
  }),
);

4th: Now you can use the material-ui with styled-components

import { IconButton, styled, TableContainer, Theme } from "@material-ui/core";

const NavListButton = styled(IconButton)(
  ({ theme, $panelOpen }: { theme?: Theme, $panelOpen: boolean }) => ({
    display: "inline-block",
    width: 48,
    height: 48,
    borderRadius: 24,
    margin: theme?.spacing(1),
    backgroundColor: $panelOpen ? theme?.palette.secondary.dark : "transparent"
  })
);

const PrintableTableContainer = styled(TableContainer)(() => ({
  "@media print": {
    "@page": { size: "landscape" }
  }
}));

...

<NavListButton $panelOpen={true} />
<PrintableTableContainer />

For the 1st question, React does not recognize the `panelOpen` prop on a DOM element. .

styled-components provides a transient props - $ to avoid the custom props to pass to the DOM.

https://styled-components.com/docs/api#transient-props


A demo git repo for your reference and cross-checking in case you cannot make it work

Crosscurrent answered 30/6, 2021 at 10:27 Comment(2)
Thanks in advance! Actually, I didn't realize Material UI has the new version 5. I will give it a shot.Villeneuve
Tried all the steps and also tried the example from the mui/examples repo, the warning wont go. But this answer #49614274 did solve it for meTew
H
0

Had a similar problem. In my case i had:

import styles from './MabSidebar.styles';
...
const Sidebar = styled(Box)(styles);

Solved it quick and dirty by using any:

const Sidebar = styled(Box)(styles as any);
Heliport answered 26/5, 2023 at 8:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.