Popover
The popover floats a panel next to its trigger for rich content like forms and settings, and closes when the user clicks away. For a simple text hint, reach for the tooltip; for a menu of actions, use the dropdown.
<button id="popover-demo-trigger" class="btn btn-outline">Open popover</button>
<div class="popover w-80" data-sp-toggle="#popover-demo-trigger">
<div class="popover-header">
<h4 class="popover-title">Dimensions</h4>
<p class="popover-description">Set the dimensions for the layer.</p>
</div>
<div class="grid gap-2">
<div class="grid grid-cols-3 items-center gap-4">
<label class="label" for="popover-width">Width</label>
<input class="input col-span-2 h-8" id="popover-width" value="100%" />
</div>
<div class="grid grid-cols-3 items-center gap-4">
<label class="label" for="popover-max-width">Max. width</label>
<input
class="input col-span-2 h-8"
id="popover-max-width"
value="300px"
/>
</div>
<div class="grid grid-cols-3 items-center gap-4">
<label class="label" for="popover-height">Height</label>
<input class="input col-span-2 h-8" id="popover-height" value="25px" />
</div>
<div class="grid grid-cols-3 items-center gap-4">
<label class="label" for="popover-max-height">Max. height</label>
<input
class="input col-span-2 h-8"
id="popover-max-height"
value="none"
/>
</div>
</div>
</div>Usage
Add the popover class to the panel and point it at its trigger with data-sp-toggle. It opens on click, positions itself relative to the trigger, and closes on an outside click or Escape.
<!-- This is the trigger -->
<button id="my-trigger" class="btn btn-outline">Open Popover</button>
<!-- This is the popover -->
<div class="popover" data-sp-toggle="#my-trigger">Popover content</div>Examples
Basic
A simple popover with a header, title, and description.
Placement
Set where the panel opens relative to its trigger with data-sp-placement. It accepts any Floating UI placement, like top, right, or bottom-end, and the panel flips to the opposite side on its own when there isn't room.
<div class="flex gap-6">
<button id="popover-start-trigger" class="btn btn-outline btn-sm">
Start
</button>
<button id="popover-center-trigger" class="btn btn-outline btn-sm">
Center
</button>
<button id="popover-end-trigger" class="btn btn-outline btn-sm">End</button>
</div>
<div
class="popover w-40"
data-sp-toggle="#popover-start-trigger"
data-sp-placement="bottom-start"
>
Aligned to start
</div>
<div
class="popover w-40"
data-sp-toggle="#popover-center-trigger"
data-sp-placement="bottom"
>
Aligned to center
</div>
<div
class="popover w-40"
data-sp-toggle="#popover-end-trigger"
data-sp-placement="bottom-end"
>
Aligned to end
</div>With form
A popover holding a compact form, laid out with horizontal fields.
<button id="popover-form-trigger" class="btn btn-outline">Open Popover</button>
<div class="popover w-64" data-sp-toggle="#popover-form-trigger">
<div class="popover-header">
<h4 class="popover-title">Dimensions</h4>
<p class="popover-description">Set the dimensions for the layer.</p>
</div>
<div class="field-group gap-4">
<div class="field field-horizontal">
<label class="label w-1/2" for="popover-form-width">Width</label>
<input class="input" id="popover-form-width" value="100%" />
</div>
<div class="field field-horizontal">
<label class="label w-1/2" for="popover-form-height">Height</label>
<input class="input" id="popover-form-height" value="25px" />
</div>
</div>
</div>Hover
Add data-sp-mode="hover" to open on hover instead of click.
<button id="popover-hover-trigger" class="btn btn-outline">Hover me</button>
<div
class="popover"
data-sp-toggle="#popover-hover-trigger"
data-sp-mode="hover"
>
<div class="popover-header">
<h4 class="popover-title">Quick preview</h4>
<p class="popover-description">This popover opens on hover.</p>
</div>
</div>Options
Popover
Set each option with its own data-sp-* attribute on the popover element.
<div
class="popover"
data-sp-toggle="#my-trigger"
data-sp-placement="bottom-start"
></div>With data-sp-static the popover skips anchored positioning entirely and you position it yourself with utility classes. The toggle wiring, dismissal, and top layer behavior stay. Use it for panels that are viewport-relative instead of trigger-relative, like a full-screen mobile menu:
<div
class="popover inset-x-0 top-14 bottom-0 h-auto w-auto rounded-none"
data-sp-toggle="#menu-trigger"
data-sp-static
>
...
</div>JavaScript
Events
Lifecycle events fire on the popover element; before* events are cancelable.
el.addEventListener("sp-beforeshow", (e) => {
if (!ready) e.preventDefault(); // veto the open
});Methods
Get the instance with sp.popover(el), then call its methods:
const popover = sp.popover(document.querySelector("#my-popover"));
popover.show();