# Presence

A keyed state enters after the previous state has made room.

- Family: Motion, imported from `mizu-ui` or `mizu-ui/motion`
- Docs: https://mizu.user64bit.world/components/presence
- Source: https://github.com/0xuser64bit/mizu/blob/main/packages/mizu/src/motion/Presence.tsx

## Usage

```tsx
"use client";

import { useState } from "react";
import { Presence, Stack, Button, Alert } from "mizu-ui";

export function Example() {
  const [saved, setSaved] = useState(false);
  return (
    <Stack gap={20}>
      <Button size="sm" onClick={() => setSaved(!saved)}>
        Change state
      </Button>
      <Presence presenceKey={String(saved)}>
        <Alert
          title={saved ? "Changes saved" : "Draft in progress"}
          tone={saved ? "success" : "neutral"}
        >
          {saved
            ? "The current draft is ready for review."
            : "Keep shaping the idea."}
        </Alert>
      </Presence>
    </Stack>
  );
}
```

## 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/presence 0xuser64bit/mizu/stack 0xuser64bit/mizu/button 0xuser64bit/mizu/alert
```

## Props

- `presenceKey`: `string | number`. Stable identity of the visible state.
- `children / className`: `ReactNode / string`. The changing content and wrapper styling.

## Accessibility

Content stays in document order. Do not move a focused control between keyed states; use persistent controls outside Presence.

## Motion

AnimatePresence waits for exit and displays the latest state. Reduced motion replaces content without travel.
