Skip to content
Components

Generation frame

Hold a generated image's place from queued to done, so it develops without moving anything.

TS
import { … } from "@fungi.computer/caps/components/generation-frame";

Hero

TSX
import { GenerationFrame } from "@fungi.computer/caps/components/generation-frame";
const svg = [
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300">',
'<rect width="400" height="300" fill="#2f3b2a"/>',
'<ellipse cx="200" cy="170" rx="120" ry="70" fill="#c97b4a"/>',
'<ellipse cx="200" cy="140" rx="150" ry="50" fill="#e0a868"/>',
'<circle cx="90" cy="60" r="6" fill="#f3e6c4"/>',
'<circle cx="310" cy="90" r="4" fill="#f3e6c4"/>',
"</svg>",
].join("");
const spores = "data:image/svg+xml," + encodeURIComponent(svg);
export default function Hero() {
return (
<div className="w-72">
<GenerationFrame
aspectRatio={4 / 3}
status="done"
label="A chanterelle cluster, rendered"
>
<img alt="A cluster of chanterelle mushrooms" src={spores} />
</GenerationFrame>
</div>
);
}

States

TSX
import { GenerationFrame } from "@fungi.computer/caps/components/generation-frame";
export default function States() {
return (
<div className="grid grid-cols-3 gap-2">
<GenerationFrame
aspectRatio={1}
status="queued"
label="Queued"
className="max-w-28"
/>
<GenerationFrame
aspectRatio={1}
status="generating"
label="Generating"
className="max-w-28"
/>
<GenerationFrame
aspectRatio={1}
status="failed"
label="Failed"
failure={<span className="text-xs">Refused</span>}
className="max-w-28"
/>
</div>
);
}

Run

TSX
import { Button } from "@fungi.computer/caps/components/button";
import {
GenerationFrame,
type GenerationStatus,
} from "@fungi.computer/caps/components/generation-frame";
import { useState } from "react";
const svg = [
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300">',
'<rect width="400" height="300" fill="#2f3b2a"/>',
'<ellipse cx="200" cy="170" rx="120" ry="70" fill="#c97b4a"/>',
'<ellipse cx="200" cy="140" rx="150" ry="50" fill="#e0a868"/>',
"</svg>",
].join("");
const spores = "data:image/svg+xml," + encodeURIComponent(svg);
export default function Run() {
const [status, setStatus] = useState<GenerationStatus>("done");
const run = () => {
setStatus("queued");
window.setTimeout(() => {
setStatus("generating");
}, 400);
window.setTimeout(() => {
setStatus("refining");
}, 1_100);
window.setTimeout(() => {
setStatus("done");
}, 1_700);
};
return (
<div className="grid max-w-sm gap-sm">
<Button onClick={run} size="sm">
Generate a new cluster
</Button>
<GenerationFrame aspectRatio={4 / 3} status={status}>
<img alt="A cluster of chanterelle mushrooms" src={spores} />
</GenerationFrame>
</div>
);
}

Props

GenerationFrameProps

PropTypeDescription
status"queued" | "generating" | "refining" | "done" | "failed"
children?ReactNodeThe finished media (or, while refining, a rough preview of it).
aspectRatio?numberWidth over height. Omit when the parent already sizes the frame.
label?ReactNodeWhat is happening, for people using a screen reader.
indicator?ReactNodeThe working indicator; Caps' bloom loader by default.
failure?ReactNodeShown over the dimmed frame when generation fails.
  • status"queued" | "generating" | "refining" | "done" | "failed"
  • children?ReactNode

    The finished media (or, while refining, a rough preview of it).

  • aspectRatio?number

    Width over height. Omit when the parent already sizes the frame.

  • label?ReactNode

    What is happening, for people using a screen reader.

  • indicator?ReactNode

    The working indicator; Caps' bloom loader by default.

  • failure?ReactNode

    Shown over the dimmed frame when generation fails.

Full types: API reference.