Conversation

Keeps a scrollable message history at the latest response until the reader scrolls back.

You
What changed in the brief?
Assistant
Each decision now has an owner, a next step, and a supporting source.

History

Scroll back, then add a reply. Your place stays fixed until you choose Jump to latest.

YouComplete
What changed in the project brief?
AssistantComplete

The brief now names the owner and next step for each decision.

YouComplete
Are the sources still included?
AssistantComplete

Yes. Each decision keeps its supporting source beside the summary.

YouComplete
What should we finish before sharing it?
AssistantComplete

Confirm the owner for the launch review and add a date to the next step.

YouComplete
Can you summarize that as a checklist?
AssistantComplete

Check the owner, confirm the date, and review the source for each decision.

Recorded messages · No model connected

Use it for

  • A message history whose contents grow during a streamed response.
  • Keep MessageComposer outside the scrollable history.
  • Set autoScroll={false} to keep scrolling entirely manual.
  • CSS-only markup provides native scrolling; following and the jump action require React or application code.

Avoid

  • Putting an entire workbench in the message log.
  • Using this component to fetch messages, render Markdown, or own a model connection.

React package

npm install @noorddev/vlak-react

Load the stylesheet once at your app root, then import the components you use.

import "@noorddev/vlak-react/css";
import { Conversation, MessageComposer, Response, ResponseActions, type ComposedMessage } from "@noorddev/vlak-react";

Per-component imports are available at @noorddev/vlak-react/components/conversation.

Copy the source

npx @noorddev/vlak-cli add conversation

Adds the component and its dependencies to components/vlak/. Follow the StyleX setup to compile the source in your application.

shadcn registry

npx shadcn add https://vlak.dev/r/conversation.json

Installs the same source through the shadcn CLI.

import { Conversation, MessageComposer, Response, ResponseActions, type ComposedMessage } from "@noorddev/vlak-react";

export function DocumentConversation({ onSend, generating, onStop }: {
  onSend: (message: ComposedMessage) => void | Promise<void>;
  generating: boolean;
  onStop: () => void;
}) {
  return <>
    <Conversation label="Document conversation" maxHeight="28rem">
      <Response from="user">Summarize this document.</Response>
      <Response actions={<ResponseActions text="The document has three sections." />}>
        <p>The document has three sections.</p>
      </Response>
    </Conversation>
    <MessageComposer compact maxRows={6} sendOnEnter onSend={onSend} generating={generating} onStop={onStop} />
  </>;
}

See the integration example to compose these components with your application's model and data.

Conversation

A message history that follows new content without taking the reader away from earlier messages.

PropTypeDefaultDescription
labelstring"Conversation"Accessible name of the scrollable message history.
maxHeightProperty.MaxHeight<string | number>"28rem"Maximum height of the message history, before it scrolls.
autoScrollbooleantrueFollow new content while the reader is at the end.
latestLabelstring"Jump to latest"

Also accepts HTMLAttributes<HTMLDivElement>.

The ref reaches HTMLDivElement.

KeysDoes
TabFocuses the scrollable log and its interactive contents
Arrow keys, Page Up, Page DownScrolls the focused history using native browser behavior
Enter, SpaceActivates Jump to latest and returns focus to the history
  • The message log has a supplied accessible label and a keyboard entry point.
  • The log uses aria-live=off; use Response status announcements rather than announcing every streamed token.
  • New content follows only while the reader is within 24px of the end. Scrolling back preserves the reading position.
  • Jump to latest is a native 44px Button. Automatic scrolling is immediate and never moves focus.
  • The ref and native attributes reach the outer div; maxHeight sets the inner scrollable history.

The same styles are available as CSS. Native HTML provides the static presentation; React or application code supplies state updates and actions.

npm install @noorddev/vlak
import "@noorddev/vlak/css";
<div class="rs-conversation"><div class="rs-conversation-viewport" role="log" aria-label="Conversation" aria-live="off" tabindex="0" style="max-height:28rem"><div class="rs-conversation-content"><p>You: Summarize this document.</p><p>Assistant: The document has three sections.</p></div></div></div>

Classes

.rs-conversation.rs-conversation-viewport.rs-conversation-content.rs-conversation-footer