# Popover

A sheet of panel stock lifted off the page on the shared light, with a folded tab at its trigger. It lifts toward you and settles; Escape or a click outside puts it down and returns focus.

- Category: Essentials
- Docs: https://bevel-ui.vercel.app/components/popover
- Import from: `@/components/ui/popover`

## Install

```bash
npx shadcn@latest add @bevel/popover
```

npm dependencies (installed by the CLI): `@base-ui/react`, `cn`.

## Anatomy

```tsx
<Popover>
  <PopoverTrigger />
  <PopoverContent>
    <PopoverHeader>
      <PopoverTitle />
      <PopoverDescription />
      <PopoverClose />
    </PopoverHeader>
  </PopoverContent>
</Popover>
```

## Parts

| Part | Renders | Description |
| --- | --- | --- |
| `Popover` | Popover root | open, defaultOpen, onOpenChange, modal. |
| `PopoverTrigger` | button | Opens the sheet. Pass render to use your own button. |
| `PopoverContent` | Popover popup | The sheet, 20rem wide (--popover-width), padded and stacked. side (default bottom), align, sideOffset, alignOffset, collisionPadding. tab={false} leaves out the folded tab. |
| `PopoverHeader` | div | Title and description; leaves room for a corner close. |
| `PopoverTitle` | h2 | Names the sheet for screen readers. |
| `PopoverDescription` | p | Muted text under the title. |
| `PopoverClose` | button | With no children, a × in the top corner labelled “Close”. With children, an unstyled close button. |

## Example: Share a page

A link to copy and who can see it.

```tsx
"use client"

import * as React from "react"
import { Check, Copy, Share } from "lucide-react"
import {
  Popover,
  PopoverClose,
  PopoverContent,
  PopoverDescription,
  PopoverHeader,
  PopoverTitle,
  PopoverTrigger,
} from "@/components/ui/popover"

/** Share a page: a link to copy, and who can see it. */
export function PopoverShare({ url = "https://bevel-ui.vercel.app/components/popover" }: { url?: string }) {
  const [copied, setCopied] = React.useState(false)
  const timer = React.useRef<number | undefined>(undefined)
  const inputId = React.useId()
  React.useEffect(() => () => window.clearTimeout(timer.current), [])

  async function copy() {
    await navigator.clipboard?.writeText(url).catch(() => {})
    setCopied(true)
    window.clearTimeout(timer.current)
    timer.current = window.setTimeout(() => setCopied(false), 2000)
  }

  return (
    <Popover>
      <PopoverTrigger className="inline-flex h-8 items-center gap-1.5 rounded-(--bevel-radius-sm) border bg-background px-3 text-sm font-medium outline-none hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring data-popup-open:bg-muted">
        <Share className="size-4" aria-hidden />
        Share
      </PopoverTrigger>
      <PopoverContent>
        <PopoverHeader>
          <PopoverTitle>Share this page</PopoverTitle>
          <PopoverDescription>Anyone with the link can view it.</PopoverDescription>
          <PopoverClose />
        </PopoverHeader>
        <div className="flex items-center gap-2">
          <label htmlFor={inputId} className="sr-only">
            Link
          </label>
          <input
            id={inputId}
            readOnly
            value={url}
            onFocus={(event) => event.currentTarget.select()}
            className="h-8 min-w-0 flex-1 rounded-(--bevel-radius-sm) border border-current/15 bg-transparent px-2 font-mono text-xs text-ellipsis shadow-(--bevel-depth-pressed) outline-none focus-visible:ring-2 focus-visible:ring-(--bevel-pen-blue)/50"
          />
          <button
            type="button"
            onClick={copy}
            className="inline-flex h-8 shrink-0 items-center gap-1.5 rounded-(--bevel-radius-sm) bg-foreground px-3 text-xs font-medium text-background outline-none focus-visible:ring-2 focus-visible:ring-(--bevel-pen-blue)/50 focus-visible:ring-offset-1"
          >
            {copied ? <Check className="size-3.5" aria-hidden /> : <Copy className="size-3.5" aria-hidden />}
            {copied ? "Copied" : "Copy"}
          </button>
        </div>
        <p role="status" className="sr-only">
          {copied ? "Link copied" : ""}
        </p>
      </PopoverContent>
    </Popover>
  )
}
```
