npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@iv-swat/chat-widget

v2.0.13

Published

A modern, animated chat interface component for React applications with CopilotKit integration

Downloads

30

Readme

@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:
# Using npm
npm install @iv-swat/chat-widget lucide-react framer-motion

# Using yarn
yarn add @iv-swat/chat-widget lucide-react framer-motion
  1. Add Tailwind CSS configuration:

Make sure you have Tailwind CSS installed and add these configurations to your tailwind.config.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: [],
}
  1. Import the styles in your main CSS file:
@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.

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.

// 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

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)

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)

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)

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

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

Welcome Message Configuration

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

Message UI Configuration

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:

<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