AsyncBoundary
One readable contract for ready, loading, empty and failed content.
Live — this one is real
The archive is ready.
Usage
import { useState } from "react";
import { AsyncBoundary } from "mizu-ui";
export function Example() {
const [state, setState] = useState<"ready" | "loading" | "empty" | "error">(
"ready",
);
return (
<>
<select
aria-label="Demo content state"
value={state}
onChange={(e) => setState(e.target.value as typeof state)}
>
{["ready", "loading", "empty", "error"].map((v) => (
<option key={v}>{v}</option>
))}
</select>
<AsyncBoundary state={state} onRetry={() => setState("ready")}>
<p>The archive is ready.</p>
</AsyncBoundary>
</>
);
}
Source & setup
Import mizu-ui/styles.css once. Fonts are optional via mizu-ui/fonts.css. Override --mizu-* tokens or use className for local styling. Uses native React and CSS; install the package peers for root imports.
Inspect status/Feedback.tsx
Source is included in the npm package under src/status/Feedback.tsx.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| 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.