Skip to Content
Components

Thread panel

Switch between agent threads and reply in place.

A thread panel holds several conversations with an agent, one tab each, with a reply field under the open one. The tabs switch which thread is shown and an underline slides to the open one; switching staggers that thread's messages in, and a later message glides into view. Each agent message can carry sources — the files or pages it used — and a thinking message shimmers while the agent works on a reply.

Preview
Why is the workspace step losing people?
It asks for a team name before anyone has made anything. Moving it after the first project, with the name filled from the email domain, should help.

Usage

<!-- include core.css + thread-panel.css -->
<div class="dm-thp dm-panel">
  <div class="dm-thp-tabs" role="tablist">
    <button class="dm-thp-tab" role="tab" aria-selected="true">
      <span class="dm-dot" style="color:var(--dm-ok-mark)"></span>Onboarding
    </button>
    <!-- more tabs -->
    <span class="dm-thp-ink"></span>
  </div>
  <div class="dm-thp-body" aria-live="polite">
    <div class="dm-bub">Why is the workspace step losing people?</div>
    <div class="dm-thp-ag">Moving the team-name step after the first project should help.</div>
  </div>
  <form class="dm-thp-in">
    <input class="dm-thp-field" aria-label="Reply" placeholder="Reply to the agent" />
    <button class="dm-thp-send" aria-label="Send" disabled><!-- up arrow --></button>
  </form>
</div>

Properties

NameTypeDescription
threadsThread[]The conversations, one tab each.
valuestringThe id of the open thread. Leave it out to let the tabs switch it.
defaultValuestringThe thread open at first when uncontrolled. Defaults to the first thread.
onValueChange(id) => voidCalled when a tab opens another thread.
onSend(text, threadId) => voidCalled with the reply and the open thread's id. Add the message to that thread to show it.
draftstringThe reply being written. Leave it out to let the field keep its own.
defaultDraftstringThe reply written at first when uncontrolled.
onDraftChange(text) => voidCalled as the reply field changes.
placeholderstringThe reply field's placeholder. Defaults to Reply to the agent.
barebooleanSits flat in a chat column (the default). Set false to give it a card of its own.
Thread.colorstringThe dot in front of the title, any CSS colour. Defaults to a quiet grey.
ThreadMessage.sourcesSource[]Files or pages the agent used, shown as chips above its reply.
ThreadMessage.thinkingbooleanShows a shimmering line while the agent works on a reply.

Theming

Works in light and dark (data-theme="dark") and in the Soft style (data-style="soft"). The open tab's underline uses the accent mark token and the reply field sits on a surface with an inset field line, so it reads against the dark stage; in Soft the field is rounder (squircle).

On this page