Popover

A floating card that appears next to a trigger element. Popovers use the same elevated surface treatment as floating cards and can contain interactive content such as menus, forms, or action lists.

Props

PopoverTrigger

PropTypeRequiredDescription
PopoverComponent(props: { close: () => void } & Input) => JSX.ElementYesComponent to render in the popover
children(props: { toggle: (input: Input) => void }) => JSX.ElementYesRender function for the trigger element
jssJSSNoCustom styles for the wrapper
jssDialogJSSNoCustom styles for the popover dialog
growbooleanNoAllow wrapper to grow
shrinkbooleanNoAllow wrapper to shrink
tagkeyof HTMLElementTagNameMapNoHTML tag for the wrapper

Popover

PropTypeRequiredDescription
childrenReactNodeYesPopover content
close() => voidYesFunction to close the popover

Basic usage

Use PopoverTrigger to create a button that opens a popover with interactive options:

<PopoverTrigger
  PopoverComponent={({ close }) => (
    <Popover close={close}>
      <List ariaLabel="Options">
        <ListButtonItem
          headline="Edit"
          onClick={() => close()}
          color="secondary"
        />
        <ListButtonItem
          headline="Duplicate"
          onClick={() => close()}
          color="secondary"
        />
        <ListButtonItem
          headline="Delete"
          onClick={() => close()}
          color="negative"
        />
      </List>
    </Popover>
  )}
>
  {({ toggle }) => (
    <Button color="primary" onClick={() => toggle(undefined)}>
      Show Options
    </Button>
  )}
</PopoverTrigger>

Passing data to popover

Use TypeScript generics to pass data when opening the popover:

interface Item {
  id: string;
  name: string;
}

<PopoverTrigger<Item>
  PopoverComponent={({ close, id, name }) => (
    <Popover close={close}>
      <Column padding="medium" gap="small">
        <P>Edit: {name}</P>
        <Button color="primary" onClick={() => {
          saveItem(id);
          close();
        }}>
          Save
        </Button>
      </Column>
    </Popover>
  )}
>
  {({ toggle }) => (
    <Button
      color="secondary"
      onClick={() => toggle({ id: "123", name: "My Item" })}
    >
      Edit Item
    </Button>
  )}
</PopoverTrigger>

Behavior

  • Toggle on click: Clicking the trigger opens/closes the popover
  • Focus management: Focus moves into the popover when opened
  • Focus trap: Tab cycles through focusable elements within the popover
  • Escape to close: Pressing Escape closes the popover
  • Outside click: Clicking outside closes the popover
  • Focus restoration: Focus returns to the trigger when closed

Common patterns

<PopoverTrigger
  PopoverComponent={({ close }) => (
    <Popover close={close}>
      <List ariaLabel="Menu">
        <ListButtonItem headline="Profile" onClick={() => close()} />
        <ListButtonItem headline="Settings" onClick={() => close()} />
        <ListButtonItem
          headline="Logout"
          onClick={() => close()}
          color="negative"
        />
      </List>
    </Popover>
  )}
>
  {({ toggle }) => (
    <IconButton
      bare
      icon="more-vertical"
      color="secondary"
      onClick={() => toggle(undefined)}
    />
  )}
</PopoverTrigger>

Action confirmation

<PopoverTrigger
  PopoverComponent={({ close }) => (
    <Popover close={close}>
      <Column padding="medium" gap="medium">
        <P>Are you sure you want to delete?</P>
        <Row gap="small" justify="end">
          <Button bare color="secondary" onClick={close}>
            Cancel
          </Button>
          <Button
            color="negative"
            onClick={() => {
              deleteItem();
              close();
            }}
          >
            Delete
          </Button>
        </Row>
      </Column>
    </Popover>
  )}
>
  {({ toggle }) => (
    <Button color="negative" onClick={() => toggle(undefined)}>
      Delete
    </Button>
  )}
</PopoverTrigger>

Accessibility

  • Uses <dialog> element with .show() for proper popover behavior
  • Focus is trapped within the popover
  • Escape key closes the popover
  • Focus returns to the trigger when closed
  • Tab navigation cycles through focusable elements

Popover vs Dialog vs Tooltip

PopoverDialogTooltip
Positioned near triggerCentered on screenPositioned near trigger
Light interactionsComplex workflowsText only
Partial page blockingFull page blockingNo blocking
Menus, quick actionsForms, confirmationsHints, labels