# React Mail Inbox Component

A fully customizable, Gmail-style inbox component built with React, featuring a rich text editor powered by Lexical.

## Features

- 📧 **Email Composition**: Full-featured email composer with To/CC/BCC fields
- ✍️ **Rich Text Editor**: Powered by Lexical with formatting options (bold, italic, underline, lists, links, etc.)
- 🎨 **Theme Support**: Built-in dark/light theme switching
- 📎 **File Attachments**: Drag-and-drop file upload with preview
- 🔍 **Email Autocomplete**: Async email suggestions as you type
- 🎯 **Fully Typed**: Written in TypeScript with complete type definitions
- 🎭 **Customizable**: Flexible API with slots for custom content

## Installation

```bash
npm install react-mail-inbox
# or
yarn add react-mail-inbox
# or
pnpm add react-mail-inbox
```

### Peer Dependencies

This package requires the following peer dependencies:

```json
{
  "react": "^18.0.0 || ^19.0.0",
  "react-dom": "^18.0.0 || ^19.0.0"
}
```

## Requirements
This package uses `@lexical` internally which requires your bundler 
to support top-level await. Add this to your `vite.config.ts`:

build: { target: "es2022" },
optimizeDeps: { esbuildOptions: { target: "es2022" } }

## Usage

### Basic Example

```tsx
import GmailInbox, { type EmailData, type EmailOption } from "react-mail-inbox";
import "react-mail-inbox/styles.css";

function App() {
  // Fetch email suggestions from your API
  const fetchEmailOptions = async (query: string): Promise<EmailOption[]> => {
    const response = await fetch(`/api/emails/search?q=${query}`);
    return response.json();
  };

  // Handle email submission
  const handleSendEmail = (emailData: EmailData) => {
    console.log("Sending email:", emailData);
    // Send to your backend API
    fetch("/api/emails/send", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(emailData),
    });
  };

  return (
    <GmailInbox
      fetchEmailOptions={fetchEmailOptions}
      handleChange={handleSendEmail}
      initialTheme="dark"
    />
  );
}
```

### With Theme Control

```tsx
import GmailInbox, { useTheme, type Theme } from "react-mail-inbox";

function ThemeToggle() {
  const { theme, toggleTheme } = useTheme();

  return (
    <button onClick={toggleTheme}>
      {theme === "dark" ? "☀️  Light" : "🌙  Dark"}
    </button>
  );
}

function App() {
  const handleThemeChange = (theme: Theme) => {
    console.log("Theme changed to:", theme);
    // Save to localStorage, etc.
  };

  return (
    <GmailInbox
      fetchEmailOptions={fetchEmailOptions}
      handleChange={handleSendEmail}
      initialTheme="dark"
      onThemeChange={handleThemeChange}
      leftChildren={<ThemeToggle />}
    />
  );
}
```

### With Initial Data

```tsx
import GmailInbox, { type EmailData } from "react-mail-inbox";

function ReplyToEmail() {
  const initialData: Partial<EmailData> = {
    to: [{ email: "recipient@example.com", name: "John Doe" }],
    subject: "Re: Previous conversation",
    body: "<p>Thanks for your message!</p>",
  };

  return (
    <GmailInbox
      fetchEmailOptions={fetchEmailOptions}
      handleChange={handleSendEmail}
      initialData={initialData}
    />
  );
}
```

## API Reference

### GmailInbox Props

| Prop                | Type                                        | Required | Description                               |
| ------------------- | ------------------------------------------- | -------- | ----------------------------------------- |
| `fetchEmailOptions` | `(query: string) => Promise<EmailOption[]>` | ✅       | Async function to fetch email suggestions |
| `handleChange`      | `(emailData: EmailData) => void`            | ✅       | Callback fired when user sends email      |
| `initialData`       | `Partial<EmailData>`                        | ❌       | Pre-populate email fields                 |
| `initialTheme`      | `'light' \| 'dark'`                         | ❌       | Initial theme (default: `'dark'`)         |
| `onThemeChange`     | `(theme: Theme) => void`                    | ❌       | Callback when theme changes               |
| `leftChildren`      | `ReactNode`                                 | ❌       | Custom content for left side of header    |
| `rightChildren`     | `ReactNode`                                 | ❌       | Custom content for right side of header   |

### Types

#### EmailData

```typescript
interface EmailData {
  to: EmailOption[];
  cc: EmailOption[];
  bcc: EmailOption[];
  subject: string;
  body: string; // HTML string
  attachments: File[];
}
```

#### EmailOption

```typescript
interface EmailOption {
  email: string;
  name: string;
}
```

#### Theme

```typescript
type Theme = "light" | "dark";
```

### useTheme Hook

Access theme state and controls from anywhere within the component tree:

```typescript
const { theme, toggleTheme, setTheme } = useTheme();
```

## Styling

The component comes with default styles that you must import:

```tsx
// Option 1 (recommended)
import "react-mail-inbox/styles.css";

// Option 2 (if the above doesn't work with your bundler)
import "react-mail-inbox/dist/index.css";
```

### CSS Custom Properties

You can customize the appearance using CSS variables:

```css
:root {
  --toolbar-bg: #f5f5f5;
  --toolbar-popup-bg: #ffffff;
  --text-color: #000000;
  --input-border: #cccccc;
  /* ... more variables */
}

[data-theme="dark"] {
  --toolbar-bg: #2d2d2d;
  --toolbar-popup-bg: #1e1e1e;
  --text-color: #ffffff;
  --input-border: #555555;
  /* ... more variables */
}
```

## Editor Features

The rich text editor includes:

- **Text Formatting**: Bold, Italic, Underline, Strikethrough
- **Lists**: Ordered and unordered lists
- **Alignment**: Left, center, right alignment
- **Font**: Font family and size selection
- **Colors**: Text and background color picker
- **Links**: Insert and edit hyperlinks
- **Indentation**: Increase/decrease indent
- **Undo/Redo**: Full history support

## File Uploads

The component supports drag-and-drop file uploads with:

- Multiple file selection
- File preview with name and size
- Remove individual files
- HEIC to JPEG conversion support
- Configurable file size limits

## Browser Support

- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)

## License

MIT

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## Support

For issues and feature requests, please use the GitHub issue tracker.
