Feedback Molecules
Available via @stackmates/ui-interactive/molecules
Progress
Determinate progress bar built on Radix Progress. Value controls fill percentage via CSS transform.
Empty (0%)
ProgressProps
| Prop | Type | Default | Description |
|---|---|---|---|
| value | number | — | Progress percentage (0-100) |
| className | string | — | Override track height/color via Tailwind |
Installation
import { Progress } from '@stackmates/ui-interactive/molecules';Accessibility
- Built on Radix Progress with role="progressbar" and aria-valuenow
- Indicator uses CSS transform for smooth animation
Toast (useToast)
Imperative toast system with 5 semantic variants and convenience methods. Requires Toaster provider in the tree.
Click a button to trigger a toast in the bottom-right corner.
toast() options
| Prop | Type | Default | Description |
|---|---|---|---|
| title | ReactNode | — | Bold heading text |
| description | ReactNode | — | Body text with detail |
| variant | 'default' | 'destructive' | 'success' | 'warning' | 'info' | 'default' | Semantic color variant with icon |
| action | ToastActionElement | — | Action button beside message |
Installation
import { toast, Toaster } from '@stackmates/ui-interactive/molecules';
// Layout: <Toaster /> | Handler: toast.success({ title: 'Saved' })Accessibility
- Built on Radix Toast with role="status" and aria-live
- Close button rendered for keyboard dismissal; swipe-to-dismiss on touch
AlertNotice (SimpleAlert)
Static alert banner with 5 variants. Compound: SimpleAlertTitle + SimpleAlertDescription for structured content.
Default alert
This is a default alert with title and description.
Info alert
This is a info alert with title and description.
Warning alert
This is a warning alert with title and description.
Error alert
This is a error alert with title and description.
Success alert
This is a success alert with title and description.
SimpleAlertProps
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | 'default' | 'info' | 'warning' | 'error' | 'success' | 'default' | Semantic color variant |
| children* | ReactNode | — | Content (use SimpleAlertTitle + SimpleAlertDescription) |
Installation
import { SimpleAlert, SimpleAlertTitle, SimpleAlertDescription } from '@stackmates/ui-interactive/molecules';Accessibility
- Root has role="alert" for screen reader announcement
- Title uses h5 for semantic heading structure
ErrorCard
Centered error card with icon, title, description, and a retry button that reloads the page.
Error Loading Data
Failed to load data
Connection Lost
Unable to reach the server. Check your network.
ErrorCardProps
| Prop | Type | Default | Description |
|---|---|---|---|
| title | string | 'Error Loading Data' | Error heading |
| description | string | 'Failed to load data' | Error message |
Installation
import { ErrorCard } from '@stackmates/ui-interactive/molecules';Accessibility
- Uses destructive color tokens; retry is a focusable Button atom
- Clear hierarchy: icon, title, description, action
ErrorRetryButton
Flexible error display with retry in three layouts: inline, card, and compact. Handles async retry with loading state.
Failed to load contacts
The server returned a 500 error.
Data sync failed
Changes could not be saved.
ErrorRetryButtonProps
| Prop | Type | Default | Description |
|---|---|---|---|
| message* | string | — | Error message to display |
| description | string | — | Optional detailed description |
| variant | 'error' | 'warning' | 'info' | 'error' | Visual variant |
| layout | 'inline' | 'card' | 'compact' | 'inline' | Layout style |
| onRetry | () => void | Promise<void> | — | Retry callback. Reloads page if omitted. |
| retryLabel | string | 'Retry' | Retry button text |
Installation
import { ErrorRetryButton } from '@stackmates/ui-interactive/molecules';Accessibility
- Semantic alert regions for screen readers
- Loading spinner on retry button during async operations
LoadingSkeletons
Pre-composed skeleton patterns for 9 content types. Each variant mimics real content layout during loading.
card
list
table
profile
metric
LoadingSkeletonsProps
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | 'card' | 'list' | 'table' | 'form' | 'article' | 'profile' | 'metric' | 'dashboard' | 'timeline' | 'card' | Skeleton layout pattern |
| count | number | 1 | Number of skeleton instances |
| className | string | — | Additional wrapper classes |
Installation
import { LoadingSkeletons } from '@stackmates/ui-interactive/molecules';Accessibility
- Uses animate-pulse (respects prefers-reduced-motion)
- Pair with aria-busy="true" on the loading container
StreamingText
Typewriter text display with animated cursor for AI-generated content. Fires onStreamComplete when streaming ends.
StreamingTextProps
| Prop | Type | Default | Description |
|---|---|---|---|
| content* | string | — | Text content to display |
| isStreaming* | boolean | — | Shows animated cursor when true |
| showCursor | boolean | true | Show cursor while streaming |
| cursorChar | string | '\u258B' | Custom cursor character |
| onStreamComplete | () => void | — | Callback when streaming stops |
Installation
import { StreamingText } from '@stackmates/ui-interactive/molecules';Accessibility
- aria-live="polite" announces new content; aria-busy during streaming
- Cursor is aria-hidden; sr-only text says "Content is being generated..."
AIInsightsPanel
Panel displaying AI-generated insights with type icons, confidence scores, optional actions, and dismissal. Supports loading skeleton and "show more" overflow.
AI Insights
High-value deal at risk
87%Deal #1042 has not had contact in 14 days. Similar deals that go cold have a 30% lower close rate.
Related to: Enterprise SaaS License
Follow up with Acme Corp
72%Based on engagement patterns, scheduling a call this week could increase close probability by 15%.
Pipeline concentration risk
91%60% of your Q2 pipeline is in a single industry vertical.
AIInsightsPanelProps
| Prop | Type | Default | Description |
|---|---|---|---|
| insights* | AIInsight[] | — | Array of insights with id, type, title, description, confidence |
| title | string | 'AI Insights' | Panel heading text |
| dismissible | boolean | false | Show dismiss button on each insight |
| onDismiss | (id: string) => void | — | Callback when an insight is dismissed |
| maxVisible | number | 5 | Max insights shown before "show more" button |
| isLoading | boolean | false | Show loading skeleton state |
Installation
import { AIInsightsPanel } from '@stackmates/ui-interactive/molecules';
import type { AIInsight } from '@stackmates/ui-interactive/molecules';Usage
Dashboard insights panel
<AIInsightsPanel
insights={insights}
dismissible
onDismiss={(id) => markDismissed(id)}
maxVisible={3}
isLoading={isLoading}
/>Accessibility
- Each insight card has data-testid for test targeting
- Dismiss button has aria-label "Dismiss insight"
- Confidence score rendered via AIConfidenceScoreCompact atom
StepsList
Progress steps indicator with status icons (pending, active, complete, error). Suited for pipeline and workflow visualization.
Data Pipeline
Fetch source data
2.4s
Validate schema
132 rows valid
Transform records
Processing batch 3 of 5...
Load into warehouse
Send notifications
SMTP timeout after 30s
StepsListProps
| Prop | Type | Default | Description |
|---|---|---|---|
| steps* | StepInfo[] | — | Array of { label, status, message? } where status is pending | active | complete | error |
| title | string | 'Pipeline Steps' | Heading text above the steps list |
Installation
import { StepsList } from '@stackmates/ui-interactive/molecules';
import type { StepInfo } from '@stackmates/ui-interactive/molecules';Usage
Basic pipeline steps
<StepsList
title="Import Pipeline"
steps={[
{ label: 'Upload file', status: 'complete' },
{ label: 'Validate', status: 'active', message: 'Checking...' },
{ label: 'Import', status: 'pending' },
]}
/>Accessibility
- Uses distinct icons (check, spinner, X) alongside color to convey status
- data-testid="steps-section" for test targeting
- Returns null when steps array is empty
AlertDialog
Modal confirmation dialog built on Radix AlertDialog. Requires explicit user action to dismiss -- there is no close button or click-outside dismissal. Ideal for destructive or irreversible actions.
AlertDialog (root)
| Prop | Type | Default | Description |
|---|---|---|---|
| open | boolean | — | Controlled open state |
| onOpenChange | (open: boolean) => void | — | Callback when open state changes |
| defaultOpen | boolean | false | Initial open state (uncontrolled) |
Installation
import {
AlertDialog, AlertDialogTrigger, AlertDialogContent,
AlertDialogHeader, AlertDialogTitle, AlertDialogDescription,
AlertDialogFooter, AlertDialogAction, AlertDialogCancel,
} from '@stackmates/ui-interactive/molecules';Usage
Delete confirmation
<AlertDialog>
<AlertDialogTrigger asChild>
<Button variant="destructive">Delete</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Confirm deletion</AlertDialogTitle>
<AlertDialogDescription>This cannot be undone.</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction onClick={handleDelete}>Delete</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>Accessibility
- Built on Radix AlertDialog with role="alertdialog"
- Focus trapped inside the dialog while open
- No close-on-click-outside -- user must choose an action
- Cancel and Action buttons use Button atom variants
HoverCardRx
Hover-triggered popover card built on Radix HoverCard. Displays rich content on pointer hover with animated enter/exit transitions. Best for previewing supplementary info without a click.
HoverCardContent
| Prop | Type | Default | Description |
|---|---|---|---|
| align | 'start' | 'center' | 'end' | 'center' | Alignment relative to trigger (on HoverCardContent) |
| sideOffset | number | 4 | Distance in px from trigger (on HoverCardContent) |
| openDelay | number | 700 | Delay in ms before card opens on hover |
| closeDelay | number | 300 | Delay in ms before card closes on leave |
Installation
import { HoverCard, HoverCardTrigger, HoverCardContent } from '@stackmates/ui-interactive/molecules';Accessibility
- Content accessible via pointer hover and focus (Radix Portal)
- Not suitable for essential info (hover unavailable on touch)
- Use Tooltip for brief labels; HoverCard for rich previews