npm package: @iv-swat/chat-widget
Description: A modern, animated chat interface component for React applications with CopilotKit integration
Author: IV SWAT
Latest version: 2.0.13

# @iv-swat/chat-widget

A modern, customizable chat widget for React applications with file upload support.

## Installation

1. Install the package and its peer dependencies:
```bash
# Using npm
npm install @iv-swat/chat-widget lucide-react framer-motion

# Using yarn
yarn add @iv-swat/chat-widget lucide-react framer-motion
```

2. Add Tailwind CSS configuration:

Make sure you have Tailwind CSS installed and add these configurations to your `tailwind.config.js`:

```js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    // ... your content configuration
    './node_modules/@iv-swat/chat-widget/**/*.{js,ts,jsx,tsx}'
  ],
  theme: {
    extend: {
      colors: {
        'hola': '#0EA5E9',
        'hola-dark': '#0284C7',
      },
      animation: {
        'fadeIn': 'fadeIn 0.5s ease-in-out',
        'slideDown': 'slideDown 0.3s ease-out',
        'slideUp': 'slideUp 0.3s ease-out',
        'spin-once': 'spin 0.5s ease-in-out',
        'text-slide-up': 'text-slide-up 0.5s ease-out forwards',
        'text-slide-up-1': 'text-slide-up 0.7s ease-out forwards',
        'text-slide-up-2': 'text-slide-up 0.9s ease-out forwards',
        'typing-1': 'typing 1s steps(20, end) forwards',
        'typing-2': 'typing 1.5s steps(40, end) 1s forwards',
        'typing-3': 'typing 2s steps(60, end) 2.5s forwards',
        'cursor-blink': 'cursor-blink 0.75s step-end infinite',
      },
      keyframes: {
        fadeIn: {
          '0%': { opacity: '0' },
          '100%': { opacity: '1' },
        },
        slideDown: {
          '0%': { transform: 'translateY(-100%)', opacity: '0' },
          '100%': { transform: 'translateY(0)', opacity: '1' },
        },
        slideUp: {
          '0%': { transform: 'translateY(100%)', opacity: '0' },
          '100%': { transform: 'translateY(0)', opacity: '1' },
        },
        'text-slide-up': {
          '0%': { 
            transform: 'translateY(40px)',
            opacity: '0'
          },
          '100%': {
            transform: 'translateY(0)',
            opacity: '1'
          },
        },
        typing: {
          '0%': { 
            width: '0',
            opacity: '1',
          },
          '100%': { 
            width: '100%',
            opacity: '1',
          },
        },
        'cursor-blink': {
          '0%, 100%': { borderRightColor: 'transparent' },
          '50%': { borderRightColor: 'currentColor' },
        },
      },
    },
  },
  plugins: [],
}
```

3. Import the styles in your main CSS file:

```css
@tailwind base;
@tailwind components;
@tailwind utilities;

/* Add these custom utilities */
@layer utilities {
  .no-scrollbar::-webkit-scrollbar {
    display: none;
  }
  
  .no-scrollbar {
    -ms-overflow-style: none;
    scrollbar-width: none;
  }
}
```

## Features

- 🎨 Modern and responsive design
- 📁 File upload support (drag & drop or button)
- ⌨️ Keyboard shortcuts:
  - ESC to close chat
  - Ctrl + N (or Command + N on Mac) for new chat
  - Enter to send message
- 🎯 Quick action buttons
- 🌈 Customizable themes
- 📱 Responsive layout integration
- 🔧 Highly configurable

## Integration Methods

### 1. Using Layout (For Sidebar Integration)

The `Layout` component provides a smooth, animated sidebar layout with your main content. This is ideal for applications that want a persistent chat interface that smoothly transitions in and out.

```tsx
import { Layout } from '@iv-swat/chat-widget';

function App() {
  const [isChatExpanded, setIsChatExpanded] = useState(false);

  return (
    <Layout 
      isChatExpanded={isChatExpanded}
      chatWidth={500} // Optional: customize chat sidebar width (default: 500px)
      chatContent={
        <ChatBox 
          onClose={() => setIsChatExpanded(false)}
          title="Chat with AI"
          theme={{
            primary: '#0EA5E9',
            secondary: '#0284C7',
            textColor: '#1F2937'
          }}
          // ... other ChatBox props
        />
      }
    >
      {/* Your main content */}
      <div className="p-4">
        <h1>Your Application</h1>
        {/* ... */}
      </div>
    </Layout>
  );
}
```

