> ## Documentation Index
> Fetch the complete documentation index at: https://araf.badr.co.id/llms.txt
> Use this file to discover all available pages before exploring further.

# Popover

> A floating panel anchored to a trigger element — used for contextual content, settings panels, and quick forms without blocking the page.

## Overview

<div style={{padding:"28px 24px",background:"#f9fafb",borderRadius:"12px",border:"1px solid #e5e7eb",display:"flex",gap:"32px",alignItems:"flex-start",flexWrap:"wrap"}}>
  <div style={{display:"flex",flexDirection:"column",gap:"8px",fontFamily:"Inter,sans-serif"}}>
    <button style={{display:"inline-flex",alignItems:"center",gap:"6px",padding:"8px 14px",border:"1px solid #D0D5DD",borderRadius:"8px",background:"#fff",fontSize:"14px",color:"#344054",fontWeight:500,cursor:"pointer",alignSelf:"flex-start"}}>
      <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
        <circle cx="12" cy="12" r="3" />

        <path d="M12 2v2M12 20v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M2 12h2M20 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42" />
      </svg>

      Appearance
    </button>

    <div style={{background:"#fff",border:"1px solid #E5E7EB",borderRadius:"10px",boxShadow:"0 4px 16px rgba(0,0,0,0.1)",padding:"16px",width:"240px"}}>
      <div style={{fontSize:"13px",fontWeight:600,color:"#101828",marginBottom:"4px"}}>Appearance settings</div>
      <div style={{fontSize:"12px",color:"#667085",marginBottom:"12px"}}>Customize your display preferences.</div>

      <div style={{display:"flex",flexDirection:"column",gap:"8px"}}>
        <div style={{display:"flex",justifyContent:"space-between",alignItems:"center"}}>
          <span style={{fontSize:"13px",color:"#344054"}}>Dark mode</span>

          <div style={{width:"36px",height:"20px",borderRadius:"10px",background:"#0479CE",position:"relative",cursor:"pointer"}}>
            <div style={{width:"16px",height:"16px",borderRadius:"50%",background:"#fff",position:"absolute",top:"2px",right:"2px",boxShadow:"0 1px 3px rgba(0,0,0,0.2)"}} />
          </div>
        </div>

        <div style={{display:"flex",justifyContent:"space-between",alignItems:"center"}}>
          <span style={{fontSize:"13px",color:"#344054"}}>Compact view</span>

          <div style={{width:"36px",height:"20px",borderRadius:"10px",background:"#E5E7EB",position:"relative",cursor:"pointer"}}>
            <div style={{width:"16px",height:"16px",borderRadius:"50%",background:"#fff",position:"absolute",top:"2px",left:"2px",boxShadow:"0 1px 3px rgba(0,0,0,0.2)"}} />
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

**Popover** is a non-modal floating panel anchored to a trigger. Unlike `Tooltip` (hover, read-only), Popover can contain interactive elements — forms, toggles, pickers — and is triggered by click.

<Note>
  Popover vs Tooltip: use **Popover** for interactive content (buttons, inputs, forms). Use **Tooltip** for short read-only labels shown on hover.
</Note>

***

## Installation

<CodeGroup>
  ```bash npm theme={null}
  npm install @araf-ds/core
  ```

  ```bash yarn theme={null}
  yarn add @araf-ds/core
  ```

  ```bash pnpm theme={null}
  pnpm add @araf-ds/core
  ```
</CodeGroup>

***

## Usage

```tsx theme={null}
import {
  Popover,
  PopoverTrigger,
  PopoverContent,
} from "@araf-ds/core"

export default function Example() {
  return (
    <Popover>
      <PopoverTrigger asChild>
        <Button variant="outline">Open popover</Button>
      </PopoverTrigger>
      <PopoverContent className="w-64">
        <p className="text-sm text-muted-foreground">
          Popover content goes here.
        </p>
      </PopoverContent>
    </Popover>
  )
}
```

***

## Variants

### Basic

<div style={{padding:"24px",background:"#f9fafb",borderRadius:"12px",border:"1px solid #e5e7eb",display:"flex",flexDirection:"column",gap:"8px",alignItems:"flex-start"}}>
  <button style={{padding:"8px 14px",border:"1px solid #D0D5DD",borderRadius:"8px",background:"#fff",fontSize:"14px",color:"#344054",fontWeight:500,cursor:"pointer",fontFamily:"Inter,sans-serif"}}>
    Open popover
  </button>

  <div style={{background:"#fff",border:"1px solid #E5E7EB",borderRadius:"10px",boxShadow:"0 4px 16px rgba(0,0,0,0.1)",padding:"16px",maxWidth:"240px",fontFamily:"Inter,sans-serif"}}>
    <div style={{fontSize:"13px",fontWeight:600,color:"#101828",marginBottom:"4px"}}>Quick info</div>
    <div style={{fontSize:"13px",color:"#667085"}}>This component anchors floating content to any trigger element.</div>
  </div>
</div>

```tsx theme={null}
<Popover>
  <PopoverTrigger asChild>
    <Button variant="outline">Open popover</Button>
  </PopoverTrigger>
  <PopoverContent className="w-60">
    <div className="space-y-1">
      <h4 className="font-medium text-sm">Quick info</h4>
      <p className="text-sm text-muted-foreground">
        This component anchors floating content to any trigger element.
      </p>
    </div>
  </PopoverContent>
</Popover>
```

### With Form

