Skip to content

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

Merged
merged 10 commits into from
Jun 22, 2023

Conversation

mattcosta7
Copy link
Contributor

@mattcosta7 mattcosta7 commented Jun 21, 2023

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

  • Added/updated tests
  • Added/updated documentation
  • Changes are SSR compatible
  • Tested in Chrome
  • Tested in Firefox
  • Tested in Safari
  • Tested in Edge

Take a look at the What we look for in reviews section of the contributing guidelines for more information on how we review PRs.

@changeset-bot
Copy link

changeset-bot bot commented Jun 21, 2023

🦋 Changeset detected

Latest commit: 67f9ea3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@primer/react Patch

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

@github-actions
Copy link
Contributor

github-actions bot commented Jun 21, 2023

size-limit report 📦

Path Size
dist/browser.esm.js 101.81 KB (+0.79% 🔺)
dist/browser.umd.js 102.36 KB (+0.78% 🔺)

@@ -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
Copy link
Contributor Author

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

Copy link
Member

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 🤔

Copy link
Contributor Author

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()
Copy link
Contributor Author

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

@github-actions github-actions bot temporarily deployed to storybook-preview-3437 June 21, 2023 08:52 Inactive
@@ -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}
Copy link
Contributor Author

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?

Copy link
Member

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

Copy link
Member

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

@mattcosta7 mattcosta7 changed the title use react-is for checking valid element type use react-is for checking valid element type, update primer/octicons-react Jun 21, 2023
@@ -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",
Copy link
Contributor Author

@mattcosta7 mattcosta7 Jun 21, 2023

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

@github-actions github-actions bot temporarily deployed to storybook-preview-3437 June 21, 2023 08:59 Inactive
@mattcosta7 mattcosta7 marked this pull request as ready for review June 21, 2023 09:03
@mattcosta7 mattcosta7 requested review from a team and siddharthkp June 21, 2023 09:03
@mattcosta7
Copy link
Contributor Author

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

@github-actions github-actions bot temporarily deployed to storybook-preview-3437 June 21, 2023 09:04 Inactive
@mattcosta7 mattcosta7 temporarily deployed to github-pages June 21, 2023 09:08 — with GitHub Actions Inactive
@github-actions github-actions bot temporarily deployed to storybook-preview-3437 June 21, 2023 09:09 Inactive
@github-actions github-actions bot temporarily deployed to storybook-preview-3437 June 21, 2023 09:10 Inactive
@joshblack joshblack requested a review from broccolinisoup June 21, 2023 15:10
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",
Copy link
Contributor Author

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

@mattcosta7 mattcosta7 temporarily deployed to github-pages June 21, 2023 17:06 — with GitHub Actions Inactive
@github-actions github-actions bot temporarily deployed to storybook-preview-3437 June 21, 2023 17:06 Inactive
@github-actions github-actions bot temporarily deployed to storybook-preview-3437 June 21, 2023 17:06 Inactive
Copy link
Member

@broccolinisoup broccolinisoup left a 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
Copy link
Member

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}
Copy link
Member

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

@broccolinisoup
Copy link
Member

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 🙂

@mattcosta7 mattcosta7 temporarily deployed to github-pages June 22, 2023 07:03 — with GitHub Actions Inactive
@github-actions github-actions bot temporarily deployed to storybook-preview-3437 June 22, 2023 07:04 Inactive
@mattcosta7
Copy link
Contributor Author

mattcosta7 commented Jun 22, 2023

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!

@mattcosta7 mattcosta7 temporarily deployed to github-pages June 22, 2023 07:42 — with GitHub Actions Inactive
@github-actions github-actions bot temporarily deployed to storybook-preview-3437 June 22, 2023 07:42 Inactive
@mattcosta7
Copy link
Contributor Author

mattcosta7 commented Jun 22, 2023

VRT failures seem related to the actual icon changing slightly - not sure how to update those

comparison of icons in vrt output

@github-actions
Copy link
Contributor

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.

@broccolinisoup
Copy link
Member

VRT failures seem related to the actual icon changing slightly - not sure how to update those

comparison of icons in vrt output

I added update snapshot label, hopefully that should take care of it 😊

@broccolinisoup
Copy link
Member

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?

Yay! Once we get the vrt green, feel free to merge it. Thanks again 🎉

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.

Primer leading/trailingVisual and Icons cannot be lazy, memo, forwardRef
3 participants