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

[Typography] Improve custom component types support #18868

Merged
merged 1 commit into from
Dec 17, 2019
Merged

[Typography] Improve custom component types support #18868

merged 1 commit into from
Dec 17, 2019

Conversation

fyodore82
Copy link
Contributor

@fyodore82 fyodore82 commented Dec 16, 2019

Fix #18473

@mui-pr-bot
Copy link

No bundle size changes comparing 4e07461...57c238b

Generated by 🚫 dangerJS against 57c238b

@oliviertassinari oliviertassinari changed the title [Typography] Fix typecheck for Typography with custom component (#18473) [Typography] Improve custom component types support Dec 16, 2019
@oliviertassinari
Copy link
Member

The changes look safe, especially with the added test case (thank you for that) and the prior work with the other components we replicate here.

@oliviertassinari oliviertassinari merged commit b6ff4f5 into mui:master Dec 17, 2019
@oliviertassinari
Copy link
Member

@fyodore82 Well done.

@dohomi
Copy link
Contributor

dohomi commented Dec 29, 2019

@oliviertassinari @fyodore82 I am missing the right typings after this change. I was using component as a typing prop but this fails after I upgraded.

Property 'component' does not exist on type 'OverrideProps<TypographyTypeMap<{}, "span">, "span">'.
    11 |   const props: TypographyProps = {}
  > 12 |   content.tag && (props.component = content.tag)

@fyodore82
Copy link
Contributor Author

fyodore82 commented Dec 29, 2019

@dohomi, this became a bit tricky now, but that's how it implemented in OverridableComponent.d.ts which is the base for many other component typing's.

var t: TypographyProps<'a', {component: 'a'}> = {
  component: 'a',
  href: 'a'
}

If you don't know in advance what component you'll use you can do

const content = { tag: 'a' }
const props: TypographyProps<React.ElementType, {component?: string}> = {}
content.tag && (props.component = content.tag)

}

declare const Typography: OverridableComponent<TypographyTypeMap>;
Copy link
Member

@rosskevin rosskevin Dec 30, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change makes the export of TypographyProps unused, does it not @fyodore82? So code that used to reference and Pick from TypographyProps I see is now broken and a mismatch for the Typography component itself.

For example:

// simple override of default variant
export const Typo = React.forwardRef<any, TypographyProps>((props, ref) => (
  <Typography variant="body2" ref={ref} {...props} />
))

        // valid
        <Typography component="a" href="url" display="block" />
        // now invalid
        <Typo component="a" href="url" display="block" />

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see this is an updated pattern elsewhere in the code (e.g. Chip, Grid, Link etc), but unsure how the *Props exports relate.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pattern I've employed for Typography is used in several other components in Material-UI as you already mentioned. So I've decided not to invent different solution but follow already established mainline.

The TypographyProps and Typography itself are related. Both inherit from OverrideProps interface. Typography does it indirectly, rhru OverridableComponent and TypographyProps does it directly.

forwardRef will also work fine if specialize TypographyProps with correct component

export const Typo = React.forwardRef<any, TypographyProps<'a', {component: 'a'}>>((props, ref) => (
    <Typography variant="body2" ref={ref} {...props} />
))

// now valid
<Typo component="a" href="url" display="block" />

I have also checked how it was before Typography change. This code <Typo component="a" href="url" display="block" /> was not valid due to presence of href attribute. And we had no means to make it valid.

I may suggest to extend Typography documentation and include samples of how to use component prop in different scenarios

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fyodore82 So was the documentation ever updated? Because now I can't use FC<TypographyProps> anymore, which was a bit of a low blow to sneak into a minor release.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[prop component] Doesn't allow for htmlFor prop in typescript when component="label"
6 participants