Design System

Interactive Molecules

ImportCC

Available via @stackmates/ui-interactive/molecules

Dialog

Modal dialogs built on Radix UI Dialog primitive. Use for focused interactions that require user attention.

DialogProps

PropTypeDefaultDescription
openbooleanControlled open state
onOpenChange(open: boolean) => voidCalled when open state changes
children*ReactNodeDialogTrigger + DialogContent

Installation

typescript
import {
  Dialog, DialogContent, DialogHeader, DialogTitle,
  DialogDescription, DialogFooter, DialogTrigger,
} from '@stackmates/ui-interactive/molecules';

Usage

Controlled dialog

tsx
<Dialog open={open} onOpenChange={setOpen}>
  <DialogTrigger asChild><Button>Open</Button></DialogTrigger>
  <DialogContent>
    <DialogHeader><DialogTitle>Title</DialogTitle></DialogHeader>
    <DialogFooter><Button onClick={() => setOpen(false)}>Done</Button></DialogFooter>
  </DialogContent>
</Dialog>

Accessibility

  • Focus trapped inside dialog when open
  • Escape key closes the dialog
  • aria-labelledby linked to DialogTitle automatically
  • Background content marked as aria-hidden

Accordion

Expandable content sections. Supports single or multiple open items.

AccordionProps

PropTypeDefaultDescription
type*'single' | 'multiple'Allow one or many items open
collapsiblebooleanfalseAllow collapsing all items (single mode)

Installation

typescript
import {
  Accordion, AccordionContent, AccordionItem, AccordionTrigger,
} from '@stackmates/ui-interactive/molecules';

Usage

Single collapsible

tsx
<Accordion type="single" collapsible>
  <AccordionItem value="item-1">
    <AccordionTrigger>Section Title</AccordionTrigger>
    <AccordionContent>Content here</AccordionContent>
  </AccordionItem>
</Accordion>

Accessibility

  • Keyboard navigable with arrow keys
  • Space/Enter toggles sections
  • aria-expanded state managed automatically

AlertDialog

Confirmation dialog that interrupts workflow. Use for destructive actions requiring explicit user consent.

AlertDialogProps

PropTypeDefaultDescription
openbooleanControlled open state
onOpenChange(open: boolean) => voidCalled when open state changes

Installation

typescript
import {
  AlertDialog, AlertDialogAction, AlertDialogCancel,
  AlertDialogContent, AlertDialogDescription,
  AlertDialogFooter, AlertDialogHeader, AlertDialogTitle,
  AlertDialogTrigger,
} from '@stackmates/ui-interactive/molecules';

Accessibility

  • role="alertdialog" for screen readers
  • Cannot be dismissed by clicking outside (requires explicit action)
  • Focus returns to trigger on close
Related:

MessageRow

Single message with avatar. User right-aligned, assistant left-aligned. Supports streaming indicator.

OR
Orchestrator

I'll analyze your pipeline using the optimal-stopping algorithm.

Run the sales-rfp workflow for the Acme deal.

OR
Orchestrator

Starting the sales-rfp-workflow...

MessageRowProps

PropTypeDefaultDescription
message*MessageRowDataMessage data object with id, role, content, agentName, isStreaming
classNamestringAdditional CSS classes

Installation

typescript
import { MessageRow } from '@stackmates/ui-interactive/molecules';

Usage

Assistant message

tsx
<MessageRow message={{ id: '1', role: 'assistant', content: 'Hello!', agentName: 'Bot' }} />

Streaming message

tsx
<MessageRow message={{ id: '2', role: 'assistant', content: 'Typing...', isStreaming: true }} />

Accessibility

  • Messages use semantic list structure
  • Role (user/assistant) conveyed via visual alignment and labels

MessageComposer

Textarea + send button. Enter sends, Shift+Enter for newline.

MessageComposerProps

PropTypeDefaultDescription
value*stringCurrent textarea value
onChange*(value: string) => voidValue change handler
onSubmit*() => voidSend handler (also triggered by Enter key)
isLoadingbooleanfalseDisable input while sending
placeholderstring'Type a message...'Placeholder text

Installation

typescript
import { MessageComposer } from '@stackmates/ui-interactive/molecules';

Accessibility

  • Textarea auto-resizes to content
  • Enter key submits (keyboard shortcut)
  • Shift+Enter creates newline
  • Send button disabled when loading

EntitySelector

Pick entity from list with avatar initials, description, and badges.

EntitySelectorProps

PropTypeDefaultDescription
entities*EntityItem[]List of selectable entities (id, name, description, badges)
selectedIdstringCurrently selected entity ID
onSelect*(id: string) => voidSelection handler

Installation

typescript
import { EntitySelector } from '@stackmates/ui-interactive/molecules';

Usage

Basic usage

tsx
<EntitySelector
  entities={[{ id: '1', name: 'Agent', description: 'Desc', badges: ['tag'] }]}
  selectedId={selected}
  onSelect={setSelected}
/>
Accessibility notesContribute this section

StageCard

Workflow stage with status badge, agent name, duration, and confidence score.

Research & Discovery
Knowledge Architect
8.5s92%completed
Strategy Analysis
Navigator
running
Content Generation
Orchestrator
pending
Data Validation
Navigator
3.2sfailed

StageCardProps

PropTypeDefaultDescription
stage*StageCardDataStage data (id, name, status, agent, durationMs, confidence)
classNamestringAdditional CSS classes

Installation

typescript
import { StageCard } from '@stackmates/ui-interactive/molecules';

Usage

Completed stage

tsx
<StageCard stage={{
  id: '1', name: 'Research', status: 'completed',
  agent: 'Architect', durationMs: 8500, confidence: 0.92
}} />
Accessibility notesContribute this section