@riehadi/gemini-image-components
v1.0.3
Published
A collection of React components for Gemini AI image generation features
Downloads
3
Maintainers
Readme
Gemini Image Components
A collection of React components for building Gemini AI image generation applications.
Features
- Image Generation: Text-to-image and image editing with Gemini
- Chat Edit: Interactive image editing through conversation
- Refine by Annotation: Precise image editing with mask annotations
- Comic Creation: Multi-panel comic generation
- Human Verification: CAPTCHA-style human verification gate
- UI Components: Pre-built UI components for common patterns
Installation
npm install @riehadi/gemini-image-componentsUsage
Basic Image Generation
import { ImageGenerator } from '@riehadi/gemini-image-components';
function App() {
return (
<ImageGenerator
apiEndpoint="/api/generate-image"
/>
);
}With Human Verification Gate
import { GatedLanding, ImageGenerator } from '@riehadi/gemini-image-components';
function App() {
return (
<GatedLanding>
<ImageGenerator
apiEndpoint="/api/generate-image"
/>
</GatedLanding>
);
}Chat-based Image Editing
import { ChatEdit } from '@riehadi/gemini-image-components';
function App() {
return (
<ChatEdit
generateApiEndpoint="/api/generate-image"
editApiEndpoint="/api/generate-chat-edit"
/>
);
}Refine by Annotation
import { RefineByAnnotation } from '@riehadi/gemini-image-components';
function App() {
return (
<RefineByAnnotation
apiEndpoint="/api/generate-image"
/>
);
}Comic Creation
import { Comic } from '@riehadi/gemini-image-components';
function App() {
return (
<Comic
apiEndpoint="/api/generate-image"
/>
);
}Using UI Components
import { Button, Input, Label } from '@riehadi/gemini-image-components';
function App() {
return (
<div>
<Label htmlFor="email">Email</Label>
<Input type="email" id="email" placeholder="Enter your email" />
<Button>Submit</Button>
</div>
);
}Using Gate Components
import { ChatEditGate, RefineAnnotationGate, ComicGate } from '@riehadi/gemini-image-components';
function App() {
return (
<div>
<ChatEditGate />
<RefineAnnotationGate />
<ComicGate />
</div>
);
}Components
ImageGenerator
The core component for generating images with text prompts and image inputs.
Props:
apiEndpoint(string, optional): Endpoint for your image generation API (default: "/api/generate-image")className(string, optional): Additional CSS classestitle(string, optional): Title for the component (default: "Gemini Image Generation")description(string, optional): Description for the component (default: "Generate an image from a prompt, or upload an image with a prompt to edit/compose.")
GatedLanding
A container component that wraps content with human verification.
Props:
children(ReactNode, required): Content to show after verificationgateComponent(ReactNode, optional): Custom gate component (defaults to HumanGate)className(string, optional): Additional CSS classes
HumanGate
A CAPTCHA-style component that requires users to click numbers in order.
Props:
onPassed(function, required): Callback when verification is successfuldigitCount(number, optional): Number of digits to show (default: 5)className(string, optional): Additional CSS classes
ChatEdit
Interactive image editing through conversation.
Props:
generateApiEndpoint(string, optional): Endpoint for initial image generation (default: "/api/generate-image")editApiEndpoint(string, optional): Endpoint for chat-based editing (default: "/api/generate-chat-edit")className(string, optional): Additional CSS classes
Composer
A component for composing messages with text and image attachments.
Props:
disabled(boolean, optional): Whether the composer is disabledprimaryLabel(string, optional): Label for the primary button (default: "Send")onSubmit(function, required): Callback when the form is submittedplaceholder(string, optional): Placeholder text for the textarea (default: "Write a prompt or edit instruction...")className(string, optional): Additional CSS classes
MessageList
A component for displaying a list of chat messages.
Props:
messages(ChatMessage[], required): Array of chat messages to displayclassName(string, optional): Additional CSS classes
ChatEditGate
A component that wraps ChatEdit with human verification.
Props:
gateComponent(ReactNode, optional): Custom gate component (defaults to HumanGate)className(string, optional): Additional CSS classestitle(string, optional): Title for the component (default: "Generate-Chat-Edit")description(string, optional): Description for the component (default: "Start with a prompt (and optional images), then iteratively refine via chat with attachments.")
RefineByAnnotation
Precise image editing with mask annotations.
Props:
apiEndpoint(string, optional): Endpoint for image generation (default: "/api/generate-image")className(string, optional): Additional CSS classestitle(string, optional): Title for the component (default: "Refine-by-Annotation")description(string, optional): Description for the component (default: "Start with a prompt (and optional initial image). Once an image is generated, draw annotations over it and send follow-up instructions. Each refine replaces the image.")initialPromptPlaceholder(string, optional): Placeholder for the initial prompt (default: "Describe the image to generate...")refineInstructionPlaceholder(string, optional): Placeholder for the refinement instruction (default: "Explain how the drawing should change the image...")
RefineAnnotationGate
A component that wraps RefineByAnnotation with human verification.
Props:
gateComponent(ReactNode, optional): Custom gate component (defaults to HumanGate)className(string, optional): Additional CSS classestitle(string, optional): Title for the component (default: "Refine-by-Annotation")description(string, optional): Description for the component (default: "Draw over the image and add instructions to iteratively refine results.")
Comic
Multi-panel comic generation.
Props:
apiEndpoint(string, optional): Endpoint for image generation (default: "/api/generate-image")className(string, optional): Additional CSS classestitle(string, optional): Title for the component (default: "Comic")description(string, optional): Description for the component (default: "Enter a topic once, then advance panels with the arrow to continue the story.")topicPlaceholder(string, optional): Placeholder for the topic input (default: "e.g., A day in the life of a space cat")
ComicGate
A component that wraps Comic with human verification.
Props:
gateComponent(ReactNode, optional): Custom gate component (defaults to HumanGate)className(string, optional): Additional CSS classes
UI Components
Pre-built UI components for common patterns.
Button: A customizable button component- Props:
variant("default" | "destructive" | "outline" | "secondary" | "ghost" | "link"),size("default" | "sm" | "lg" | "icon"),asChild(boolean)
- Props:
Input: A styled input component- Props: All standard HTML input attributes
Label: A styled label component- Props: All standard HTML label attributes
CompareSlider: A before/after image comparison slider- Props:
beforeUrl(string, required),afterUrl(string, required),beforeLabel(string),afterLabel(string),className(string)
- Props:
ImageLightbox: A fullscreen image viewer- Props:
open(boolean, required),src(string, required),alt(string),onClose(function, required),className(string)
- Props:
NavTabs: Navigation tabs component- Props:
tabs(array of {href: string, label: string}),className(string)
- Props:
Utility Functions
compressImageFile
Compresses an image file to a specified maximum width and height.
import { compressImageFile } from '@riehadi/gemini-image-components';
const compressed = await compressImageFile(file, maxWidth, maxHeight, quality);Parameters:
file(File): The image file to compressmaxWidth(number, optional): Maximum width in pixels (default: 1024)maxHeight(number, optional): Maximum height in pixels (default: 1024)quality(number, optional): JPEG quality (0-1, default: 0.8)
Returns: Promise resolving to an object with mimeType, dataUrl, and base64
cn
Combines class names using clsx and tailwind-merge.
import { cn } from '@riehadi/gemini-image-components';
const className = cn("base-class", { "conditional-class": condition });Parameters:
inputs(ClassValue[]): Class names to combine
Returns: Merged class names
Types
ChatImage
type ChatImage = {
mimeType: string;
dataUrl: string
};ChatMessage
type ChatMessage = {
role: "user" | "assistant";
text?: string;
images?: ChatImage[];
createdAt: number;
};Styling
This library uses Tailwind CSS for styling. Make sure you have Tailwind configured in your project.
The components use the following CSS variables for theming:
--primary: Primary color--primary-foreground: Primary foreground color--secondary: Secondary color--secondary-foreground: Secondary foreground color--background: Background color--foreground: Foreground color--muted: Muted color--muted-foreground: Muted foreground color--accent: Accent color--accent-foreground: Accent foreground color--destructive: Destructive color--destructive-foreground: Destructive foreground color--border: Border color--input: Input color--ring: Ring color
API Routes
You'll need to implement API routes in your application to proxy requests to the Gemini API. The components expect the following endpoints by default:
/api/generate-image: For image generation/api/generate-chat-edit: For chat-based editing
Example API route implementation:
// pages/api/generate-image.ts
import { GoogleGenerativeAI } from "@google/generative-ai";
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY!);
export default async function handler(req, res) {
if (req.method !== "POST") {
return res.status(405).json({ error: "Method not allowed" });
}
try {
const { prompt, images } = req.body;
const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });
const imageParts = images?.map((image) => ({
inlineData: {
data: image.dataBase64,
mimeType: image.mimeType,
},
})) || [];
const result = await model.generateContent([prompt, ...imageParts]);
const response = await result.response;
const imageBase64 = response.candidates[0].content.parts[0].inlineData?.data;
if (imageBase64) {
res.status(200).json({
type: "image",
data: imageBase64,
mimeType: response.candidates[0].content.parts[0].inlineData?.mimeType,
});
} else {
res.status(200).json({
type: "text",
text: response.text(),
});
}
} catch (error) {
console.error("API Error:", error);
res.status(500).json({ error: error.message });
}
}Publishing Workflow
To publish the library to npm:
- Update the version in
package.json - Run
npm run buildto build the library - Run
npm publishto publish to npm
Make sure you're logged in to npm (npm login) before publishing.
License
MIT
