-
Notifications
You must be signed in to change notification settings - Fork 616
use react-is for checking valid element type, update primer/octicons-react #3437
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
Conversation
🦋 Changeset detectedLatest commit: 67f9ea3 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
size-limit report 📦
|
@@ -24,11 +25,11 @@ export type TextInputNonPassthroughProps = { | |||
/** | |||
* A visual that renders inside the input before the typing area | |||
*/ | |||
leadingVisual?: string | React.ComponentType<React.PropsWithChildren<{className?: string}>> | |||
leadingVisual?: React.ElementType | React.ReactNode |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't pass props internally, so we don't need to actually care what the props the element can take are
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might a be novice ts question but I assumed that only passing React.ReactNode
will make ts happy (it doesn't!) because as far as I understand React.ReactNode
includes React.ElementType
as well? So I am curious why we need to explicitly type React.ElementType
here as well 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ooo interesting. I didn't realize ReactNode included that, and i'm suprised it does (since ElementType isn't renderable as children directly). I think i'd prefer this since it's a bit more explicit that this could be a Component, but could also be renderable content?
@@ -57,10 +57,56 @@ describe('TextInput', () => { | |||
|
|||
it('renders leadingVisual', () => { | |||
expect(render(<TextInput name="search" placeholder={'Search'} leadingVisual={SearchIcon} />)).toMatchSnapshot() | |||
expect(render(<TextInput name="search" placeholder={'Search'} leadingVisual={<SearchIcon />} />)).toMatchSnapshot() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just a bunch of tests that validate rendered content given a bunch of different element types
@@ -296,7 +297,7 @@ function TextInputWithTokensInnerComponent<TokenComponentType extends AnyReactCo | |||
visualPosition="leading" | |||
showLoadingIndicator={showLeadingLoadingIndicator} | |||
> | |||
{typeof LeadingVisual === 'function' ? <LeadingVisual /> : LeadingVisual} | |||
{typeof LeadingVisual !== 'string' && isValidElementType(LeadingVisual) ? <LeadingVisual /> : LeadingVisual} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we have to check for string
explicitly here, because things like 'div'
is a valid element type, but we don't want to try and render an empty div, but instead just pass through that text.
We may want to consider whether accepting raw element types makes sense longterm (I don't think there's a good reason to accept a raw Component instead of just React.ReactNode).
<Component leadingVisual={SearchIcon} /> // imo this shouldn't be allowed
<Component leadingVisual={<SearchIcon />} /> // imo this should be the way
but that might be a later breaking change at this point?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mattcosta7 I think you're dead-on and I bet we could look to introduce this behavior in v36 and deprecate the raw element type and remove support for it in v37
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh great point! Thanks for the note as well, that was one of my questions until I came to that point!
➕ 1 for using ReactNodes instead of raw components
@@ -99,12 +99,13 @@ | |||
"@github/relative-time-element": "^4.1.2", | |||
"@lit-labs/react": "1.1.1", | |||
"@primer/behaviors": "1.3.4", | |||
"@primer/octicons-react": "18.3.0", | |||
"@primer/octicons-react": "^19.3.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved from an exact dep, to avoid version conflicts in dotcom, which this would cause eventually otherwise (if dotcom installed, for instance, 19.4.0).
Should octicons-react just be a peer dependency and not a direct dep? This would likely help consumer bundlesize some
this will superceed #3428 which I should have looked for last night before starting this work, and only saw today - however this PR already fixes some issues with that one, so may be easier to just push through |
package.json
Outdated
@@ -118,6 +119,7 @@ | |||
"lodash.isempty": "4.4.0", | |||
"lodash.isobject": "3.0.2", | |||
"react-intersection-observer": "9.4.3", | |||
"react-is": "18.2.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
going to loosen this and types so they can be managed better in dotcom
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you so much for this PR! and thanks for the notes as well, super helpful. Just had one question - other than that. looks great to me!
@@ -24,11 +25,11 @@ export type TextInputNonPassthroughProps = { | |||
/** | |||
* A visual that renders inside the input before the typing area | |||
*/ | |||
leadingVisual?: string | React.ComponentType<React.PropsWithChildren<{className?: string}>> | |||
leadingVisual?: React.ElementType | React.ReactNode |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might a be novice ts question but I assumed that only passing React.ReactNode
will make ts happy (it doesn't!) because as far as I understand React.ReactNode
includes React.ElementType
as well? So I am curious why we need to explicitly type React.ElementType
here as well 🤔
@@ -296,7 +297,7 @@ function TextInputWithTokensInnerComponent<TokenComponentType extends AnyReactCo | |||
visualPosition="leading" | |||
showLoadingIndicator={showLeadingLoadingIndicator} | |||
> | |||
{typeof LeadingVisual === 'function' ? <LeadingVisual /> : LeadingVisual} | |||
{typeof LeadingVisual !== 'string' && isValidElementType(LeadingVisual) ? <LeadingVisual /> : LeadingVisual} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh great point! Thanks for the note as well, that was one of my questions until I came to that point!
➕ 1 for using ReactNodes instead of raw components
I closed my PR and we can continue with this. The only thing is that because the original PR is reverted, we should individually test this at dotcom as a part of the re-introducing strategy. Are you happy to do that @mattcosta7 or do you prefer for me to do it? Either way works for me 🙂 |
Opened: https://github.com/github/github/pull/277602 CI looks good there - let me know whehter I should merge this or y'all want to later? @joshblack re deprecation - I'm not sure what the best way to note that is here, but I agree that sounds reasoable! |
Uh oh! @mattcosta7, the image you shared is missing helpful alt text. Check #3437 (comment). Alt text is an invisible description that helps screen readers describe images to blind or low-vision users. If you are using markdown to display images, add your alt text inside the brackets of the markdown image. Learn more about alt text at Basic writing and formatting syntax: images on GitHub Docs. |
Yay! Once we get the vrt green, feel free to merge it. Thanks again 🎉 |
This change allows for trailing/leading components to properly accept React component types other than function components (
memo
,lazy
,forwardRef
, etc).This also bumps the version of primer/octicons-react which could be done separately, but why not just land this together.
This change is backward compat, since function components are still allowed, but properly allows for more types to be considered
Closes #3430
Screenshots
Please provide before/after screenshots for any visual changes
Merge checklist
Take a look at the What we look for in reviews section of the contributing guidelines for more information on how we review PRs.