组件 · 浮层
Popover
A small panel that opens next to the element people click, for a little input such as a choice, a field and a button.
import { Popover } from "@botiverse/raft-ui";A popover is a small panel that opens next to the element people click and holds a little input: a choice of a few options, a field, a button. Snoozing a notification or renaming something fits in one. It closes on a click outside or Esc.
When to use
| Situation | Use |
|---|---|
| One sentence about something, on hover | Tooltip |
| A summary of a person or an agent, on hover, with links | PreviewCard |
| A little choice or input, on click (snooze, rename) | Popover, with a RadioGroup, an Input and buttons |
| A list of actions | DropdownMenu |
| Something that stays open and scrolls | Drawer |
Which overlay fits which job is in Choosing a component.
Anatomy
Popover: the root. Owns the open state. Required.PopoverTrigger: the element that opens it. Required.PopoverContent: the panel, portaled and positioned next to the trigger. Required.PopoverHeader: a row withPopoverTitleand an optionalPopoverClose.PopoverTitleandPopoverDescription: the title and a sentence under it.PopoverSeparator: a hairline between parts of the panel.PopoverClose: a button that closes the popover.PopoverArrow: an optional pointer toward the trigger.PopoverBackdrop: a transparent layer behind the panel that catches clicks outside it.PopoverPortal,PopoverViewportandPopoverPopup: lower-level parts.PopoverPopupis the panel surface without positioning.
Behavior
- The popover opens below its trigger, aligned to its start edge, and moves or flips when it meets the window edge (Elevation).
- A click outside and Esc close it. A Cancel button closes it too.
- It has no scrim; the page behind it stays as it is.
Content
- Write button labels in Title Case, with the confirm button repeating the verb: Snooze, Rename (Writing).
Accessibility
- Popover wraps the Base UI Popover. It provides the
dialogrole on the panel, moves focus into it on open, and returns focus to the trigger on Esc. - Name the panel:
PopoverTitlelabels it. Without a visible title, put anaria-labelonPopoverContent. - Give an icon-only trigger an
aria-label.
Rules
- Make a popover 300px wide, with 16px padding.
- Don't put a pink button in a popover. Confirm with an ink-border button (
variant="outline") and cancel withvariant="ghost": a popover is a small step, not the screen's primary action.
API
Popover
| Prop | 类型 | 默认值 |
|---|---|---|
| A ref to imperative actions. - `unmount`: Manually unmounts the popover. Call this after any externally controlled closing animation finishes. - `close`: Closes the popover imperatively when called. | RefObject<PopoverRootActions | null> | |
| The content of the popover. This can be a regular React node or a render function that receives the `payload` of the active trigger. | ReactNode | PayloadChildRenderFunction<unknown> | |
| Whether the popover is initially open. | boolean | false |
| ID of the trigger that the popover is associated with. This is useful in conjunction with the `defaultOpen` prop to create an initially open popover. | string | |
| A handle to associate the popover with a trigger. If specified, allows external triggers to control the popover's open state. | BasePopover.Handle<unknown> | |
| Determines if the popover enters a modal state when open. - `true`: user interaction is limited to the popover: document page scroll is locked, and pointer interactions on outside elements are disabled. - `false`: user interaction with the rest of the document is allowed. - `'trap-focus'`: focus is trapped inside the popover, but document page scroll is not locked and pointer interactions outside of it remain enabled. | boolean | "trap-focus" | false |
| Event handler called when the popover is opened or closed. | (open: boolean, eventDetails: BasePopover.Root.ChangeEventDetails) => void | |
| Event handler called after any animations complete when the popover is opened or closed. | (open: boolean) => void | |
| Whether the popover is currently open. | boolean | |
| ID of the trigger that the popover is associated with. This is useful in conjunction with the `open` prop to create a controlled popover. There's no need to specify this prop when the popover is uncontrolled (that is, when the `open` prop is not set). | string |
PopoverArrow, PopoverBackdrop
| Prop | 类型 | 默认值 |
|---|---|---|
| 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.
PopoverClose
| Prop | 类型 | 默认值 |
|---|---|---|
| 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 |
| 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.
PopoverContent
| Prop | 类型 | 默认值 |
|---|---|---|
| HTMLElement | ShadowRoot | RefObject<HTMLElement | ShadowRoot | null> | ||
| PopoverPortalProps | ||
| 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 |
| 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 popover is closed. | boolean | RefObject<HTMLElement | null> | ((closeType: InteractionType) => void | boolean | HTMLElement | null) | |
| Determines the element to focus when the popover is opened. By default, focus moves to the first tabbable element inside the popup, except when the popover is opened by touch — then the popup itself is focused to avoid opening the virtual keyboard. | boolean | RefObject<HTMLElement | null> | ((openType: InteractionType) => void | boolean | HTMLElement | null) | |
| 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 | 4 |
| 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.
PopoverDescription
| Prop | 类型 | 默认值 |
|---|---|---|
| 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.
PopoverHeader, PopoverPopup
接受其元素的全部属性。
PopoverPortal
| 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.
PopoverSeparator
接受其元素的全部属性。
PopoverTitle
| Prop | 类型 | 默认值 |
|---|---|---|
| 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.
PopoverTrigger
| Prop | 类型 | 默认值 |
|---|---|---|
| How long to wait before closing the popover that was opened on hover. Specified in milliseconds. | number | 0 |
| How long to wait before the popover may be opened on hover. Specified in milliseconds. | number | 300 |
| A handle to associate the trigger with a popover. | BasePopover.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>`). 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 (e.g. `<div>`). | boolean | true |
| Whether the popover should also open when the trigger is hovered. | boolean | false |
| A payload to pass to the popover 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) |
Also takes the attributes of its element.
PopoverViewport
| Prop | 类型 | 默认值 |
|---|---|---|
| The content to render inside the transition container. | ReactNode | |
| 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.