-
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
Implement <Menu>
component
#7
Comments
Hey @GavinJoyce I'm trying to understand the context behind the |
I don't remember the details. I seem to recall it was needed to keep parity with the Vue version, something to do with needing to have the flexibility of using a yielded item property on the element itself, eg: <items.Item as |item|>
<item.Element data-test-is-selected={{item.isActive}}>
Item A
</item.Element>
</items.Item> |
Hmm. Ok. I’ll take a look at the vue version to try and understand the rationale. On the face of it it looked like an unnecessary extra layer but I’m sure there was a reason behind it. I’ll try and uncover it, for my own knowledge if nothing else. Thanks for the heads up man. |
👍 I'd be delighted to remove the |
Yeh, I think we can. I can't see anything in the Vue component (https://headlessui.dev/vue/menu) that references the concept and I can't make out in my mind why we'd need it (could totally be missing something). The only thing that seems close to this is this section which talks about rendering as We're going to be needing to use the |
Nice. It's possible that the Vue API changed since I last looked at it late last year. It's also possible that I made it more complex that it needed to be. Either way, 🍺 if you manage to remove the need for it |
Absolutely. I get the feeling you started this repo when the headlessui work was pretty much in its infancy. All good my man, I'll see what I can do when I shift my focus to that component 👍 |
I spent a while yesterday thinking about the "menu item" vs. "menu element" problem and whether there's a way to remove the need for the element component. Here's how I'm wrapping my head around it right now:
From looking at the implementation of the React components (and I'm assuming the Vue components are similar), they are able to look up the first child element of the "menu item" and automatically configure it with the attributes it needs, without needing a specific wrapper element. Ember doesn't give us any kind of API for a component to dynamically look at/configure it's children before they are rendered. What could be done is changing the "menu element" component into a "menu element" modifier, that the user of So, if an API like this might be better: <Menu as |menu|>
<menu.Items as |items|>
<items.Item as |item|>
<span {{item.setElement}} class={{if menu.isActive "bg-blue"}}>
I am the menu item!
</span>
</items.Item>
</menu.Items>
</Menu> and we're OK with imperatively setting attributes and event listeners, we could make that API change! Unfortunately I don't think there's any sort of compositional API for combining modifiers, so we'd need to essentially re-implement the |
BTW
This is done as of #57 |
Thanks for digging into this @alexlafroscia and for refreshing my memory on why I initially added two components for each item. If we can't find a way to collapse the definition of an item into a single component, I personally don't see much of a difference between these two APIs: two components: <Menu as |menu|>
<menu.Items as |items|>
<items.Item as |item|>
<item.Element @tagName="span" class={{if menu.isActive "bg-blue"}}>
I am the menu item!
</item.Element>
</items.Item>
</menu.Items>
</Menu> one component and one modifier: <Menu as |menu|>
<menu.Items as |items|>
<items.Item as |item|>
<span {{item.setElement}} class={{if menu.isActive "bg-blue"}}>
I am the menu item!
</span>
</items.Item>
</menu.Items>
</Menu>
If there's a downside to using a modifier, perhaps the existing API is preferable? |
I think you're right! One API clean-up thing that we could look into is doing something more like this: <Menu as |menu|>
<menu.Items>
<menu.Item as |item|>
<menu.ItemElement @tagName="span" class={{if menu.isActive "bg-blue"}}>
I am the menu item!
</menu.ItemElement>
</menu.Item>
</menu.Items>
</Menu> (Specific names certainly can be bike-shedded) There's a few nice things here:
|
This component should try to have as close to the same behaviour and API as the Vue and React original versions in https://github.com/tailwindlabs/headlessui.
TODO:
The text was updated successfully, but these errors were encountered: