Stepwise UI

Conversation Timeline

A dense rail of thin marks, one per message, that expands into a labelled list on hover. Hover or keyboard-focus the rail and it expands: every row grows and its label fades in. The row under the cursor gets extra emphasis on top - its mark brightens, its label bolds and nudges out. Click any mark to select it.

Installation

npx stepwise-ui add conversation-timeline

Default

Hover the rail (or Tab into it) to expand every row at once. Then hover a specific row for its extra emphasis.
import { ConversationTimeline } from '@/components/stepwise/conversation-timeline'

const checkpoints = [
  { id: '1', role: 'system',    label: 'System prompt' },
  { id: '2', role: 'user',      label: 'Can you help me set up auth?' },
  { id: '3', role: 'assistant', label: 'Of course - let me walk you through it' },
]

const [activeId, setActiveId] = useState('2')

<ConversationTimeline
  checkpoints={checkpoints}
  activeId={activeId}
  onSelect={setActiveId}
/>

Left side

Flip the labels to the left of the marks and recolour the active line with accent.
<ConversationTimeline
  checkpoints={checkpoints}
  side="left"
  accent="#8b5cf6"
/>

Props

PropTypeDescription
checkpoints
TimelineCheckpoint[]
Array of checkpoint objects.
activeId
string
The currently selected checkpoint id.
onSelect
(id: string) => void
Called when a mark is clicked.
side
"left" | "right"
Which side labels appear on. Default "right".
rowHeight
number
Per-row height once expanded (px). Default 24.
collapsedRowHeight
number
Per-row height at rest (px). Default 8.
accent
string
Active line colour. Default '#0ea5e9'.

TimelineCheckpoint

PropTypeDescription
id
string
Unique identifier.
label
string
The chat label revealed on hover.
sublabel
string
Optional - reserved for richer labels.
role
"user" | "assistant" | "system"
Optional role tag for your own styling.