Popover
A non-modal contextual dialog anchored to a trigger for concise content that may include actions and interactive components.
Design
Anatomy
Popover title
Concise contextual content.
- Trigger — Button controlling open state and
aria-expanded. - Panel — elevated surface with
role="dialog". - Header — optional title and absolutely positioned close control.
- Body — independent Content Text and Content Slot.
- Actions — up to two independently replaceable and hideable Buttons.
- Arrow — closed Shape pointing to the trigger.
Interactive example · HTML/CSS/JS
Running with the stable ds-tis/popover JavaScript runtime.
Loading functional preview…
Additional Content Slot · HTML/CSS/JS
Executed by the stable HTML/CSS/JavaScript runtime with a real DS field and actions.
Loading functional preview…
Placements
| Modifier | Panel position |
|---|---|
ds-popover--bottom | Below the trigger |
ds-popover--top | Above the trigger |
ds-popover--left | To the trigger's left |
ds-popover--right | To the trigger's right |
Token mapping
| Part | Component tokens |
|---|---|
| Panel | component.popover.panel.{bg,border-color,border-width,gap,max-width,padding-x,padding-y,radius,shadow}.default |
| Title / Body | component.popover.title.color.default, component.popover.body.{color,gap,padding-bottom}.default |
| Close | component.popover.close.{size,icon-size,padding,color}.default, component.popover.close.icon.stroke-width.default |
| Content Slot | component.popover.content-slot.gap.default |
| Actions | component.popover.actions.{gap,padding-top}.default |
| Arrow | component.popover.arrow.{base,fill}.default |
Usage
When to use
Use Popover when
Contextual content needs actions, links, a simple field, or richer guidance than a Tooltip without blocking the rest of the page.
Do not use Popover when
Content is only a short label (use Tooltip), requires a blocking decision or long flow (use Modal), or represents a command list (use Menu).
Related
Implementation
- Status
- Stable
- Distribution
- npm package
Installation
npm install ds-tispnpm add ds-tisyarn add ds-tisbun add ds-tisImports
import 'ds-tis/css'
import { initPopovers } from 'ds-tis/popover'
initPopovers()Markup
<div class="ds-popover ds-popover--bottom">
<button class="ds-button ds-popover__trigger" type="button">Detalhes</button>
<div class="ds-popover__panel" role="dialog" aria-labelledby="popover-title" hidden>
<div class="ds-popover__header">
<h2 class="ds-popover__title" id="popover-title">Detalhes</h2>
</div>
<button class="ds-popover__close" type="button" aria-label="Fechar popover">…</button>
<div class="ds-popover__body">Conteúdo breve.</div>
</div>
</div>Web implementation contract
Public runtime
The ds-tis/popover module is required to synchronize ARIA, focus, Escape, outside click, and lifecycle. Popover is non-modal and does not trap focus.
Public events: ds-popover-open and ds-popover-close.
import {
initPopovers,
destroyPopovers,
openPopover,
closePopover
} from 'ds-tis/popover';
initPopovers();
// destroyPopovers(root) ao desmontar / on unmount
Accessibility
Accessibility and keyboard
| Input | Behavior |
|---|---|
| Enter / Space | The Button trigger opens or closes through native click behavior. |
| Escape | Closes the Popover and returns focus to the trigger. |
| Tab | Follows natural order; there is no focus trap. |
role="dialog" | Use aria-labelledby for a visible title or aria-label when there is no header. |
Output responsibility
Initialize the public runtime after render and destroy it when the owning view unmounts.
Validation evidence
Covered by the stable Storybook, public runtime tests when applicable, keyboard scenarios, responsive checks, and Axe.