#### Layout Features:
- 🎯 Customizable chat sidebar width (default: 500px)
- 🌊 Smooth spring animations using Framer Motion
- 📱 Consistent sidebar behavior across all screen sizes
- 🎨 Clean and modern design
- 🔄 Automatic content resizing

#### Layout Props

| Prop | Type | Description |
|------|------|-------------|
| `children` | `ReactNode` | Your main application content |
| `isChatExpanded` | `boolean` | Controls whether the chat sidebar is visible |
| `chatContent` | `ReactNode` | The chat interface to show in the sidebar (typically `ChatBox`) |
| `chatWidth` | `number` | Width of the chat sidebar in pixels (default: 500) |

### 2. Using ChatLayout (Alternative)

The `ChatLayout` component is the recommended way to integrate the chat widget into your application. It handles responsive behavior and layout adjustments automatically.

```tsx
// pages/_app.tsx or App.tsx
import { ChatLayout } from '@iv-swat/chat-widget';

function MyApp({ Component, pageProps }) {
  // Handle chat messages with your backend
  const handleMessage = async (message: string) => {
    try {
      const response = await fetch('your-api-endpoint', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ message })
      });
      const data = await response.json();
      return data.response;
    } catch (error) {
      console.error('Error:', error);
      return "Sorry, I'm having trouble connecting to the server.";
    }
  };

  return (
    <ChatLayout
      onMessage={handleMessage}
      config={{
        theme: {
          primary: '#0EA5E9',
          secondary: '#0284C7',
          textColor: '#1F2937'
        },
        welcomeConfig: {
          title: "Hi, How can I help you?",
          description: "I'm here to assist you!"
        },
        messageUIConfig: {
          userBubbleColor: '#0EA5E9',
          botBubbleColor: '#F8F9FA'
        }
      }}
    >
      <Component {...pageProps} />
    </ChatLayout>
  );
}

export default MyApp;
```

The `ChatLayout` component provides:
- Automatic responsive layout management
- Smooth transitions for chat widget
- Chat state management (open/close)
- Proper layout on all screen sizes
- Main content adjustment when chat is open
- Full-screen overlay on mobile

#### Layout Behavior

1. **Desktop (lg screens)**:
   - Main content shrinks by 400px when chat is open
   - Chat appears as a sidebar
   - Smooth transitions

2. **Tablet (md screens)**:
   - Main content shrinks by 320px when chat is open
   - Chat appears as a narrower sidebar
   - Smooth transitions

3. **Mobile (sm screens)**:
   - Chat appears as a full-screen overlay
   - Main content remains unchanged
   - Smooth transitions

## Basic Usage

```tsx
import { ChatWidget, ChatBox, ChatLayout } from '@iv-swat/chat-widget';

// Basic implementation
function App() {
  return (
    <ChatWidget
      title="Chat with AI"
      onSendMessage={async (message, file) => {
        // Handle message and file here
        console.log('Message:', message);
        console.log('File:', file);
        return 'Response from AI';
      }}
    />
  );
}
```

## Components

### 1. ChatWidget (Floating Button + Chat)

```tsx
import { ChatWidget } from '@iv-swat/chat-widget';

function App() {
  return (
    <ChatWidget
      title="Chat with AI"
      theme={{
        primary: '#0EA5E9',
        secondary: '#0284C7',
        textColor: '#1F2937'
      }}
      welcomeMessage={{
        title: 'Welcome!',
        description: 'How can I help you today?'
      }}
      quickActions={[
        { text: 'Help', onClick: (text) => console.log(text) },
        { text: 'Features', onClick: (text) => console.log(text) }
      ]}
      messageConfig={{
        userBubbleColor: '#0EA5E9',
        botBubbleColor: '#F8F9FA'
      }}
      onSendMessage={async (message, file) => {
        // Handle message and optional file
        return 'AI response';
      }}
      onError={(error) => {
        console.error('Error:', error);
      }}
      maxFileSize={5} // Maximum file size in MB
      acceptedFileTypes={['image/*', '.pdf', '.doc', '.docx']}
    />
  );
}
```

