Popover
A floating content panel with configurable trigger, side, and alignment.
bun x bosia@latest add popoverA floating panel anchored to a trigger. Supports click (default) and hover modes. Dismisses on click-outside (click mode) and Escape.
Preview
Props
Popover
| Prop | Type | Default |
|---|---|---|
open |
boolean |
false |
trigger |
"click" | "hover" |
"click" |
closeDelay |
number |
150 |
class |
string |
"" |
PopoverContent
| Prop | Type | Default |
|---|---|---|
side |
"top" | "right" | "bottom" | "left" |
"bottom" |
align |
"start" | "center" | "end" |
"center" |
sideOffset |
number |
4 |
class |
string |
"" |
Sub-components
Popover— root wrapper, manages open statePopoverTrigger— button that toggles the popoverPopoverContent— the floating panel
Usage
<script lang="ts">
import { Popover, PopoverTrigger, PopoverContent } from "$lib/components/ui/popover";
import { Button } from "$lib/components/ui/button";
import { Label } from "$lib/components/ui/label";
import { Input } from "$lib/components/ui/input";
</script>
<Popover>
<PopoverTrigger>
<Button variant="outline">Open popover</Button>
</PopoverTrigger>
<PopoverContent>
<div class="grid gap-4">
<div class="space-y-1">
<h4 class="font-medium leading-none">Dimensions</h4>
<p class="text-sm text-muted-foreground">Set the dimensions for the layer.</p>
</div>
<div class="grid gap-2">
<div class="grid grid-cols-3 items-center gap-4">
<Label for="width">Width</Label>
<Input id="width" value="100%" class="col-span-2 h-8" />
</div>
</div>
</div>
</PopoverContent>
</Popover>Positioning
Use side and align to place the content relative to the trigger.
<!-- Above, aligned to the start -->
<PopoverContent side="top" align="start">...</PopoverContent>
<!-- To the right, centered -->
<PopoverContent side="right">...</PopoverContent>
<!-- Below, aligned to the end with extra offset -->
<PopoverContent side="bottom" align="end" sideOffset={8}>...</PopoverContent>Hover Trigger
Set trigger="hover" to open the popover on mouse enter. The popover stays open while the cursor is over the trigger or content. On touch devices, hover mode degrades to tap-to-toggle. Adjust closeDelay (ms) to control the delay before closing.
<Popover trigger="hover" closeDelay={200}>
<PopoverTrigger>
<Button variant="outline">Hover me</Button>
</PopoverTrigger>
<PopoverContent>Tooltip-style content</PopoverContent>
</Popover>Controlled Open State
<script lang="ts">
let open = $state(false);
</script>
<Popover bind:open>
<PopoverTrigger>
<Button variant="outline">Toggle</Button>
</PopoverTrigger>
<PopoverContent>Content</PopoverContent>
</Popover>
<p>Popover is {open ? "open" : "closed"}</p>