Skip to content

SaveIndicator

Keep the difference between saved, dirty, saving and failed visible.

Live — this one is real

Unsaved changes

Usage

import { useState } from "react";
import { SaveIndicator } from "mizu-ui";

export function Example() {
  const [state, setState] = useState<"saved" | "unsaved" | "saving" | "error">(
    "unsaved",
  );
  return (
    <>
      <SaveIndicator state={state} onRetry={() => setState("saving")} />
      <select
        aria-label="Demo save state"
        value={state}
        onChange={(e) => setState(e.target.value as typeof state)}
      >
        {["saved", "unsaved", "saving", "error"].map((v) => (
          <option key={v}>{v}</option>
        ))}
      </select>
    </>
  );
}

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"saved" | "unsaved" | "saving" | "error"—Actual persistence state supplied by your app.
onRetry() => void—Optional retry for a failed save.

Accessibility

Changes are announced politely. The retry control appears only when it can recover a failure.

Motion

CSS transitions explain state changes. Reduced motion removes travel.

Works alongside