Raft 设计系统

组件 · 浮层

ContextMenu

The menu of actions on one thing that opens at the pointer on right-click, or on press and hold on a touch screen.

稳定也叫 Right-click menu
import { ContextMenu } from "@botiverse/raft-ui";
本页尚未翻译
译文完成之前,这里显示英文原文。 阅读英文版

A context menu is the menu of actions on one thing that opens where people right-click on desktop, or where they press and hold on a touch screen. It is the same menu that the thing's ⋯ button opens as a DropdownMenu: the same items, in the same order.

context-menu/context-menu

When to use

SituationUse
Right-click or press and hold on a message, a channel, a task or an agentContextMenu
The same actions, from a visible buttonDropdownMenu
Acting on something on a phoneContextMenu on press and hold, never a bottom sheet
A value submitted with a formSelect

Which overlay fits which job is in Choosing a component.

Anatomy

ContextMenu has the same parts as DropdownMenu, with the ContextMenu prefix: ContextMenuItem, ContextMenuItemLabel, ContextMenuShortcut, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuCheckboxItem, ContextMenuLabel, ContextMenuSeparator, ContextMenuSubmenu, ContextMenuSubmenuTrigger, ContextMenuFooter, ContextMenuPortal and ContextMenuPopup. They look and behave as described in DropdownMenu. It has no item count part.

  • ContextMenu: the root. Required.
  • ContextMenuTrigger: the area that opens the menu: the message, the row, the card. Required.
  • ContextMenuContent: the menu, portaled and opened at the pointer. Required.

States

The highlight, the current value and disabled items are the same as in DropdownMenu.

Behavior

  • The menu opens at the pointer, or at the finger after press and hold, with its top-left corner there.
  • When it would cross the window edge, it shifts to stay at least 8px inside the window instead of flipping.
  • It stays where it opened while the page behind it scrolls.
  • Choosing an action closes the menu; Esc and a click outside close it too.
  • An item is as tall as its content, with constant padding, as in a DropdownMenu (Forms).

Content

The item labels follow DropdownMenu: Title Case, and the same words as the dialog an item opens.

Accessibility

  • ContextMenu wraps the Base UI ContextMenu. It provides the menu role, the item roles, arrow keys, typeahead and Esc.
  • Name the menu after the thing it acts on with aria-label on ContextMenuContent ("Message from Wug").
  • Right-click and press and hold are not available from the keyboard. Offer every action of a context menu from a visible control as well, usually the ⋯ DropdownMenu.

Rules

  • Build the context menu and the ⋯ menu from one list of items, so they never drift apart.
  • Use the same menu on desktop and on a phone. Don't build a separate phone sheet for the same actions.
  • Follow the rules of DropdownMenu: no color on destructive items, and the quick reactions first in the message menu.

API

ContextMenu

Prop类型默认值
actionsRefA ref to imperative actions. - `unmount`: Manually unmounts the menu. Call this after any externally controlled closing animation finishes. - `close`: When specified, the menu can be closed imperatively.RefObject<MenuRootActions | null>
childrenReactNode
closeParentOnEsc已弃用。boolean
defaultOpenWhether the menu is initially open.booleanfalse
disabledWhether the component should ignore user interaction.booleanfalse
highlightItemOnHoverWhether moving the pointer over items should highlight them. Disabling this prop allows CSS `:hover` to be differentiated from the `:focus` (`data-highlighted`) state.booleantrue
loopFocusWhether to loop keyboard focus back to the first item when the end of the list is reached while using the arrow keys.booleantrue
onOpenChangeEvent handler called when the menu is opened or closed.(open: boolean, eventDetails: BaseContextMenu.Root.ChangeEventDetails) => void
onOpenChangeCompleteEvent handler called after any animations complete when the menu is opened or closed.(open: boolean) => void
openWhether the menu is currently open.boolean
orientationThe visual orientation of the menu. Controls whether roving focus uses up/down or left/right arrow keys.MenuRootOrientation'vertical'

ContextMenuCheckboxItem

Prop类型默认值
checkedWhether the checkbox item is currently ticked.boolean
closeOnClickWhether to close the menu when the item is clicked.booleanfalse
defaultCheckedWhether the checkbox item is initially ticked.booleanfalse
disabledWhether the component should ignore user interaction.booleanfalse
idstring
labelOverrides the text label to use when the item is matched during keyboard text navigation.string
nativeButtonWhether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `true` if the rendered element is a native button.booleanfalse
onCheckedChangeEvent handler called when the checkbox item is ticked or unticked.(checked: boolean, eventDetails: BaseContextMenu.CheckboxItem.ChangeEventDetails) => void
onClickThe click handler for the menu item.(event: BaseUIEvent<MouseEvent<HTMLDivElement, MouseEvent>>) => void
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

ContextMenuCheckboxItemIndicator

Prop类型默认值
keepMountedWhether to keep the HTML element in the DOM when the checkbox item is not checked.booleanfalse
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

ContextMenuContent

