lettuceai

Chat Composer

Component

About

A chat message composer with an auto-growing textarea, a live voice-recording waveform, attachment chips, and a single action button that adapts between send, stop, and continue.

Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds Chat Composer to your project and fits it to your theme.

Code

How Chat Composer is used: the demo's code. The component's own source comes with a free account.

Usage.tsx

"use client";

import { Composer } from "@/components/ui/composer";
import { useState } from "react";

interface ChatMessage {
  id: string;
  sender: "user" | "assistant";
  text: string;
}

export default function ComposerDemo() {
  const [value, setValue] = useState("");
  const [sending, setSending] = useState(false);
  const [messages, setMessages] = useState<ChatMessage[]>([
    {
      id: "1",
      sender: "assistant",
      text: "Hey! What are we working on today?",
    },
  ]);

  const handleSend = () => {
    const text = value.trim();
    if (!text) return;
    const userMessage: ChatMessage = {
      id: `${Date.now()}-user`,
      sender: "user",
      text,
    };
    setMessages((prev) => [...prev, userMessage]);
    setValue("");
    setSending(true);
    window.setTimeout(() => {
      setMessages((prev) => [
        ...prev,
        {
          id: `${Date.now()}-assistant`,
          sender: "assistant",
          text: "Got it — give me a moment.",
        },
      ]);
      setSending(false);
    }, 900);
  };

  return (
    <div className="flex min-h-[520px] w-full flex-col justify-end gap-4 bg-surface p-6">
      <div className="flex flex-1 flex-col justify-end gap-2 overflow-hidden">
        {messages.map((message) => (
          <div
            key={message.id}
            className={
              message.sender === "user"
                ? "ml-auto max-w-[75%] rounded-2xl bg-accent px-4 py-2 text-sm text-on-accent"
                : "mr-auto max-w-[75%] rounded-2xl bg-fill-2 px-4 py-2 text-sm text-fg"
            }
          >
            {message.text}
          </div>
        ))}
      </div>
      <Composer
        value={value}
        onChange={setValue}
        onSend={handleSend}
        onStop={() => setSending(false)}
        sending={sending}
        placeholder="Send a message…"
      />
    </div>
  );
}

Dependencies