npm package: @riehadi/gemini-image-components
Description: A collection of React components for Gemini AI image generation features
Author: Your Name
Latest version: 1.0.3

# 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

```bash
npm install @riehadi/gemini-image-components
```

## Usage

### Basic Image Generation

```tsx
import { ImageGenerator } from '@riehadi/gemini-image-components';

function App() {
  return (
    <ImageGenerator 
      apiEndpoint="/api/generate-image"
    />
  );
}
```

### With Human Verification Gate

```tsx
import { GatedLanding, ImageGenerator } from '@riehadi/gemini-image-components';

function App() {
  return (
    <GatedLanding>
      <ImageGenerator 
        apiEndpoint="/api/generate-image"
      />
    </GatedLanding>
  );
}
```

### Chat-based Image Editing

```tsx
import { ChatEdit } from '@riehadi/gemini-image-components';

function App() {
  return (
    <ChatEdit 
      generateApiEndpoint="/api/generate-image"
      editApiEndpoint="/api/generate-chat-edit"
    />
  );
}
```

### Refine by Annotation

```tsx
import { RefineByAnnotation } from '@riehadi/gemini-image-components';

function App() {
  return (
    <RefineByAnnotation 
      apiEndpoint="/api/generate-image"
    />
  );
}
```

### Comic Creation

```tsx
import { Comic } from '@riehadi/gemini-image-components';

function App() {
  return (
    <Comic 
      apiEndpoint="/api/generate-image"
    />
  );
}
```

### Using UI Components

```tsx
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

```tsx
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 classes
- `title` (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 verification
- `gateComponent` (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 successful
- `digitCount` (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 disabled
- `primaryLabel` (string, optional): Label for the primary button (default: "Send")
- `onSubmit` (function, required): Callback when the form is submitted
- `placeholder` (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 display
- `className` (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 classes
- `title` (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 classes
- `title` (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 classes
- `title` (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 classes
- `title` (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)
- `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)
- `ImageLightbox`: A fullscreen image viewer
  - Props: `open` (boolean, required), `src` (string, required), `alt` (string), `onClose` (function, required), `className` (string)
- `NavTabs`: Navigation tabs component
  - Props: `tabs` (array of {href: string, label: string}), `className` (string)

## Utility Functions

### compressImageFile
Compresses an image file to a specified maximum width and height.

```ts
import { compressImageFile } from '@riehadi/gemini-image-components';

const compressed = await compressImageFile(file, maxWidth, maxHeight, quality);
```

Parameters:
- `file` (File): The image file to compress
- `maxWidth` (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.

```ts
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
```ts
type ChatImage = { 
  mimeType: string; 
  dataUrl: string 
};
```

### ChatMessage
```ts
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:

```ts
// 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:

1. Update the version in `package.json`
2. Run `npm run build` to build the library
3. Run `npm publish` to publish to npm

Make sure you're logged in to npm (`npm login`) before publishing.

## License

MIT