ContextMenuItemView

Updated: Sep 24, 2026
ContextMenuItemView is the one supported child of ContextMenu. It is a Container with a menu-item role, a minimum square footprint, fully rounded corners, and a material that draws no idle fill at all — so an item at rest reads as part of the menu surface, and only lights up when it is focused or pressed.
Two presets cover the common cases and are exported alongside it: ButtonContextMenuItemView for an icon-and-label action, and EmojiContextMenuItemView for an emoji with an optional selected dot. Reach for the base component only when you need custom content inside the item.

Usage

import {
  ButtonContextMenuItemView,
  ButtonItemIconSize,
  ContextMenu,
  ContextMenuItemView,
  EmojiContextMenuItemView,
  IconTintColor,
} from '@wearables-ui-toolkit/mrbd';

<ContextMenu aria-label="Message actions" onDismiss={closeMenu}>
  <ButtonContextMenuItemView
    title="Reply"
    icon={replyIcon}
    onClick={reply}
  />
  <ButtonContextMenuItemView
    title="Delete"
    icon={trashIcon}
    iconSize={ButtonItemIconSize.LARGE}
    iconTintColor={IconTintColor.NEGATIVE}
    onClick={confirmDelete}
  />
  <EmojiContextMenuItemView
    emoji="👍"
    ariaLabel="React with thumbs up"
    isEmojiSelected={reaction === 'thumbsUp'}
    onClick={() => react('thumbsUp')}
  />
  <ContextMenuItemView ariaLabel="Add reaction" onClick={openPicker}>
    <MyReactionGlyph />
  </ContextMenuItemView>
</ContextMenu>;
An icon-only action is legitimate when the glyph is unambiguous, but it must carry its own name:
<ButtonContextMenuItemView
  icon={starIcon}
  ariaLabel="Add to favourites"
  onClick={addToFavourites}
/>

Props

Each component below has its own exported prop type: ContextMenuItemViewProps, ButtonContextMenuItemViewProps, and EmojiContextMenuItemViewProps.

ContextMenuItemView

Extends ContainerProps with width and height removed — the item owns its minimum size. Every other interaction, disabled, material, and shape prop documented on Container applies here too; the notable ones are listed after the own props.
PropTypeDefaultDescription
children
ReactNode
—
Arbitrary item content. When present it replaces the convenience icon/label layout entirely.
icon
IconSource
—
Convenience icon, laid out at the start of the item row.
label
string
—
Convenience text next to the icon. Also becomes the accessible name unless ariaLabel is set.
onClick
() => void
—
Activation handler. Enter, Space, and a pointer click all reach it. The type takes no arguments, but the handler is invoked with the DOM click event, so declaring an optional event parameter lets you call stopPropagation() on it.
shapeProvider
ShapeProvider
Fully rounded rectangle
Geometry used for clipping and for the material’s fill and stroke paths.
material
ContainerMaterial
Context-menu item material
Overrides the item material. See MaterialLibrary.
style
CSSProperties
{}
Merged after the component’s minimum width and height, so a larger explicit size wins.
className
string
''
Extra class on the item root.
Notable inherited props:
PropTypeDefaultDescription
ariaLabel
string
Falls back to label
Accessible name. Required whenever the item has no readable text.
disabled
boolean
false
Renders the unavailable state and blocks activation. The item stays focusable so it remains discoverable.
focusable
boolean
Follows interactive, which is true
Whether the item can take focus at all.
onActivate
(event: InteractableActivationEvent) => void
—
Fires once per activation and reports the originating pointer or keyboard event.

ButtonContextMenuItemView

Everything from ContextMenuItemView except children and label, plus:
PropTypeDefaultDescription
icon
IconSource
—
Optional leading icon. Decorative: it contributes no accessible name.
title
string
—
Optional label text, rendered with the label type ramp on a single line. It is not truncated, so keep it short.
iconSize
ButtonItemIconSize
ButtonItemIconSize.MEDIUM
LARGE enlarges the icon and tightens the item’s horizontal content padding one step.
iconTintColor
IconTintColor
IconTintColor.PRIMARY
Semantic tint for the icon. Use NEGATIVE for destructive actions.
ariaLabel
string
Falls back to title
Required for an icon-only item.

