Documentation
AI IntegrationAI Components

AI Components

Customizable AI interface components with multiple style variants for building chat applications

Sushify Next.js includes pre-built, customizable AI components that make it easy to create beautiful chat interfaces. Each component comes with multiple style variants to match your design preferences.

Overview

The AI components are located in /apps/web/modules/saas/ai/components/ui/ and provide ready-to-use building blocks for AI chat interfaces. All components are fully typed with TypeScript and integrate seamlessly with the project's theme system.

Available Components

Message Input

A rich text input component for sending messages to AI. Comes with 5 style variants to match different design aesthetics.

Location: /apps/web/modules/saas/ai/components/ui/MessageInput/

Features:

  • File attachment support
  • Character count display
  • Voice input option
  • Keyboard shortcuts (Enter to send, Shift+Enter for new line)
  • Loading states

Variants:

1. Modern (ModernMessageInput.tsx)

  • Card-based design with backdrop blur
  • Separate action buttons (attach, voice, send)
  • Status bar with file count and keyboard hints
  • Gradient send button
  • Character counter badge
import { MessageInput } from "@/modules/saas/ai/components/ui/MessageInput/ModernMessageInput";

<MessageInput
  value={input}
  onChange={setInput}
  onSubmit={handleSubmit}
  onFileSelect={handleFileSelect}
  fileCount={files.length}
  isLoading={isLoading}
  maxLength={2000}
/>

2. Bubble (BubbleMessageInput.tsx)

  • Rounded bubble design (border-radius: 3xl)
  • Compact inline layout
  • Circular send button
  • Minimalist appearance
  • Status info below input
import { MessageInput } from "@/modules/saas/ai/components/ui/MessageInput/BubbleMessageInput";

<MessageInput
  value={input}
  onChange={setInput}
  onSubmit={handleSubmit}
  placeholder="Type your message..."
/>

3. Classic (ClassicMessageInput.tsx)

  • Traditional two-layer design
  • Separate header and footer areas
  • Explicit send button with label
  • Multiple action buttons in footer
  • Border-based styling
import { MessageInput } from "@/modules/saas/ai/components/ui/MessageInput/ClassicMessageInput";

<MessageInput
  value={input}
  onChange={setInput}
  onSubmit={handleSubmit}
  showFileButton={true}
/>

4. Compact (CompactMessageInput.tsx)

  • Single-line minimal design
  • Space-efficient layout
  • Ideal for tight spaces
  • Small action buttons
  • No extra status bars
import { MessageInput } from "@/modules/saas/ai/components/ui/MessageInput/CompactMessageInput";

<MessageInput
  value={input}
  onChange={setInput}
  onSubmit={handleSubmit}
/>

5. Minimal (MinimalMessageInput.tsx)

  • Bottom-border only design
  • Ultra-clean appearance
  • No background or borders
  • Icon-only buttons
  • Perfect for minimal UIs
import { MessageInput } from "@/modules/saas/ai/components/ui/MessageInput/MinimalMessageInput";

<MessageInput
  value={input}
  onChange={setInput}
  onSubmit={handleSubmit}
/>

Message Item

A component for displaying chat messages with user/AI avatars. Comes with 3 style variants.

Location: /apps/web/modules/saas/ai/components/ui/MessageItem/

Features:

  • User and AI avatar display
  • File preview support
  • Timestamp display
  • Action buttons (copy, regenerate)
  • Role-based styling

Variants:

1. Modern (ModernMessageItem.tsx)

  • Card-based message bubbles
  • Gradient avatars (rounded-xl)
  • Role badges (You / AI Assistant)
  • Timestamps with clock icon
  • Hover-visible action buttons
  • Shadow and border styling
import { MessageItem } from "@/modules/saas/ai/components/ui/MessageItem/ModernMessageItem";

<MessageItem
  message={{
    id: "msg-1",
    role: "user",
    content: "Hello, how can I help?"
  }}
  showTimestamp={true}
  showActions={true}
  onCopy={handleCopy}
  onRegenerate={handleRegenerate}
/>

2. Bubble (BubbleMessageItem.tsx)

  • Classic chat bubble appearance
  • Rounded corners with small tail
  • Left-aligned for AI, right-aligned for user
  • Smaller circular avatars
  • Color-coded by role (primary for user, muted for AI)
  • Floating layout
import { MessageItem } from "@/modules/saas/ai/components/ui/MessageItem/BubbleMessageItem";

<MessageItem
  message={{
    id: "msg-2",
    role: "assistant",
    content: "I'm here to help!"
  }}
/>

3. Minimal (MinimalMessageItem.tsx)

  • List-style layout
  • Border-bottom separator
  • Small circular avatars
  • Text-based role labels
  • Clean and simple
  • Efficient use of space
