Skip to content

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.

Open full source ↗

Props

PropTypeDefaultDescription
state"loading" | "empty" | "error" | "ready"—External async state.
loading / emptyReactNode—Optional state-specific surfaces.
error / onRetrystring / 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.

Works alongside