Skip to content

Popover

Displays supplementary information or content in a compact overlay without navigating away from the current page. Popovers provide contextual details or actions while maintaining focus on the primary interface.

Usage

Use popovers to show contextual help, tips, or additional options related to a specific element. Avoid using popovers as dropdowns and use the Menu component for selectable lists or navigation. The trigger should be clearly indicated.

API Reference

Component attribute(s)

x-h-popover
x-h-popover-trigger

Trigger and menu placement

The x-h-popover element must be placed somewhere AFTER the x-h-popover-trigger and they must have the same direct parent. Otherwise, the popover will not be able to find the trigger.

Attributes

x-h-popover-trigger

AttributeTypeRequiredDescription
selfbooleanfalseOptional boolean variable bound to the open state. On its own it stays in sync two-way: the popover still opens and closes automatically (toggle on trigger click, dismiss on outside click), and you can also show or hide it by setting the variable. Add your own @click handler on the trigger to take full manual control instead (see below).

x-h-popover

AttributeTypeRequiredDescription
data-alignbottom-start
bottom
bottom-end
right-start
right
right-end
left-start
left
left-end
top-start
top
top-end
falseAligns the popover body relative to the trigger.
data-innerclicksbooleanfalsePrevents the popover from closing when there is a click inside it.
This is not a dynamic attribute. Its value is read on initialization and it is not monitored for changes.
data-max-w3xs
2xs
xs
sm
md
lg
xl
2xl
3xl
4xl
5xl
6xl
7xl
8xl
9xl
10xl
falseSets the popover's maximum width to the matching container size (for example md sets max-width: var(--container-md)). The popover still sizes to its content. This only limits how wide it can get. Without it, the maximum is the width available in the viewport.

Modifiers

x-h-popover-trigger

ModifierDescription
chevronRotates the last icon inside the trigger at 180 degrees.

x-h-popover

ModifierDescription
no-scrollUsed when the popover body must not scroll.

Examples

Popover

html
<button x-h-button x-h-popover-trigger>Popover</button>
<div class="w-64 p-4" x-h-popover>Popover content</div>

Constrained width

The popover sizes to its content, up to a maximum width. That maximum defaults to the width available in the viewport. Set data-max-w to a container size to cap it smaller (here sm), so long content wraps instead of stretching the popover wider.

html
<button x-h-button x-h-popover-trigger>Popover</button>
<div class="p-4" x-h-popover data-max-w="sm">Long content wraps once the popover reaches the small container width instead of getting any wider.</div>

Disable closing on inner click events

html
<button x-h-button x-h-popover-trigger>Popover</button>
<div class="w-64 p-4" x-h-popover data-innerclicks="true">
  <button x-h-button data-variant="primary">Click</button>
</div>

Bind the open state (two-way)

Bind a variable to the trigger to read or control the open state while keeping the automatic behavior. The popover still toggles on click and dismisses on an outside click, and setting the variable elsewhere shows or hides it. This is useful to close the popover from a button inside it (for example a "confirm" action) while other inner controls leave it open.

html
<div x-data="{ open: false }">
  <button x-h-button x-h-popover-trigger="open">Popover</button>
  <div class="vbox w-64 gap-2 p-4" x-h-popover data-innerclicks="true">
    <span>Clicking confirm closes the popover.</span>
    <button x-h-button data-variant="primary" data-size="sm" @click="open = false">Confirm</button>
  </div>
</div>

Manually open and close the popover

Add your own @click handler on the trigger, alongside the bound variable, to take full manual control. The directive then leaves open/close entirely to you, so the automatic outside-click dismiss is disabled.

html
<div x-data="{ open: false }">
  <button x-h-button x-h-popover-trigger="open" @click="open = !open">Popover</button>
  <div class="w-64 p-4" x-h-popover>Popover content</div>
</div>

Chevron

In order to use the chevron modifier, the trigger label must be placed inside a nested element (usually a span).

html
<button x-h-button x-h-popover-trigger.chevron>
  <span>Popover</span>
  <svg x-h-lucide role="presentation" data-lucide="chevron-down"></svg>
</button>
<div class="p-4" x-h-popover>With chevron</div>

Alignment

html
<div class="flex flex-col" style="gap: 4rem">
  <div class="flex items-center justify-between gap-4">
    <button x-h-button x-h-popover-trigger>Bottom start</button>
    <div class="w-64 p-4" x-h-popover data-align="bottom-start">Bottom start content</div>
    <button x-h-button x-h-popover-trigger>Bottom</button>
    <div class="w-64 p-4" x-h-popover data-align="bottom">Bottom center content</div>
    <button x-h-button x-h-popover-trigger>Bottom end</button>
    <div class="w-64 p-4" x-h-popover data-align="bottom-end">Bottom end content</div>
  </div>
  <div class="flex items-center justify-between gap-4">
    <button x-h-button x-h-popover-trigger>Right start</button>
    <div class="w-64 p-4" x-h-popover data-align="right-start">Right start content</div>
    <button x-h-button x-h-popover-trigger>Left start</button>
    <div class="w-64 p-4" x-h-popover data-align="left-start">Left start content</div>
  </div>
  <div class="flex items-center justify-between gap-4">
    <button x-h-button x-h-popover-trigger>Right</button>
    <div class="w-64 p-4" x-h-popover data-align="right">Right center content</div>
    <button x-h-button x-h-popover-trigger>Left</button>
    <div class="w-64 p-4" x-h-popover data-align="left">Left center content</div>
  </div>
  <div class="flex items-center justify-between gap-4">
    <button x-h-button x-h-popover-trigger>Right end</button>
    <div class="w-64 p-4" x-h-popover data-align="right-end">Right end content</div>
    <button x-h-button x-h-popover-trigger>Left end</button>
    <div class="w-64 p-4" x-h-popover data-align="left-end">Left end content</div>
  </div>
  <div class="flex items-center justify-between gap-4">
    <button x-h-button x-h-popover-trigger>Top start</button>
    <div class="w-64 p-4" x-h-popover data-align="top-start">Top start content</div>
    <button x-h-button x-h-popover-trigger>Top</button>
    <div class="w-64 p-4" x-h-popover data-align="top">Top center content</div>
    <button x-h-button x-h-popover-trigger>Top end</button>
    <div class="w-64 p-4" x-h-popover data-align="top-end">Top end content</div>
  </div>
</div>