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

Ensure PopoverPanel can be used inside <transition> #1653

Merged
merged 4 commits into from
Jul 7, 2022

Conversation

RobinMalfait
Copy link
Collaborator

This is a bit sad, but it is how Vue works

We used to render just a simple PopoverPanel that resolved to let's say a <div>, that's all good. Because the native <transition> component requires that there is only 1 DOM child (regardless of the Vue "tree"). This is the sad part, because we simplified focus trapping for the Popover by introducing sibling hidden buttons to capture focus instead of managing this ourselves.

Since we can't just return multiple items we wrap them in a Fragment component.
If you wrap items in a Fragment, then a lot of Vue's magic goes away (automatically adding class to the root node). Luckily, Vue has a solution for that, which is inheritAttrs: false and then manually spreading the attrs onto the correct element.

This all works beautiful, but not for the <transition> component... so... let's move the focus trappable elements inside the actual Panel and update the logic slightly to go to the Next/Previous item instead of the First/Last because the First/Last will now be the actual focus guards.

Fixes: #1483
Fixes: #1629

This is a bit sad, but it is how Vue works...

We used to render just a simple PopoverPanel that resolved to let's say
a `<div>`, that's all good. Because the native `<transition>` component
requires that there is only 1 DOM child (regardless of the Vue "tree").
This is the sad part, because we simplified focus trapping for the
Popover by introducing sibling hidden buttons to capture focus instead
of managing this ourselves.

Since we can't just return multiple items we wrap them in a `Fragment`
component.
If you wrap items in a Fragment, then a lot of Vue's magic goes away
(automatically adding `class` to the root node). Luckily, Vue has a
solution for that, which is `inheritAttrs: false` and then manually
spreading the `attrs` onto the correct element.

This all works beautiful, but not for the `<transition>` component...
so... let's move the focus trappable elements inside the actual Panel
and update the logic slightly to go to the Next/Previous item instead of
the First/Last because the First/Last will now be the actual focus guards.
@vercel
Copy link

vercel bot commented Jul 7, 2022

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated
headlessui-react ✅ Ready (Inspect) Visit Preview Jul 7, 2022 at 4:31PM (UTC)
headlessui-vue ✅ Ready (Inspect) Visit Preview Jul 7, 2022 at 4:31PM (UTC)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant