Skip to main content

Popover

Two popover components are exported:

  • TriggeredPopover — the easy path. Renders a trigger (a Button by default) and manages the open/close state internally.
  • Popover — the lower-level primitive. You bring your own trigger via a triggerRef and either let it manage its own state with openByDefault or drive it from the outside with isOpen / onOpenChange.

Both share placement, offset and styling props.

Triggered popover

<TriggeredPopover>
<div>This is demo content</div>
</TriggeredPopover>

Highlighted props

For the complete list of props, use your IDE's autocomplete functionality.

Trigger button customization

<TriggeredPopover
triggerButtonLabel='Click me'
triggerButtonIcon={pointerHand}
>
<div>This is demo content</div>
</TriggeredPopover>
More advanced customizations

triggerButtonProps accepts all props a Button accepts.

<TriggeredPopover
triggerButtonIcon={trash}
triggerButtonProps={{ type: 'danger' }}
>
<div>This is demo content</div>
</TriggeredPopover>

Offset from trigger

offset controls the space between the trigger and the popover on the main opening axis.

<TriggeredPopover
offset={20}
>
<div>This is demo content</div>
</TriggeredPopover>

crossOffset controls the space between the trigger and the popover on the axis perpendicular to the main opening axis.

<TriggeredPopover
crossOffset={80}
>
<div>This is demo content</div>
</TriggeredPopover>

Standalone Popover

Use the standalone Popover when you need full control of the trigger — for example, when the trigger isn't a Button, when the open state is driven by external logic, or when several elements should be able to open the same popover.

Popover requires a triggerRef that points to the element the popover should anchor to.

Uncontrolled (managed internally)

Pass openByDefault and let Popover manage its own state. It will open and close based on user interaction with the referenced trigger.

import { useRef } from 'react';
import { Popover, Button } from '@eightshift/ui-components';

const triggerRef = useRef(null);

<Button forwardedRef={triggerRef}>Open popover</Button>

<Popover
triggerRef={triggerRef}
openByDefault
>
<div>This is demo content</div>
</Popover>

Controlled

Drive the open state from outside using isOpen and onOpenChange.

import { useRef, useState } from 'react';
import { Popover, Button } from '@eightshift/ui-components';

const triggerRef = useRef(null);
const [isOpen, setIsOpen] = useState(false);

<Button
forwardedRef={triggerRef}
onPress={() => setIsOpen(true)}
>
Open popover
</Button>

<Popover
triggerRef={triggerRef}
isOpen={isOpen}
onOpenChange={setIsOpen}
>
<div>This is demo content</div>
</Popover>

Highlighted props

PropDescription
triggerRefRefObject to the element the popover should anchor to. Required.
isOpen / onOpenChangeControlled open state.
openByDefaultUncontrolled initial state.
placementtop, bottom, left, right (with start/end variants).
offset / crossOffsetDistance from the trigger on the main and cross axes.
containerPaddingMinimum padding kept between the popover and the viewport edge.
shouldFlipWhether the popover may flip to the opposite side when there isn't enough space. Defaults to true.
shouldCloseOnInteractOutsideFunction receiving the interacted element; return false to keep the popover open.
aria-labelAccessible label for the dialog. Pass false to opt out when the popover already contains a label.