DocsGitHub
Getting Started
  • Overview
  • Design Tokens
Components
  • Accordion
  • Alert
  • Announcement
  • Avatar
  • Badge
  • BigCalendar
  • Breadcrumb
  • Button
  • ButtonGroup
  • Calendar
  • Card
  • Checkbox
  • Chip
  • CloseButton
  • Combobox
  • CommandPalette
  • ContextMenu
  • Currency
  • DatePicker
  • DescriptionList
  • Drawer
  • DropdownMenu
  • EmptyState
  • Field
  • FileUpload
  • FormGrid
  • Hotkey
  • Icon
  • Input
  • Metric
  • Modal
  • MultiSelect
  • NumberInput
  • Pagination
  • Popover
  • ProgressBar
  • Radio
  • Rating
  • SegmentedControl
  • Select
  • SelectionCard
  • Sidebar
  • Skeleton
  • Slider
  • Spinner
  • Stepper
  • Switch
  • Table
  • Tabs
  • Textarea
  • Timeline
  • TimePicker
  • Toast
  • Tooltip
  • TransferList
  • TreeView
  • Wizard
Charts
  • Overview
  • Area Chart
  • Bar Chart
  • Donut Chart
  • Line Chart
  • Pie Chart
  • Stacked Bar Chart

Popover

A focusable, non-modal surface anchored to a trigger with logical placement and viewport collision handling.

Installation

tsx
import { Popover, PopoverTrigger, PopoverContent } from "madagent";

Default

The trigger can compose a design-system Button without adding another DOM element. Focus moves into the panel when it opens and returns to the trigger when it closes.

tsx
<Popover>
  <PopoverTrigger asChild>
    <Button variant="outline">Open details</Button>
  </PopoverTrigger>
  <PopoverContent aria-label="Record details">
    Contextual content
  </PopoverContent>
</Popover>

Mini-form

Popover content is non-modal and can hold regular focusable controls for compact editing and filtering workflows.

tsx
<Popover>
  <PopoverTrigger asChild><Button>Filters</Button></PopoverTrigger>
  <PopoverContent aria-label="Filter records">
    <Select label="Status" options={statusOptions} />
    <Switch label="Include archived" />
    <Button size="sm">Apply filters</Button>
  </PopoverContent>
</Popover>

Placement and alignment

Placement names follow logical axes. The shared positioning hook flips panels at viewport edges and clamps their inline position in both LTR and RTL.

Block placement

tsx
<PopoverContent placement="block-start" align="start">
  Content
</PopoverContent>

Logical inline placement

tsx
<PopoverContent placement="inline-end" align="center">
  Content
</PopoverContent>

Controlled state

Use open and onOpenChange when application state decides whether the panel is visible.

State: closed
tsx
const [open, setOpen] = useState(false);

<Popover open={open} onOpenChange={setOpen}>
  <PopoverTrigger asChild><Button>Details</Button></PopoverTrigger>
  <PopoverContent>Controlled content</PopoverContent>
</Popover>

Overflow content

Content is capped at nine items and becomes scrollable so the panel remains compact.

tsx
<PopoverContent aria-label="Recent activity">
  {items.slice(0, 9).map((item) => <button key={item.id}>{item.label}</button>)}
</PopoverContent>

Popover Props

PropTypeDefaultDescription
open
boolean
-Controlled open state
defaultOpen
boolean
falseInitial open state for uncontrolled usage
onOpenChange
(open: boolean) => void
-Called whenever the requested open state changes
closeOnOutsideClick
boolean
trueCloses the panel when pointer interaction starts outside it
children*
ReactNode
-PopoverTrigger and PopoverContent composition

PopoverTrigger Props

PropTypeDefaultDescription
asChild
boolean
falseClones one interactive child instead of rendering a button wrapper
children*
ReactNode
-Trigger label or one interactive child when asChild is enabled

PopoverContent Props

PropTypeDefaultDescription
placement
"block-end""block-start""inline-end""inline-start"
"block-end"Preferred logical side; collision handling can flip it
align
"start""center""end"
"start"Logical alignment relative to the trigger
gap
number
8Distance from the trigger in pixels
collisionPadding
number
8Minimum viewport-edge padding in pixels
children*
ReactNode
-Focusable or presentational panel content

RTL Support

Components automatically adapt to right-to-left languages using CSS logical properties.

Preview

Usage

tsx
<Popover>
  <PopoverTrigger asChild>
    <Button variant="outline">خيارات التقرير</Button>
  </PopoverTrigger>
  <PopoverContent align="start" aria-label="خيارات التقرير">
    <Input label="اسم التقرير" />
    <Button size="sm">تطبيق</Button>
  </PopoverContent>
</Popover>