registry:component

Aavya AI Image Studio

v0.3.0beta

Compact prompt + upload surface for n8n-powered asset generation.

Registry Endpoint
Open JSON

https://registry.aavya.com/r/aavya-ai-image-studio.json

npx shadcn@latest add https://registry.aavya.com/r/aavya-ai-image-studio.json

Live Preview
Preview Route
Dependencies
buttoninputselect
Usage Snippet
import CompactAiImageStudio from '@/components/layout/compact-ai-image-studio.tsx'

export default function Example() {
  return (
    <div className="p-6">
      <CompactAiImageStudio />
    </div>
  )
}
Source Preview
'use client'

import {
  ChangeEvent,
  FormEvent,
  useEffect,
  useMemo,
  useRef,
  useState,
} from 'react'
import Image from 'next/image'
import {
  Cpu,
  ImagePlus,
  Loader2,
  Ratio,
  Upload,
  X,
} from 'lucide-react'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { PillSelect } from '@/components/ui/pill-select'

interface WorkflowResponse {
  imageUrl?: string
  prompt?: string
  [key: string]: unknown
}

export function CompactAiImageStudio() {
  const [prompt, setPrompt] = useState('')
  const [model, setModel] = useState('gpt-image-1')
  const [resolution, setResolution] = useState('1024x1024')
  const [aspectRatio, setAspectRatio] = useState('1:1')
  const [file, setFile] = useState<File | null>(null)
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [result, setResult] = useState<WorkflowResponse | null>(null)
  const mode = file ? 'modify' : 'create'
  const fileInputRef = useRef<HTMLInputElement | null>(null)

  const previewUrl = useMemo(() => {
    if (!file) return null
    return URL.createObjectURL(file)
  }, [file])

  useEffect(() => {
    return () => {
      if (previewUrl) URL.revokeObjectURL(previewUrl)
    }
  }, [previewUrl])

  const isSubmitDisabled = useMemo(() => {
    if (!prompt.trim()) return true
    return loading
  }, [