# Popover

A small panel anchored to the button that opens it, for content the user acts in without leaving the page: a short form, filters, a share link. It sits on the raised surface with a border and a medium shadow, and closes on Escape, an outside press or its trigger.

## Cách dùng

### Khi nào dùng

- A few controls next to the button that opens them: a share link, filters, a quick setting.
- Content the user acts in without leaving the page, which closes on Escape or a press outside.

### Khi nào không dùng

- A list of actions. Use DropdownMenu.
- A hint on hover or focus, with no controls. Use Tooltip.
- A long form, or input the user must not lose on a press outside. Use Dialog.

## Biến thể

### side

Set on PopoverContent. The side of the trigger it opens on. It flips when there is no room.

Giá trị: `top`, `right`, `bottom`, `left`. Mặc định: `bottom`.

### align

Set on PopoverContent. How it lines up with the trigger along that side. Use start or end when the trigger sits near an edge.

Giá trị: `start`, `center`, `end`. Mặc định: `center`.

## Ví dụ

### Share link

```tsx
<Popover>
  <PopoverTrigger asChild>
    <Button variant="secondary">Share</Button>
  </PopoverTrigger>
  <PopoverContent aria-labelledby="share-heading" className="flex flex-col gap-md">
    <p id="share-heading" className="text-md font-medium">Share this project</p>
    <Field>
      <FieldLabel>Link</FieldLabel>
      <FieldControl>
        <Input readOnly defaultValue="https://example.com/p/42" />
      </FieldControl>
    </Field>
    <PopoverClose asChild>
      <Button>Done</Button>
    </PopoverClose>
  </PopoverContent>
</Popover>
```

### Next to an edge

align end keeps the panel on screen when the trigger sits at the right of a toolbar.

```tsx
<Popover>
  <PopoverTrigger asChild>
    <Button variant="secondary" iconOnly aria-label="Filters">
      <IconList size={16} />
    </Button>
  </PopoverTrigger>
  <PopoverContent align="end" aria-label="Filters" className="flex flex-col gap-md">
    <Checkbox label="Only my projects" />
    <Checkbox label="Show archived" />
  </PopoverContent>
</Popover>
```

## Nên và không nên

### Nên

- Keep it short: a few controls, a link to copy, a set of filters.
- Give the panel a heading, or an aria-label when it has none.
- Apply changes at once, or close it with a PopoverClose button such as Done.

### Không nên

- Don't put a list of actions in it; use DropdownMenu.
- Don't use it for a long form or anything the user must not lose on an outside press; use Dialog.
- Don't open it on hover; use Tooltip for a hint.

## Props

| Tên | Kiểu | Giá trị | Mặc định | Mô tả |
| --- | --- | --- | --- | --- |
| `open` | `boolean` |  |  | Set on Popover. Whether it is open, when you control it. Pair it with onOpenChange. |
| `defaultOpen` | `boolean` |  | `false` | Set on Popover. Opens it on first render, when you don't control it. |
| `onOpenChange` | `function` |  |  | Set on Popover. Called with true or false when it opens or closes (trigger, Escape, an outside press, PopoverClose). |
| `modal` | `boolean` |  | `false` | Set on Popover. true keeps focus inside and hides the rest of the page from assistive tech until it closes. Leave it false for a panel the user works next to. |
| `side` | `enum` | `top`, `right`, `bottom`, `left` | `bottom` | Set on PopoverContent. The side of the trigger it opens on. It flips when there is no room. |
| `align` | `enum` | `start`, `center`, `end` | `center` | Set on PopoverContent. How it lines up with the trigger along that side. Use start or end when the trigger sits near an edge. |
| `sideOffset` | `number` |  | `4` | Set on PopoverContent. Space between the trigger and the panel, in px. 4 is spacing-xs. |

### Slot

| Tên | Bắt buộc | Mô tả |
| --- | --- | --- |
| `trigger` | có | PopoverTrigger with asChild around a Button. |
| `content` | có | PopoverContent with a heading or an aria-label, and the controls. |

## Cấu tạo

| Phần | Mô tả |
| --- | --- |
| `root` | Popover. Holds the open state; renders nothing itself. |
| `trigger` | PopoverTrigger: the button that opens it, usually a Button with asChild. |
| `content` | PopoverContent: the panel. Raised fill, border, radius-container, shadow-med, px-lg py-md, 288px wide and never wider than the screen minus spacing-sm on each side. |
| `anchor` | PopoverAnchor (optional): another element to position the panel against. |
| `close` | PopoverClose (optional): a button inside that closes it, such as Done. |

## Khả năng truy cập

Role: `dialog`

| Phím | Hành động |
| --- | --- |
| `Space, Enter` | On the trigger: opens or closes the popover. Focus moves to the first focusable element inside, or to the panel. |
| `Tab` | Moves through the controls inside. With modal, focus stays inside; otherwise it can leave, and the popover stays open. |
| `Escape` | Closes the popover and returns focus to the trigger. |

- The trigger gets aria-expanded and aria-controls, and the panel is a dialog. Name it with aria-label or aria-labelledby when it has no heading.
- An outside press closes it. Put anything the user must not lose (unsaved input) in a Dialog instead.
- Not for a list of actions: that is a DropdownMenu, which has menu semantics and arrow keys.
- Not for a hint on hover: that is a Tooltip, which holds no controls.

## Cài đặt

```bash
npx shadcn add https://werewolf-ui.vercel.app/r/popover.json
```

Lệnh này thêm luôn `styles/werewolf.css`, bộ token mà mọi component dùng, và các component khác mà nó cần. Import file đó một lần trong CSS gốc, ngay sau `@import "tailwindcss"`, với đường dẫn tính từ file CSS đó (từ `app/globals.css` là `@import "../styles/werewolf.css"`).
