Skip to main content

Overview

The Popover component displays floating content anchored to a trigger element. Supports both click and hover modes with flexible positioning options.

Basic Usage

<template>
  <UPopover>
    <template #default="{ open }">
      <UButton>{{ open ? 'Close' : 'Open' }} Popover</UButton>
    </template>
    <template #content>
      <div class="p-4">
        <p>Popover content goes here</p>
      </div>
    </template>
  </UPopover>
</template>

Props

mode
'click' | 'hover'
default:"'click'"
The display mode of the popover. Use 'hover' for hover cards.
content
PopoverContentProps
Configuration object for popover content positioning and behavior.
arrow
boolean | PopoverArrowProps
default:"false"
Display an arrow pointing to the trigger element.
portal
boolean | string | HTMLElement
default:"true"
Render the popover in a portal.
reference
HTMLElement
The reference (or anchor) element for positioning. If not provided, uses the trigger element.
dismissible
boolean
default:"true"
When false, the popover will not close when clicking outside or pressing escape.
open
boolean
Controls the open state of the popover (v-model:open).
defaultOpen
boolean
The default open state when uncontrolled.
modal
boolean
The modality of the popover (only for click mode).
openDelay
number
default:"0"
Delay in milliseconds before opening (for hover mode).
closeDelay
number
default:"0"
Delay in milliseconds before closing (for hover mode).
class
any
CSS class for styling the trigger element.
ui
object
Theme customization object for component slots.

Events

update:open
(open: boolean) => void
Emitted when the open state changes.
close:prevent
() => void
Emitted when a close attempt is prevented (when dismissible is false).

Slots

default
{ open: boolean }
The trigger element for the popover. Receives the current open state.
content
{ close?: () => void }
The content displayed inside the popover. In click mode, receives a close function.
anchor
{ close?: () => void }
Optional anchor element for positioning (when different from trigger).

Examples

Hover Mode (Hover Card)

<template>
  <UPopover mode="hover" :open-delay="200" :close-delay="100">
    <template #default>
      <span>Hover over me</span>
    </template>
    <template #content>
      <div class="p-4">
        <p>This appears on hover</p>
      </div>
    </template>
  </UPopover>
</template>

With Arrow

<template>
  <UPopover :arrow="true">
    <template #default>
      <UButton>Open Popover</UButton>
    </template>
    <template #content>
      <div class="p-4">
        <p>Popover with arrow pointer</p>
      </div>
    </template>
  </UPopover>
</template>

Different Positions

<template>
  <UPopover :content="{ side: 'top', sideOffset: 12 }">
    <template #default>
      <UButton>Open Above</UButton>
    </template>
    <template #content>
      <div class="p-4">
        <p>This opens above the trigger</p>
      </div>
    </template>
  </UPopover>
</template>

With Custom Reference Element

<template>
  <div>
    <div ref="anchorRef" class="p-4 border">
      Anchor Element
    </div>
    <UPopover :reference="anchorRef">
      <template #default>
        <UButton>Open at Anchor</UButton>
      </template>
      <template #content>
        <div class="p-4">
          <p>Positioned relative to anchor</p>
        </div>
      </template>
    </UPopover>
  </div>
</template>

<script setup>
const anchorRef = ref(null)
</script>

Non-dismissible Popover

<template>
  <UPopover :dismissible="false">
    <template #default>
      <UButton>Open Popover</UButton>
    </template>
    <template #content="{ close }">
      <div class="p-4">
        <p>You must close this explicitly</p>
        <UButton @click="close" size="sm">Close</UButton>
      </div>
    </template>
  </UPopover>
</template>

Rich Content Popover

<template>
  <UPopover :content="{ side: 'right', align: 'start' }">
    <template #default>
      <UButton>User Info</UButton>
    </template>
    <template #content>
      <div class="p-4 space-y-2 max-w-sm">
        <div class="flex items-center gap-2">
          <UAvatar src="/avatar.jpg" />
          <div>
            <p class="font-semibold">John Doe</p>
            <p class="text-sm text-muted">[email protected]</p>
          </div>
        </div>
        <p class="text-sm">Software developer with 5 years of experience.</p>
        <UButton size="sm" block>View Profile</UButton>
      </div>
    </template>
  </UPopover>
</template>

Content Props

The content prop accepts the following positioning options:
  • side: 'top' | 'right' | 'bottom' | 'left' - Which side to position the popover
  • sideOffset: number - Distance in pixels from the trigger
  • align: 'start' | 'center' | 'end' - Alignment along the side
  • alignOffset: number - Offset along the alignment axis
  • collisionPadding: number | Partial<Record<'top' | 'right' | 'bottom' | 'left', number>> - Padding from viewport edges
  • avoidCollisions: boolean - Whether to adjust position to avoid collisions
  • sticky: 'partial' | 'always' - Sticky behavior during scrolling

Build docs developers (and LLMs) love