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

[Link] LinkProps missing component prop #29942

Closed
2 tasks done
vedrxn opened this issue Nov 29, 2021 · 6 comments · Fixed by #35924
Closed
2 tasks done

[Link] LinkProps missing component prop #29942

vedrxn opened this issue Nov 29, 2021 · 6 comments · Fixed by #35924
Labels
bug 🐛 Something doesn't work component: link This is the name of the generic UI component, not the React module! typescript

Comments

@vedrxn
Copy link

vedrxn commented Nov 29, 2021

Duplicates

  • I have searched the existing issues

Latest version

  • I have tested the latest version

Current behavior 😯

The LinkProps type does not include a component field.

Expected behavior 🤔

The LinkProps type does include a component field.

Steps to reproduce 🕹

Following these docs, the example code throws an error:
the LinkProps type does not include a component field.

The ThemeOptions type is using LinkProps as the type for theme.components.MuiLink.defaultProps.

See this alternate example, typescript playground.

The alternate example shows that this issue also affects users who use Link as a root node (assuming props spread).

Context 🔦

Discovered while using react-router's Link component as MuiLink's default component, following these docs. A simplified approach to reproduce, try "a" or "div" as MuiLink's component prop value in createTheme.

A quick look at the material-ui source code:

This ThemeOptions type
uses this components type
which uses this props type
which uses this LinkProps type.

That LinkProps type doesn't appear to use OverridableComponent, which may be the issue. The Link type in the same file does.

Your environment 🌎

N/A

@vedrxn vedrxn added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Nov 29, 2021
@mbrookes mbrookes added bug 🐛 Something doesn't work component: link This is the name of the generic UI component, not the React module! typescript and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Nov 29, 2021
@mbrookes mbrookes changed the title LinkProps missing component prop [Link] LinkProps missing component prop Nov 29, 2021
@plmwd
Copy link

plmwd commented Jan 18, 2022

Is there a workaround for this?

@geirsagberg
Copy link
Contributor

@plmwd A workaround is to cast the props:

import { createTheme, LinkProps as MuiLinkProps } from '@mui/material'
import React from 'react'
import { Link, LinkProps } from 'react-router-dom'

export const colors = {
  linkBlue: '#2C73FF',
}

const LinkBehavior = React.forwardRef<
  any,
  Omit<LinkProps, 'to'> & { href: LinkProps['to'] }
>((props, ref) => {
  const { href, ...other } = props
  // Map href (MUI) -> to (react-router)
  return <Link ref={ref} to={href} {...other} />
})
LinkBehavior.displayName = 'LinkBehavior'

export const theme = createTheme({
  components: {
    MuiButtonBase: {
      defaultProps: {
        LinkComponent: LinkBehavior,
      },
    },
    MuiLink: {
      defaultProps: {
        color: colors.linkBlue,
        component: LinkBehavior,
      } as MuiLinkProps, // https://github.com/mui/material-ui/issues/29942
    },
  },
}

@jayKayEss
Copy link

@geirsagberg I had to cast to LinkBaseProps to get the workaround to work, but thank you!

@plmwd
Copy link

plmwd commented Feb 16, 2022

This is great. Thank you @geirsagberg!

@mnajdova
Copy link
Member

mnajdova commented Jun 8, 2022

I think this doesn't work for more components. We need to add a TS spec test and verify if this works for all components. Then we should either try to find a fix to the issues or document how it can be used. cc @mui/core

@michaldudak
Copy link
Member

The problem with overriding the component prop in a theme is that TS won't suggest/allow props of the overridden component.

Consider the following example: https://codesandbox.io/s/component-override-in-theme-qk0p5t?file=/src/Demo.tsx

Even though Chip's component is set to a, TS complains when we use the href prop on it.
Because of this, I think we should recommend wrapping MUI components in custom ones when a global component prop override is needed:

const LinkChip = React.forwardRef(function LinkChip(props: ChipProps<"a">, ref: React.ForwardedRef<HTMLAnchorElement>) {
  return <Chip {...props} ref={ref} component="a" />
});

sai6855 added a commit to sai6855/material-ui that referenced this issue Jan 24, 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 component: link This is the name of the generic UI component, not the React module! typescript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants