Summary
Add a general-purpose ct-popover component for floating content panels anchored to a trigger element. While Tooltip handles simple text hints, Popover is needed for rich interactive content: filter panels, mini forms, hover cards, settings dropdowns, or any floating UI that goes beyond a single line of text.
The Datepicker already uses an internal popover pattern (ct-datepicker__popover). This component extracts and generalizes that pattern for reuse.
Requirements
Core behavior
- Anchored to a trigger element, displayed on click (not hover — that's Tooltip territory)
data-state="open|closed" controls visibility
- Positioning via
data-side="top|bottom|left|right" and data-align="start|center|end"
- Enter/exit animation (opacity + slight translate), respecting
prefers-reduced-motion
Structure
ct-popover — wrapper (contains trigger + content)
ct-popover__trigger — the element that opens the popover
ct-popover__content — the floating panel
ct-popover__arrow (optional) — CSS triangle pointing to trigger
ct-popover__header / ct-popover__body / ct-popover__footer (optional) — structured layout inside content
Sizes
ct-popover--sm — narrow (240px)
- default (md) — 320px (matches current
--ct-popover-width)
ct-popover--lg — wide (480px)
Accessibility
- Trigger:
aria-expanded="true|false", aria-haspopup="dialog"
- Content:
role="dialog", aria-labelledby pointing to header or trigger
- Focus trap inside popover when open
- Close on
Escape
- Close on outside click
- Return focus to trigger on close
Naming
.ct-popover
.ct-popover--sm / --lg
.ct-popover__trigger
.ct-popover__content
.ct-popover__arrow
.ct-popover__header
.ct-popover__body
.ct-popover__footer
Design Tokens
Reuse existing variables:
--ct-popover-width: 320px (already defined in :root)
--ct-popover-bg: var(--color-bg-elevated)
--ct-popover-border: var(--color-border-default)
--ct-popover-radius: var(--radius-lg)
--ct-popover-shadow: var(--shadow-lg)
Files
components/components.css — component styles
stories/Popover.stories.js — stories for all positions, sizes, with form content, arrow variant
Summary
Add a general-purpose
ct-popovercomponent for floating content panels anchored to a trigger element. While Tooltip handles simple text hints, Popover is needed for rich interactive content: filter panels, mini forms, hover cards, settings dropdowns, or any floating UI that goes beyond a single line of text.The Datepicker already uses an internal popover pattern (
ct-datepicker__popover). This component extracts and generalizes that pattern for reuse.Requirements
Core behavior
data-state="open|closed"controls visibilitydata-side="top|bottom|left|right"anddata-align="start|center|end"prefers-reduced-motionStructure
ct-popover— wrapper (contains trigger + content)ct-popover__trigger— the element that opens the popoverct-popover__content— the floating panelct-popover__arrow(optional) — CSS triangle pointing to triggerct-popover__header/ct-popover__body/ct-popover__footer(optional) — structured layout inside contentSizes
ct-popover--sm— narrow (240px)--ct-popover-width)ct-popover--lg— wide (480px)Accessibility
aria-expanded="true|false",aria-haspopup="dialog"role="dialog",aria-labelledbypointing to header or triggerEscapeNaming
Design Tokens
Reuse existing variables:
--ct-popover-width: 320px(already defined in:root)--ct-popover-bg: var(--color-bg-elevated)--ct-popover-border: var(--color-border-default)--ct-popover-radius: var(--radius-lg)--ct-popover-shadow: var(--shadow-lg)Files
components/components.css— component stylesstories/Popover.stories.js— stories for all positions, sizes, with form content, arrow variant