To source

a-popover

A floating element that positions itself relative to a trigger, using Floating UI for smart placement.

The a-popover element creates floating content that positions itself intelligently relative to a trigger element. It uses Floating UI for positioning and includes built-in support for focus management, click-outside detection, and smooth transitions.

Popover Content

Click outside to close

Used by the Popover, Dropdown, and Combobox components.

Usage

Basic Popover

The popover system consists of two elements: a-popover-trigger (the wrapper) and a-popover (the floating content).

<a-popover-trigger>
  <button slot="trigger" type="button">
    Open Menu
  </button>

  <a-popover>
    <div class="popover-content">
      <p>Popover content here</p>
    </div>
  </a-popover>
</a-popover-trigger>

Controlling Placement

Use the placements attribute to specify allowed positions. The popover will automatically choose the best available placement:

<!-- Prefer bottom, fall back to top -->
<a-popover placements="bottom,top">
  <div>Content</div>
</a-popover>

<!-- Prefer bottom-start with alignment -->
<a-popover placements="bottom-start,bottom-end,top-start,top-end" alignment="start">
  <div>Content</div>
</a-popover>

Available placements:

  • top, top-start, top-end
  • bottom, bottom-start, bottom-end
  • left, right

With Arrow Indicator

Add a <a-popover-arrow> element to show a pointing arrow:

<a-popover placements="bottom,top">
  <div class="popover-content">
    <a-popover-arrow>
      <div class="arrow"></div>
    </a-popover-arrow>
    <p>Content with arrow</p>
  </div>
</a-popover>

Style the arrow based on placement:

.arrow {
  width: 10px;
  height: 10px;
  background: white;
  transform: rotate(45deg);
}

[data-placement="top"] .arrow {
  box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.1);
}

[data-placement="bottom"] .arrow {
  box-shadow: -2px -2px 2px rgba(0, 0, 0, 0.1);
}

Tooltips

For hover-based tooltips, use a-tooltip instead of a-popover. Tooltips are non-modal and don't trap focus:

<a-popover-trigger showdelay="300" hidedelay="100">
  <button slot="trigger" type="button">
    Hover me
  </button>

  <a-tooltip>
    <div class="tooltip">
      Helpful tooltip text
    </div>
  </a-tooltip>
</a-popover-trigger>

Programmatic Control

Show and Hide

const trigger = document.querySelector('a-popover-trigger');

// Show the popover
trigger.show();

// Hide the popover
trigger.hide();

// Toggle visibility
trigger.toggle();

Listening to Events

const trigger = document.querySelector('a-popover-trigger');

trigger.addEventListener('show', () => {
  console.log('Popover opened');
});

trigger.addEventListener('hide', () => {
  console.log('Popover closed');
});

Checking State

const trigger = document.querySelector('a-popover-trigger');

if (trigger.opened) {
  console.log('Popover is visible');
}

Styling

Transition Animations

The popover content can be animated using CSS transitions. The enabled attribute on the portal indicates visibility:

/* Popover content styling */
a-popover > div {
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 0.15s ease, transform 0.15s ease;
}

[enabled] a-popover > div {
  opacity: 1;
  transform: translateY(0);
}

Placement-Based Styling

The data-placement attribute is set on the content element, allowing placement-specific styles:

[data-placement="top"] {
  transform-origin: bottom center;
}

[data-placement="bottom"] {
  transform-origin: top center;
}

[data-placement^="top"] .popover-content {
  margin-bottom: 8px;
}

[data-placement^="bottom"] .popover-content {
  margin-top: 8px;
}

Full Styled Example

<style>
  .popover-content {
    background: white;
    width: max-content;
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    padding: 12px 16px;
    box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
    min-width: 200px;
  }
</style>

<a-popover-trigger>
  <button slot="trigger">Open</button>
  <a-popover>
    <div class="popover-content">
      <h3>Title</h3>
      <p>Description text</p>
    </div>
  </a-popover>
</a-popover-trigger>

Title

Description text

Accessibility

  • Focus Management: When opened focus moves into the popover. When closed, focus returns to the trigger.
  • ARIA Attributes: The trigger automatically sets aria-haspopup="dialog" and aria-expanded.
  • Escape Key: Pressing Escape closes the popover.
  • Click Outside: Clicking outside the popover closes it.
  • Keyboard Navigation: Tab key cycles through focusable elements inside the popover.

Popover

A popover element. It positions itself relative to the trigger element using Floating UI, a-portal and a-blur for focus management.

Example


<a-popover>
  <div>Content</div>
</a-popover>

Methods


Popover.hide()

src/Popover.ts:236

Hide the popover.

Popover.show()

src/Popover.ts:160

Show the popover.

PopoverTrigger

A wrapper element that controls the visibility of a popover. Either using hover/contextmenu or click on a trigger. Calls

on the target when the trigger is clicked. Calls

on the target when the trigger is clicked outside of the popover.

TODO: Generalized a-trigger. So it can be used for lightbox and other overlays.

Example


<a-popover-trigger>
  <button type="button" slot="trigger">
    Label
  </button>

  <a-popover>
    <div>Content</div>
  </a-popover>
</a-popover-trigger>

Attributes


Name Type Default value Description
hidedelay number 250

The time in milliseconds to wait before hiding the popover.

opened boolean false

Wether the content is shown or not.

showdelay number 550

The time in milliseconds to wait before showing the popover.

Events


Name Description
show

Fired when the popover is shown.

hide

Fired when the popover is hidden.

Methods


PopoverTrigger.hide()

src/Popover.ts:607

Closes the inner popover.

PopoverTrigger.show()

src/Popover.ts:583

Show the inner popover.

PopoverTrigger.toggle()

src/Popover.ts:626

Toggles the inner popover.

References