-
Notifications
You must be signed in to change notification settings - Fork 538
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
SelectPanel2: Only render children when open #4348
Conversation
🦋 Changeset detectedLatest commit: 828df34 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 📦
|
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 should avoid doing this because it can cause issues for AT users. If we need to set up a button that points to a dialog, it cannot if the dialog is not on the page. For example, your examples are missing aria-details
which sets up said relationship:
<button type="button" aria-haspopup="true" aria-expanded="true" aria-details="my-dialog"></button>
<dialog id="my-dialog" open></dialog>
To address some of your points:
Data fetching: Data that is meant to be fetched only when the Dialog is open might be fetched early
Code should avoid doing this, but we could render the dialog and skip the children rendering, if we deem it necessary. The problem, however, is that complex dialogs will experience slow INP if we end up rendering a lot of DOM as the dialog is rendered.
Testing: When there are multiple dialogs on the page, unless you are more specific, getting element by role dialog returns the first dialog, not the open dialog. screen.getByRole('dialog')
This seems true for all elements, no? I would not expect div
to return anything but the first div
, why would dialog
be any different?
Imperative code: When there are multiple dialogs on the page, querySelector for dialog would return the first dialog, not necessarily the open dialog.
Is there an instance where there is a negative effect here? Same applies, as above I believe.
If there are concrete examples of where this is causing failure points we should investigate those.
I think for this PR to land I'd expect to see the <dialog>
always be rendered, and other mitigations put in place to directly address the concrete failure modes.
Interesting! This did not come up in the a11y spec, let me confirm with them once more.
I think that's a fair solution, let me try that and see if it has any unintended side effects.
There are concrete examples of this in dotcom 😢 I've lost multiple days at this point debugging jest tests in dotcom because of these. Folks I talked to were genuinely surprised by behavior. Honestly, it comes back to this:
|
Updated! Rendering the dialog but not its contents now. It solves the main user-land problem (side effects & data fetching), but not the one with selectors in testing which I think is okay for 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.
Great, thanks for updating this!
* only render Overlay when open * Create fair-cooks-return.md * Update fair-cooks-return.md * render dialog but not contents when closed * Update fair-cooks-return.md
By default a
<dialog>
renders asopen="false"
, but it does exist in the dom. This can be unintuitive in the react paradigm where you expect dialog to not be rendered in the dom until it's visible.Places where this shows up:
screen.getByRole('dialog')
Before:
After:
<!-- closed state: --> <button type="button" aria-haspopup="true" aria-expanded="false"></button> - <dialog></dialog>