Components / Overlays

Popover

A non-modal panel for a few interactive controls.

Preview

Use cases

Inline settings

Show a few controls beside their trigger without blocking the rest of the page.

Small form

Collect a short value and close after the action completes.

Usage example

Vue
<script setup lang="ts">
import Popover from './components/ui/popover/Popover.vue'
import PopoverTrigger from './components/ui/popover/PopoverTrigger.vue'
import PopoverContent from './components/ui/popover/PopoverContent.vue'
import Button from './components/ui/button/Button.vue'
import Input from './components/ui/input/Input.vue'
import Label from './components/ui/label/Label.vue'
</script>

<template>
  <Popover :width="360">
    <PopoverTrigger>Share project</PopoverTrigger>
    <PopoverContent aria-label="Share project">
      <template #default="{ close }">
        <div class="space-y-4">
          <div>
            <p class="font-semibold">Share “Orbit mobile app”</p>
            <p class="text-sm text-muted-foreground">Invite collaborators to view and comment.</p>
          </div>
          <div class="space-y-2">
            <Label for="invite-email">Invite by email</Label>
            <div class="flex gap-2">
              <Input id="invite-email" type="email" placeholder="name@company.com" />
              <Button>Invite</Button>
            </div>
          </div>
          <Button class="w-full" variant="outline" @click="close">Done</Button>
        </div>
      </template>
    </PopoverContent>
  </Popover>
</template>

More examples

View preferences

The content slot provides a close function.

View preferences
<script setup lang="ts">
import { ref } from 'vue'
import Popover from './components/ui/popover/Popover.vue'
import PopoverTrigger from './components/ui/popover/PopoverTrigger.vue'
import PopoverContent from './components/ui/popover/PopoverContent.vue'
const compact = ref(false)
</script>
<template>
  <Popover>
    <PopoverTrigger>View options</PopoverTrigger>
    <PopoverContent aria-label="View options">
      <template #default="{ close }">
        <label><input v-model="compact" type="checkbox" /> Compact rows</label>
        <button type="button" @click="close()">Done</button>
      </template>
    </PopoverContent>
  </Popover>
</template>

Controlled details

The parent can open or close a popover through v-model:open.

Controlled details
<script setup lang="ts">
import { ref } from 'vue'
import Popover from './components/ui/popover/Popover.vue'
import PopoverTrigger from './components/ui/popover/PopoverTrigger.vue'
import PopoverContent from './components/ui/popover/PopoverContent.vue'
const open = ref(false)
</script>
<template>
  <Popover v-model:open="open" side="top" align="end">
    <PopoverTrigger>Project details</PopoverTrigger>
    <PopoverContent aria-label="Project details"><p>Last edited today.</p></PopoverContent>
  </Popover>
</template>

Key API

The most useful props, models, slots, events, and methods for this component.

Key API for Popover
NameTypeDefault or requirement
PopoverContent aria-labelstringrequired for unnamed content
v-model:openbooleanfalse
width / gapnumber, px320 / 8
align / sidestart | center | end / top | bottomstart / bottom

Compose trigger and content directly. The trigger has visible hover, focus, and open states. Escape closes and restores trigger focus.

Implementation notes

  • Popover is non-modal; background controls remain available.
  • Its panel remains in the local subtree, so avoid clipped or transformed ancestors.

Accessibility and localization

  • Name PopoverContent with aria-label or another suitable relationship.
  • Escape closes and returns focus to the trigger; outside interaction closes without stealing focus.
Weini UIDesign system · Vue component library · Free and public