EmojiContextMenuItemView

Everything from ContextMenuItemView except children, icon, and label, plus:
PropTypeDefaultDescription
emoji
string
—
The emoji character to display.
isEmojiSelected
boolean
false
Shows the selection dot under the emoji.
ariaLabel
string
Falls back to emoji
Prefer a spoken phrase such as “React with thumbs up”.

Types and enums

ButtonItemIconSize

MemberValueDescription
MEDIUM
'medium'
Default icon size and content padding.
LARGE
'large'
Larger icon with the next-smaller horizontal content padding.

IconTintColor

Shared semantic icon tints. Each resolves to a design token; free-form CSS colors are deliberately not accepted.
MemberValueTypical use
PRIMARY
'primary'
Default glyph tint.
SECONDARY
'secondary'
De-emphasised glyph. Composites with a lighten blend so it still lifts off the surface.
ACCENT
'accent'
Accent glyph.
ON_CHECKED
'on-checked'
Glyph drawn on a checked control’s fill.
ACTION
'action'
Actionable status, such as a pending call to action.
POSITIVE
'positive'
Success or confirmation.
WARNING
'warning'
Caution.
NEGATIVE
'negative'
Destructive or error.
INFO
'info'
Neutral informational status.
getIconTintCSSVariable(tint) and getIconTintBlendMode(tint) are exported alongside the enum if you need to apply the same tint to a glyph of your own.

Behavior

  • Sizing. The item enforces a minimum square footprint and grows with its content. width and height are not part of the API; a larger box can only come from style, which is merged after the minimums.
  • Shape. Corners are fully rounded by default, giving the pill silhouette the menu expects. Swap shapeProvider only if the whole menu is being restyled coherently.
  • Material. The item has no idle surface fill, and its glow stroke is held at zero in the idle state so it fades up into focus and press rather than popping in. That is what lets a row of items look like one continuous menu surface.
  • Convenience layout. With no children, icon and label are laid out as a single centred horizontal row: icon first, then text, separated by a spacing token. The label stays on one line and truncates with an ellipsis.
  • Presets.ButtonContextMenuItemView uses the same horizontal layout with the label type ramp and a tinted icon, but its title stays on one line without truncating: a long title widens the item and pushes the rest of the row into the scroller. EmojiContextMenuItemView centres the emoji and, when isEmojiSelected is set, adds a small dot beneath it.
  • Activation. Enter and Space activate the focused item; a pointer click works too. Left and Right are consumed by the parent menu for movement, so an item must not rely on horizontal keys of its own.
  • Custom content. Passing children replaces the built-in layout but keeps the item’s role, material, shape, and minimum size. Anything focusable inside the item becomes the focus target the parent menu moves to.

Accessibility

  • Every item exposes role="menuitem".
  • Icons are decorative and carry no name of their own. The accessible name comes from ariaLabel, then title (or emoji, or label on the base component).
  • An item with an icon and no text must set ariaLabel, otherwise it is announced as an unnamed menu item.
  • An item built from children has no derived name at all — set ariaLabel.
  • isEmojiSelected is a visual dot only. If selection state must be spoken, put it in ariaLabel.
  • Do not rely on iconTintColor alone to convey that an action is destructive; the label has to say so too.
  • Use ButtonContextMenuItemView for labelled actions and EmojiContextMenuItemView for reactions.
  • Give destructive actions the NEGATIVE tint and a confirmation path because color alone is not a warning.
  • Keep labels to one short, verb-led phrase that fits on a single line.
  • An ariaLabel is required for every icon-only item so the action has an accessible name.

Avoid

  • Prefer the provided presets over building a custom row that imitates a menu item.
  • Preserve the component-owned width, height, and internal padding.
  • Keep the menu item as one interaction target; a nested control creates ambiguous focus and activation.
  • Use these items inside ContextMenu, which provides their navigation and menu semantics.