# Dialog

A modal with focus trap, Escape handling, scroll lock and an expo entrance.

- Family: Composites, imported from `mizu-ui` or `mizu-ui/composite`
- Docs: https://mizu.user64bit.world/components/dialog
- Source: https://github.com/0xuser64bit/mizu/blob/main/packages/mizu/src/composite/Dialog.tsx

## Usage

```tsx
"use client";

import { useState } from "react";
import {
  Button,
  Dialog,
  DialogTitle,
  DialogBody,
  DialogFooter,
  DialogClose,
} from "mizu-ui";

export function Modal() {
  const [open, setOpen] = useState(false);
  return (
    <>
      <Button onClick={() => setOpen(true)}>Open dialog</Button>
      <Dialog open={open} onOpenChange={setOpen} label="Archive notice">
        <DialogClose />
        <DialogTitle>Release when ready</DialogTitle>
        <DialogBody>…</DialogBody>
        <DialogFooter>
          <Button onClick={() => setOpen(false)}>Close</Button>
        </DialogFooter>
      </Dialog>
    </>
  );
}
```

## Copy it with the shadcn CLI

```sh
npx shadcn@latest init 0xuser64bit/mizu/preset # once, where there is no components.json
npx shadcn@latest add 0xuser64bit/mizu/dialog 0xuser64bit/mizu/button
```

## Props

- `open / onOpenChange`: `boolean / fn`. Controlled open state.
- `label`: `string`. Accessible name for the dialog.

## Accessibility

Native showModal supplies background inertness and focus containment. Escape requests close, focus returns to the trigger and body scroll is locked. Local themes are preserved.

## Motion

A CSS expo entrance communicates opening. Reduced motion removes the entrance.