<div style={{padding:"24px",background:"#f9fafb",borderRadius:"12px",border:"1px solid #e5e7eb",display:"flex",flexDirection:"column",gap:"8px",alignItems:"flex-start"}}>
  <button style={{padding:"8px 14px",border:"1px solid #D0D5DD",borderRadius:"8px",background:"#fff",fontSize:"14px",color:"#344054",fontWeight:500,cursor:"pointer",fontFamily:"Inter,sans-serif"}}>
    Edit dimensions
  </button>

  <div style={{background:"#fff",border:"1px solid #E5E7EB",borderRadius:"10px",boxShadow:"0 4px 16px rgba(0,0,0,0.1)",padding:"16px",width:"220px",fontFamily:"Inter,sans-serif"}}>
    <div style={{fontSize:"13px",fontWeight:600,color:"#101828",marginBottom:"12px"}}>Dimensions</div>

    <div style={{display:"flex",flexDirection:"column",gap:"8px"}}>
      {["Width","Height"].map(field => (
                  <div key={field} style={{display:"flex",flexDirection:"column",gap:"4px"}}>
                    <label style={{fontSize:"12px",color:"#344054",fontWeight:500}}>{field}</label>
                    <input readOnly defaultValue="100%" style={{border:"1px solid #D0D5DD",borderRadius:"6px",padding:"6px 10px",fontSize:"13px",color:"#101828",background:"#fff",outline:"none"}}/>
                  </div>
                ))}

      <button style={{marginTop:"4px",padding:"7px 12px",borderRadius:"8px",border:"none",background:"#0479CE",color:"#fff",fontSize:"13px",fontWeight:500,cursor:"pointer"}}>Apply</button>
    </div>
  </div>
</div>

```tsx theme={null}
<Popover>
  <PopoverTrigger asChild>
    <Button variant="outline">Edit dimensions</Button>
  </PopoverTrigger>
  <PopoverContent className="w-56">
    <div className="grid gap-3">
      <h4 className="font-medium text-sm">Dimensions</h4>
      <FormItem>
        <FormLabel>Width</FormLabel>
        <Input defaultValue="100%" />
      </FormItem>
      <FormItem>
        <FormLabel>Height</FormLabel>
        <Input defaultValue="100%" />
      </FormItem>
      <Button size="sm">Apply</Button>
    </div>
  </PopoverContent>
</Popover>
```

### Placement

<div style={{padding:"24px",background:"#f9fafb",borderRadius:"12px",border:"1px solid #e5e7eb",display:"flex",gap:"12px",flexWrap:"wrap",alignItems:"center",justifyContent:"center",fontFamily:"Inter,sans-serif"}}>
  {["top","right","bottom","left"].map(side => (
      <div key={side} style={{display:"flex",flexDirection:"column",alignItems:"center",gap:"4px"}}>
        <div style={{background:"#fff",border:"1px solid #E5E7EB",borderRadius:"8px",boxShadow:"0 2px 8px rgba(0,0,0,0.08)",padding:"8px 12px",fontSize:"12px",color:"#344054",whiteSpace:"nowrap"}}>
          {side}
        </div>
        <button style={{padding:"6px 10px",border:"1px solid #D0D5DD",borderRadius:"6px",background:"#fff",fontSize:"12px",color:"#667085",cursor:"pointer"}}>trigger</button>
      </div>
    ))}
</div>

```tsx theme={null}
// Control placement with the `side` prop
<PopoverContent side="top">...</PopoverContent>
<PopoverContent side="right">...</PopoverContent>
<PopoverContent side="bottom">...</PopoverContent>  {/* default */}
<PopoverContent side="left">...</PopoverContent>
```

***

## API Reference

### Popover

<ParamField path="open" type="boolean">
  Controlled open state.
</ParamField>

<ParamField path="onOpenChange" type="(open: boolean) => void">
  Callback fired when open state changes.
</ParamField>

<ParamField path="defaultOpen" type="boolean" default="false">
  Uncontrolled default open state.
</ParamField>

### PopoverContent

<ParamField path="side" type="string" default="bottom">
  Which side of the trigger to render on. Values: `top` · `right` · `bottom` · `left`
</ParamField>

<ParamField path="align" type="string" default="center">
  Alignment relative to the trigger. Values: `start` · `center` · `end`
</ParamField>

<ParamField path="sideOffset" type="number" default="4">
  Distance in px between trigger and popover panel.
</ParamField>

<ParamField path="className" type="string">
  Additional class names for the popover panel.
</ParamField>

***

## Accessibility

* Popover uses `role="dialog"` and is not modal — background content remains accessible
* Trigger has `aria-haspopup="dialog"` and `aria-expanded`
* Focus moves into the popover when it opens; Escape closes it and returns focus to the trigger
* Unlike `Tooltip`, Popover is not announced on hover — it requires a deliberate click

***

## Do's & Don'ts

<CardGroup cols={2}>
  <Card title="Do" icon="check" iconType="solid" color="#16A34A">
    * Use Popover for interactive content: forms, pickers, toggles
    * Keep popover content focused — avoid making it too wide or tall
    * Provide a clear close mechanism (Escape key or a close button)
    * Use `align="end"` for popovers triggered from right-aligned buttons
  </Card>

  <Card title="Don't" icon="xmark" iconType="solid" color="#DC2626">
    * Don't use Popover for read-only labels — use `Tooltip`
    * Don't use Popover for critical blocking decisions — use `AlertDialog`
    * Don't put navigation inside a Popover — use `DropdownMenu`
    * Don't make Popover content taller than the viewport
  </Card>
</CardGroup>
