Developer
Component playground
Buttons
Usage
<button className="btn btn-primary">Primary</button> <button className="btn btn-outline">Outline</button> <button className="btn btn-ghost">Ghost</button> <button className="btn btn-danger">Danger</button> <button className="btn btn-primary btn-sm">Small</button> <button className="btn btn-primary" disabled>Disabled</button>
Status & badges
ActivePendingFailedInfoTagRemovable
Usage
<StatusBadge tone="green">Active</StatusBadge> <StatusBadge tone="yellow">Pending</StatusBadge> <StatusBadge tone="red">Failed</StatusBadge> <StatusBadge tone="blue">Info</StatusBadge> <span className="chip">Tag</span>
Alerts
Saved! Changes have been published.
Heads up. API quota at 87%.
Payment failed. Retry to continue.
Usage
<div className="alert alert-success">…Saved!…</div> <div className="alert alert-warning">…Heads up.…</div> <div className="alert alert-error">…Payment failed.…</div>
Cards
Plain card
A simple card with header and body. The most common building block.
With subtitle
Plus an action
Header has room for actions on the right.
Usage
<Card> <CardHeader><CardTitle>Plain card</CardTitle></CardHeader> <CardBody>A simple card with header and body.</CardBody> </Card>
Form inputs
Usage
<input className="form-control" placeholder="Type here…" /> <select className="form-control"><option>Option A</option></select> <label className="switch"><input type="checkbox" defaultChecked /><span className="track" /></label>
Advanced form controls
Date-range picker
<DateRangePicker />
DesignEngineering
Multi-select
<MultiSelect options={...} defaultSelected={['design', 'eng']} />Rich text editor
<RichTextEditor initialHtml="<p>…</p>" />
Tables
| Name | Plan | Status | MRR |
|---|---|---|---|
SK Sarah K. | Pro | Active | $199 |
MR Michael R. | Business | Active | $499 |
Usage
<table className="table"> <thead><tr><th>Name</th><th>Plan</th><th>Status</th><th>MRR</th></tr></thead> <tbody>…</tbody> </table>
Tabs
Usage
<div className="chart-tabs"> <button className="chart-tab active">Overview</button> <button className="chart-tab">Activity</button> </div>
Progress
Storage62 / 100 GB
API quota87,400 / 100,000
Usage
<div className="progress-thin"><div className="bar" style={{ width: '62%' }} /></div>Stat tiles
Active users
8,432↑ 14%
vs last week
Churn
2.4%↓ 0.4pp
improving
Usage
<StatCard icon={...} iconTone="teal" label="Active users" value="8,432" change={{ direction: 'up', text: '↑ 14%' }} subtext="vs last week" />Timeline
Just now
Deployment succeeded
v4.0.2 in production · 28s
14 min ago
PR #248 merged
3 hours ago
Review requested
Usage
<Timeline> <TimelineItem tone="primary" time="Just now" title="Deployment succeeded" desc="v4.0.2 in production · 28s" /> </Timeline>
Accordion
First panel
Content for the first panel goes here.
Second panel
Click the chevron to expand.
Usage
<Accordion> <AccordionItem summary="First panel" defaultOpen>Content for the first panel goes here.</AccordionItem> <AccordionItem summary="Second panel">Click the chevron to expand.</AccordionItem> </Accordion>
Empty state
No messages yet
When you receive messages, they'll show up here.
Usage
<div className="empty-state"> <div className="empty-state-icon">…</div> <div className="empty-state-title">No messages yet</div> <div className="empty-state-text">…</div> </div>
Skeleton table
Render placeholder rows while data loads. Width variation across columns prevents the "jelly bean" look — the shimmer animation lives in ui-kit.css.
| Customer | Plan | Status | MRR |
|---|---|---|---|
Skeleton tiles
Use for card grids — dashboards, file managers, product galleries. Avatar circle + headline + 2 lines is the canonical shape.
List lifecycle — interactive
Click a button below to simulate each state. This is exactly what orders and the inbox use under the hood.
Click a button above to simulate a state.
Submit spinner
Disable the button + swap label for a spinner during the request. Re-enable + restore label when it resolves. Click below to simulate a 1.5s submit.
Banners — feedback at the page level
Usage
<div className="banner"><strong>Saved.</strong> Changes are live.</div>
StatCard
<StatCard
icon={<RevenueIcon />}
iconTone="green"
label="Revenue"
value="$84,520"
change={{ direction: 'up', text: '+18%' }}
subtext="$3,218 today"
/>Revenue
$84,520+18%
$3,218 today
Pending
42-3%
5 awaiting payment
StatusBadge
<StatusBadge tone="green">Paid</StatusBadge> <StatusBadge tone="yellow">Pending</StatusBadge> <StatusBadge tone="red">Failed</StatusBadge>
PaidProcessingPendingFailed
Customer cell — table cell with avatar + name
<div className="cell-customer">
<div className="cell-avatar" style={{ background: color }}>{initials}</div>
<span className="cell-strong">{name}</span>
</div>SK Sarah Klein |
MR Michael Reese |
EW Emily Wang |
Activity item — feeds, audit logs
<ul className="activity-list">
<li className="activity-item">
<div className="activity-avatar" style={{ background }}>{initials}</div>
<div><div className="activity-body"><strong>{user}</strong> {text}</div><div className="activity-time">{time}</div></div>
</li>
</ul>- SKSarah K. placed a new order for $245.002 min ago
- MRMichael R. registered a new account18 min ago
Visitor row — distribution bars
<div className="visitor-row">
<span className="visitor-flag">{flag}</span>
<span className="visitor-name">{name}</span>
<span className="visitor-pct">{pct}%</span>
<div className="visitor-bar"><div className="fill" style={{ width: pct + '%' }} /></div>
</div>🇺🇸United States33%
🇫🇷France27%
🇩🇪Germany16%
Empty state — fallback for no results
<div className="empty-state"> <div className="empty-state-icon">…</div> <div className="empty-state-title">No orders yet</div> <div className="empty-state-desc">Orders will appear here once your first customer checks out.</div> <button className="btn btn-primary btn-sm">Create test order</button> </div>
No orders yet
Orders will appear here once your first customer checks out.