npm

Guides

Chat

A messaging demo at /chat: a searchable conversation list on the left, a message thread with sent and received bubbles on the right, and a composer that keeps the thread pinned to the newest message. No chat library, just Input, Button, cn, and a little state.

See it live

Open /chat (sidebar → shadcn/ui → Chat). Pick a conversation, type a message, press Enter or Send.

Anatomy

  • Conversation list: a search Input plus one button per conversation (avatar initials, name, last message, time). The active row is tinted with bg-accent.
  • Thread: a header naming the contact, then a scrolling column of bubbles. Messages you send use the primary token and align right; the ones you receive use a bordered card and align left.
  • Composer: an Input plus a primary Send. Enter sends; empty messages are blocked.

Data

model
type Msg = { id: number; from: "me" | "them"; text: string; time: string };
type Convo = {
  id: number;
  name: string;
  role: string;
  color: string;   // avatar bg (static Tailwind class)
  messages: Msg[];
};

Auto-scroll

A ref on the thread, plus an effect keyed on the message count, keeps the view pinned to the latest bubble.

auto-scroll
React.useEffect(() => {
  const el = scrollRef.current;
  if (el) el.scrollTop = el.scrollHeight;
}, [active.messages.length, activeId]);

Swap the demo state for your API

Conversations and messages live in local state here. Point setConvos at your backend (or a socket) and the UI stays exactly the same. Avatar colors follow the same static-Tailwind convention as the tab and calendar color labels.