组件 · 浮层
DropdownMenu
A list of actions on one thing, opened from a button, that can also hold a setting-style choice with a check mark on the current value.
import { DropdownMenu } from "@botiverse/raft-ui";A dropdown menu is a list of actions on one thing (a message, a channel, a task, an agent), opened from a button such as ⋯. It can also hold a setting-style choice, such as sort order or status, with a check mark on the current value. Right-click on desktop and press and hold on a phone open the same menu as a ContextMenu.
When to use
| Situation | Use |
|---|---|
| Act on one thing, from a button | DropdownMenu |
| The same actions, on right-click or press and hold | ContextMenu, with the same items |
| A setting-style choice that applies at once (sort, status) | DropdownMenu with radio items |
| A value submitted with a form | Select |
| A little input on click (snooze, rename) | Popover |
| A place to go, on a phone | A bottom sheet (Drawer) |
Which overlay fits which job is in Choosing a component.
Anatomy
DropdownMenu: the root. Owns the open state. Required.DropdownMenuTrigger: the button that opens the menu. Renders an outline Button unless you passrender. Required.DropdownMenuContent: the menu, portaled and positioned next to the trigger, at least 240px wide. Required.DropdownMenuItem: one action. A 16px icon, then the label. Wrap the label inDropdownMenuItemLabelto truncate it.DropdownMenuShortcut: the keyboard shortcut at the end of an item, intext-mono-metaandforeground-hint.DropdownMenuItemCount: a count at the end of an item.DropdownMenuRadioGroupandDropdownMenuRadioItem: a set of values with one current value, marked with a check mark.DropdownMenuCheckboxItem: an option that is on or off by itself.DropdownMenuLabel: a heading over a group of items. Not interactive.DropdownMenuSeparator: the line between sections.DropdownMenuSubmenuandDropdownMenuSubmenuTrigger: a nested menu, opened from an item with a chevron.DropdownMenuFooter: a line of quiet text at the bottom, such as a count.DropdownMenuPortalandDropdownMenuPopup: lower-level parts.DropdownMenuPopupis the menu surface without positioning.
States
Hover, keyboard highlight, the current value and disabled items follow States. In a menu:
- Keep the highlight and the current value apart. The
brand-softhighlight shows where the pointer or keyboard is; the check mark and bold text show which value is chosen. Never use the highlight to mark the current value. - Show a disabled item with
foreground-disabledtext and icon, and nothing else.
Behavior
- The menu opens below its trigger, aligned to the trigger's start edge, and moves or flips when it meets the window edge (Elevation).
- Choosing an action closes the menu. Choosing a radio or checkbox item leaves it open, so people can see the result.
- Esc and a click outside close the menu.
- An item is as tall as its content: one line is 36px, and a second line, such as a description under the label, adds only its own height, with the same space above and below the text (Forms). This holds for radio and checkbox items too.
Content
- Write item labels in Title Case: Copy Link, Reply in Thread (Writing).
- Make the label of an item that opens a dialog the dialog's title (Writing).
Accessibility
- DropdownMenu wraps the Base UI Menu. It provides the
menurole, the item roles, arrow-key movement, typeahead, Esc, and focus return to the trigger. - Name the menu after the thing it acts on: put
aria-labelonDropdownMenuContent("Message from Wug"). - Give an icon-only trigger, such as ⋯, an
aria-label("More Actions"). - Make every row in the menu a menu item, so arrow keys reach it. This includes each quick reaction: give it an
aria-label("React with thumbs up") and hide the drawing from assistive technology. - Leave item icons decorative; the label names the action.
Rules
- Don't color destructive items such as Delete or Stop. They open an AlertDialog, whose orange or red button carries the consequence (Feedback).
- Use the same separator between every two sections of a menu.
- Don't put a control that submits a form value in a menu; use a Select.
The message menu
The message menu starts with the quick reactions (Conversation; sizes in Brand).
- End the row of quick reactions with a
smile-plusicon button that opens every emoji. - Put one separator between the reactions and the first action, then group the actions into sections.
API
DropdownMenu
| Prop | 类型 | 默认值 |
|---|---|---|
| A 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> | |
| The content of the menu. This can be a regular React node or a render function that receives the `payload` of the active trigger. | ReactNode | PayloadChildRenderFunction<unknown> | |
| When in a submenu, determines whether pressing the Escape key closes the entire menu, or only the current child menu. | boolean | false |
| Whether the menu is initially open. | boolean | false |
| ID of the trigger that the menu is associated with. This is useful in conjunction with the `defaultOpen` prop to create an initially open menu. | string | |
| Whether the component should ignore user interaction. | boolean | false |
| A handle to associate the menu with a trigger. If specified, allows external triggers to control the menu's open state. | BaseMenu.Handle<unknown> | |
| Whether moving the pointer over items should highlight them. Disabling this prop allows CSS `:hover` to be differentiated from the `:focus` (`data-highlighted`) state. | boolean | true |
| Whether to loop keyboard focus back to the first item when the end of the list is reached while using the arrow keys. | boolean | true |
| Determines if the menu enters a modal state when open. - `true`: user interaction is limited to the menu: document page scroll is locked and pointer interactions on outside elements are disabled. - `false`: user interaction with the rest of the document is allowed. | boolean | true |
| Event handler called when the menu is opened or closed. | (open: boolean, eventDetails: BaseMenu.Root.ChangeEventDetails) => void | |
| Event handler called after any animations complete when the menu is opened or closed. | (open: boolean) => void | |
| Whether the menu is currently open. | boolean | |
| The visual orientation of the menu. Controls whether roving focus uses up/down or left/right arrow keys. | MenuRootOrientation | 'vertical' |
| ID of the trigger that the menu is associated with. This is useful in conjunction with the `open` prop to create a controlled menu. There's no need to specify this prop when the menu is uncontrolled (that is, when the `open` prop is not set). | string |
DropdownMenuCheckboxItem
| Prop | 类型 | 默认值 |
|---|---|---|
| Whether the checkbox item is currently ticked. | boolean | |
| Whether to close the menu when the item is clicked. | boolean | false |
| Whether the checkbox item is initially ticked. | boolean | false |
| Whether the component should ignore user interaction. | boolean | false |
| string | ||
| Overrides the text label to use when the item is matched during keyboard text navigation. | string | |
| Whether 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. | boolean | false |
| Event handler called when the checkbox item is ticked or unticked. | (checked: boolean, eventDetails: BaseMenu.CheckboxItem.ChangeEventDetails) => void | |
| The click handler for the menu item. | (event: BaseUIEvent<MouseEvent<HTMLDivElement, MouseEvent>>) => void | |
| Allows 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.
DropdownMenuCheckboxItemIndicator
| Prop | 类型 | 默认值 |
|---|---|---|
| Whether to keep the HTML element in the DOM when the checkbox item is not checked. | boolean | false |
| Allows 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.
DropdownMenuContent
| Prop | 类型 | 默认值 |
|---|---|---|
| ContextMenuPortalProps | ||
| How to align the popup relative to the specified side. | Align | "start" |
| Additional 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 | OffsetFunction | 0 |
| An element to position the popup against. By default, the popup will be positioned against the trigger. | Element | VirtualElement | RefObject<Element | null> | (() => Element | VirtualElement | null) | |
| Minimum distance to maintain between the arrow and the edges of the popup. | number | 5 |
| ReactNode | ||
| Determines how to handle collisions when positioning the popup. | CollisionAvoidance | |
| An element or a rectangle that delimits the area that the popup is confined to. | Boundary | 'clipping-ancestors' |
| Additional space to maintain from the edge of the collision boundary. | Padding | 5 |
| Whether to disable the popup from tracking any layout shift of its positioning anchor. | boolean | false |
| Determines the element to focus when the menu is closed. | boolean | RefObject<HTMLElement | null> | ((closeType: InteractionType) => boolean | HTMLElement | null | void) | |
| string | ||
| Determines which CSS `position` property to use. | "fixed" | "absolute" | "fixed" |
| Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ReactElement | ((props, state) => ReactElement) | |
| Which side of the anchor element to align the popup against. May automatically change to avoid collisions. | Side | "bottom" |
| Distance 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 | OffsetFunction | 0 |
| Whether to maintain the popup in the viewport after the anchor element was scrolled out of view. | boolean | false |
Also takes the attributes of its element.
DropdownMenuFooter
接受其元素的全部属性。
DropdownMenuItem
| Prop | 类型 | 默认值 |
|---|---|---|
| Whether to close the menu when the item is clicked. | boolean | true |
| Whether the component should ignore user interaction. | boolean | false |
| string | ||
| Overrides the text label to use when the item is matched during keyboard text navigation. | string | |
| Whether 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. | boolean | false |
| The click handler for the menu item. | (event: BaseUIEvent<MouseEvent<HTMLDivElement, MouseEvent>>) => void | |
| Allows 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.
DropdownMenuItemCount
| Prop | 类型 | 默认值 |
|---|---|---|
| "outline" | "solid" | "soft" | ||
| "primary" | "accent" | "warning" | "danger" | "default" | "information" | "muted" | "success" | ||
| Allows 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.
DropdownMenuItemLabel, DropdownMenuLabel, DropdownMenuPopup
接受其元素的全部属性。
DropdownMenuPortal
| Prop | 类型 | 默认值 |
|---|---|---|
| A parent element to render the portal element into. | HTMLElement | ShadowRoot | RefObject<HTMLElement | ShadowRoot | null> | |
| Whether to keep the portal mounted in the DOM while the popup is hidden. | boolean | false |
| Allows 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.
DropdownMenuRadioGroup
| Prop | 类型 | 默认值 |
|---|---|---|
| The content of the component. | ReactNode | |
| The uncontrolled value of the radio item that should be initially selected. | any | |
| Whether the component should ignore user interaction. | boolean | false |
| Function called when the selected value changes. | (value: any, eventDetails: BaseMenu.RadioGroup.ChangeEventDetails) => void | |
| Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ReactElement | ((props, state) => ReactElement) | |
| The controlled value of the radio item that should be currently selected. | any |
Also takes the attributes of its element.
DropdownMenuRadioItem
| Prop | 类型 | 默认值 |
|---|---|---|
| Whether to close the menu when the item is clicked. | boolean | false |
| Whether the component should ignore user interaction. | boolean | false |
| string | ||
| Overrides the text label to use when the item is matched during keyboard text navigation. | string | |
| Whether 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. | boolean | false |
| The click handler for the menu item. | (event: BaseUIEvent<MouseEvent<HTMLDivElement, MouseEvent>>) => void | |
| Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ReactElement | ((props, state) => ReactElement) | |
| 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.
DropdownMenuRadioItemIndicator
| Prop | 类型 | 默认值 |
|---|---|---|
| Whether to keep the HTML element in the DOM when the radio item is inactive. | boolean | false |
| Allows 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.
DropdownMenuSeparator
| Prop | 类型 | 默认值 |
|---|---|---|
| The orientation of the separator. | Orientation | 'horizontal' |
| Allows 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.
DropdownMenuShortcut
接受其元素的全部属性。
DropdownMenuSubmenu
| Prop | 类型 | 默认值 |
|---|---|---|
| A 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> | |
| The content of the submenu. | ReactNode | |
| When in a submenu, determines whether pressing the Escape key closes the entire menu, or only the current child menu. | boolean | false |
| Whether the menu is initially open. | boolean | false |
| Whether the component should ignore user interaction. | boolean | false |
| Whether moving the pointer over items should highlight them. Disabling this prop allows CSS `:hover` to be differentiated from the `:focus` (`data-highlighted`) state. | boolean | true |
| Whether to loop keyboard focus back to the first item when the end of the list is reached while using the arrow keys. | boolean | true |
| Event handler called when the menu is opened or closed. | (open: boolean, eventDetails: BaseMenu.SubmenuRoot.ChangeEventDetails) => void | |
| Event handler called after any animations complete when the menu is opened or closed. | (open: boolean) => void | |
| Whether the menu is currently open. | boolean | |
| The visual orientation of the menu. Controls whether roving focus uses up/down or left/right arrow keys. | MenuRootOrientation | 'vertical' |
DropdownMenuSubmenuTrigger
| Prop | 类型 | 默认值 |
|---|---|---|
| How long to wait before closing the menu that was opened on hover. Specified in milliseconds. | number | 0 |
| How long to wait before the menu may be opened on hover. Specified in milliseconds. | number | 100 |
| Whether the component should ignore user interaction. | boolean | false |
| string | ||
| Overrides the text label to use when the item is matched during keyboard text navigation. | string | |
| Whether 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. | boolean | false |
| (event: BaseUIEvent<MouseEvent<HTMLDivElement, MouseEvent>>) => void | ||
| Whether the menu should also open when the trigger is hovered. | boolean | true |
| Allows 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.
DropdownMenuTrigger
| Prop | 类型 | 默认值 |
|---|---|---|
| ReactNode | ||
| How long to wait before closing the menu that was opened on hover. Specified in milliseconds. | number | 0 |
| How long to wait before the menu may be opened on hover. Specified in milliseconds. | number | 100 |
| Whether the component should ignore user interaction. | boolean | false |
| A handle to associate the trigger with a menu. | BaseMenu.Handle<unknown> | |
| Whether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `false` if the rendered element is not a button (for example, `<div>`). | boolean | true |
| Whether the menu should also open when the trigger is hovered. | boolean | |
| A payload to pass to the menu when it is opened. | {} | |
| Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ReactElement | ((props, state) => ReactElement) | <Button variant="outline" size="md" /> |
Also takes the attributes of its element.
相关组件
改动
- 0.0.20 · AddedAdded
ContextMenuItemLabel,ContextMenuFooter,DropdownMenuItemLabel, andDropdownMenuFooterfor truncatable menu labels and structured footer content.