Masonry image studio
AI image studio with a floating glass composer.
Usage
import { ImageStudio } from '@/components/blocks/image-gen-01'
<ImageStudio />
// Fill a parent that has a height instead of the viewport
<ImageStudio height="100%" />
// Your own images, models and generator
<ImageStudio
images={gallery}
models={[
{ id: 'fast', name: 'Kestrel Fast', description: 'Quick drafts' },
{ id: 'fine', name: 'Kestrel Fine', description: 'Sharper detail' },
]}
defaultAspectRatioId="3:4"
onGenerate={async ({ prompt, aspectRatio, count, model, style, signal }) => {
const response = await fetch('/api/images', {
method: 'POST',
body: JSON.stringify({ prompt, count, model: model.id, style: style?.id, ratio: aspectRatio.id }),
signal,
})
return response.json()
}}
/>
Install
pnpm dlx shadcn@latest add @pastaui-pro/image-gen-01npx shadcn@latest add @pastaui-pro/image-gen-01yarn dlx shadcn@latest add @pastaui-pro/image-gen-01bunx --bun shadcn@latest add @pastaui-pro/image-gen-01Source
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| images | ImageGenImage[] | = 43 generated images | Images in the masonry grid. Each: id, src, width, height, alt, prompt, model, size and seed. Width and height set the tile shape before the image loads. Image URLs with w and h params get a srcset automatically. |
| models | ImageGenModel[] | = GPT Image 2.5, Nano Banana 2, FLUX.2 Pro, Midjourney V8.1 | Models in the model menu. Each: id, name, a one-line description and an optional logo. The active one gets a blue check. |
| styles | ImageGenStyle[] | = Six style presets | Style presets in the style menu. Each: id, name and description. |
| aspectRatios | ImageGenAspectRatio[] | = 1:1, 3:4, 4:3 and 16:9 | Ratios in the aspect ratio menu. Each: id, label and the output width and height, which also shape the placeholders. |
| reserve | ImageGenReserveImage[] | = The same 43 images | Photos the built-in fake generator reveals in turn. Each: src and alt. Ignored when onGenerate is set. |
| defaultPrompt | string | = '' | Text in the prompt box on first render. |
| defaultModelId / defaultStyleId / defaultAspectRatioId | string | = First of each list | Menu values selected on first render. |
| defaultCount / maxCount | number | = 2 / 4 | Images per generation on first render, and the highest choice in the count menu. |
| placeholder | string | = 'Describe an image…' | Placeholder of the prompt box. |
| onGenerate | (request: ImageGenRequest) => Promise<ImageGenImage[]> | = A fake generator | Replaces the fake generator. The request holds the prompt, aspect ratio, count, model, style, the reference file and an AbortSignal that fires when Stop is pressed. Resolve with one image per placeholder. |
| onFavouriteChange | (id: string, favourite: boolean) => void | = — | Called when an image is favourited or unfavourited. |
| height | number | string | = '100dvh' | Height of the shell; the panes scroll inside it. Numbers are pixels and strings take any CSS length: '100%' fills a parent that has a height, such as the area under your own header, and 800 gives a fixed frame. |
| className / style | string / CSSProperties | = — | Classes for the root (use height rather than an h-* class) and inline overrides for the --pp-* theme variables. |