2026-03-18 15:19:16 +01:00
# Cameleer3 Component Guide
> This file is for Claude Code to reference when building UI features.
> Keep it up to date when components are added or changed.
## Quick Decision Trees
### "I need to show a message to the user"
- Inline contextual note → **InfoCallout **
- Page-level attention banner → **Alert **
- Temporary non-blocking feedback → **Toast ** (via `useToast` )
- Destructive action confirmation → **AlertDialog **
2026-03-19 11:39:54 +01:00
- Destructive action needing typed confirmation → **ConfirmDialog **
2026-03-18 15:19:16 +01:00
- Generic dialog with custom content → **Modal **
### "I need a form input"
- Single line text → **Input **
- Multiline text → **Textarea **
- On/off toggle → **Toggle **
- Yes/no with label → **Checkbox **
- One of N options (≤5) → **RadioGroup ** + **RadioItem **
- One of N options (>5) → **Select **
2026-03-19 11:39:54 +01:00
- Select multiple from a list → **MultiSelect **
- Edit text inline without a form → **InlineEdit **
2026-03-18 15:19:16 +01:00
- Date/time → **DateTimePicker **
- Date range → **DateRangePicker **
- Wrap any input with label/error/hint → **FormField **
### "I need to show loading state"
- Full component placeholder → **Skeleton ** (text, circular, or rectangular)
- Inline spinner → **Spinner ** (sm, md, lg)
- Operation progress → **ProgressBar ** (determinate or indeterminate)
### "I need to show status"
- Dot indicator → **StatusDot ** (live, stale, dead, success, warning, error, running)
2026-03-24 12:35:11 +01:00
- Inline colored status value → **StatusText ** (success, warning, error, running, muted — with optional bold)
2026-03-18 15:19:16 +01:00
- Labeled status → **Badge ** with semantic color
- Removable label → **Tag **
### "I need navigation"
2026-04-02 18:30:27 +02:00
- App-level sidebar nav → **Sidebar ** (compound component — compose sections, trees, footer links)
- Sidebar tree section → **SidebarTree ** (data-driven tree with expand/collapse, starring, keyboard nav)
- Starred items persistence → **useStarred ** hook (localStorage-backed)
2026-03-18 15:19:16 +01:00
- Breadcrumb trail → **Breadcrumb **
- Paginated data → **Pagination ** (standalone) or **DataTable ** (built-in pagination)
2026-04-02 18:30:27 +02:00
- Hierarchical tree navigation → **TreeView ** (generic)
2026-03-18 15:19:16 +01:00
### "I need floating content"
- Tooltip on hover → **Tooltip **
- Click-triggered panel → **Popover **
- Action menu → **Dropdown **
- Full-screen search/command → **CommandPalette **
### "I need to display data"
- Key metrics → **StatCard ** (with optional sparkline/trend)
- Tabular data → **DataTable ** (sortable, paginated)
- Time series → **LineChart ** , **AreaChart **
- Categorical comparison → **BarChart **
- Inline trend → **Sparkline **
2026-03-30 14:31:02 +02:00
- Advanced charts (treemap, radar, heatmap, pie, etc.) → **Recharts ** with `rechartsTheme` (see [Charting Strategy ](#charting-strategy ))
2026-03-18 15:19:16 +01:00
- Event log → **EventFeed **
2026-03-19 16:33:34 +01:00
- Processing pipeline (Gantt view) → **ProcessorTimeline **
- Processing pipeline (flow diagram) → **RouteFlow **
2026-03-24 12:35:11 +01:00
- Row of summary KPIs → **KpiStrip ** (horizontal strip with colored borders, trends, sparklines)
- Scrollable log output → **LogViewer ** (timestamped, severity-colored monospace entries)
- Searchable, selectable entity list → **EntityList ** (search header, selection highlighting, pairs with SplitPane)
2026-03-18 15:19:16 +01:00
### "I need to organize content"
- Collapsible sections (standalone) → **Collapsible **
- Multiple collapsible sections (one/many open) → **Accordion **
- Tabbed content → **Tabs **
2026-03-19 11:39:54 +01:00
- Tab switching with pill/segment style → **SegmentedTabs **
2026-03-18 15:19:16 +01:00
- Side panel inspector → **DetailPanel **
2026-03-24 12:35:11 +01:00
- Master/detail split layout → **SplitPane ** (list on left, detail on right, configurable ratio)
2026-03-18 15:19:16 +01:00
- Section with title + action → **SectionHeader **
- Empty content placeholder → **EmptyState **
2026-03-24 12:35:11 +01:00
- Grouped content box → **Card ** (with optional accent and title)
2026-03-18 18:26:13 +01:00
- Grouped items with header + meta + footer → **GroupCard ** (e.g., app instances)
2026-03-18 15:19:16 +01:00
### "I need to display text"
- Code/JSON payload → **CodeBlock ** (with line numbers, copy button)
- Monospace inline text → **MonoText **
- Keyboard shortcut hint → **KeyboardHint **
2026-03-24 12:35:11 +01:00
- Colored inline status text → **StatusText ** (semantic color + optional bold, see also "I need to show status")
2026-03-18 15:19:16 +01:00
### "I need to show people/users"
- Single user avatar → **Avatar **
- Stacked user avatars → **AvatarGroup **
2026-03-19 16:33:34 +01:00
### "I need to group buttons or toggle selections"
- Multi-select toggle group with colored indicators → **ButtonGroup ** (e.g., status filters)
- Tab switching with pill/segment style → **SegmentedTabs **
2026-03-18 22:26:36 +01:00
2026-03-18 15:19:16 +01:00
### "I need filtering"
2026-03-19 16:33:34 +01:00
- Multi-select status/category filter → **ButtonGroup ** (toggle items on/off)
- Filter pill/chip → **FilterPill ** (individual toggleable pills)
2026-03-18 15:19:16 +01:00
- Full filter bar with search → **FilterBar **
2026-03-19 11:39:54 +01:00
- Select multiple from a list → **MultiSelect **
2026-03-18 15:19:16 +01:00
## Composition Patterns
### Standard page layout
```
2026-04-02 18:30:27 +02:00
AppShell → Sidebar (compound) + TopBar + main content + optional DetailPanel
Sidebar compound API:
<Sidebar collapsed={bool} onCollapseToggle={fn} searchValue={str} onSearchChange={fn}>
<Sidebar.Header logo={node} title="str" version="str" />
<Sidebar.Section label="str" icon={node} open={bool} onToggle={fn} active={bool}>
<SidebarTree nodes={[...]} selectedPath="..." filterQuery="..." ... />
</Sidebar.Section>
<Sidebar.Footer>
<Sidebar.FooterLink icon={node} label="str" onClick={fn} active={bool} />
</Sidebar.Footer>
</Sidebar>
2026-04-02 22:43:00 +02:00
Notes:
- Search input auto-renders between Header and first Section (not above Header)
- Section headers have no chevron — the entire row is clickable to toggle
- The app controls all content — sections, order, tree data, collapse state
- Sidebar provides the frame, search input, and icon-rail collapse mode
2026-03-18 15:19:16 +01:00
```
### Data page pattern
```
FilterBar (top)
→ DataTable (center, with built-in sorting + pagination)
→ optional DetailPanel (right slide, on row click)
```
### Form layout
```
FormField wraps any input (Input, Textarea, Select, RadioGroup, etc.)
provides: label, required indicator, hint text, error message
gap: 6px between label and input, 4px to hint/error
```
### KPI dashboard
```
Row of StatCard components (each with optional Sparkline and trend)
Below: charts (AreaChart, LineChart, BarChart)
```
2026-03-24 12:35:11 +01:00
### Master/detail management pattern
```
SplitPane + EntityList for CRUD list/detail screens (users, groups, roles)
EntityList provides: search header, add button, selectable list
SplitPane provides: responsive two-column layout with empty state
```
2026-03-18 15:19:16 +01:00
### Detail/inspector pattern
```
2026-03-19 16:33:34 +01:00
DetailPanel (right slide) with Tabs for sections OR children for scrollable content
Tabbed: use tabs prop for multiple panels
Scrollable: use children for stacked sections (overview, errors, route flow, timeline)
Each section: Cards with data, CodeBlock for payloads,
ProcessorTimeline or RouteFlow for exchange flow
2026-03-18 15:19:16 +01:00
```
### Feedback flow
```
User action → Toast (success/error feedback)
Destructive action → AlertDialog (confirmation) → Toast (result)
```
### Tree navigation pattern
```
TreeView for hierarchical data (Application → Routes → Processors)
onSelect navigates or opens DetailPanel
```
2026-03-18 18:26:13 +01:00
### Agent/instance health pattern
```
StatCard strip (top, recalculates per scope)
→ GroupCard grid (2-col for all, full-width for single app)
Each GroupCard: header (app name + count) + meta (TPS, routes) + instance rows
Instance rows: StatusDot + name + Badge + metrics
Single instance: expanded with LineChart panels
→ EventFeed (bottom, filtered by scope)
URL-driven progressive filtering: /agents → /agents/:appId → /agents/:appId/:instanceId
```
2026-03-30 14:31:02 +02:00
## Charting Strategy
The design system includes built-in **AreaChart ** , **BarChart ** , **LineChart ** , and **Sparkline ** components for standard use cases. For advanced chart types (treemap, radar, heatmap, pie, sankey, etc.), consuming apps should use **Recharts ** directly with the design system's theme preset for visual consistency.
**Recharts is the app's dependency, not the design system's.** The design system only exports a theme config object.
### Setup in consuming app
```bash
npm install recharts
```
### Usage with theme preset
```tsx
import { rechartsTheme, CHART_COLORS } from '@cameleer/design -system'
import {
ResponsiveContainer, LineChart, Line,
CartesianGrid, XAxis, YAxis, Tooltip, Legend,
} from 'recharts'
<ResponsiveContainer width="100%" height={300}>
<LineChart data={data}>
<CartesianGrid {...rechartsTheme.cartesianGrid} />
<XAxis dataKey="name" {...rechartsTheme.xAxis} />
<YAxis {...rechartsTheme.yAxis} />
<Tooltip {...rechartsTheme.tooltip} />
<Legend {...rechartsTheme.legend} />
<Line dataKey="value" stroke={CHART_COLORS[0]} strokeWidth={2} dot={false} />
<Line dataKey="other" stroke={CHART_COLORS[1]} strokeWidth={2} dot={false} />
</LineChart>
</ResponsiveContainer>
```
### Exports
| Export | Description |
|--------|-------------|
| `rechartsTheme.cartesianGrid` | Dashed gridlines, subtle stroke |
| `rechartsTheme.xAxis` | Mono font axis ticks, subtle color |
| `rechartsTheme.yAxis` | Mono font axis ticks, no axis line |
| `rechartsTheme.tooltip` | Surface bg, border, shadow, monospace values |
| `rechartsTheme.legend` | Matching text size and color |
| `rechartsTheme.colors` | The 8 `CHART_COLORS` (CSS variables with light/dark support) |
| `CHART_COLORS` | Array of `var(--chart-1)` through `var(--chart-8)` |
| `ChartSeries` / `DataPoint` | Type interfaces for chart data |
2026-03-18 15:19:16 +01:00
## Component Index
| Component | Layer | When to use |
|-----------|-------|-------------|
| Accordion | composite | Multiple collapsible sections, single or multi-open mode |
| Alert | primitive | Page-level attention banner with variant colors |
| AlertDialog | composite | Confirmation dialog for destructive/important actions |
| AreaChart | composite | Time series visualization with filled area |
| Avatar | primitive | User representation with initials and color |
| AvatarGroup | composite | Stacked overlapping avatars with overflow count |
| Badge | primitive | Labeled status indicator with semantic colors |
| BarChart | composite | Categorical data comparison, optional stacking |
| Breadcrumb | composite | Navigation path showing current location |
| Button | primitive | Action trigger (primary, secondary, danger, ghost) |
2026-03-19 16:33:34 +01:00
| ButtonGroup | primitive | Multi-select toggle group with optional colored dot indicators. Props: items (value, label, color?), value (Set), onChange |
2026-03-24 12:35:11 +01:00
| Card | primitive | Content container with optional accent border and title header |
2026-03-18 15:19:16 +01:00
| Checkbox | primitive | Boolean input with label |
| CodeBlock | primitive | Syntax-highlighted code/JSON display |
| Collapsible | primitive | Single expand/collapse section |
2026-04-02 23:23:32 +02:00
| CommandPalette | composite | Full-screen search and command interface. `SearchCategory` is an open `string` type — known categories (application, exchange, attribute, route, agent) have built-in labels; custom categories render with title-cased labels and appear as dynamic tabs. |
2026-03-19 11:39:54 +01:00
| ConfirmDialog | composite | Type-to-confirm destructive action dialog built on Modal. Props: open, onClose, onConfirm, title, message, confirmText, confirmLabel, cancelLabel, variant, loading, className |
2026-03-18 22:26:36 +01:00
| DataTable | composite | Sortable, paginated data table with row actions. Use `flush` prop when embedded inside a container that provides its own border/radius |
2026-03-18 15:19:16 +01:00
| DateRangePicker | primitive | Date range selection with presets |
| DateTimePicker | primitive | Single date/time input |
2026-03-19 16:33:34 +01:00
| DetailPanel | composite | Slide-in side panel with tabs or children for scrollable content |
2026-03-18 15:19:16 +01:00
| Dropdown | composite | Action menu triggered by any element |
| EmptyState | primitive | Placeholder for empty content areas |
2026-03-24 12:35:11 +01:00
| EntityList | composite | Searchable, selectable entity list with add button. Pair with SplitPane for CRUD management screens |
2026-03-18 15:19:16 +01:00
| EventFeed | composite | Chronological event log with severity |
| FilterBar | composite | Search + filter controls for data views |
2026-03-18 18:22:14 +01:00
| GroupCard | composite | Card with header, meta row, children, and optional footer/alert. Used for grouping instances by application. |
2026-03-18 22:26:36 +01:00
| FilterPill | primitive | Individual filter chip (active/inactive), supports forwardRef |
2026-03-18 15:19:16 +01:00
| FormField | primitive | Wrapper adding label, hint, error to any input |
| InfoCallout | primitive | Inline contextual note with variant colors |
2026-03-19 11:39:54 +01:00
| InlineEdit | primitive | Click-to-edit text field. Enter saves, Escape/blur cancels. Props: value, onSave, placeholder, disabled, className |
2026-03-18 15:19:16 +01:00
| Input | primitive | Single-line text input with optional icon |
| KeyboardHint | primitive | Keyboard shortcut display |
2026-03-24 12:35:11 +01:00
| KpiStrip | composite | Horizontal row of KPI cards with colored left border, trend, subtitle, optional sparkline |
2026-03-18 15:19:16 +01:00
| Label | primitive | Form label with optional required asterisk |
| LineChart | composite | Time series line visualization |
2026-03-24 12:35:11 +01:00
| LogViewer | composite | Scrollable log output with timestamped, severity-colored monospace entries |
2026-03-18 15:19:16 +01:00
| MenuItem | composite | Sidebar navigation item with health/count |
| Modal | composite | Generic dialog overlay with backdrop |
2026-03-19 11:39:54 +01:00
| MultiSelect | composite | Dropdown with searchable checkbox list and Apply action. Props: options, value, onChange, placeholder, searchable, disabled, className |
2026-03-18 15:19:16 +01:00
| MonoText | primitive | Inline monospace text (xs, sm, md) |
| Pagination | primitive | Page navigation controls |
| Popover | composite | Click-triggered floating panel with arrow |
2026-03-24 19:49:07 +01:00
| ProcessorTimeline | composite | Gantt-style pipeline visualization with selectable rows and optional action menus. Props: processors, totalMs, onProcessorClick?, selectedIndex?, actions?, getActions?. Use `actions` for static menus or `getActions` for per-processor dynamic actions. |
| RouteFlow | composite | Vertical processor node flow diagram with status coloring, connectors, click support, and optional action menus. Props: nodes, onNodeClick?, selectedIndex?, actions?, getActions?. Same action pattern as ProcessorTimeline. |
2026-03-18 15:19:16 +01:00
| ProgressBar | primitive | Determinate/indeterminate progress indicator |
| RadioGroup | primitive | Single-select option group (use with RadioItem) |
| RadioItem | primitive | Individual radio option within RadioGroup |
| SectionHeader | primitive | Section title with optional action button |
2026-03-19 11:39:54 +01:00
| SegmentedTabs | composite | Pill-style segmented tab bar with sliding animated indicator. Same API as Tabs but with elevated active state. Props: tabs, active, onChange, trailing, trailingValue, className |
2026-03-18 15:19:16 +01:00
| Select | primitive | Dropdown select input |
| ShortcutsBar | composite | Keyboard shortcuts reference bar |
| Skeleton | primitive | Loading placeholder (text, circular, rectangular) |
| Sparkline | primitive | Inline mini chart for trends |
2026-03-24 12:35:11 +01:00
| SplitPane | composite | Two-column master/detail layout with configurable ratio and empty state |
2026-03-18 15:19:16 +01:00
| Spinner | primitive | Animated loading indicator |
| StatCard | primitive | KPI card with value, trend, optional sparkline |
| StatusDot | primitive | Colored dot for status indication |
2026-03-24 12:35:11 +01:00
| StatusText | primitive | Inline colored status span (success, warning, error, running, muted) with optional bold |
2026-03-18 15:19:16 +01:00
| Tabs | composite | Tabbed content switcher with optional counts |
| Tag | primitive | Removable colored label |
| Textarea | primitive | Multi-line text input with resize control |
| Toast | composite | Temporary notification (via ToastProvider + useToast) |
| Toggle | primitive | On/off switch input |
| Tooltip | primitive | Hover-triggered text tooltip |
| TreeView | composite | Hierarchical tree with keyboard navigation |
### Layout Components
| Component | Purpose |
|-----------|---------|
| AppShell | Page shell: sidebar + topbar + main + optional detail panel |
2026-04-02 18:30:27 +02:00
| Sidebar | Composable compound sidebar shell with icon-rail collapse mode. Sub-components: `Sidebar.Header` , `Sidebar.Section` , `Sidebar.Footer` , `Sidebar.FooterLink` . The app controls all content via children — the DS provides the frame. |
| SidebarTree | Data-driven tree for sidebar sections. Accepts `nodes: SidebarTreeNode[]` with expand/collapse, starring, keyboard nav, search filter, and path-based selection highlighting. |
| useStarred | Hook for localStorage-backed starred item IDs. Returns `{ starredIds, isStarred, toggleStar }` . |
2026-04-04 15:25:20 +02:00
| TopBar | Header bar with breadcrumb, search trigger, ButtonGroup status filters, time range selector, theme toggle, environment slot (`ReactNode` — pass a string for a static label or a custom dropdown for interactive selection), user avatar |
2026-03-18 15:19:16 +01:00
## Import Paths
2026-03-18 20:34:23 +01:00
### Within this repo (design system development)
2026-03-18 15:19:16 +01:00
2026-03-18 20:34:23 +01:00
```tsx
import { Button, Input, Badge } from './design-system/primitives'
import { DataTable, Modal, Toast } from './design-system/composites'
import type { Column, SearchResult, FeedEvent } from './design-system/composites'
2026-03-18 15:19:16 +01:00
import { AppShell } from './design-system/layout/AppShell'
2026-04-02 18:30:27 +02:00
import { Sidebar } from './design-system/layout/Sidebar/Sidebar'
import { SidebarTree } from './design-system/layout/Sidebar/SidebarTree'
import type { SidebarTreeNode } from './design-system/layout/Sidebar/SidebarTree'
import { useStarred } from './design-system/layout/Sidebar/useStarred'
2026-03-18 15:19:16 +01:00
import { ThemeProvider, useTheme } from './design-system/providers/ThemeProvider'
```
2026-03-18 20:34:23 +01:00
### From consuming apps (via npm package)
```tsx
import '@cameleer/design -system/style.css' // once at app root
import { Button, Input, Modal, DataTable, AppShell, ThemeProvider } from '@cameleer/design -system'
import type { Column, DataTableProps, SearchResult } from '@cameleer/design -system'
```
See `CLAUDE.md` "Using This Design System in Other Apps" for full setup instructions.
2026-04-06 17:17:36 +02:00
## Brand Assets
The design system ships logo assets as static files via package exports. These are not React components — they resolve to file URLs when imported via a bundler.
| Export | Size | Use case |
|--------|------|----------|
| `@cameleer/design-system/logo` | Original | Full resolution for print/marketing |
| `@cameleer/design-system/logo-16` | 16× 16 | Browser tab favicon |
| `@cameleer/design-system/logo-32` | 32× 32 | Standard favicon, bookmarks |
| `@cameleer/design-system/logo-48` | 48× 48 | Windows taskbar |
| `@cameleer/design-system/logo-180` | 180× 180 | Apple touch icon |
| `@cameleer/design-system/logo-192` | 192× 192 | Android/PWA icon |
| `@cameleer/design-system/logo-512` | 512× 512 | PWA splash, og:image |
| `@cameleer/design-system/logo-svg` | Vector | SVG logo for scalable usage |
### Usage
```tsx
import logo from '@cameleer/design -system/logo-512'
<img src={logo} alt="Cameleer3" />
```
```html
<!-- Favicons in index.html -->
<link rel="icon" type="image/png" sizes="32x32" href="/cameleer3-32.png">
<link rel="apple-touch-icon" sizes="180x180" href="/cameleer3-180.png">
```
2026-03-18 15:19:16 +01:00
## Styling Rules
- **CSS Modules only** — no inline styles except dynamic values (width, color from props)
- **Use existing tokens** from `tokens.css` — never hardcode hex colors
- **Theme support** — all colors via CSS custom properties, never hardcode light/dark
- **forwardRef** on all form controls (Input, Textarea, Select, Checkbox, Toggle, Label)
- **className prop** on every component for style overrides
- **Semantic color variants** — use `'success' | 'warning' | 'error'` pattern consistently