Page MenuHomePhabricator

MenuButton: use Button instead of ToggleButton
Closed, ResolvedPublic3 Estimated Story Points

Description

Background

Currently, the MenuButton component only supports a quiet ToggleButton to display the menu. In some cases, this quiet MenuButton could not be visible enough, and we may want to use a normal button (or a progressive button).

Captura de pantalla 2024-06-28 a las 12.36.50.png (842×2 px, 122 KB)

To enable this, MenuButton should use a regular Button instead of a ToggleButton. This will allow us to support the full range of weights (normal, quiet, primary) and actions (progressive, destructive). The behavior when the menu is expanded wouldn't quite match the mockup above, because we wouldn't be showing the toggled-on state of the ToggleButton, but that's fine: we don't need a visual indication on the button that it's toggled on, since you already know that from the menu being expanded.

Ideally this change should also fix T379075: MenuButton: selecting an item with Enter doesn't close the menu and T399905: MenuButton: Pressing Enter when a menu item is highlighted should select that item as a side effect.

Acceptance criteria

Design

  • Update the component in the Figma library

Code

  • Change MenuButton to use a Button instead of a ToggleButton
    • But preserve the current behavior where clicking the button opens the menu if it's closed, or closes it if it's open, and clicking away closes the menu
  • Add action and weight props that are passed through to Button
    • But make the default weight quiet, to preserve compatibility with the current behavior

Event Timeline

DTorsani-WMF moved this task from Backlog to Upcoming on the Codex board.

We should also explore basing MenuButton on Button instead of ToggleButton, which would make it easier to provide the full suite of actions and weights (primary, progressive, destructive). That might also help with some other MenuButton bugs: T399905: MenuButton: Pressing Enter when a menu item is highlighted should select that item, T379075: MenuButton: selecting an item with Enter doesn't close the menu

Catrope raised the priority of this task from Low to Medium.Aug 25 2025, 9:38 PM
Catrope updated the task description. (Show Details)
Catrope added a project: Reader Growth Team.
Catrope moved this task from Incoming/Inbox to Needs Refinement on the Reader Growth Team board.

RG can't look at this one until the designs are complete.

Hey @DTorsani-WMF feel free to tag Reader Growth again when designs are ready, and we'll estimate and pick up when we can.

@HSwan-WMF @egardner what designs do you think you need for this? The idea is that a MenuButton would use a Button component instead of a ToggleButton, and so it would have all the same design styles and options for variants that a Button has. The Button itself would no longer have a "menu opened" state, which I don't think is necessary.

DTorsani-WMF renamed this task from MenuButton: explore available options for other button flavors to MenuButton: use Button instead of ToggleButton.Sep 29 2025, 6:13 PM

As @DTorsani-WMF said I think this is mostly an engineering task that shouldn't really need explicit designs. The MenuButton should accept action and weight props, and it should look the same as the Button component does when given those props. Does that make sense?

@egardner I think that answers our questions and we should have what we need at this point. I'll pull this one to our next refinement session.

HSwan-WMF set the point value for this task to 3.Oct 8 2025, 4:36 PM

Change #1217314 had a related patch set uploaded (by LWatson; author: LWatson):

[design/codex@main] MenuButton: replace internal toggle button with button

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

This patch is ready for code review and addresses bugs about selection and toggling the menu with keyboard navigation (T379075 and T399905)

Preview unmerged changes: https://1217314--wikimedia-codex.netlify.app/components/demos/menu-button.html

Change #1217314 merged by jenkins-bot:

[design/codex@main] MenuButton: replace internal toggle button with button

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

My mistake! I should have put this in design review for @DTorsani-WMF. The code was merged. When you return from the end-of-year break, please let me know any feedback on this. Do you plan on completing the design requirement?

Update the component in the Figma library

There was a post-merge build failure (details). I reached out to #developer-experience and Tyler C. re-ran the checks in the Jenkins UI, and it was successful 🎉

QA Test Plan

The MenuButton component was refactored to use an internal Button component instead of ToggleButton. The test plan should verify the component's visual appearance, prop configurations, and interaction behaviors.

Test Environment:

Setup Steps

  1. Navigate to the Codex MenuButton documentation page
  2. Open browser DevTools
  3. Locate the configurable demo at the top of the page
  4. Use the configuration controls to test different prop combinations

