Skip to main content

Popover

Source ↗

A Popover is a non-modal overlay that anchors itself to a trigger element. Unlike a standard tooltip, it is designed to hold interactive rich content such as forms, lists, or navigation, without breaking the user's current context.

Popover is used as an underlying component for other components like Dropdown, Select and Tooltip.

Key Characteristics

  • Non-Modal: The user can still interact with the rest of the page while the popover is open.
  • Floating Context: It uses position: fixed in combination with react-portals to ensure it remains visible and correctly placed relative to its disclosure, even within scrolling containers, or in any other context. It just works.
  • Rich Interaction: Specifically built to handle interactive elements (buttons, inputs) that require focus management and keyboard navigation.

Import

There are 3 popover related components:

  • Popover: The main popover component.
  • PopoverTrigger: The component that triggers the popover to open or close.
  • PopoverContent: The content that is displayed when the popover is open.
import { Popover, PopoverTrigger, PopoverContent } from '@andrejground/lab';

Compound pattern is also supported:

  • Popover.Trigger
  • Popover.Content

Customization

Add your styles and your component is ready to be used.

import { Popover, PopoverProps } from '@andrejground/lab';
import styles from './MyPopover.module.scss';

type Props = PopoverProps;

function MyPopover(props: Props) {
return (
<Popover
{...props}
classNames={{
content: styles.popoverContent,
}}
/>
);
}

MyPopover.Content = Popover.Content;
MyPopover.Trigger = Popover.Trigger;

export default MyPopover;

Usage

Placement

Controlled

Open: false

Offset

With Form

Backdrop

API

Popover Props

PropTypeDefaultDescription
childrenReactNode-Popover content (expects Popover.Trigger and Popover.Content)
triggerReactNode-Element that triggers the popover
contentReactNode-Content displayed inside the popover
sizePopoverSize-Controls the width of the popover content
isOpenboolean-Controls the popover open state (controlled mode)
isDisabledboolean-Disables the popover trigger
isNestedbooleanfalseIndicates the popover is nested inside another popover
placementPopoverPlacement"bottom-center"Preferred placement of the popover relative to the trigger
offsetnumber8Distance in pixels between the popover and the trigger
backdropBackdrop"none"The backdrop style displayed behind the popover
shouldFlipbooleantrueFlips placement when there is not enough space
shouldBlockScrollbooleantrueBlocks page scroll when the popover is open
shouldCloseOnScrollboolean!shouldBlockScrollCloses the popover when the page is scrolled
shouldCloseOnClickOutsidebooleantrueCloses the popover when clicking outside of it
shouldCloseOnEscbooleantrueCloses the popover when the Escape key is pressed
shouldCloseOnTriggerBlurbooleanfalseCloses the popover when the trigger loses focus
showArrowbooleanfalseShows an arrow pointing toward the trigger
openOnHoverboolean-Opens the popover on hover instead of click
openOnFocusbooleanfalseOpens the popover when the trigger receives focus
focusTriggerOnClosebooleantrueReturns focus to the trigger when the popover closes
delayShownumber0Delay in milliseconds before showing the popover
delayHidenumber0Delay in milliseconds before hiding the popover
hoverableContentbooleantrueKeeps the popover open while hovering over its content
growContentbooleanfalseAllows the popover content to grow beyond the trigger width
onOpen() => void-Callback fired when the popover opens
onClose() => void-Callback fired when the popover closes
onClickOutside() => void-Callback fired when clicking outside the popover
onOpenChange(isOpen: boolean) => void-Callback fired when the open state changes
onTriggerFocus() => void-Callback fired when the trigger receives focus
onTriggerBlur() => void-Callback fired when the trigger loses focus
triggerWrapperbooleanfalseWraps the trigger in a span instead of using Slot
fullWidthTriggerWrapperbooleanfalseMakes the trigger wrapper take full width
focusTrapProps{ trapFocus?: boolean; autoFocus?: boolean }{ trapFocus: true, autoFocus: true }Configuration for focus trap behavior
classNamesPopoverClassNames-Custom class names for the popover slots

Popover.Trigger Props

PropTypeDefaultDescription
childrenReactNode-A single element that acts as the popover trigger

Popover.Content Props

PropTypeDefaultDescription
childrenReactNode-Content displayed inside the popover