@biem/ui

Popover

A panel that opens next to its trigger and holds details or controls that belong to it.

A popover opens a panel next to its trigger, where users read details or use controls that belong to the trigger without leaving the page. A press on the trigger opens the popover and moves focus into it. The popover closes when users press the trigger again, press Escape, press outside of the popover or move focus out of it. The rest of the page stays usable while the popover is open. The trigger is a button without styles of its own, so the examples render it as a Button, and the content is 18rem wide.

Usage

popover-default.tsx
import { Button } from "@biem/ui/components/ui/button";
import {
	Popover,
	PopoverContent,
	PopoverDescription,
	PopoverHeader,
	PopoverTitle,
	PopoverTrigger,
} from "@biem/ui/components/ui/popover";

export function PopoverDefault() {
	return (
		<Popover>
			<PopoverTrigger render={<Button variant="outline"/>}>Reorder point</PopoverTrigger>
			<PopoverContent>
				<PopoverHeader>
					<PopoverTitle>Reorder point</PopoverTitle>
					<PopoverDescription>
						The store orders 24 cases from the warehouse when its stock falls to 6 cases.
					</PopoverDescription>
				</PopoverHeader>
			</PopoverContent>
		</Popover>
	);
}

Examples

Top Side

Triggers near the lower edge of a screen, such as the actions in a footer bar, leave little room below them. With side set to "top", the popover opens above its trigger instead. If the space above runs short, it moves below the trigger.

Right Side

In a narrow column, such as a list of stores along the left edge of a screen, a popover finds more room beside its trigger than below it. Set to "right", side opens it toward the wider area of the screen, and the entries further down the list stay readable.

Bottom Side

Reading runs from top to bottom, so details below a trigger follow the order in which users take in a screen. The popover takes this side by default, and side set to "bottom" states it explicitly. When the space below runs short, it opens above the trigger.

Left Side

Actions at the end of a table row sit close to the right edge of a screen, where little room remains beside them. With side set to "left", the popover opens toward the middle of the screen, next to the row it belongs to.

Open on Hover

Users who scan a screen want to see details without a press for each one. Once openOnHover is set on the trigger, the popover opens when the mouse pointer rests on the trigger, and it stays open while the pointer moves into the popover. Opened this way, it leaves focus where it is. On a touch screen, where no pointer rests on the trigger, a press opens the popover as before.

Open by Default

A popover can draw attention to a detail the moment a page loads, such as a figure that has changed since the last visit. Through defaultOpen it is open at first render, and users close it like any other popover once they have read it.

Controlled

In some workflows the application decides when the popover is open, for example to close it as soon as users have applied a change inside it. With open and onOpenChange, the application holds that state, so any part of the interface can open or close the popover.

Disabled Trigger

Not every item has details at every moment, for example a product that has no sales history yet. Set on the trigger, disabled keeps users from opening the popover, while the trigger stays in view and shows where the details will appear once they exist.

API Reference

Popover

Propopen
Typeboolean
Default–
DescriptionSets whether the popover is open and makes it controlled. Update it in onOpenChange.
PropdefaultOpen
Typeboolean
Defaultfalse
DescriptionOpens the popover at first render. The popover then tracks its open state itself.
ProponOpenChange
Type(open: boolean, eventDetails: PopoverRootChangeEventDetails) => void
Default–
DescriptionRuns when users open or close the popover. It receives the open state that follows.
ProponOpenChangeComplete
Type(open: boolean) => void
Default–
DescriptionRuns after the popover has opened or closed and its animations have finished.
Propmodal
Typeboolean | "trap-focus"
Defaultfalse
DescriptionSets how the popover limits the rest of the page while it is open. With false, the rest of the page stays usable. With true, the page doesn't scroll and elements outside of the popover don't react to the pointer. When a touch opened the popover, the page still scrolls unless the popover is about as wide as the viewport. With true or "trap-focus", focus also stays in the popover, provided that the content holds a Popover.Close from @base-ui/react/popover. "trap-focus" leaves scrolling and the pointer as they are. A popover that users open by hover is never modal.
ProptriggerId
Typestring | null
Default–
DescriptionSets the ID of the trigger that a controlled popover is associated with. A popover without open doesn't need it.
PropdefaultTriggerId
Typestring | null
Default–
DescriptionSets the ID of the trigger that the popover is associated with when defaultOpen opens it at first render.
Prophandle
TypePopoverHandle<Payload>
Default–
DescriptionConnects the popover with triggers that are rendered outside of it. Create the handle with Popover.createHandle() from @base-ui/react/popover.
PropactionsRef
TypeRefObject<PopoverRootActions | null>
Default–
DescriptionReceives the functions close and unmount. close closes the popover from code, and unmount removes it from the DOM after a closing animation that the code controls itself.
Propchildren
TypeReactNode | ((arg: { payload: Payload | undefined }) => ReactNode)
Default–
DescriptionHolds the parts of the popover. A function receives the payload of the trigger that opened the popover.

