# AsyncBoundary

One readable contract for ready, loading, empty and failed content.

- Family: Status, imported from `mizu-ui` or `mizu-ui/status`
- Docs: https://mizu.user64bit.world/components/async-boundary
- Source: https://github.com/0xuser64bit/mizu/blob/main/packages/mizu/src/status/Feedback.tsx

## Usage

```tsx
"use client";

import { useState } from "react";
import { AsyncBoundary, SegmentedControl } from "mizu-ui";

export function Example() {
  const [state, setState] = useState<"ready" | "loading" | "empty" | "error">(
    "ready",
  );
  return (
    <div style={{ display: "grid", gap: 16, justifyItems: "start" }}>
      <SegmentedControl
        label="Demo content state"
        value={state}
        onValueChange={(v) => setState(v as typeof state)}
        options={["ready", "loading", "empty", "error"].map((v) => ({
          value: v,
          label: v,
        }))}
      />
      <AsyncBoundary state={state} onRetry={() => setState("ready")}>
        <p style={{ margin: 0 }}>The archive is ready.</p>
      </AsyncBoundary>
    </div>
  );
}
```

## 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/async-boundary 0xuser64bit/mizu/segmented-control
```

## Props

- `state`: `"loading" | "empty" | "error" | "ready"`. External async state.
- `loading / empty`: `ReactNode`. Optional state-specific surfaces.
- `error / onRetry`: `string / function`. Failure explanation and recovery.

## Accessibility

Default placeholders are labelled; error recovery is keyboard accessible. It does not fetch or infer emptiness.

## Motion

CSS transitions explain state changes. Reduced motion removes travel.