### 2. ChatBox (Chat Interface Only)

```tsx
import { ChatBox } from '@iv-swat/chat-widget';

function App() {
  return (
    <div className="h-screen">
      <ChatBox
        title="Chat with AI"
        onClose={() => console.log('Chat closed')}
        // Same props as ChatWidget
      />
    </div>
  );
}
```

### 3. ChatLayout (Responsive Layout with Chat)

```tsx
import { ChatLayout } from '@iv-swat/chat-widget';

function App() {
  return (
    <ChatLayout
      config={{
        theme: {
          primary: '#0EA5E9',
          secondary: '#0284C7',
          textColor: '#1F2937'
        },
        welcomeConfig: {
          title: 'Welcome!',
          description: 'How can I help you today?'
        },
        messageUIConfig: {
          userBubbleColor: '#0EA5E9',
          botBubbleColor: '#F8F9FA'
        }
      }}
      onMessage={async (message) => {
        return 'AI response';
      }}
    >
      <main>
        {/* Your main content */}
        <h1>Your Application</h1>
      </main>
    </ChatLayout>
  );
}
```

## Props

### Common Props

| Prop | Type | Description |
|------|------|-------------|
| `title` | `string` | Chat widget title |
| `theme` | `Theme` | Custom theme colors |
| `welcomeMessage` | `WelcomeConfig` | Welcome message configuration |
| `quickActions` | `QuickAction[]` | Quick action buttons |
| `messageConfig` | `MessageUIConfig` | Message UI configuration |
| `onSendMessage` | `(message: string, file?: File) => Promise<string>` | Handler for sending messages |
| `onError` | `(error: Error) => void` | Error handler |
| `maxFileSize` | `number` | Maximum file size in MB |
| `acceptedFileTypes` | `string[]` | Accepted file types |

### Theme Configuration

```typescript
interface Theme {
  primary: string;    // Primary color
  secondary: string;  // Secondary color
  textColor: string;  // Text color
}
```

### Welcome Message Configuration

```typescript
interface WelcomeConfig {
  title: string;       // Welcome title
  description: string; // Welcome description
  icon?: ReactNode;    // Optional icon
}
```

### Message UI Configuration

```typescript
interface MessageUIConfig {
  userBubbleColor: string; // User message bubble color
  botBubbleColor: string;  // Bot message bubble color
}
```

## File Upload

The chat widget supports file uploads with the following features:
- Drag and drop files
- Click to upload button
- File size validation
- File type validation
- File preview before sending
- Attach files to messages

Example file upload handling:

```tsx
<ChatWidget
  maxFileSize={5} // 5MB
  acceptedFileTypes={['image/*', '.pdf', '.doc', '.docx']}
  onSendMessage={async (message, file) => {
    if (file) {
      const formData = new FormData();
      formData.append('file', file);
      formData.append('message', message);
      
      // Upload to your server
      const response = await fetch('your-api/upload', {
        method: 'POST',
        body: formData
      });
      
      return 'File uploaded successfully!';
    }
    
    // Handle text-only message
    return 'Message received!';
  }}
  onError={(error) => {
    console.error('Upload error:', error);
  }}
/>
```

## Keyboard Shortcuts

- `Enter`: Send message
- `Shift + Enter`: New line in message

## Styling

The chat widget uses Tailwind CSS classes by default. You can override styles by:

1. Using the theme prop for colors
2. Targeting specific classes in your CSS
3. Using the messageConfig prop for message bubbles

## Best Practices

1. **Error Handling**: Always provide an onError handler to manage errors gracefully
2. **File Validation**: Set appropriate maxFileSize and acceptedFileTypes
3. **Responsive Design**: Use ChatLayout for better integration with your app
4. **Message Handling**: Implement proper message handling in onSendMessage
5. **Theme Consistency**: Use theme colors that match your application

## License

MIT