Popover
Manual until a YAML contract lands in
monochrome/spec/components/.
Anchored contextual panel. Ids: mct:popover:<id> / mcc:popover:<id>. Uses the Popover API (popover="manual"). Mutually exclusive with other popovers (opening one closes another).
Unlike Menu, Popover has no menuitem keyboard model. Optional Title and Description for accessible naming.
Composition
Root
Trigger
Content (div popover="manual")
Title? (optional)
Description? (optional)
(body)Usage
HTML
<button type="button" id="mct:popover:details" aria-controls="mcc:popover:details" aria-expanded="false">
Show details
</button>
<div id="mcc:popover:details" aria-labelledby="mct:popover:details" aria-hidden="true" popover="manual" tabindex="-1">
<p>A popover reveals contextual information.</p>
</div>Author CSS may wrap or style these elements; monochrome ships no classes.
With a description:
<div id="mcc:popover:details"
aria-labelledby="mct:popover:details"
aria-describedby="mcc:popover-description:details"
aria-hidden="true"
popover="manual"
tabindex="-1">
<p id="mcc:popover-description:details">A short description for AT.</p>
<button type="button">Action</button>
</div>Bare label (skip aria-labelledby):
<div id="mcc:popover:filter" aria-label="Filter results" aria-hidden="true" popover="manual" tabindex="-1">
...
</div>React
import { Popover } from "@monochrome-ui/react"
<Popover.Root>
<Popover.Trigger>Show details</Popover.Trigger>
<Popover.Content>
<Popover.Title>Details</Popover.Title>
<Popover.Description>A popover reveals contextual information.</Popover.Description>
</Popover.Content>
</Popover.Root>Vue
<script setup lang="ts">
import { Popover } from "@monochrome-ui/vue"
</script>
<template>
<Popover.Root>
<Popover.Trigger>Show details</Popover.Trigger>
<Popover.Content>
<Popover.Title>Details</Popover.Title>
<Popover.Description>A popover reveals contextual information.</Popover.Description>
</Popover.Content>
</Popover.Root>
</template>Parts
Root
Required for wrappers. Element: div. Mints shared <id> for Trigger and Content.
Trigger
Required. Element: button.
| Kind | Name | Type / value | Default | Description |
|---|---|---|---|---|
| attr | type |
"button" |
||
| attr | id |
mct:popover:<id> |
||
| attr | aria-controls |
mcc:popover:<id> |
||
| attr | aria-expanded |
"true" | "false" |
"false" |
|
| attr | aria-disabled |
"true" | absent |
absent | Blocks open when "true". |
| prop | disabled |
boolean |
false |
Emits aria-disabled. |
No aria-haspopup (unlike Menu/Dialog).
Content
Required. Element: div.
| Kind | Name | Type / value | Default | Description |
|---|---|---|---|---|
| attr | id |
mcc:popover:<id> |
||
| attr | aria-labelledby |
mct:popover:<id> | absent |
Default when no aria-label. Points at the trigger, not at Title. |
|
| attr | aria-describedby |
mcc:popover-description:<id> | absent |
Wrappers emit unless aria-description is passed. |
|
| attr | aria-label |
string | absent | Bare accessible name; skips aria-labelledby. |
|
| attr | aria-description |
string | absent | Bare description; skips wrapper aria-describedby. |
|
| attr | aria-hidden |
"true" | "false" |
"true" |
|
| attr | popover |
"manual" |
||
| attr | tabindex |
"-1" |
Focusable panel. | |
| attr | role |
"dialog" | absent |
absent | Optional dialog semantics (fixtures use this for filter-style panels). |
Title
Optional. Element: h2 (or h1-h6 via as). Id: mcc:popover-title:<id>.
Title is for the visual outline and heading structure. Wrappers do not wire Content aria-labelledby to Title; the accessible name still comes from the trigger (aria-labelledby → Trigger) or from Content aria-label.
| Kind | Name | Type | Default | Description |
|---|---|---|---|---|
| prop | as |
"h1" … "h6" |
"h2" |
Heading level. |
Description
Optional. Element: p. Id: mcc:popover-description:<id>.
Wrappers emit aria-describedby pointing here by default. Render Description, or pass aria-label / aria-description on Content, so the reference does not dangle.
Notes
- Open:
showPopover(), Triggeraria-expanded="true", Contentaria-hidden="false", position CSS vars published. - Close: Trigger toggle, outside click, Escape (after tooltip/menu layers), scroll that moves the anchor, focusout patterns handled by core.
- Structure independence: Trigger and Content need not be adjacent; linkage is ids /
aria-controls/ labelling. - Positioning: Author CSS using
--top,--right,--bottom,--left,--pw,--phon the content element. No CSS shipped. - Vs Menu: No
role="menu", no typeahead, no menuitem roles. Prefer Menu for action lists; Popover for free-form content.
Keyboard
| Key | Behavior |
|---|---|
| Enter / Space on Trigger | Toggle open/closed |
| Escape | Close open popover; focus returns to trigger |
| Tab | Moves through focusables inside Content when open |
No arrow-key roving inside the popover.