Page MenuHomePhabricator

MenuItem: include a demo to illustrate a menu's header with actions
Closed, ResolvedPublic2 Estimated Story Points

Description

Background

We need to demo a MenuItem which works as a header with actions in Menu. This can be done by customizing a MenuItem as a header.

One real use case is the Recent Changes filters T382952, where some buttons need to be included in the MultiselectLookup menu:

Captura de pantalla 2025-01-16 a las 17.35.16.png (491×1 px, 139 KB)

User stories

  • As a designer or developer, I need to be able to include a header with some actions within a Menu.

Design spec

image.png (764×1 px, 80 KB)

Open questions

Add here the questions to be answered in order to design and implement the component

Acceptance criteria (or Done)

Design

  • Design the Figma spec sheet and add it in this task
  • Update the Menu component in the Figma library. This step will be done by a DST member.

Code

  • Include a sandbox demo to illustrate a menu with header and actions

Event Timeline

I wonder if we can use the MenuItem component's default slot to create the header instead of modifying the Menu and MultiselectLookup components. You could add a special menu item to the top of the list that represents the header, and then in the template use the slot to create the header UI just for that first menu item. This is what we do in TypeaheadSearch to set up the footer item that will send you straight to the search page - we tack on a menu item for the footer (technically, we use the Menu component's footer prop), and then in the template look for that value and set up the search footer UI.

I wonder if we can use the MenuItem component's default slot to create the header instead of modifying the Menu and MultiselectLookup components. You could add a special menu item to the top of the list that represents the header, and then in the template use the slot to create the header UI just for that first menu item. This is what we do in TypeaheadSearch to set up the footer item that will send you straight to the search page - we tack on a menu item for the footer (technically, we use the Menu component's footer prop), and then in the template look for that value and set up the search footer UI.

If the list was long and needed to be scrollable (which I think it would need to be for the RCFilters UI), could the special header menu item be sticky? I see in the scrolling menu demos that we can support a sticky footer, so maybe these actions could be moved to the footer instead?

bmartinezcalvo renamed this task from Menu: support a header with actions to MenuItem: support actions.Jan 20 2025, 10:52 AM
bmartinezcalvo updated the task description. (Show Details)
bmartinezcalvo renamed this task from MenuItem: support actions to MenuItem: create as header with actions.Jan 20 2025, 7:08 PM
bmartinezcalvo added a project: Design.
bmartinezcalvo renamed this task from MenuItem: create as header with actions to MenuItem: support header with actions.Jan 21 2025, 10:36 AM

If the list was long and needed to be scrollable (which I think it would need to be for the RCFilters UI), could the special header menu item be sticky? I see in the scrolling menu demos that we can support a sticky footer, so maybe these actions could be moved to the footer instead?

This can probably be done with CSS on the feature end if it's needed for the first menu item

CCiufo-WMF moved this task from Backlog to Needs Refinement on the Design-System-Team board.

Change #1116830 had a related patch set uploaded (by Anne Tomasevich; author: Anne Tomasevich):

[design/codex@main] demo: Add MultiselectLookup with sticky menu header

https://gerrit.wikimedia.org/r/1116830

I was able to achieve this pretty easily using the menu-item slot of the MultiselectLookup component. See the new "MultiselectLookup with sticky menu header" demo I added to the sandbox. Try entering "a" in the input to test out the sticky behavior.

In the code, I did the following:

  • Add a special menu item to the beginning of the array of menu items that gets passed into MultiselectLookup. This special menu item has only a value, which we'll use in the template.
  • In the template, use the menu-item slot with v-if to set up the UI for the menu header only if the current menu item's value matches that special menu item.
  • Use @click.stop to prevent the header item from being selected.
  • Add some styles to make the header item sticky and make the menu item itself appear non-interactive (since only the buttons are interactive).

Is this sufficient for the RCFilters use case? If so, the new demo could be used as an example.

