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

Use JSX.IntrinsicElements instead of custom HTMLTags and SVGTags #1084

Merged

Conversation

devrelm
Copy link
Contributor

@devrelm devrelm commented Aug 11, 2017

I'm not sure if there's a good reason we're maintaining our own list of element tags, but from what I can tell, we should be able to just use the JSX.IntrinsicElements types straight from the react type defs.

This PR kills tags.d.ts in favor of using JSX.IntrinsicElements, which contains both HTML and SVG elements (and thus replaces both our HTMLTags and SVGTags.) JSX.IntrinsicElements also maps from element names to prop-types, rather than from names to element-types. This means that we will output the actual detailed props used by each individual html component rather than HTMLProps, which contains all props for all elements (i.e. href on div, which shouldn't be there.)

@mxstbr
Copy link
Member

mxstbr commented Aug 12, 2017

Waaaaiiiitttt can we use that in the JavaScript somehow too so we don't have to maintain our own whitelist?

@devrelm
Copy link
Contributor Author

devrelm commented Aug 13, 2017

@mxstbr I don't think so, since JSX.IntrinsicElements is just a type in the react.d.ts file. It's only used for type-checking, and doesn't actually transpile into javascript.

I went searching for a physical whitelist within React's repo, but as best I can tell React itself hasn't kept a whitelist of elements since ~0.14 — maybe even earlier (see facebook/react#2746).

I was about to ask why style-components enforces a whitelist, but I guess it doesn't really look like it does. Instead it just has a list used to support the styled.tagname helpers (for styled.div, styled.button, etc.) It might be worth duplicating that list to our d.ts in case react.d.ts adds a tagname that we don't have a helper for. If we want to have one shared list for both our d.ts file and our styled.tagname helpers, then we'll have to add it as part of our build process.

@quantizor
Copy link
Contributor

@mxstbr you guys don't actually need to implement a whitelist. Could implement a getter on the default styled export that inspects the requested key and does something with it. Or just do away with that pattern entirely like styled('div') which probably is better in the long run.

@kitten
Copy link
Member

kitten commented Aug 13, 2017

@probablyup We can't just define a getter for arbitrary input. That requires proxies and their support is not far spread enough. The polyfill requires a list of possible keys which brings us full circle. We've discussed this before and decided against it.

@mxstbr We've also discussed this point before. We could use an internal file in React with a list of all elements, but they might remove it at any time (Or have moved/removed it already? As @devrelm stated, it's gone now). This also is a problem when someone is switching to a minified bundle or does anything similar. In that case the list will be duplicated as well...

I think the only sane and realistic solution is to add it to our v3 babel plugin. I already have an idea on how to structure it so that preprocessing and non-preprocessing SC code can be used at the same time. We can then also remove the tag list from the SC code for preprocessing.

@devrelm
Copy link
Contributor Author

devrelm commented Aug 17, 2017

@philpl @mxstbr Are there any more action items on this that I should take care of? There was a bit of discussion there and ideas proposed, but I can't tell if any decisions were made.

@kitten
Copy link
Member

kitten commented Aug 17, 2017

cc @styled-components/typers

@patrick91
Copy link
Contributor

Looks good to me, the only issue I can see is that if the react.d.ts list gets updated but we don't update styled-components to support the new tags (or remove one) there can be some discrepancies between the typings and the actual implementation, but I don't see this happening often (also, we'd need to update our elements list when, and if, we do change the list of elements we support).

So for me it's +1

PS. When I did the initial typings I didn't know about the existence of JSX.IntrinsicElements, so that the main reason why we have our own list :)

Copy link
Contributor

@patrick91 patrick91 left a comment

Choose a reason for hiding this comment

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

So good 👍

Copy link
Contributor

@Igorbek Igorbek left a comment

Choose a reason for hiding this comment

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

I like it, I wanted to have this some time ago but didn't have time to address it.

@Igorbek
Copy link
Contributor

Igorbek commented Aug 17, 2017

@patrick91 your concern is legit, but, to me, it is acceptable risk. Moreover, it would push people to file issues if something is not supported from the list of jsx elements. 😃

@kitten
Copy link
Member

kitten commented Aug 17, 2017

Thanks @devrelm for contributing and thanks @Igorbek and @patrick91 for reviewing it this quickly 👍

@kitten kitten merged commit 3b4f543 into styled-components:master Aug 17, 2017
@devrelm devrelm deleted the devrelm/intrinsic-element-types branch August 28, 2017 13:09
luke-john added a commit to luke-john/glamorous that referenced this pull request Sep 3, 2017
This replaces the use of `React.HTMLProps` and `React.SVGAttributes` with `JSX.IntrinsicElements`.

Inspired by styled-components/styled-components#1084
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants