Skip to content

feat: Popover component #44

Description

@Samyssmile

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    componentComponent-level issueenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions