:::warning AUTO-GENERATED — do not edit
This page is generated from the MCP server snapshot content/guide-mcp.json.
Edit the source MCP server (not this file), then run npm run generate.
:::
Component Catalog
| Component | Description |
|---|---|
PageLayout | Standard Rystad page layout with top navbar. Uses shadcn components for structure. |
DataTable | Generic data table using TanStack Table with shadcn Table primitives. Supports sorting, pagination. |
ChartCard | Card wrapper for charts using shadcn Card compound component with optional toolbar. |
FilterPanel | Collapsible filter panel using shadcn Collapsible and Button components. |
KPICard | Key performance indicator card using shadcn Card with trend indicator. |
PageLayout
Standard Rystad page layout with top navbar. Uses shadcn components for structure.
{
"name": "PageLayout",
"description": "Standard Rystad page layout with top navbar. Uses shadcn components for structure.",
"props": {
"title": "string — Page title displayed in the header",
"children": "ReactNode — Main content area"
},
"shadcnDeps": [
"button",
"skeleton"
],
"installCommand": "npx shadcn@latest add button skeleton",
"code": "import type { ReactNode } from \"react\";\nimport { useAuth } from \"@rystad/auth\";\nimport { Button } from \"@/components/ui/button\";\n\ntype PageLayoutProps = {\n title: string;\n children: ReactNode;\n};\n\nexport function PageLayout({ title, children }: PageLayoutProps) {\n const { user, logout } = useAuth();\n\n return (\n <div className=\"flex min-h-screen flex-col\">\n <header className=\"flex h-14 items-center justify-between border-b border-border bg-card px-6 sticky top-0\">\n <h1 className=\"text-lg font-semibold text-foreground\">{title}</h1>\n <div className=\"flex items-center gap-3\">\n <span className=\"text-sm text-muted-foreground\">{user?.name}</span>\n <Button variant=\"ghost\" size=\"sm\" onClick={logout}>\n Log out\n </Button>\n </div>\n </header>\n <main className=\"flex-1 p-6\">{children}</main>\n </div>\n );\n}"
}
DataTable
Generic data table using TanStack Table with shadcn Table primitives. Supports sorting, pagination.
{
"name": "DataTable",
"description": "Generic data table using TanStack Table with shadcn Table primitives. Supports sorting, pagination.",
"props": {
"columns": "ColumnDef<TData, TValue>[] — TanStack Table column definitions",
"data": "TData[] — Array of row data",
"tableTitle": "string? — Optional title above the table"
},
"shadcnDeps": [
"table"
],
"installCommand": "npx shadcn@latest add table",
"code": "import type { ColumnDef } from \"@tanstack/react-table\";\nimport {\n flexRender,\n getCoreRowModel,\n useReactTable,\n} from \"@tanstack/react-table\";\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from \"@/components/ui/table\";\n\ntype DataTableProps<TData, TValue> = {\n columns: ColumnDef<TData, TValue>[];\n data: TData[];\n tableTitle?: string;\n};\n\nexport function DataTable<TData, TValue>({\n columns,\n data,\n tableTitle,\n}: DataTableProps<TData, TValue>) {\n const table = useReactTable({\n data,\n columns,\n getCoreRowModel: getCoreRowModel(),\n });\n\n return (\n <div>\n {tableTitle && (\n <h3 className=\"mb-4 text-lg font-semibold\">{tableTitle}</h3>\n )}\n <div className=\"rounded-md border border-border\">\n <Table>\n <TableHeader>\n {table.getHeaderGroups().map((headerGroup) => (\n <TableRow key={headerGroup.id}>\n {headerGroup.headers.map((header) => (\n <TableHead key={header.id}>\n {header.isPlaceholder\n ? null\n : flexRender(header.column.columnDef.header, header.getContext())}\n </TableHead>\n ))}\n </TableRow>\n ))}\n </TableHeader>\n <TableBody>\n {table.getRowModel().rows.length ? (\n table.getRowModel().rows.map((row) => (\n <TableRow key={row.id}>\n {row.getVisibleCells().map((cell) => (\n <TableCell key={cell.id}>\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </TableCell>\n ))}\n </TableRow>\n ))\n ) : (\n <TableRow>\n <TableCell colSpan={columns.length} className=\"h-24 text-center text-muted-foreground\">\n No results.\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n </div>\n );\n}"
}
ChartCard
Card wrapper for charts using shadcn Card compound component with optional toolbar.
{
"name": "ChartCard",
"description": "Card wrapper for charts using shadcn Card compound component with optional toolbar.",
"props": {
"title": "string — Chart title",
"subtitle": "string? — Optional subtitle",
"children": "ReactNode — Chart component (Recharts wrapped in ChartContainer)",
"toolbar": "ReactNode? — Optional toolbar actions"
},
"shadcnDeps": [
"card"
],
"installCommand": "npx shadcn@latest add card",
"code": "import type { ReactNode } from \"react\";\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@/components/ui/card\";\n\ntype ChartCardProps = {\n title: string;\n subtitle?: string;\n children: ReactNode;\n toolbar?: ReactNode;\n};\n\nexport function ChartCard({ title, subtitle, children, toolbar }: ChartCardProps) {\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between\">\n <div>\n <CardTitle>{title}</CardTitle>\n {subtitle && <CardDescription>{subtitle}</CardDescription>}\n </div>\n {toolbar && <div className=\"flex items-center gap-2\">{toolbar}</div>}\n </CardHeader>\n <CardContent>{children}</CardContent>\n </Card>\n );\n}"
}
FilterPanel
Collapsible filter panel using shadcn Collapsible and Button components.
{
"name": "FilterPanel",
"description": "Collapsible filter panel using shadcn Collapsible and Button components.",
"props": {
"children": "ReactNode — Filter form controls",
"onApply": "() => void — Called when filters are applied",
"onReset": "() => void — Called when filters are reset",
"defaultOpen": "boolean? — Whether panel starts open (default: true)"
},
"shadcnDeps": [
"collapsible",
"button"
],
"installCommand": "npx shadcn@latest add collapsible button",
"code": "import { useState, type ReactNode } from \"react\";\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"@/components/ui/collapsible\";\nimport { Button } from \"@/components/ui/button\";\nimport { ChevronsUpDown } from \"lucide-react\";\n\ntype FilterPanelProps = {\n children: ReactNode;\n onApply: () => void;\n onReset: () => void;\n defaultOpen?: boolean;\n};\n\nexport function FilterPanel({ children, onApply, onReset, defaultOpen = true }: FilterPanelProps) {\n const [isOpen, setIsOpen] = useState(defaultOpen);\n\n return (\n <Collapsible open={isOpen} onOpenChange={setIsOpen} className=\"rounded-lg border border-border bg-card p-4\">\n <CollapsibleTrigger asChild>\n <Button variant=\"ghost\" className=\"flex w-full items-center justify-between\">\n <span className=\"text-sm font-medium\">Filters</span>\n <ChevronsUpDown className=\"h-4 w-4\" />\n </Button>\n </CollapsibleTrigger>\n <CollapsibleContent className=\"mt-4 space-y-4\">\n <div className=\"space-y-3\">{children}</div>\n <div className=\"flex items-center gap-2 pt-2\">\n <Button variant=\"secondary\" size=\"sm\" onClick={onReset}>\n Reset\n </Button>\n <Button size=\"sm\" onClick={onApply}>\n Apply\n </Button>\n </div>\n </CollapsibleContent>\n </Collapsible>\n );\n}"
}
KPICard
Key performance indicator card using shadcn Card with trend indicator.
{
"name": "KPICard",
"description": "Key performance indicator card using shadcn Card with trend indicator.",
"props": {
"label": "string — KPI label",
"value": "string | number — Current value",
"unit": "string? — Unit of measurement",
"trend": "{ direction: 'up' | 'down' | 'flat'; percentage: number }? — Trend indicator"
},
"shadcnDeps": [
"card"
],
"installCommand": "npx shadcn@latest add card",
"code": "import { Card, CardContent, CardHeader, CardTitle } from \"@/components/ui/card\";\nimport { cn } from \"@/lib/utils\";\n\ntype KPICardProps = {\n label: string;\n value: string | number;\n unit?: string;\n trend?: { direction: \"up\" | \"down\" | \"flat\"; percentage: number };\n};\n\nexport function KPICard({ label, value, unit, trend }: KPICardProps) {\n return (\n <Card>\n <CardHeader className=\"pb-2\">\n <CardTitle className=\"text-sm font-medium text-muted-foreground\">{label}</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"flex items-baseline gap-1\">\n <span className=\"text-2xl font-bold\">{value}</span>\n {unit && <span className=\"text-sm text-muted-foreground\">{unit}</span>}\n </div>\n {trend && (\n <p\n className={cn(\n \"mt-1 text-xs\",\n trend.direction === \"up\" && \"text-green-600\",\n trend.direction === \"down\" && \"text-red-600\",\n trend.direction === \"flat\" && \"text-muted-foreground\",\n )}\n >\n {trend.direction === \"up\" ? \"↑\" : trend.direction === \"down\" ? \"↓\" : \"→\"}{\" \"}\n {trend.percentage}%\n </p>\n )}\n </CardContent>\n </Card>\n );\n}"
}