import { MessageItem } from "@/modules/saas/ai/components/ui/MessageItem/MinimalMessageItem";

<MessageItem
  message={{
    id: "msg-3",
    role: "user",
    content: "What can you do?"
  }}
/>

Common Props

MessageInput Props

PropTypeDefaultDescription
valuestring-Current input value (required)
onChange(value: string) => void-Input change handler (required)
onSubmit(e: FormEvent) => void-Form submit handler (required)
onKeyDown(e: KeyboardEvent) => void-Keyboard event handler
onFileSelect() => void-File selection handler
disabledbooleanfalseDisable input
placeholderstringvariesPlaceholder text
isLoadingbooleanfalseShow loading state
fileCountnumber0Number of attached files
maxLengthnumber-Maximum character count
showFileButtonbooleantrueShow file attachment button
showCharacterCountbooleantrueShow character counter
classNamestring-Additional CSS classes

MessageItem Props

PropTypeDefaultDescription
messageMessageItemData-Message data object (required)
isLastbooleanfalseIs this the last message
avatarobjectdefaultCustom avatar components
classNamestring-Additional CSS classes
showTimestampbooleantrueShow message timestamp
showActionsbooleantrueShow action buttons
onCopy(content: string) => void-Copy content handler
onRegenerate(id: string) => void-Regenerate handler

MessageItemData Type

interface MessageItemData {
  id: string;
  role: "user" | "assistant" | "system";
  content?: string;
  parts?: MessagePart[];
  files?: FilePreviewItem[];
}

interface MessagePart {
  type: string;
  text?: string;
  mediaType?: string;
  filename?: string;
  url?: string;
}

Choosing a Style

When selecting a component variant, consider:

  1. Modern - Best for feature-rich applications with lots of metadata
  2. Bubble - Perfect for mobile-first or messaging-style interfaces
  3. Classic - Ideal for professional/enterprise applications
  4. Compact - Use when screen space is limited
  5. Minimal - Great for clean, distraction-free experiences

All variants:

  • Support the same core functionality
  • Work with the theme system
  • Are fully responsive
  • Include accessibility features
  • Are TypeScript-typed

Theme Integration

All components automatically adapt to your chosen color kit. They use CSS variables for colors:

  • --background
  • --foreground
  • --primary
  • --secondary
  • --muted
  • --accent
  • --border

See the Styling documentation for more information on customizing themes.

Example: Complete Chat Interface

Here's a complete example combining both components:

ChatInterface.tsx
"use client";

import { useState } from "react";
import { MessageInput } from "@/modules/saas/ai/components/ui/MessageInput/ModernMessageInput";
import { MessageItem } from "@/modules/saas/ai/components/ui/MessageItem/ModernMessageItem";

export function ChatInterface() {
  const [input, setInput] = useState("");
  const [messages, setMessages] = useState([
    {
      id: "1",
      role: "assistant" as const,
      content: "Hello! How can I help you today?"
    }
  ]);

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    if (!input.trim()) return;

    // Add user message
    const userMessage = {
      id: Date.now().toString(),
      role: "user" as const,
      content: input
    };
    setMessages([...messages, userMessage]);
    setInput("");

    // Simulate AI response
    setTimeout(() => {
      const aiMessage = {
        id: (Date.now() + 1).toString(),
        role: "assistant" as const,
        content: "This is a simulated response."
      };
      setMessages(prev => [...prev, aiMessage]);
    }, 1000);
  };

  return (
    <div className="flex flex-col h-screen">
      {/* Messages */}
      <div className="flex-1 overflow-y-auto p-4">
        {messages.map((message, index) => (
          <MessageItem
            key={message.id}
            message={message}
            isLast={index === messages.length - 1}
          />
        ))}
      </div>

      {/* Input */}
      <div className="border-t p-4">
        <MessageInput
          value={input}
          onChange={setInput}
          onSubmit={handleSubmit}
        />
      </div>
    </div>
  );
}

Mixing Variants

You can mix and match different variants in the same application:

// Use Modern input with Bubble messages
import { MessageInput } from "@/modules/saas/ai/components/ui/MessageInput/ModernMessageInput";
import { MessageItem } from "@/modules/saas/ai/components/ui/MessageItem/BubbleMessageItem";

// Or Minimal input with Modern messages
import { MessageInput } from "@/modules/saas/ai/components/ui/MessageInput/MinimalMessageInput";
import { MessageItem } from "@/modules/saas/ai/components/ui/MessageItem/ModernMessageItem";

Additional Components

The AI module also includes other utility components:

  • ChatSidebar - Conversation history sidebar
  • FilePreview - File display component
  • EmptyState - Empty chat placeholder
  • LoadingMessage - AI thinking indicator
  • FileUploadArea - Drag & drop file upload

These components work together with MessageInput and MessageItem to create complete chat interfaces.