← All proposals

Menu Button

Starting point for a MenuButton proposal.

Extends a PDS componentOpen in Storybook

proposals/MenuButton/decisions.md17 lines · View on GitHub

Decisions

  • Base is the unmodified v2 MenuButton (MenuButton.tsx, menu-button.css, sample data, stories). Proposal changes go on top.
  • Trigger uses the local Button and IconButton (../Button, ../IconButton), not the package's, so the agentic work in those proposals reaches the menu trigger. Nothing is passed through yet.
  • Taken from the published package: useDropdown, useIsMobile, Icon, Tally, and the menu item types and guards. @floating-ui/react comes along as a dependency of the package (hoisted in node_modules); it isn't in this repo's package.json. The port has it already.
  • Copied locally because the package doesn't export them: NavAccordion.tsx + nav-accordion.css (mobile accordion), and mergeClasses / extractText / StatusDotType / ButtonVariant via ../Button/utils.
  • useOverlayZIndex is not copied. v2 raises the panel's z-index when the menu sits inside a Modal or Drawer; here it's always --pds-z-index-dropdown. The port restores useOverlayZIndex.
  • Strict-null fixes only, behavior unchanged: group aria-label uses undefined instead of null, and the sample callback takes an optional item. v2 isn't strict, this repo is.
  • The package's own MenuButton CSS also loads, so the local menu-button.css overrides it by class name (as with Button).
  • Storybook: Proposals/Buttons/Menu Button.
  • isAgentic boolean on MenuButton, passed to the trigger: Button in label mode, IconButton in iconOnly mode (where it also sets hasBorder, since the icon button only shows the gradient on a border). Same model as Button and Icon Button. Supported on primary and secondary only; other variants (subtle, navbar, reverse-secondary) get Button's dev warning. The dropdown panel is unchanged.
  • Icon-only + agentic needs a small CSS override in menu-button.css so the open (expanded) state still shows a fill on top of the gradient border.
  • Storybook defaults isAgentic to true.
  • Stories removed: WithTallyMobile (mobile navbar accordion demo, where isAgentic doesn't apply) and CustomClickHandler. The props they cover (isMobileAccordion, onClick) are unchanged and still in the controls.
  • isSelected on menu items (extension, added for ModelSelector). Optional boolean, not in the v2 item type. When set (true or false) the item gets role='menuitemradio' and aria-checked; the selected one shows a trailing check icon. Items that don't set it are unchanged. Desktop dropdown only (the mobile accordion ignores it). The port adds isSelected to MenuItemType.
  • isSelected items that are not selected render a hidden check (visibility: hidden) so the panel width doesn't change with the selection.