-
Notifications
You must be signed in to change notification settings - Fork 9
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
@cambly/syntax-floating-components: Tooltip + Popover v2.0.0, built on top of AriaKit #247
Conversation
…tories in node_modules when one workspace package depends on another
- also, `"span"` is now valid for `as` prop
🦋 Changeset detectedLatest commit: 83b9215 The changes in this PR will be included in the next version bump. This PR includes changesets to release 3 packages
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 |
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
…s rather than package requires in the test files
@@ -21,6 +21,8 @@ | |||
"test:watch": "vitest" | |||
}, | |||
"dependencies": { | |||
"@ariakit/react": "^0.3.0", | |||
"@cambly/syntax-core": "workspace:^", | |||
"@cambly/syntax-design-tokens": "workspace:0.9.0", | |||
"@floating-ui/react": "^0.24.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.
@benjroy can we make sure to remove the @floating-ui/react
dependency now?
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.
@benjroy thanks for putting this PR together! I like the simplified API and improved accessibility features.
Ariakit vs other libraries
Curious why you picked Ariakit vs something like React Aria or Radix UI.
Number of weekly downloads:
https://npmtrends.com/@ariakit/react-vs-@radix-ui/react-tooltip-vs-@react-aria/tooltip
Maintenance
https://npmcompare.com/compare/@ariakit/react,@radix-ui/primitive,react-aria
Ariakit | React Aria | Radix UI | |
---|---|---|---|
Owned & maintained by | 1 person - Diego Daz | Adobe | WorkOS |
What is going to happen to Ariakit if Diego no longer works on it?
Other comparisons
- Side-by-side: https://npmcompare.com/compare/@ariakit/react,@radix-ui/primitive,react-aria
- Side-by-side: https://moiva.io/?npm=@ariakit/react+@radix-ui/primitive+react-aria
- Security: @radix-ui/primitive / react-aria / @ariakit/react (all 90+)
Todo's for this PR if we want to go ahead with Ariakit
- Add SSR test files for both Popover and Tooltip - to avoid issues like we had with Layer: Layer: fix document is not defined on SSR #255
- Address comments in this PR
- Figure out root cause as to why hovering / focussing doesn’t keep a Popover or Tooltip open in Storybook
tooltip-tooltip-does-not-stay-open-on-hover-storybook.mp4
Action items after this PR lands:
- Update all Popover / Tooltip components in Cambly-Frontend
@@ -0,0 +1,8 @@ | |||
--- | |||
"@cambly/syntax-floating-components": minor |
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.
@benjroy can we make this a major
release for syntax-floating-components
?
|
||
_Breaking_: @cambly/syntax-floating-components: Popover + Tooltip v2.0.0, built on AriaKit | ||
|
||
Patch: @cambly/syntax-core/Typography: `inline` renders as `"span"` by default |
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.
@benjroy could we move this out to a separate PR?
// so use globby to exclude stories from this workspace matched in node_modules | ||
// (this happens because syntax-floating components has a dependency on syntax-core + pnpm linking behavior for workspace management) | ||
// | ||
// see: https://github.com/storybookjs/storybook/issues/19446#issuecomment-1276067149 |
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.
@benjroy would a Storybook upgrade not fix this for us? Looks like they fixed it in Storybook itself:
storybookjs/storybook#19446 (comment)
storybookjs/storybook#22873
If so, I would rather upgrade Storybook than having this workaround.
@@ -6,7 +6,7 @@ | |||
"changeset": "changeset", | |||
"clean": "turbo run clean && rm -rf node_modules", | |||
"dev": "turbo run dev --no-cache --continue", | |||
"format": "prettier --write \"**/*.{ts,tsx,md}\"", | |||
"format": "prettier --write \"**/*.{ts,tsx,md,css}\"", |
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.
@benjroy thanks for adding this in!
@@ -113,7 +113,8 @@ const Typography = ({ | |||
*/ | |||
weight?: "regular" | "interactive" | "semiBold" | "bold" | "heavy"; | |||
}): ReactElement => { | |||
const Tag = as; | |||
const defaultTag = inline ? "span" : "div"; |
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.
@benjroy as mentioned above, please
- put this in a separate PR
- add tests around this change
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.
@benjroy also, I'm curious what happens if we set inline={false}
+ as="span"
- won't that render a span
which is still inline?
* Wires a handler to fire when visibility changes to an ariakit DisclosureStore store (tooltip, hovercard, popover, etc...) | ||
* Use for analytics and controlling open state externally | ||
*/ | ||
export default function useChangeContentVisibility( |
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.
@benjroy could you add some tests for these 2 utility methods we added?
|
||
type OnFocusHandler = FocusEventHandler<HTMLElement>; | ||
|
||
export default function useForwardFocus( |
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.
@benjroy could you also add docs for this default export?
anchorElement === anchorRef.current | ||
) | ||
return; | ||
// ariakit Tooltip uses html data attr to determine if mouse moves closes the tooltip or not |
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.
@benjroy this doesn't feel great... seems like we need to know about Ariakit internals to make this work. Let's definitely add tests around this.
TooltipContent, | ||
TooltipTrigger, | ||
}; | ||
export { Popover, Tooltip }; |
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.
@benjroy way cleaner, thank you
<Story /> | ||
</Box> | ||
), | ||
], |
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.
@benjroy let's make sure all the properties listed here are still available on the component - e.g. onOpenChange
/ strategy
@christianvuerings I haven't checked out radix yet, but from these results alone in a two way matchup b/w react-aria and ariakit, Bundle size is 33.4 kB -> 11.2 kB (gzip): Bundle size is 154 kB -> 49.7 kB (gzip) *edit: Bundle size is 184 kB -> 60.5 kB (gzip)
Another point in react-aria's favor: they have a date-picker. it's still pending in ariakit, and has been since it's reakit days.
Okay, more comparisons: from the DatePicker example in react-aria, here is bundle size for what look to be most of the react-aria exports needed to implement the example: Bundle size is 287 kB -> 87.8 kB (gzip) for just the datepicker hooks from that example: I think our team compared all three of these back at nerdwallet (~2020), and reakit won out at the time for a few reasons: bundle-size, level of opinionated-ness (we needed something we could make work with as few breaking changes as possible to legacy code), ssr support, and state of the projects themselves. At the time I was the one pushing for us to adopt and use I'm happy to take another pass at it now! Especially with those numbers from the tooltip bundle size. But also, that 87.8kb DatePicker bundle says that we need to consider multiple permutations to really get confidence in bundle-size numbers. Anyway, as long as we focus a lot of energy on the external props interface that we ship from syntax at this initial stage, I think we should be able to change out whatever library we build on top of in the future without having to ship a breaking change to our syntax packages in order to achieve that. |
Hi! I happened upon this PR during my weekly search. As this project is open source, I want to mention that if you end up using Ariakit, please feel free to mention me on PRs/issues for reviews or any questions you might have. A few notes:
|
@@ -21,6 +21,8 @@ | |||
"test:watch": "vitest" | |||
}, | |||
"dependencies": { | |||
"@ariakit/react": "^0.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.
@benjroy could we make sure that we use the latest version of @ariakit/react v0.3.3
Changes
This PR rewrites
Tooltip
andPopover
on top ofAriakit
. This will introduce a breaking change to this repositoryWhy?
We have bugs in our current Tooltip + Popover, as well as issues in mixing our components from this repo with similar components from material-ui. @christianvuerings showed me a new one just this morning
This PR is here to simplify the interfaces to these components + introduce something we can build on top of to save us a ton of development time.
The main breaking change is the shape of the components themselves.
Instead of three components that must be used together, e.g.
Tooltip / TooltipTrigger / TooltipContent
there is only one:In this PR, the thing I am most concerned about is the interfaces we ship to these components. We should make them as minimal and stable as possible. That will allow us to continue making improvements or adjusting behavior internally in these comopnents without having a large impact to the callsites where they exist in our app.
Take the Tooltip + Popover for a spin at the storybook build for this PR
About AriaKit
Ariakit is an open-source project with deep development history whose goal is to make it easy to develop fully accessible applications. It can hit two birds with one stone for us:
The difference to user experience is immense and also the abstractions will allow us to write more immediately usable components with smaller prop interfaces.
Browser accessibility quirks
AriaKit
has deep knowledge and handling of the quirks that exist in different environments. For example, here is some quirks handling for safari re: tabbing & focus behavior inSafari/VoiceOver
:If we choose not to rely on a library like this, we will absolutely run into a subset of all the edge cases that AriaKit is already handling. These quirks and issues will take us weeks of development time to research/understand/fix, and often through our research we will eventually find the fix in the ariakit repo itself.
SSR
Ariakit (and Reakit before it) were designed from the start with ServerSideRendering in mind. That's why in 2019 we chose to rely on it at my previous job. The repo is not stale, and is still very active and responsive to issues and community PRs.
Here's an example describing an SSR flow with NextJS, where a dialog is rendered on the the server and immediately interactable on the client
Bundle size comparisons:
We'll ship a few extra kilobytes compared to what we have right now, but the difference is small.
AriaKit builds on top of
floating-ui
, just like the current implementations here in@cambly/syntax-floating-components
Tooltip v1 bundle:
Bundle size is 185 kB -> 60.7 kB (gzip)
Popover v1 bundle:
Bundle size is 185 kB -> 60.7 kB (gzip)
Tooltip v1 + Popover v1 bundle:
Bundle size is 186 kB -> 60.7 kB (gzip)
Popover components from AriaKit:
Bundle size is 202 kB -> 66.9 kB (gzip)
Tooltip Components from Ariakit:
Bundle size is 207 kB -> 68.4 kB (gzip)
Tooltip + Popover components from aria kit:
Bundle size is 211 kB -> 69.5 kB (gzip)
The following is a little GPT output from phind.com on some quick selling points for the library:
Accessibility: Ariakit is built with accessibility in mind, following WAI-ARIA recommendations. This ensures your interfaces will be accessible to all users, including those with disabilities 231314.
Composability and Customizability: Ariakit components can be easily composed to create new components, and they are fully customizable. This allows you to integrate them into any design or styling framework 39.
Adaptive: Ariakit supports various input modes, making your UI components adaptable to different user needs and assistive technologies. It ensures consistent behavior across different UIs and has been tested across a variety of browsers, devices, and platforms 39.
React Hooks: Ariakit provides a set of React Hooks designed to help developers build accessible UI components. These hooks include features like focus management and accessible labels 3.
Convenience and Efficiency: Ariakit handles many common accessibility considerations, allowing developers to focus more on the design and functionality of their applications. This can save time and effort in the development process 310.
Open and Community Support: Ariakit is an open-project, benefiting from the contributions and support of a community of developers. This can lead to regular updates, improvements, and a wealth of resources and solutions for common issues 214.
Let's look at some code examples of using Ariakit:
Creating an Accessible Button
Creating an Accessible Dialog **
Creating an Accessible Menu