Prop类型默认值
portalPropsContextMenuPortalProps
alignHow to align the popup relative to the specified side.Align"start"
alignOffsetAdditional offset along the alignment axis in pixels. Also accepts a function that returns the offset to read the dimensions of the anchor and positioner elements, along with its side and alignment.number | OffsetFunction0
anchorAn element to position the popup against. By default, root context menus are positioned at the pointer, and submenus are positioned against their trigger.Element | VirtualElement | RefObject<Element | null> | (() => Element | VirtualElement | null)
arrowPaddingMinimum distance to maintain between the arrow and the edges of the popup.number
childrenReactNode
collisionAvoidanceDetermines how to handle collisions when positioning the popup.CollisionAvoidanceCONTENT_COLLISION_AVOIDANCE
collisionBoundaryAn element or a rectangle that delimits the area that the popup is confined to.Boundary'clipping-ancestors'
collisionPaddingAdditional space to maintain from the edge of the collision boundary.Padding8
disableAnchorTrackingWhether to disable the popup from tracking any layout shift of its positioning anchor.booleanfalse
finalFocusDetermines the element to focus when the menu is closed.boolean | RefObject<HTMLElement | null> | ((closeType: InteractionType) => boolean | HTMLElement | null | void)
idstring
positionMethod已弃用。"fixed" | "absolute""fixed"
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)
sideWhich side of the anchor element to align the popup against. May automatically change to avoid collisions.Side"right"
sideOffsetDistance between the anchor and the popup in pixels. Also accepts a function that returns the distance to read the dimensions of the anchor and positioner elements, along with its side and alignment.number | OffsetFunction0
stickyWhether to maintain the popup in the viewport after the anchor element was scrolled out of view.booleanfalse

Also takes the attributes of its element.

ContextMenuFooter

接受其元素的全部属性。

ContextMenuItem

Prop类型默认值
closeOnClickWhether to close the menu when the item is clicked.booleantrue
disabledWhether the component should ignore user interaction.booleanfalse
idstring
labelOverrides the text label to use when the item is matched during keyboard text navigation.string
nativeButtonWhether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `true` if the rendered element is a native button.booleanfalse
onClickThe click handler for the menu item.(event: BaseUIEvent<MouseEvent<HTMLDivElement, MouseEvent>>) => void
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

ContextMenuItemLabel, ContextMenuLabel, ContextMenuPopup

接受其元素的全部属性。

ContextMenuPortal

Prop类型默认值
containerA parent element to render the portal element into.HTMLElement | ShadowRoot | RefObject<HTMLElement | ShadowRoot | null>
keepMountedWhether to keep the portal mounted in the DOM while the popup is hidden.booleanfalse
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

ContextMenuRadioGroup

Prop类型默认值
childrenThe content of the component.ReactNode
defaultValueThe uncontrolled value of the radio item that should be initially selected.any
disabledWhether the component should ignore user interaction.booleanfalse
onValueChangeFunction called when the selected value changes.(value: any, eventDetails: BaseContextMenu.RadioGroup.ChangeEventDetails) => void
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)
valueThe controlled value of the radio item that should be currently selected.any

Also takes the attributes of its element.

ContextMenuRadioItem

Prop类型默认值
closeOnClickWhether to close the menu when the item is clicked.booleanfalse
disabledWhether the component should ignore user interaction.booleanfalse
idstring
labelOverrides the text label to use when the item is matched during keyboard text navigation.string
nativeButtonWhether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `true` if the rendered element is a native button.booleanfalse
onClickThe click handler for the menu item.(event: BaseUIEvent<MouseEvent<HTMLDivElement, MouseEvent>>) => void
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)
value (required)Value of the radio item. This is the value that will be set in the MenuRadioGroup when the item is selected.any

Also takes the attributes of its element.

ContextMenuRadioItemIndicator

Prop类型默认值
keepMountedWhether to keep the HTML element in the DOM when the radio item is inactive.booleanfalse
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

ContextMenuSeparator

Prop类型默认值
orientationThe orientation of the separator.Orientation'horizontal'
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

ContextMenuShortcut

接受其元素的全部属性。

ContextMenuSubmenu

Prop类型默认值
actionsRefA ref to imperative actions. - `unmount`: Manually unmounts the menu. Call this after any externally controlled closing animation finishes. - `close`: When specified, the menu can be closed imperatively.RefObject<MenuRootActions | null>
childrenThe content of the submenu.ReactNode
closeParentOnEscWhen in a submenu, determines whether pressing the Escape key closes the entire menu, or only the current child menu.booleanfalse
defaultOpenWhether the menu is initially open.booleanfalse
disabledWhether the component should ignore user interaction.booleanfalse
highlightItemOnHoverWhether moving the pointer over items should highlight them. Disabling this prop allows CSS `:hover` to be differentiated from the `:focus` (`data-highlighted`) state.booleantrue
loopFocusWhether to loop keyboard focus back to the first item when the end of the list is reached while using the arrow keys.booleantrue
onOpenChangeEvent handler called when the menu is opened or closed.(open: boolean, eventDetails: BaseContextMenu.SubmenuRoot.ChangeEventDetails) => void
onOpenChangeCompleteEvent handler called after any animations complete when the menu is opened or closed.(open: boolean) => void
openWhether the menu is currently open.boolean
orientationThe visual orientation of the menu. Controls whether roving focus uses up/down or left/right arrow keys.MenuRootOrientation'vertical'

ContextMenuSubmenuTrigger

Prop类型默认值
closeDelayHow long to wait before closing the menu that was opened on hover. Specified in milliseconds.number0
delayHow long to wait before the menu may be opened on hover. Specified in milliseconds.number100
disabledWhether the component should ignore user interaction.booleanfalse
idstring
labelOverrides the text label to use when the item is matched during keyboard text navigation.string
nativeButtonWhether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `true` if the rendered element is a native button.booleanfalse
onClick(event: BaseUIEvent<MouseEvent<HTMLDivElement, MouseEvent>>) => void
openOnHoverWhether the menu should also open when the trigger is hovered.booleantrue
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

ContextMenuTrigger

Prop类型默认值
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

改动

  • 0.1.0 · AddedExtended Lightbox with thumbnail strip and related chrome parts; added ComboboxTriggerCount and ContextMenuPopup.
  • 0.0.20 · AddedAdded ContextMenuItemLabel, ContextMenuFooter, DropdownMenuItemLabel, and DropdownMenuFooter for truncatable menu labels and structured footer content.