-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Ensure the main tree and parent Dialog
components are marked as inert
#2290
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
We want to apply `inert` when we _don't_ have nested dialogs, because if we _do_ have nested dialogs, then the inert should be applied from the nested dialog (or visually the top most dialog).
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
RobinMalfait
changed the title
Ensure other elements are marked with
Ensure the main tree and parent Feb 17, 2023
inert
when the Dialog
is openDialog
components are marked with inert
RobinMalfait
changed the title
Ensure the main tree and parent
Ensure the main tree and parent Feb 17, 2023
Dialog
components are marked with inert
Dialog
components are marked as inert
As well as the parent dialogs in case of nested dialogs.
RobinMalfait
force-pushed
the
fix/issue-2289
branch
from
February 17, 2023 15:45
f8d18f4
to
54ce6e4
Compare
RobinMalfait
added a commit
that referenced
this pull request
Apr 24, 2024
We used to have a `useInertOthers` hook, but it also made everything inside `document.body` inert. This means that third party packages or browser extensions that inject something in the `document.body` were also marked as `inert`. This is something we don't want. We fixed that previously by introducing a simpler `useInert` where we explicitly marked certain elements as inert: #2290 But I believe this new implementation is better, especially with this commit where we stop once we hit `document.body`. This means that we will never mark `body > *` elements as `inert`.
RobinMalfait
added a commit
that referenced
this pull request
Apr 24, 2024
…onents (#3124) * move duplicated `useScrollLock` to dedicated hook * accept `enabled` prop on `Portal` component This way we can always use `<Portal>`, but enable / disable it conditionally. * use `useSyncRefs` in portal This allows us to _not_ provide the ref is no ref was passed in. * refactor inner workings of `useInert` moved logic from the `useEffect`, to module scope. We will re-use this logic in a future commit. * add `useInertOthers` hook Mark all elements on the page as inert, except for the ones that are allowed. We move up the tree from the allowed elements, and mark all their siblings as `inert`. If any of the children happens to be a parent of one of the elements, then that child will not be marked as `inert`. ``` <body> <!-- Stop at body --> <header></header> <!-- Inert, sibling of parent of allowed element --> <main> <!-- Not inert, parent of allowed element --> <div>Sidebar</div> <!-- Inert, sibling of parent of allowed element --> <div> <!-- Not inert, parent of allowed element --> <Listbox> <!-- Not inert, parent of allowed element --> <ListboxButton></ListboxButton> <!-- Not inert, allowed element --> <ListboxOptions></ListboxOptions> <!-- Not inert, allowed element --> </Listbox> </div> </main> <footer></footer> <!-- Inert, sibling of parent of allowed element --> </body> ``` * add `portal` prop, and change meaning of `modal` prop on `MenuItems` - This adds a `portal` prop that renders the `MenuItems` in a portal. Defaults to `false`. - If you pass an `anchor` prop, the `portal` prop will always be set to `true`. - The `modal` prop enables the following behavior: - Scroll locking is enabled when the `modal` prop is passed and the `Menu` is open. - Other elements but the `Menu` are marked as `inert`. * add `portal` prop, and change meaning of `modal` prop on `ListboxOptions` - This adds a `portal` prop that renders the `ListboxOptions` in a portal. Defaults to `false`. - If you pass an `anchor` prop, the `portal` prop will always be set to `true`. - The `modal` prop enables the following behavior: - Scroll locking is enabled when the `modal` prop is passed and the `Listbox` is open. - Other elements but the `Listbox` are marked as `inert`. * add `portal` and `modal` prop on `ComboboxOptions` - This adds a `portal` prop that renders the `ComboboxOptions` in a portal. Defaults to `false`. - If you pass an `anchor` prop, the `portal` prop will always be set to `true`. - The `modal` prop enables the following behavior: - Scroll locking is enabled when the `modal` prop is passed and the `Combobox` is open. - Other elements but the `Combobox` are marked as `inert`. * add `portal` prop, and change meaning of `modal` prop on `PopoverPanel` - This adds a `portal` prop that renders the `PopoverPanel` in a portal. Defaults to `false`. - If you pass an `anchor` prop, the `portal` prop will always be set to `true`. - The `modal` prop enables the following behavior: - Scroll locking is enabled when the `modal` prop is passed and the `Panel` is open. * simplify popover playground, use provided `anchor` prop * remove internal `Modal` component This is now implemented on a per component basis with some hooks. * remove `Modal` handling from `Dialog` The `Modal` component is removed, so there is no need to handle this in the `Dialog`. It's also safe to remove because the components with "portals" that are rendered inside the `Dialog` are portalled into the `Dialog` and not as a sibling of the `Dialog`. * ensure we use `groupTarget` if it is already available Before this, we were waiting for a "next render" to mount the portal if it was used inside a specific group. This happens when using `<Portal/>` inside of a `<Dialog/>`. * update changelog * add tests for `useInertOthers` * ensure we stop before the `body` We used to have a `useInertOthers` hook, but it also made everything inside `document.body` inert. This means that third party packages or browser extensions that inject something in the `document.body` were also marked as `inert`. This is something we don't want. We fixed that previously by introducing a simpler `useInert` where we explicitly marked certain elements as inert: #2290 But I believe this new implementation is better, especially with this commit where we stop once we hit `document.body`. This means that we will never mark `body > *` elements as `inert`. * add `allowed` and `disallowed` to `useInertOthers` This way we have a list of allowed and disallowed containers. The `disallowed` elements will be marked as inert as-is. The allowed elements will not be marked as `inert`, but it will mark its children as inert. Then goes op the parent tree and repeats the process. * simplify `useInertOthers` in `Dialog` code * update `use-inert` tests to always use `useInertOthers` * remove `useInert` hook in favor of `useInertOthers` * rename `use-inert` to `use-inert-others` * cleanup default values for `useInertOthers`
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR fixes a bug where the logic for enabling the
useInertOthers
hook was incorrect. We replaced theuseInertOthers
with a simpleruseInert
hook. This is required because before we marked all other elements but theDialog
as inert. This is not correct because there will be elements that we don't have control over.For example: 3rd party tools that inject a portal in the root. We will mark these elements as "valid" containers. Therefore all the direct children of the
body
are valid elements.To solve this issue, we will make sure that we mark the main tree as
inert
. This is valid to do because theDialog
will be rendered in aPortal
as a sibling of the main tree.We also have to solve a similar issue for nested dialogs. We will mark all the parent dialogs as
inert
while keeping the top most dialog as non-inert.Fixes: #2289