Skip to main content

Popover

Popover is an overlay that shows content beside a trigger, such as display settings, filters, or quick actions.

Import

import { Popover } from '@vortexlabs/vortex';
import type { PopoverProps } from '@vortexlabs/vortex';

Allied components

Other links

"use client";

import { Button, Popover } from "@vortexlabs/vortex";

export const PopoverExample = () => (
  <Popover>
    <Popover.Trigger>
      {(attributes) => <Button attributes={attributes}>Open popover</Button>}
    </Popover.Trigger>
    <Popover.Content attributes={{ "aria-label": "Example popover" }}>
      Popover content
    </Popover.Content>
  </Popover>
);

Features

  • Opens on click, hover, or focus.
  • Supports text, controls, and actions.
  • Adjusts placement when space is limited.
  • Can match the trigger width.

Anatomy

<Popover>
  <Popover.Trigger>
    {(attributes) => <Button attributes={attributes}>Open popover</Button>}
  </Popover.Trigger>
  <Popover.Content />
</Popover>
Component Part
Description
Controls visibility and placement.
Connects a trigger to the panel.
Displays the panel content.

Position

Set position to choose a side and alignment; start and end follow text direction.

"use client";

import { Button, Popover, Stack } from "@vortexlabs/vortex";

export const PopoverPositionExample = () => (
  <Stack direction="row" gap={2}>
    {(
      ["top-center", "bottom-center", "start-center", "end-center"] as const
    ).map((position) => (
      <Popover key={position} position={position}>
        <Popover.Trigger>
          {(attributes) => <Button attributes={attributes}>{position}</Button>}
        </Popover.Trigger>
        <Popover.Content>Popover content</Popover.Content>
      </Popover>
    ))}
  </Stack>
);

Padding

The default is md. Use none when the content supplies its own spacing.

"use client";

import { Button, Popover, Stack } from "@vortexlabs/vortex";

export const PopoverPaddingExample = () => (
  <Stack direction="row" gap={2}>
    {(["none", "xs", "sm", "md", "lg", "xl"] as const).map((padding) => (
      <Popover key={padding} padding={padding}>
        <Popover.Trigger>
          {(attributes) => <Button attributes={attributes}>{padding}</Button>}
        </Popover.Trigger>
        <Popover.Content>{`Content with padding “${padding}”.`}</Popover.Content>
      </Popover>
    ))}
  </Stack>
);

Width

Set width="trigger" to match the trigger width.

"use client";

import { Button, Popover } from "@vortexlabs/vortex";

export const PopoverWidthExample = () => (
  <Popover position="bottom-start" width="trigger">
    <Popover.Trigger>
      {(attributes) => (
        <Button attributes={attributes}>Wide trigger button label</Button>
      )}
    </Popover.Trigger>
    <Popover.Content>Popover content</Popover.Content>
  </Popover>
);

Triggers

Set triggerType to open on click, hover, or focus; hover also opens on keyboard focus.

"use client";

import { Button, Popover, Stack } from "@vortexlabs/vortex";

export const PopoverTriggerExample = () => (
  <Stack direction="row" gap={2}>
    <Popover triggerType="click">
      <Popover.Trigger>
        {(attributes) => <Button attributes={attributes}>Click</Button>}
      </Popover.Trigger>
      <Popover.Content>Popover content</Popover.Content>
    </Popover>
    <Popover triggerType="hover">
      <Popover.Trigger>
        {(attributes) => <Button attributes={attributes}>Hover</Button>}
      </Popover.Trigger>
      <Popover.Content>Popover content</Popover.Content>
    </Popover>
    <Popover triggerType="focus">
      <Popover.Trigger>
        {(attributes) => <Button attributes={attributes}>Focus me</Button>}
      </Popover.Trigger>
      <Popover.Content>Popover content</Popover.Content>
    </Popover>
  </Stack>
);

Initial Focus

Set autoFocus={false} to focus the panel instead of its first control.

"use client";

import { Button, Popover, Stack } from "@vortexlabs/vortex";

export const PopoverFocusExample = () => (
  <Stack direction="row" gap={2}>
    {([true, false] as const).map((autoFocus) => (
      <Popover key={String(autoFocus)} autoFocus={autoFocus}>
        <Popover.Trigger>
          {(attributes) => (
            <Button attributes={attributes}>
              {autoFocus
                ? "Focus first control"
                : "Focus panel"}
            </Button>
          )}
        </Popover.Trigger>
        <Popover.Content>
          <Stack gap={3}>
            <p>Popover content</p>
            <Button size="sm">Inner action</Button>
          </Stack>
        </Popover.Content>
      </Popover>
    ))}
  </Stack>
);

Use Tooltip for brief supporting text.

Accessibility

Key
Description
TabShiftTab
Moves within the panel; hover-triggered panels let focus leave.
EnterSpace
Toggles a click-triggered popover from its button.
Escape
Requests dismissal; update active in controlled mode.
Set aria-label in Popover.Content.attributes when the trigger label does not describe the panel.