-
Notifications
You must be signed in to change notification settings - Fork 34
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
Menu
Component Improvements
#58
Menu
Component Improvements
#58
Conversation
d40eab1
to
72244d6
Compare
Something isn't quite right with the way the focus trap is being used -- I'll mark this is ready once I fix that up! |
0049925
to
1008117
Compare
Menu
Component Improvemenets
Menu
Component ImprovemenetsMenu
Component Improvements
This change brings the Ember implementation closer inline with the React/Vue implementations, which do not create a DOM node for this component automatically. This makes working with the component easier, as it no longer introduces un-necessary DOM nodes. Note: the React and Vue implementations allow for optionally creating a DOM node for the `Menu` component. This is possible in Ember, technically, but probably more trouble than it's worth, since the user of `Menu` can just wrap the component in an additional DOM node themselves if that's what they want. I believe the React and Vue implementations include this functionality for consistency, so that _all_ Headless UI components can optionally render an alternate DOM node, but those frameworks have an easier ability to pull this off than Ember does. A focus trap has been introduced to power the click-outside-to-dismiss functionality, which also resolves the issue of focus needing to be locked in the `Menu::Items` component when rendered, which was previously not the case. BREAKING CHANGE: If you were previously depending on `Menu` rendering a DOM node, you'll want to wrap your usage of `Menu` with a `div` and move any attributes or modifiers to that element instead.
1008117
to
e46741d
Compare
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.
I think the existing API is a little nicer to work with, but 👍 on the change if it brings us closer to the React/Vue APIs
Just to clarify, you'd prefer that I'm thinking about a case where someone builds out a component that wraps {{! app/components/my-menu.hbs }}
<Menu as |menu|>
<menu.Trigger
{{did-insert (set this 'menuTrigger')}}
...attributes
/>
<menu.Items
{{popper-tooltip this.menuTrigger}}
/>
</Menu> If |
I'd love to get a review from @achambers as well before merging, just to make sure everyone's on the same page with the changes here since it's a breaking change! Edit: Upon thinking about it more, I'd love verification that this indeed closes the two tickets that I linked to as well. I'm pretty sure it does but would love to make sure! |
👍 I'm convinced by your example, thanks |
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.
Love your work @alexlafroscia. I'm in support of this improvement. Thanks.
Thanks @achambers ! |
Menu
Avoids Rendering a DOM NodeThe
Menu
component in the React/Vue implementations does not render a DOM node by default. It can, because I believe they want to make sure that all components can use anas=
property to configure the node that's rendered, but by default it just renders aFragment
(which results in nothing in the DOM).Since Ember doesn't really have a concept of a
Fragment
, I think that not rendering a DOM node at all is closer to the React/Vue implementation than rendering adiv
.Note: This is a breaking change, as any attributes or modifiers placed on this element should be moved to a new parent
div
elementBefore
After
Menu::Items
Focusing on RenderFrom the Headless UI documentation on the Menu:
Using the focus trap here is a little unintuitive, because the menu item elements themselves are not focusable. However, this is a useful approach because
focus-trap
modifier will do for usThe documentation for the
focus-trap
library describes how you should handle a case where the element that focus is trapped within has no focusable children, which is to focus the "wrapper" element itself usinginitialFocus
, which is the approach taken here!Using the
focus-trap
library to return focus to the trigger button should resolve the weirdness around focus returning to the wrong element sometimes.focus-trap
will also handle the "press-escape
-to-dismiss-the-menu" behavior for us without needing additional logic for that.Closes #55
Closes #54