Test

  1. Component Structure
    • Verify the Button component is used. Inspect the MenuButton. Expect: The Button element has cdx-button class.
  2. Default behavior (no props set)
    • Default weight and action. Load page without changing any props in demo. Expect: Button has classes: cdx-button--weight-quiet and cdx-button--action-default.
    • Default framed state. Load page without changing any props in demo. Expect: Button does not have cdx-button--framed class.
  3. Action prop
    • Progressive action. Set action prop to "progressive" in demo. Expect: Button has cdx-button--action-progressive class.
    • Destructive action. Set action prop to "destructive" in demo. Expect: Button has cdx-button--action-destructive class.
    • Default action. Set action prop to "default" in demo. Expect: Button has cdx-button--action-default class.
  4. Weight prop
    • Quiet weight. Set weight prop to "quiet" in demo. Expect: Button has cdx-button--weight-quiet class. Button does not have cdx-button--framed class.
    • Normal weight. Set weight prop to "normal" in demo. Expect: Button has cdx-button--weight-normal and cdx-button--framed classes.
    • Primary weight. Set weight prop to "primary" in demo. Expect: Button has cdx-button--weight-primary and cdx-button--framed classes.
  5. Combined prop variations
    • Normal + progressive. Set weight to normal and action to progressive. Expect: Button has cdx-button--weight-normal, cdx-button--action-progressive, cdx-button--framed classes.
    • [other combinations]
  6. Mouse/Click Interactions
    • Click opens menu. Click the MenuButton when the menu is closed. Expect: Menu opens and displays menu items.
    • Click closes menu. Click the MenuButton when the menu is open. Expect: Menu closes.
    • Click outside closes menu. Click MenuButton to open the menu, and then click outside the menu area. Expect: menu closes.
    • Click menu item closes menu. Click MenuButton to open the menu, and then click on a menu item. Expect: Menu closes after selection.
  7. Keyboard Navigation
    • Enter key opens menu. Tab to focus MenuButton, and then press Enter. Expect: Menu opens.
    • Enter key closes menu. Open menu with Enter key, and then press Enter again (focus still on the button). Expect: Menu closes.
    • Enter selects menu item. Open the menu, and use the arrow keys to highlight a menu item, and then press Enter. Expect: Menu item is selected and menu closes.
    • Space key opens menu. Tab to focus MenuButton, and then press Space. Expect: Menu opens.
    • Escape key closes menu. Open the menu, and then press Escape. Expect: Menu closes and focus returns to the button.
    • Arrow down key navigation. Open the menu with Enter/Space, and then press Down Arrow multiple times. Expect: Focus moves down through menu items.
    • Arrow up key navigation. Open the menu with Enter/Space, and then press Up Arrow multiple times. Expect: Focus moves up through menu items.

Notes

mfossati subscribed.

Thanks for the exhaustive QA steps @lwatson !

  1. Component Structure
    • Verify the Button component is used. Inspect the MenuButton. Expect: The Button element has cdx-button class.

  1. Default behavior (no props set)
    • Default weight and action. Load page without changing any props in demo. Expect: Button has classes: cdx-button--weight-quiet and cdx-button--action-default.

  • Default framed state. Load page without changing any props in demo. Expect: Button does not have cdx-button--framed class.

  1. Action prop
    • Progressive action. Set action prop to "progressive" in demo. Expect: Button has cdx-button--action-progressive class.

  • Destructive action. Set action prop to "destructive" in demo. Expect: Button has cdx-button--action-destructive class.

  • Default action. Set action prop to "default" in demo. Expect: Button has cdx-button--action-default class.

  1. Weight prop
    • Quiet weight. Set weight prop to "quiet" in demo. Expect: Button has cdx-button--weight-quiet class. Button does not have cdx-button--framed class.

  • Normal weight. Set weight prop to "normal" in demo. Expect: Button has cdx-button--weight-normal and cdx-button--framed classes.

  • Primary weight. Set weight prop to "primary" in demo. Expect: Button has cdx-button--weight-primary and cdx-button--framed classes.

  1. Combined prop variations
    • Normal + progressive. Set weight to normal and action to progressive. Expect: Button has cdx-button--weight-normal, cdx-button--action-progressive, cdx-button--framed classes.

  • [other combinations]

  1. Mouse/Click Interactions
    • Click opens menu. Click the MenuButton when the menu is closed. Expect: Menu opens and displays menu items.

  • Click closes menu. Click the MenuButton when the menu is open. Expect: Menu closes.

  • Click outside closes menu. Click MenuButton to open the menu, and then click outside the menu area. Expect: menu closes.

  • Click menu item closes menu. Click MenuButton to open the menu, and then click on a menu item. Expect: Menu closes after selection.

  1. Keyboard Navigation
    • Enter key opens menu. Tab to focus MenuButton, and then press Enter. Expect: Menu opens.

  • Enter key closes menu. Open menu with Enter key, and then press Enter again (focus still on the button). Expect: Menu closes.

  • Enter selects menu item. Open the menu, and use the arrow keys to highlight a menu item, and then press Enter. Expect: Menu item is selected and menu closes.

  • Space key opens menu. Tab to focus MenuButton, and then press Space. Expect: Menu opens.

  • Escape key closes menu. Open the menu, and then press Escape. Expect: Menu closes and focus returns to the button.

  • Arrow down key navigation. Open the menu with Enter/Space, and then press Down Arrow multiple times. Expect: Focus moves down through menu items.

  • Arrow up key navigation. Open the menu with Enter/Space, and then press Up Arrow multiple times. Expect: Focus moves up through menu items.

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

[mediawiki/core@master] Update Codex from v2.3.3 to v2.3.4

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

Re-adding the Reader Growth tag for sprint tracking purposes. Reader Growth and Reader Experience teams are currently handling these Codex tasks as part of our active sprint.

Change #1235058 merged by jenkins-bot:

[mediawiki/core@master] Update Codex from v2.3.3 to v2.3.4

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