Skip to content

Presence

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

Live — this one is real

Draft in progress
Keep shaping the idea.

Usage

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>
  );
}

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. Requires React and Motion.

Inspect motion/Presence.tsx

Source is included in the npm package under src/motion/Presence.tsx.

Open full source ↗

Props

PropTypeDefaultDescription
presenceKeystring | number—Stable identity of the visible state.
children / classNameReactNode / 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.

Works alongside