Skip to content

ChatInput Component

  • File: src/components/chat/chatInput.svelte

Overview

The ChatInput component provides a rich text input interface for chat messages, supporting text messages, emoji selection, file attachments, and image uploads. It features a modern UI with interactive elements and real-time preview capabilities.

Component State

svelte
interface Message {
  content: string;
  contentType: string;
}

let message = {
  content: "",
  contentType: "text"
};

let imageInput = {};
let showImage = false;
let open = false;
let textArefoucussed = false;

Features

1. Message Input

  • Text area with auto-focus management
  • Enter key handling for message sending
  • Active state styling
  • Placeholder text

2. File Attachments

Supports two types of file uploads:

1. Documents

  • Formats: .xls, .xlsx, .docx, .pdf

2. Images

  • Formats: .png, .jpeg, .jpg, .webp, .avif, .svg

Event Handlers

Message Sending

svelte
function sendMessage() {
  if (message.content.length > 0) {
    dispatch("message", message);
    message = { content: "", contentType: "text" };
  }
}

File Handling

svelte
function loadFile(e) {
  let image = e.target.files[0];
  let reader = new FileReader();
  reader.readAsDataURL(image);

  reader.onload = e => {
    imageInput = {
      name: image.name,
      content: e.target.result
    };
  }
  showImage = true;
  open = false;
}

Keyboard Events

svelte
function onKeyUp(e: KeyboardEvent) {
  if (e.code === "Enter" && message.content && !e.shiftKey) {
    dispatch("message", message);
    message = { content: "", contentType: "text" };
  }
}

UI Components

1. Message Input Area

svelte
<div class="rounded-md px-2 mx-2 bg-gray-100"
     class:active={textArefoucussed || message.content.length > 0}>
  <textarea
    bind:value={message.content}
    on:keyup={onKeyUp}
    rows="1"
    class="flex-grow rounded-full p-2 mt-1 focus:outline-none bg-transparent"
    placeholder="Type a new message"
  />
</div>

2. Action Buttons

svelte
<div class="flex justify-between mx-4">
  <!-- Left side buttons -->
  <div class="flex gap-3">
    <EmojiSelector on:emoji={onEmoji}/>
    <Icon src={PaperClip} size=19 />
  </div>

  <!-- Send button -->
  <Icon src={SendPlane2} size=19/>
</div>

3. Attachment Menu

svelte
<ul class="absolute bottom-6 left-8">
  <!-- Document upload -->
  <li class="rounded-full p-2 bg-gradient-to-b from-blue-500 to-blue-300">
    <input type="file" accept=".xls, .xlsx, .docx, .pdf" />
  </li>

  <!-- Image upload -->
  <li class="rounded-full p-2 bg-gradient-to-b from-purple-500 to-pink-500">
    <input type="file" accept=".png, .jpeg, .jpg, .webp, .avif, .svg" />
  </li>
</ul>

Styling

CSS Classes

css
.active {
  @apply border-indigo-900 border-b-2;
}

.btnText {
  @apply text-slate-400 hover:text-indigo-600;
}

Animation

Uses Svelte's fly transition for attachment menu:

svelte
transition:fly={{y:50}}

Events

Dispatched Events

svelte

// Message sent
dispatch("message", message)

// Image preview closed
dispatch("getImage")

Listened Events

svelte
// Emoji selected
on:emoji={onEmoji}

// Click outside
on:outsideclick={()=>open=false}

Dependencies

Components

Usage Example

svelte

<ChatInput
  on:message={(event) => {
    // Handle new message
    console.log(event.detail.content);
    console.log(event.detail.contentType);
  }}
/>

Released under the MIT License.