Skip to content

Popover ​

Use bo-popover for short interactive content that should remain associated with a trigger. Unlike a dialog, it is positioned beside the trigger and does not lock page scrolling. Unlike a dropdown, its content can contain arbitrary layout and controls.

Basic Usage ​

Use bo-popover-trigger in the root trigger slot and bo-popover-content in the default slot. The root owns the open state and positioning context.

<bo-popover v-model:open="open">
  <template #trigger>
    <bo-popover-trigger>Show details</bo-popover-trigger>
  </template>
  <bo-popover-content>
    <p class="max-w-xs">Content is positioned against the trigger.</p>
  </bo-popover-content>
</bo-popover>

Trigger and Content ​

bo-popover-trigger renders a button and toggles the root state. bo-popover-content teleports its surface to body, adds the configured role, and includes a decorative arrow. Put forms, links, or other interactive content inside the content slot as needed.

Placement and Offset ​

The root supports twelve placements: top, top-start, top-end, bottom, bottom-start, bottom-end, left, left-start, left-end, right, right-start, and right-end. offset is the gap from the trigger in pixels. Content can override placement or offset for one surface.

<bo-popover placement="top-start" :offset="12">
  <template #trigger>
    <bo-popover-trigger>Top start</bo-popover-trigger>
  </template>
  <bo-popover-content>Additional actions</bo-popover-content>
</bo-popover>

Scroll Anchoring ​

Popover content is positioned against the trigger and recalculated after opening, on resize, and while the window or an ancestor scrolls. This keeps teleported content anchored to a moving trigger.

<div class="h-48 overflow-y-auto">
  <div class="h-64 pt-40">
    <bo-popover v-model:open="scrollOpen">
      <template #trigger>
        <bo-popover-trigger>Scroll around this trigger</bo-popover-trigger>
      </template>
      <bo-popover-content>
        <p>The content follows the trigger while its scroll container moves.</p>
      </bo-popover-content>
    </bo-popover>
  </div>
</div>

Nested Content ​

A popover can contain another popover. Give nested content an explicit placement when the default position would overlap the parent surface, and keep nested actions short.

<bo-popover v-model:open="parentOpen">
  <template #trigger>
    <bo-popover-trigger>Open parent</bo-popover-trigger>
  </template>
  <bo-popover-content>
    <p>Parent content</p>
    <bo-popover v-model:open="childOpen" placement="right-start">
      <template #trigger>
        <bo-popover-trigger>Open nested content</bo-popover-trigger>
      </template>
      <bo-popover-content>Nested content</bo-popover-content>
    </bo-popover>
  </bo-popover-content>
</bo-popover>

Closing Behavior ​

Outside pointer interaction and Escape close the popover by default. Set closeOnOutside or closeOnEscape to false when the surrounding interaction requires the surface to stay open. The root emits update:open through v-model:open.

Usage Guidance ​

  • Keep popover content brief enough to scan without leaving the current context.
  • Use a dialog for a blocking workflow and a dropdown for a command list.
  • Provide a clear trigger label and ensure interactive content remains keyboard reachable.
  • Use role="dialog" for general content and choose a more specific role only when the content semantics require it.

API Reference ​

BoPopover Props ​

PropTypeDefaultDescription
idstringAutogeneratedThe popover root id.
dataTestIdstringAutogeneratedThe test id attribute.
openbooleanfalseVisibility state used by v-model:open.
placementBoPopoverPlacementbottomPosition relative to the trigger.
offsetnumber8Gap from the trigger in pixels.
closeOnOutsidebooleantrueCloses after a pointer interaction outside.
closeOnEscapebooleantrueCloses when Escape is pressed.
roleHTMLAttributes['role']dialogRole applied to the content surface.

BoPopover Events and Slots ​

NameTypeDescription
update:openbooleanEmitted when visibility changes.
triggerslotUsually a BoPopoverTrigger component.
defaultslotUsually a BoPopoverContent component.

BoPopoverTrigger ​

NameTypeDescription
defaultslotButton content. All native attributes are forwarded.

BoPopoverContent Props and Slots ​

PropTypeDefaultDescription
idstringgeneratedContent id and the trigger's aria-controls.
dataTestIdstringAutogeneratedThe test id attribute.
placementBoPopoverPlacementinheritedContent-level placement override.
offsetnumberinheritedContent-level offset override.
roleHTMLAttributes['role']dialogRole applied to the content surface.
defaultslot-Popover content.

Released under the MIT License.