Skip to content
Chat

ChatLayout

Full chat shell with scrollable messages and a composer dock.

ChatLayout

Full chat shell with a scrollable message area above a sticky composer dock. Includes a default scroll-to-bottom / new-messages button wired to useChatStreamScroll and useChatNewMessages.

Examples

Default

There is no @var-ui/astro ChatLayout — Astro and HTML previews show a static core-recipe shell; scroll and send behavior are React-only.

A
Assistant
Hello! How can I help?
Demo.tsxtsx
import { useState } from 'react';
import {
  Avatar,
  ChatComposer,
  ChatComposerInput,
  ChatLayout,
  ChatMessage,
  ChatMessageBubble,
  ChatMessageList,
  ChatSendButton,
} from '@var-ui/react';

function ChatShell() {
  const [value, setValue] = useState('');
  const [messages, setMessages] = useState(['Hello! How can I help?']);

  function send(text: string) {
    setMessages((prev) => [...prev, text]);
    setValue('');
  }

  return (
    <ChatLayout
      composer={
        <ChatComposer actions={<ChatSendButton onPress={() => send(value)} />}>
          <ChatComposerInput value={value} onChange={setValue} onSubmit={send} />
        </ChatComposer>
      }
    >
      <ChatMessageList>
        {messages.map((text, index) => (
          <ChatMessage
            key={`${text}-${index}`}
            sender={index % 2 === 0 ? 'assistant' : 'user'}
            name={index % 2 === 0 ? 'Assistant' : 'You'}
            avatar={<Avatar name={index % 2 === 0 ? 'Assistant' : 'You'} size="sm" />}
          >
            <ChatMessageBubble>{text}</ChatMessageBubble>
          </ChatMessage>
        ))}
      </ChatMessageList>
    </ChatLayout>
  );
}

Props

Accessibility

The message list uses role="log" with aria-live="polite". Pass isStreaming to ChatMessageList so screen readers announce completed messages once during streaming.