Appearance
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
- EmojiSelector from svelte-emoji-selector
- PreviewImage
Usage Example
svelte
<ChatInput
on:message={(event) => {
// Handle new message
console.log(event.detail.content);
console.log(event.detail.contentType);
}}
/>