Components Guide
The template ships 90+ components. They fall into a few groups under
src/components/. The ui/ folder holds the shadcn/ui primitives; everything
else is built on top of them.
Folder map
src/components/
├── ui/ shadcn/ui primitives (button, card, dialog, table,
│ calendar, radio-group, toggle-group, …)
├── layout/ AppShell, Sidebar, Topbar, command palette, theme builder,
│ notifications, logo, user menu
├── common/ StatCard, PageHeader, EmptyState, StatusBadge, ActivityFeed
├── charts/ Line / Area / Bar / Donut / Mixed wrappers + primitives
├── tables/ DataTable (TanStack Table + CSV/Excel export)
├── forms/ Date/range/time pickers, color picker, tags, multi-select,
│ combobox, OTP, rating, stepper, range slider, phone,
│ rich-text editor, image cropper, dropzone, form builder
├── ai/ ModelSelector, TokenCounter, UsageMeter, AgentStatus…
├── kanban/ Board, columns, cards, task & column dialogs
├── calendar/ Month / Week / Day views, time grid, event dialog
├── chat/ Chat view, message bubbles, streaming
├── notifications/ Notification item + full-page view
├── dashboard-builder/ Editable widget grid + widget renderer
├── audit/ Audit-log table view
├── integrations/ Connect/disconnect cards
├── onboarding/ Multi-step wizard
└── <page area>/ analytics, prompts, playground, users, billing, settings…
Common components
StatCard
src/components/common/stat-card.tsx — an animated metric card with optional
trend, icon and sparkline.
import { Activity } from "lucide-react";
import { StatCard } from "@/components/common/stat-card";
<StatCard
label="Total API Calls"
value={2_418_902}
change={14.2} // % vs last period
icon={Activity}
sparkline={[12, 18, 14, 22, 30]}
// invertTrend // set when "down" is good (e.g. cost)
/>;
PageHeader
src/components/common/page-header.tsx — title, breadcrumbs and an actions
slot. Used at the top of every page.
<PageHeader
title="Users"
description="Manage everyone in your workspace."
breadcrumbs={[{ label: "Dashboard", href: "/dashboard" }, { label: "Users" }]}
actions={<Button>Invite user</Button>}
/>
StatusBadge
src/components/common/status-badge.tsx — maps a status string (active, paused,
paid, pro, admin, …) to a consistent color tone automatically.
<StatusBadge status="active" /> {/* green dot + label */}
<StatusBadge status="pro" dot={false} />
EmptyState / ActivityFeed
EmptyState (icon + message + CTA) for empty lists; ActivityFeed renders a
vertical timeline of events.
Charts
All wrappers live in src/components/charts/ and use Recharts with shared
theming. They accept a data array and a series config.
import { LineChart } from "@/components/charts/line-chart";
<LineChart
data={apiUsageData} // [{ date, calls }, …]
series={[{ key: "calls", label: "API calls" }]}
valueFormatter={(v) => v.toLocaleString()}
/>;
Available: LineChart, AreaChart (stacked), StackedBarChart,
CategoryBarChart, DonutChart (+ ChartLegend), MixedChart (bars + line).
Colors come from the --chart-1…6 tokens; see
Customization.
Charts render after mount (via the
useMountedhook) to avoid Recharts' 0×0-size warning during server rendering — keep that pattern if you add new chart wrappers.
DataTable
src/components/tables/data-table.tsx — a TanStack Table v8 wrapper with
sorting, pagination, column visibility, optional row selection, a bulk-action
bar, and built-in CSV / Excel export (dependency-free).
import { DataTable } from "@/components/tables/data-table";
<DataTable
columns={columns} // TanStack ColumnDef[]
data={rows}
pageSize={10}
enableRowSelection
showExport // adds a CSV / Excel export menu
exportFileName="users"
onRowClick={(row) => router.push(`/users/${row.id}`)}
renderBulkActions={(selected, clear) => (
<Button onClick={() => { /* … */ clear(); }}>Delete {selected.length}</Button>
)}
toolbar={<Input placeholder="Search…" />}
/>;
Export respects current filters/sorting and only includes visible columns.
Customize a column's exported output with meta.exportHeader /
meta.exportValue, or skip it with meta.noExport. The export helpers live in
src/lib/export.ts. See src/components/users/users-view.tsx and
src/components/prompts/prompts-view.tsx for full column examples.
AI components
In src/components/ai/:
- ModelSelector — dropdown of models with provider dot + per-1K cost.
- TokenCounter — horizontal usage bar with limit and percentage.
- UsageMeter — circular quota progress meter.
- AgentStatusIndicator — colored status pill (active/paused/training/error).
- CostMetric — currency value with trend.
- ModelCard — model spec card with set-primary action.
Forms
Forms use React Hook Form + Zod. Pattern (from the auth pages):
const schema = z.object({ email: z.string().email() });
const { register, handleSubmit, formState: { errors } } = useForm({
resolver: zodResolver(schema),
});
The Form Components page (/forms) showcases a large library of inputs in
src/components/forms/, all controlled (value/onChange) so they drop straight
into RHF via <Controller>:
- Pickers:
DatePicker,DateRangePicker,TimePicker,Calendar(a dependency-free month grid built ondate-fns),ColorPicker. - Selection:
MultiSelect,Combobox,TagInput,RadioGroup,ToggleGroup(segmented control). - Specialized:
OTPInput,RatingInput,StepperInput,RangeSlider,PhoneInput,FileDropzone,RichTextEditor,ImageCropper,PasswordInput. - Form builder (
dynamic-form-builder.tsx) — add / remove / reorder fields with a live preview.
Adding a component
Put shared UI in the closest matching folder (common/, ai/, charts/…), or
a new <page-area>/ folder for page-specific views. Reuse the cn() helper
from @/lib/utils for class merging, and keep client-only logic behind
"use client".
Next: Mock Data →