Xzero UI
Pro library

Image revealPro

An image generation canvas where a soft, blurred preview made from the image's own colors sharpens top to bottom behind a soft-edged band. It works the way ChatGPT, Midjourney and Gemini show images forming, with fine film grain, a translucent progress pill and calm queued and error states.

$ pnpm dlx shadcn@4.23.0 add @xzero-ui-pro/image-reveal
Live · keyboard ready

When to use

When not to use

Installation

Register both Xzero UI namespaces in your project's components.json:

{
  "registries": {
    "@xzero-ui": "https://mcp.xzero.co.uk/r/{name}.json",
    "@xzero-ui-pro": "https://mcp.xzero.co.uk/r/pro/{name}.json"
  }
}
npx shadcn@4.23.0 add @xzero-ui-pro/image-reveal

Install xzero-foundation once, and import @/components/xzero/foundation.css in your app root. No Xzero token is used by this snapshot. For sample portraits, photos, fonts, or logos, download https://mcp.xzero.co.uk/install-assets.mjs and run node xzero-install-assets.mjs <receiving-project>.

Usage

import { ImageReveal } from "@/components/xzero/image-reveal/image-reveal";

export function GeneratedImage({ job }: { job: { status: "queued" | "generating" | "done" | "error"; step: number; url?: string } }) {
  return (
    <ImageReveal
      src={job.url}
      alt="A calm alpine lake at golden hour"
      status={job.status}
      progress={job.step / 30}
      steps={30}
      aspectRatio="4 / 5"
      onRetry={() => retry(job)}
    />
  );
}

Examples

Estimated duration, no progress events

<ImageReveal src={url} status={url ? "done" : "generating"} duration={8000} />

Staggered grid with a Generate again button

const [run, setRun] = useState(0);

<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }}>
  {urls.map((url, index) => (
    <ImageReveal key={index} src={url} size="sm" seed={index + 1}
      runKey={run} loop={false} startDelay={index * 420} style={{ maxInlineSize: "none" }} />
  ))}
</div>
<Button onClick={() => setRun(run + 1)}>Generate again</Button>

API reference

ImageReveal

Image generation the way current image models show it: a soft, heavily blurred preview sampled from the image's own colors with fine film grain, then a soft-edged band that sharpens the picture top to bottom while the rest gently comes into focus. With no props it plays a looping, simulated generation over sample photos.

PropTypeDefaultDescription
srcstring–Final image URL. Cross-origin images work (pixels are never read back). Omit to cycle through sample photos.
altstring"Generated image"Alt text for the final image, used as the canvas label once done.
status"queued" | "generating" | "done" | "error"–Controlled state. Omit for auto mode, which runs queued, generating over duration, then done. Every change transitions smoothly.
progressnumber–Controlled progress from 0 to 1 while generating. Coarse updates (one per model step) are smoothed into continuous motion. Omit to animate over duration.
durationnumber5200Milliseconds one generation takes when progress is not controlled.
stepsnumber30Steps shown in the pill, as in 18 / 30 (tabular numerals, reserved width).
aspectRationumber | string1Width over height, as a number (1.5) or a CSS ratio ("4 / 5"). The image is cover-cropped to it.
size"sm" | "md" | "lg""md"Overlay scale and corner radius. "sm" (grids, thumbnails) shows only the ring and 18 / 30; "md" and "lg" add the Generating label. The canvas always renders at device pixel ratio.
colorstring–Any CSS color for the progress ring. Defaults to the accent.
showProgressbooleantrueShows the translucent progress pill. It fades out shortly after the image resolves.
sheenbooleantruePlays one soft light sheen across the image when it resolves. Skipped with reduced motion.
queueLabelstring"Queued"Chip label while queued, such as "Queued, 2 ahead".
errorMessagestring"Generation failed"Message in the error state.
onRetry() => void–Shows a Retry button in the error state.
onStatusChange(status: ImageRevealStatus) => void–Called when the displayed status changes, including auto mode transitions.
onComplete() => void–Called once per run when the final image is fully resolved and crisp.
autoPlaybooleantrueAuto mode only: starts generating on mount.
loopbooleantrueAuto mode only: after holdDuration the image blurs back out and generates again.
startDelaynumber0Auto mode only: extra queue time in milliseconds before a run, for staggered grids.
queueDurationnumber900Auto mode only: milliseconds in the queue before each run.
holdDurationnumber2600Auto mode only: milliseconds the finished image holds before a loop restarts.
runKeystring | number–Auto mode only: change it to blur back out and run again (a Generate again button).
seednumber1Seeds the film grain and the drift of the soft preview, so tiles in a grid differ.
classNamestring–Class on the root. The root is 100% wide with a 560px max width; override max-inline-size in grids.
styleCSSProperties–Inline styles on the root.

Keyboard interactions

KeysAction
TabMoves to the Retry button in the error state. The canvas itself is not focusable.
Enter / SpaceActivates Retry.

Accessibility

Motion

Responsive behavior

Performance

Notes for AI

Also in ai

Guidance for AI tools

Image reveal: An image generation canvas where a soft, blurred preview made from the image's own colors sharpens top to bottom behind a soft-edged band. It works the way ChatGPT, Midjourney and Gemini show images forming, with fine film grain, a translucent progress pill and calm queued and error states. Follow the declared prop types and do not invent props. Keep keyboard access, reduced motion support, and both light and dark themes intact when adapting it.

Full library index: https://ui.xzero.co.uk/llms.txt

Browse all components