Popover
<ahi-popover> | AhiPopover
Popovers display rich, interactive content in a floating panel anchored to a trigger. Unlike tooltips, they can contain links, buttons, and form controls; unlike dropdowns, they are meant for arbitrary content rather than menus.
Popovers display rich, interactive content in a floating panel anchored to a trigger. Unlike tooltips, popovers can contain links, buttons, and form controls; unlike dropdowns, they’re meant for arbitrary content rather than menus.
Provide the trigger through the anchor slot and the content through the default slot.
Activating the trigger toggles the popover, and it closes when you click outside or press Escape.
The popover sets aria-haspopup="dialog" and aria-expanded on its trigger as soon
as it has rendered, and updates aria-expanded as it opens and closes, so screen readers
announce that it opens a dialog and whether it is open. That includes a popover that starts open, a trigger
that is a disabled button, and a popover inside something that isn’t shown yet or is inert, such as a closed
dialog, an inactive tab panel or an inert container. An <ahi-button> or
<ahi-icon-button> passes them to the button it renders.
How the popover picks its trigger:
-
It uses the first element in the
anchorslot that is or contains something you can tab to. -
If none does, it also counts disabled elements, then hidden or inert ones, then both, and takes the first
match. Among hidden or inert ones, an element that isn’t
display: noneon its own comes first, so inside a closed dialog or an inactive tab panel the trigger that will be shown wins over one that only some screen sizes show. -
It picks again when the slot changes, once the elements in it first render or are defined, when the
popover is added back to the page, and each time
openchanges. It doesn’t pick again when an element is shown, enabled or made interactive, or gains content inside an element already in the slot, so the element it picked keeps the state until then, even if a later one is the one that ends up shown. -
Each pick sets
aria-haspopupandaria-expandedagain. If an element stops being the trigger while the popover is on the page, it gets back the values it had before, except any you changed on it after the popover last set them.
Popovers can contain interactive content such as links and buttons.
<ahi-popover>
<ahi-button slot="anchor">Toggle popover</ahi-button>
<div style="max-width: 20rem;">
<strong>Popover title</strong>
<p style="margin: var(--ahi-space-2) 0 0;">
Popovers can contain interactive content such as <a class="ahi-link" href="#">links</a> and buttons.
</p>
</div>
</ahi-popover>
Popovers render in the browser’s native top layer, so they’re never clipped by containers with
overflow: auto|hidden|scroll — no hoisting required.
Examples
Placement
Use the placement attribute to set the preferred position. The popover will automatically flip
and shift to stay in view.
<ahi-popover placement="right">
<ahi-button slot="anchor">Right</ahi-button>
<div>This popover prefers the right side.</div>
</ahi-popover>
Distance & skidding
Use distance to change the gap between the popover and its anchor, and skidding to
offset it along the anchor.
<ahi-popover distance="16" skidding="0">
<ahi-button slot="anchor">Farther away</ahi-button>
<div>This popover sits 16px from the anchor.</div>
</ahi-popover>
Without an arrow
Add the without-arrow attribute to remove the arrow.
<ahi-popover without-arrow>
<ahi-button slot="anchor">No arrow</ahi-button>
<div>This popover has no arrow.</div>
</ahi-popover>
Interactive content
Popovers are designed for interactive content such as forms. Add data-popover="close" to any
element inside the popover to make it close the popover when activated.
<ahi-popover label="Rename">
<ahi-button slot="anchor">Rename item</ahi-button>
<form style="display: flex; flex-direction: column; gap: var(--ahi-space-3); min-width: 16rem;">
<ahi-input label="New name" value="Untitled"></ahi-input>
<div style="display: flex; gap: var(--ahi-space-2); justify-content: flex-end;">
<ahi-button size="small" data-popover="close">Cancel</ahi-button>
<ahi-button size="small" variant="primary" data-popover="close">Save</ahi-button>
</div>
</form>
</ahi-popover>
Keeping the popover open or closed
The ahi-show and ahi-hide events can be cancelled. Call
event.preventDefault() in an ahi-show listener to keep the popover closed, or in
an ahi-hide listener to keep it open. The popover’s open property and its
trigger’s aria-expanded then stay as they were. Both events bubble, so check
event.target when the popover holds a component that emits its own, such as a dropdown.
<ahi-popover label="Pinned note" class="popover-keep-open">
<ahi-button slot="anchor">Pinned note</ahi-button>
<ahi-checkbox checked>Keep this open</ahi-checkbox>
</ahi-popover>
<script>
const popover = document.querySelector('.popover-keep-open');
const keepOpen = popover.querySelector('ahi-checkbox');
// Keep the popover open while the box is checked
popover.addEventListener('ahi-hide', event => {
if (event.target === popover && keepOpen.checked) {
event.preventDefault();
}
});
</script>
Setting a maximum width
Use the --max-width custom property to constrain the body’s width.
<ahi-popover style="--max-width: 15rem;">
<ahi-button slot="anchor">Narrow</ahi-button>
<div>This popover's body is capped at 15rem, so longer content wraps sooner.</div>
</ahi-popover>
Importing
To import this component using a script tag:
<script type="module" src="/path/to/azalea-kit-ui/dist/components/popover/popover.js"></script>
To import this component using a bundler:
import '@azaleahealth/azalea-kit-ui/dist/components/popover/popover.js';
Slots
| Name | Description |
|---|---|
| (default) | The popover’s content. Interactive elements such as buttons, links, and form controls are supported. |
anchor
|
The element the popover is anchored to, usually an <ahi-button>. Activating it
toggles the popover.
|
Learn more about using slots.
Properties
| Name | Description | Type | Default | |
|---|---|---|---|---|
containingElement
|
The popover will close when the user interacts outside of this element (e.g. clicking). Useful for composing other components that use a popover internally. |
HTMLElement | undefined
|
- | |
disabled
|
Disables the popover so it will not open. |
boolean
|
false
|
|
distance
|
The distance in pixels from which to offset the panel away from its anchor. |
number
|
8
|
|
label
|
An accessible label for the popover. This is applied to the panel’s dialog role so
assistive technology can announce the popover. If the content includes its own heading, you may
prefer to label it there instead.
|
string
|
''
|
|
open
|
Indicates whether or not the popover is open. You can toggle this attribute to show and hide the
popover, or you can use the show() and hide() methods and this attribute
will reflect the popover’s open state.
|
boolean
|
false
|
|
placement
|
The preferred placement of the popover. Note that the actual placement may vary as needed to keep the panel inside of the viewport. |
'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'right' |
'right-start' | 'right-end' | 'left' | 'left-start' | 'left-end'
|
'top'
|
|
skidding
|
The distance in pixels from which to offset the panel along its anchor. |
number
|
0
|
|
withoutArrow
without-arrow
|
Removes the arrow from the popover. |
boolean
|
false
|
|
updateComplete |
A read-only promise that resolves when the component has finished updating. |
Learn more about properties and attributes.
Events
| Name | Description | Event Detail |
|---|---|---|
ahi-show |
Emitted when the popover opens. Call event.preventDefault() to keep the popover from
opening.
|
- |
ahi-after-show |
Emitted after the popover opens and all animations are complete. | - |
ahi-hide |
Emitted when the popover closes. Call event.preventDefault() to keep the popover from
closing.
|
- |
ahi-after-hide |
Emitted after the popover closes and all animations are complete. | - |
Learn more about events.
Methods
| Name | Description | Arguments |
|---|---|---|
show() |
Shows the popover. | - |
hide() |
Hides the popover. | - |
reposition() |
Instructs the popover to reposition. Useful when the position or size of the anchor changes while the popover is open. | - |
Learn more about methods.
Custom Properties
| Name | Description | Default |
|---|---|---|
--max-width |
The maximum width of the popover’s body. | 25rem |
--arrow-size |
The size of the arrow. Set to 0 to remove it (or use the
without-arrow attribute).
|
6px |
Learn more about customizing CSS custom properties.
CSS Parts
| Name | Description |
|---|---|
base |
Deprecated. Use the popover part instead. |
popover |
The component’s outer wrapper. |
base__popup |
The popup’s exported popup part. Use this to target the popover’s popup container.
|
base__arrow |
The popup’s exported arrow part. |
anchor |
The container that wraps the anchor. |
body |
The popover’s body where its content is rendered. |
Learn more about customizing CSS parts.
Animations
| Name | Description |
|---|---|
popover.show |
The animation to use when showing the popover. |
popover.hide |
The animation to use when hiding the popover. |
Learn more about customizing animations.
Dependencies
This component automatically imports the following dependencies.
<ahi-popup>