Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The component prop is not allowed on a styled() MUI component #37551

Closed
2 tasks done
thany opened this issue Jun 9, 2023 · 11 comments
Closed
2 tasks done

The component prop is not allowed on a styled() MUI component #37551

thany opened this issue Jun 9, 2023 · 11 comments
Assignees
Labels
bug 🐛 Something doesn't work duplicate This issue or pull request already exists package: system Specific to @mui/system typescript

Comments

@thany
Copy link

thany commented Jun 9, 2023

Duplicates

  • I have searched the existing issues

Latest version

  • I have tested the latest version

Steps to reproduce 🕹

Link to live example: https://codesandbox.io/s/strange-hofstadter-6668qh?file=/src/App.tsx

Observe the Typescript error.

Current behavior 😯

The typings cause an error, saying component doesn't exist on the styled() MUI component, but it does exist on the same MUI component directly. Somehow the typings for that one prop is not transferred over properly to the typings of the output of the styled() function.

It does work, though with that typescript error.

Expected behavior 🤔

No error. I don't see why this prop wouldn't be allowed, especially given that it works perfectly fine at runtime.

Context 🔦

No response

Your environment 🌎

npx @mui/envinfo
  System:
    OS: Windows 10 10.0.19045
  Binaries:
    Node: 18.15.0 - C:\Program Files\nodejs\node.EXE
    Yarn: Not Found
    npm: 9.6.7 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Chrome: 114.0.5735.110
    Edge: Spartan (44.19041.1266.0), Chromium (114.0.1823.41)
  npmPackages:
    @emotion/react:  11.10.6
    @emotion/styled:  11.10.6
    @mui/base:  5.0.0-beta.4
    @mui/core-downloads-tracker:  5.13.4
    @mui/material:  5.13.4
    @mui/private-theming:  5.13.1
    @mui/styled-engine:  5.13.2
    @mui/styles:  5.13.2
    @mui/system:  5.13.2
    @mui/types:  7.2.4
    @mui/utils:  5.13.1
    @types/react:  18.2.0
    react:  18.2.0
    react-dom:  18.2.0
    typescript:  4.9.5

I'm on Firefox 114. Not that it matters.

@thany thany added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Jun 9, 2023
@thany thany changed the title The component is not allowed in a styled MUI component The component prop is not allowed on a styled() MUI component Jun 9, 2023
@thany
Copy link
Author

thany commented Jun 9, 2023

There is a silly workaround:

- const StyledTypography = styled(Typography)({ ... });
+ const StyledTypography = styled(Typography)<{ component: string }>({ ... });

So basically forcing the component prop to exist again. The string type is obviously not correct, but it works in my scenario.

@zannager zannager added typescript package: system Specific to @mui/system labels Jun 9, 2023
@brijeshb42 brijeshb42 added bug 🐛 Something doesn't work and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Jun 9, 2023
@brijeshb42
Copy link
Contributor

I need to dig deeper into it to have more context around the component prop, but if you want to pass a custom component/tag, you could use the as prop instead of component and it has a higher precedence than component as well.

cc: @siriwatknp You might have more details.

@thany
Copy link
Author

thany commented Jun 12, 2023

If I pass as="h2" then all MUI-related classnames are no longer applied. I think because the as prop is picked up by emotion, so the MUI component never comes into play.

@chouclee
Copy link

This issue is not just limited to component prop, but any props that are inherited from some base props. For example,

import { Link as RouterLink } from "react-router-dom";

const StyledListItemButton = styled(ListItemButton)<ListItemButtonProps>(({ theme }) => ({
}));

<StyledListItemButton 
   component={RouterLink}
   to={"/"}
/>

Both component and to will not be recognized.

@brijeshb42
Copy link
Contributor

I'll check and revert.

@rishavpandey43
Copy link

@chouclee You're correct. It's removing all the system props from the component after being styled. I faced the same issue while creating a design system. Cannot override global settings always, need to create wrapper kinds of components several times.

We need to have this issue resolved.
Issue I got - #37961

@kellyrmilligan
Copy link

I have a similar issue to this, but instead of styled its for when I want to create a wrapper component for mui and also forward the ref. Is there an example of how to properly wrap a mui component that allows for the component prop usage and for fowarding refs?

@kellyrmilligan
Copy link

kellyrmilligan commented Jul 19, 2023

FWIW, I think this seems to work for styled:

export const CustomButton = styled(MuiButton)(({ theme }) => ({
  backgroundColor: theme.palette.success.dark,
})) as typeof MuiButton

https://mui.com/material-ui/guides/typescript/#complications-with-the-component-prop

@kellyrmilligan
Copy link

also, seems to be ok for this as well:

export const Button3 = React.forwardRef((props, ref) => (
  <MuiButton {...props} ref={ref} />
)) as typeof MuiButton

@kellyrmilligan
Copy link

kellyrmilligan commented Jul 19, 2023

a few storybook stories to prove it out a bit:

export const Ref: Story = {
  render: (args) => {
    const storyRef = useRef(null)
    return (
      <Button
        {...args}
        ref={storyRef}
        onClick={() => buttonAction(storyRef.current)}
      />
    )
  },
  args: {
    variant: "contained",
    color: "primary",
    children: "Click me",
  },
}

export const AsComponent: Story = {
  render: (args: any) => {
    return <Button {...args} component="a" href="/stuff" />
  },
  args: {
    variant: "contained",
    color: "primary",
    children: "Contained button",
  },
}

not great IMO, I really with the composition docs had a code example to do both ref forwarding and accept generics. The same behavior is desired with styled. styled at least seems to forward the ref for you. I really liked how chakra ui let you wrap their components with their own forwardRef, and that always allows the as prop to function properly, and for refs to be ok.

https://chakra-ui.com/community/recipes/as-prop

@mnajdova
Copy link
Member

mnajdova commented Nov 6, 2023

Duplicate of #29875

@mnajdova mnajdova marked this as a duplicate of #29875 Nov 6, 2023
@github-actions github-actions bot added the duplicate This issue or pull request already exists label Nov 6, 2023
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Nov 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 Something doesn't work duplicate This issue or pull request already exists package: system Specific to @mui/system typescript
Projects
None yet
Development

No branches or pull requests

9 participants