You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Task Description
The current Menu (and ContextMenu) component is flawed in several ways, and needs to be reworked as a more general PopupMenu component.
The new PopupMenu component should expose PopupMenu.Toggle, PopupMenu.Menu, PopupMenu.Item and PopupMenu.Section subcomponents.
The new PopupMenu component should accept a toggle and a menu as props. It should be possible to pass these as slotted props, or as children:
Both toggle and menu should be optional, resulting in the component rendering always.
When no toggle is passed, PopupMenu should render an "overflow" / "kebap" icon as a toggle, allowing it to effectively replace the curren tContextMenu component
When no menu is passed, the toggle should still render and all necessary events should fire anyways.
When passing children to the PopupMenu, the bevaviour should be as follows:
When subcomponents are being used, we render according to type / element, regardless of sequence (edge case: more than one PopupMenu and/or PopupMenu.Menu each: render the first one met, ignore the rest)
When non-subcomponent / custom component children are used, sequence matters: the first child will be rendered as toggle, the second as menu. Any more / others will be ignored.
When toggle and/or menu are being passed as both props and children, props win.
Clicking outside an open menu should close the menu
Sub-tasks
Create a new component in TS as a generic PopupMenu
Design a component architecture that wraps Headless Menu
Use sub components
Use the new PortalProvider to render the Menu into
Figure out and implement working, reliable positioning of the menu in the Portal
Make component render as an overflow menu per default, effectively replacing ContextMenu
Allow passing any Juno icon instead of default three vertical dots icon
Allow passing a custom component as a toggle as a prop into a slot
Make sure all onClick handlers on custom component toggle still run
Allow passing a PopupMenu.Menu element as a slot, containing the PopupMenu.Item elements
Allow passing the toggle as a child, too.
Allow passing the menu as a child, too, so effectively emulate the architecture/API of headless UI dropdown menu
Deprecate current Menu and ContextMenu components (as an option, we could ffw ContextMenu to PopupMenu internally, and display a deprecation warning, in effect not using the old component at all even in the deprecation phase)
Implement closing on click outside, make potentially configurable via a prop (closeOnClickOutside?: true)
Related Issues DONE: Will require migration of Menu and related MenuItem, MenuSection components to TypeScript #237
The text was updated successfully, but these errors were encountered:
The intended flexibility in terms of API and usage as outlined above leads to a large amount of complexity in the component, especially accepting any kind of component as a toggle and potentially menu, as well as allowing to pass them as children or as slotted props. Also, there will be edge cases, some of which may prove impossible to handle nicely.
(This does not yet cover rendering children properly, and already is a very large, complex component)
I am currently considering cutting some requirements and building a thin wrapper around headless ui menu first, accepting only subcomponents as children.
Having a simpler solution in place would allow us to see how well this works for our users and address shortcomings and requirements for additional functionality and features later.
@edda when you have some time after you're back from holidays would love to discuss and hear what you think.
This does not have any styling yet, but is helpful in understanding why this component is difficult to build:
When just wrapping headless ui menu, there is no way of passing an open prop, as headless ui menu manages its state internally and does not expose such a functionality. If we want to allow for passing an open prop, and there is a strong argument to do that for the sake of consistency in our system, we would need to override headless ui's internal state with our own, and render the menu as static. Th edownside of this approach is we would loose a lotof headless-ui menu's inbuilt functionality, e.g. clsoing the menu on clicking outside or clicking an item would need re-implementing in our component.
Task Description
The current Menu (and ContextMenu) component is flawed in several ways, and needs to be reworked as a more general
PopupMenu
component.The new
PopupMenu
component should exposePopupMenu.Toggle
,PopupMenu.Menu
,PopupMenu.Item
andPopupMenu.Section
subcomponents.The new
PopupMenu
component should accept atoggle
and amenu
as props. It should be possible to pass these as slotted props, or as children:Users can use subcomponents as exposed by
PopupMenu
(recommended), or their own custom components astoggle
andmenu
respectively.Additional Requirements
toggle
andmenu
should be optional, resulting in the component rendering always.toggle
is passed,PopupMenu
should render an "overflow" / "kebap" icon as a toggle, allowing it to effectively replace the curren tContextMenu
componentmenu
is passed, the toggle should still render and all necessary events should fire anyways.PopupMenu
, the bevaviour should be as follows:PopupMenu
and/orPopupMenu.Menu
each: render the first one met, ignore the rest)toggle
and/ormenu
are being passed as both props and children, props win.Sub-tasks
PopupMenu
PopupMenu.Menu
element as a slot, containing thePopupMenu.Item
elementsRelated Issues
DONE: Will require migration of
Menu
and relatedMenuItem
,MenuSection
components to TypeScript #237The text was updated successfully, but these errors were encountered: