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

feat: make IconButton polymorphic through 'as' prop #452

Merged
merged 4 commits into from
Dec 10, 2021
Merged

Conversation

thuey
Copy link
Collaborator

@thuey thuey commented Dec 9, 2021

This is necessary for https://github.com/dequelabs/walnut/issues/2488 to show a "view" icon that links to the new invoice page

* Unfortunately, eslint does not recognize the Polymorphic component has propTypes set
*
* We might be able to remove this if we upgrade eslint and associated plugins
* See: https://github.com/dequelabs/cauldron/issues/451
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I started to try upgrading eslint and associated plugins, but we are pretty far out of date. It popped 88 problems that needed to be addressed. I figured it would be better to handle upgrading in a separate PR

@@ -42,6 +42,7 @@
"@babel/preset-stage-0": "^7.8.3",
"@babel/preset-typescript": "^7.9.0",
"@babel/register": "^7.9.0",
"@radix-ui/react-polymorphic": "^0.0.14",
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I tried out several libraries and evaluated creating the prop types internally. Other libraries were either unreliable or required code changes to the runtime, which I was trying to avoid. If anything, if we decide not to use this library directly, we should consider copying the code in and citing the source.

Copy link
Member

Choose a reason for hiding this comment

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

Do we really need a library for this? It seems pretty simple to do on our own.

Copy link
Collaborator Author

@thuey thuey Dec 9, 2021

Choose a reason for hiding this comment

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

I don't mind pulling this in. I have not evaluated segmentio's implementation. The end implementation of a working solution is not overly complicated. However, getting there is pretty finicky. Other implementations I looked at (libraries, blog posts, etc.) either had shortcomings when it came to refs, allowed you to specify as but did not enforce the prop types, or slowed down Typescript a ton.

I went ahead and brought polymorphic in and referenced the source material

@@ -31,30 +51,31 @@ const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(
variant = 'secondary',
disabled,
...other
}: IconButtonProps,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Prop types are now defined in PolymorphicIconButton

@thuey thuey requested a review from a team December 9, 2021 16:04
Copy link
Member

@stephenmathieson stephenmathieson left a comment

Choose a reason for hiding this comment

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

LGTM!

We should do the same for <Link/> (see #52).

Copy link
Member

@scurker scurker left a comment

Choose a reason for hiding this comment

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

I'm a little bit confused by this change, but maybe I'm missing context.

I think for accessibility purposes, a Button should render as a Button, and a Link should render as a link - it's harder to enforce if we're swapping the rendered element under the hood.

We currently support this in <Link> with a variant of button, so I'm wondering if we should allow <Link variant="icon-button"> as well? It's not as straight forward of a change, but I think would be a clearer api by allowing the correct intrinsic underlying html element. I'm requesting changes because I'd like to have a quick discussion before we move forward with this change.

@thuey
Copy link
Collaborator Author

thuey commented Dec 10, 2021

For posterity: After jumping on a call and some further back-and-forth, @scurker and I compromised to keep the polymorphic behavior, but add things like role to help promote good accessibility practices. This is actually what material-ui does: https://github.com/mui-org/material-ui/blob/master/packages/mui-material/src/ButtonBase/ButtonBase.js#L288-L298

@thuey thuey merged commit 41ff048 into develop Dec 10, 2021
@thuey thuey deleted the icon-button-as branch December 10, 2021 20:19
stephenmathieson added a commit that referenced this pull request Dec 14, 2021
* develop:
  feat(react): add onChange prop to tabs when the active tab changes (#453)
  feat: make IconButton polymorphic through 'as' prop (#452)
  fix(Step): Add an accessible name when using `tooltip={...}` (#449)
  fix: allow TableHeader to take th attributes and TableCell to take td attributes (#444)
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.

3 participants