@AnneT thank you for working on this. Just a couple of things to align with the design:

  1. As in the footer, this header should include a border-color-subtle at the bottom to visually separate it from the menu items.
  2. Header's title: I suggested using the bold text. As in menu items, the header could optionally include a start icon and a description.
  3. I suggested RCfilters using a ToggleButtonGroup to switch between Filters, Namespaces, and Tagged Edits, with Filters opening by default. This would avoid unusual Menu uses like that back button.
  4. We will use spacing-25 (4px) to separate the buttons. While buttons can be customized, I recommend using the quiet normal ToggleButton to prevent the menus from becoming too visually crowded. It would be great if this demo reflects that decision.

image.png (872×1 px, 103 KB)

It's hacky but it looks like it should work for now. I think we should consider making menu headers a real feature in the future so that RCF doesn't have to do these kinds of hacks, but that doesn't have to be a blocker for RCF anymore.

The attached patch looks good to me. @bmartinezcalvo could you review the new demo here?

In the demo you linked, the text inputted into the MultiselectLookup doesn't get cleared when a menu item is selected. Is that intentional? It's different to how the demo directly above behaves. For the purposes of helping the RCFilters use case, it might be good to also have initial menu items set so that the menu opens by default when the input is focused.

El T383907#10521833, @Catrope escribió:

The attached patch looks good to me. @bmartinezcalvo could you review the new demo here?

Just resharing my comments from that demo:

@AnneT thank you for working on this. Just a couple of things to align with the design:

  1. As in the footer, this header should include a border-color-subtle at the bottom to visually separate it from the menu items.
  2. Header's title: I suggested using the bold text. As in menu items, the header could optionally include a start icon and a description.
  3. I suggested RCfilters using a ToggleButtonGroup to switch between Filters, Namespaces, and Tagged Edits, with Filters opening by default. This would avoid unusual Menu uses like that back button.
  4. We will use spacing-25 (4px) to separate the buttons. While buttons can be customized, I recommend using the quiet normal ToggleButton to prevent the menus from becoming too visually crowded. It would be great if this demo reflects that decision.

image.png (872×1 px, 103 KB)

Whoops sorry, I missed the previous exchange between you and Anne about the demo, ignore me.

@bmartinezcalvo I've made the updates you requested! It's not exactly like the RCFilters menu, but I hope it meets the goal of demonstrating how you can customize the first menu item to add a header, and how you can even update that header dynamically based on the toggle button group.

@CCiufo-WMF thanks for pointing that out; it was just a bug in the demo code, which I've fixed!

I've updated the demo again to add some more of @bmartinezcalvo's feedback. One thing we can't do is keep the menu open when you change the active toggle button in the ToggleButtonGroup above the MultiselectLookup. MultiselectLookup itself keeps track of when to open or close the menu; the parent component has no control over this. The RCFilters project may need to contain its own version of the MultiselectLookup. This could be done by coping the MultiselectLookup code as a starting point, then changing it to suite the RCFilters UI.

@AnneT thank you! This demo including a menu with header looks good to me.

As in T383909, the action within the header is not navigable using the keyboard, but I guess this will be addressed in this future task T385804.

bmartinezcalvo renamed this task from MenuItem: support header with actions to MenuItem: include a demo to illustrate a menu's header with actions.Feb 6 2025, 4:31 PM
bmartinezcalvo updated the task description. (Show Details)

Change #1116830 merged by jenkins-bot:

[design/codex@main] demo: Add new sandbox page for experiments + RCFilters demo

https://gerrit.wikimedia.org/r/1116830

Change #1121109 had a related patch set uploaded (by VolkerE; author: VolkerE):

[mediawiki/core@master] Update Codex from v1.20.1 to v1.20.2

https://gerrit.wikimedia.org/r/1121109

Change #1121109 merged by jenkins-bot:

[mediawiki/core@master] Update Codex from v1.20.1 to v1.20.2

https://gerrit.wikimedia.org/r/1121109