PopoverTrigger

PropopenOnHover
Typeboolean
Defaultfalse
DescriptionOpens the popover when the mouse pointer rests on the trigger, in addition to a press. A popover that opens by hover doesn't move focus into itself.
Propdelay
Typenumber
Default300
DescriptionSets how many milliseconds the pointer must rest on the trigger before the popover opens. It has an effect only with openOnHover.
PropcloseDelay
Typenumber
Default0
DescriptionSets how many milliseconds the popover stays open after the pointer has left the trigger and the content. It has an effect only with openOnHover.
Prophandle
TypePopoverHandle<Payload>
Default–
DescriptionConnects the trigger with a popover that it is rendered outside of. Pass the same handle to Popover.
Proppayload
TypePayload
Default–
DescriptionPasses a value to the popover when this trigger opens it. A function as children of Popover receives it.
Propid
Typestring
Default–
DescriptionSets the ID of the trigger element. triggerId and defaultTriggerId of Popover refer to it.
Proprender
TypeReactElement | render function
Default–
DescriptionReplaces the native element or composes the trigger with another component.
PropnativeButton
Typeboolean
Defaulttrue
DescriptionDeclares whether the rendered element is a native button. Set it to false when render returns a different element.
Propdisabled
Typeboolean
Defaultfalse
DescriptionPrevents users from opening the popover with this trigger.

PopoverContent

Propside
Type"top" | "bottom" | "left" | "right" | "inline-end" | "inline-start"
Default"bottom"
DescriptionSets the side of the trigger that the content opens on. "inline-start" and "inline-end" follow the reading direction. The content moves to the opposite side when the chosen one has too little space, and to a side on the other axis when neither of the two has enough.
PropsideOffset
Typenumber | OffsetFunction
Default4
DescriptionSets the distance between the trigger and the content in pixels. A function receives the side, the alignment and the dimensions of the trigger and the content, and returns the distance.
Propalign
Type"start" | "center" | "end"
Default"center"
DescriptionSets where the content lines up with the trigger along the chosen side: at its start, its center or its end.
PropalignOffset
Typenumber | OffsetFunction
Default0
DescriptionMoves the content along the alignment axis by a number of pixels. A function receives the same data as the one for sideOffset and returns the offset.
PropinitialFocus
Typeboolean | RefObject<HTMLElement | null> | ((openType: InteractionType) => boolean | HTMLElement | null | void)
Default–
DescriptionDetermines the element that receives focus when the popover opens. Without it, focus moves to the first focusable element in the popover. It moves to the popover itself when the content has no such element or when a touch opened the popover.
PropfinalFocus
Typeboolean | RefObject<HTMLElement | null> | ((closeType: InteractionType) => boolean | HTMLElement | null | void)
Default–
DescriptionDetermines the element that receives focus when the popover closes. Without it, focus returns to the trigger or to the element that had focus before.
Proprender
TypeReactElement | render function
Default–
DescriptionReplaces the native element or composes the content with another component.

PopoverHeader

PopoverHeader groups the title and the description. It renders a div and has no props of its own.

PopoverTitle

Proprender
TypeReactElement | render function
Default–
DescriptionReplaces the native element or composes the title with another component.

PopoverDescription

Proprender
TypeReactElement | render function
Default–
DescriptionReplaces the native element or composes the description with another component.