Files
design-system/COMPONENT_GUIDE.md
hsiegeln d775df61e4
All checks were successful
Build & Publish / publish (push) Successful in 1m49s
SonarQube Analysis / sonarqube (push) Successful in 2m36s
feat: remove expand toggle from collapsed sidebar, bump v0.1.54
Collapsed sidebar no longer shows an expand button — clicking any
section icon expands the sidebar and opens that section instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 22:05:10 +02:00

21 KiB
Raw Blame History

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
  • Destructive action needing typed confirmation → ConfirmDialog
  • 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
  • Select multiple from a list → MultiSelect
  • Edit text inline without a form → InlineEdit
  • 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)
  • Inline colored status value → StatusText (success, warning, error, running, muted — with optional bold)
  • Labeled status → Badge with semantic color
  • Removable label → Tag

"I need navigation"

  • 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)
  • Breadcrumb trail → Breadcrumb
  • Paginated data → Pagination (standalone) or DataTable (built-in pagination)
  • Hierarchical tree navigation → TreeView (generic)

"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 (quick) → LineChart or AreaChart (convenience wrappers with series data)
  • Categorical comparison (quick) → BarChart (convenience wrapper with series data)
  • Time series (custom) → ThemedChart with <Line> or <Area>
  • Categorical comparison (custom) → ThemedChart with <Bar>
  • Inline trend → Sparkline
  • Advanced charts (treemap, radar, heatmap, pie, etc.) → Recharts with rechartsTheme (see Charting Strategy)
  • Event log → EventFeed
  • Processing pipeline (Gantt view) → ProcessorTimeline
  • Processing pipeline (flow diagram) → RouteFlow
  • 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)

"I need to organize content"

  • Collapsible sections (standalone) → Collapsible
  • Multiple collapsible sections (one/many open) → Accordion
  • Tabbed content → Tabs
  • Tab switching with pill/segment style → SegmentedTabs
  • Side panel inspector → DetailPanel
  • Master/detail split layout → SplitPane (list on left, detail on right, configurable ratio)
  • Section with title + action → SectionHeader
  • Empty content placeholder → EmptyState
  • Grouped content box → Card (with optional accent and title)
  • Grouped items with header + meta + footer → GroupCard (e.g., app instances)

"I need to display text"

  • Code/JSON payload → CodeBlock (with line numbers, copy button)
  • Monospace inline text → MonoText
  • Keyboard shortcut hint → KeyboardHint
  • Colored inline status text → StatusText (semantic color + optional bold, see also "I need to show status")

"I need to show people/users"

  • Single user avatar → Avatar
  • Stacked user avatars → AvatarGroup

"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

"I need filtering"

  • Multi-select status/category filter → ButtonGroup (toggle items on/off)
  • Filter pill/chip → FilterPill (individual toggleable pills)
  • Full filter bar with search → FilterBar
  • Select multiple from a list → MultiSelect

Composition Patterns

Standard page layout

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.Section label="str" icon={node} open={bool} onToggle={fn} position="bottom" maxHeight="200px">
      <SidebarTree nodes={[...]} ... />
    </Sidebar.Section>
    <Sidebar.Footer>
      <Sidebar.FooterLink icon={node} label="str" onClick={fn} active={bool} />
    </Sidebar.Footer>
  </Sidebar>

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
- `position="bottom"` stacks sections above the footer; a spacer separates top/bottom groups
- `maxHeight` (CSS string) constrains the content area — section header stays visible, children scroll
- Both groups scroll independently when the viewport is short
- Custom thin scrollbars match the dark sidebar aesthetic
- No expand button when collapsed — clicking any section icon expands the sidebar and opens that section

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 (ThemedChart with Line, Area, or Bar)

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

Detail/inspector pattern

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

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

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 ThemedChart panels
  → EventFeed (bottom, filtered by scope)
URL-driven progressive filtering: /agents → /agents/:appId → /agents/:appId/:instanceId

Charting Strategy

The design system provides convenience chart wrappers (LineChart, AreaChart, BarChart) for common use cases, plus a lower-level ThemedChart wrapper for full Recharts control. Recharts is bundled as a dependency — consumers do not need to install it separately.

Quick Charts (convenience wrappers)

import { LineChart, AreaChart, BarChart } from '@cameleer/design-system'
import type { ChartSeries } from '@cameleer/design-system'

const series: ChartSeries[] = [
  { label: 'CPU', data: [{ x: '10:00', y: 45 }, { x: '10:05', y: 62 }] },
  { label: 'Memory', data: [{ x: '10:00', y: 70 }, { x: '10:05', y: 72 }] },
]

<LineChart series={series} height={200} yLabel="%" />
<AreaChart series={series} height={200} yLabel="%" thresholdValue={85} thresholdLabel="Alert" />
<BarChart series={series} height={200} stacked />
Prop LineChart AreaChart BarChart Description
series required required required ChartSeries[]{ label, data: { x, y }[], color? }
height optional optional optional Chart height in pixels
width optional optional optional Container width in pixels
yLabel optional optional optional Y-axis label
xLabel optional optional optional X-axis label
className optional optional optional Container CSS class
threshold { value, label } Horizontal reference line
thresholdValue optional Threshold y-value
thresholdLabel optional Threshold label
stacked optional Stack bars instead of grouping

Custom Charts (ThemedChart)

import { ThemedChart, Line, Area, ReferenceLine, CHART_COLORS } from '@cameleer/design-system'

const data = metrics.map(m => ({ time: m.timestamp, cpu: m.value * 100 }))

<ThemedChart data={data} height={160} xDataKey="time" yLabel="%">
  <Area dataKey="cpu" stroke={CHART_COLORS[0]} fill={CHART_COLORS[0]} fillOpacity={0.1} />
  <ReferenceLine y={85} stroke="var(--error)" strokeDasharray="5 3" label="Alert" />
</ThemedChart>

ThemedChart Props

Prop Type Default Description
data Record<string, any>[] required Flat array of data objects
height number 200 Chart height in pixels
xDataKey string "time" Key for x-axis values
xType 'number' | 'category' "category" X-axis scale type
xTickFormatter (value: any) => string Custom x-axis label formatter
yTickFormatter (value: any) => string Custom y-axis label formatter
yLabel string Y-axis label text
children ReactNode required Recharts elements (Line, Area, Bar, etc.)
className string Container CSS class

Available Recharts Re-exports

Line, Area, Bar, ReferenceLine, ReferenceArea, Legend, Brush

For chart types not covered (treemap, radar, pie, sankey), import from recharts directly and use rechartsTheme for consistent styling.

Theme Utilities

Export Purpose
CHART_COLORS Array of var(--chart-1) through var(--chart-8)
rechartsTheme Pre-configured prop objects for Recharts sub-components

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 Convenience area chart wrapper — pass series data, get themed chart with fills
BarChart composite Convenience bar chart wrapper — grouped or stacked mode
Avatar primitive User representation with initials and color
AvatarGroup composite Stacked overlapping avatars with overflow count
Badge primitive Labeled status indicator with semantic colors
Breadcrumb composite Navigation path showing current location
Button primitive Action trigger (primary, secondary, danger, ghost)
ButtonGroup primitive Multi-select toggle group with optional colored dot indicators. Props: items (value, label, color?), value (Set), onChange
Card primitive Content container with optional accent border and title header
Checkbox primitive Boolean input with label
CodeBlock primitive Syntax-highlighted code/JSON display
Collapsible primitive Single expand/collapse section
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.
ConfirmDialog composite Type-to-confirm destructive action dialog built on Modal. Props: open, onClose, onConfirm, title, message, confirmText, confirmLabel, cancelLabel, variant, loading, className
DataTable composite Sortable, paginated data table with row actions. Use flush prop when embedded inside a container that provides its own border/radius
DateRangePicker primitive Date range selection with presets
DateTimePicker primitive Single date/time input
DetailPanel composite Slide-in side panel with tabs or children for scrollable content
Dropdown composite Action menu triggered by any element
EmptyState primitive Placeholder for empty content areas
EntityList composite Searchable, selectable entity list with add button. Pair with SplitPane for CRUD management screens
EventFeed composite Chronological event log with severity
FilterBar composite Search + filter controls for data views
GroupCard composite Card with header, meta row, children, and optional footer/alert. Used for grouping instances by application.
FilterPill primitive Individual filter chip (active/inactive), supports forwardRef
FormField primitive Wrapper adding label, hint, error to any input
InfoCallout primitive Inline contextual note with variant colors
InlineEdit primitive Click-to-edit text field. Enter saves, Escape/blur cancels. Props: value, onSave, placeholder, disabled, className
Input primitive Single-line text input with optional icon
KeyboardHint primitive Keyboard shortcut display
KpiStrip composite Horizontal row of KPI cards with colored left border, trend, subtitle, optional sparkline
Label primitive Form label with optional required asterisk
LineChart composite Convenience line chart wrapper — pass series data, get themed chart with lines
LogViewer composite Scrollable log output with timestamped, severity-colored monospace entries
MenuItem composite Sidebar navigation item with health/count
Modal composite Generic dialog overlay with backdrop
MultiSelect composite Dropdown with searchable checkbox list and Apply action. Props: options, value, onChange, placeholder, searchable, disabled, className
MonoText primitive Inline monospace text (xs, sm, md)
Pagination primitive Page navigation controls
Popover composite Click-triggered floating panel with arrow
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.
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
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
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
SplitPane composite Two-column master/detail layout with configurable ratio and empty state
Spinner primitive Animated loading indicator
StatCard primitive KPI card with value, trend, optional sparkline
StatusDot primitive Colored dot for status indication
StatusText primitive Inline colored status span (success, warning, error, running, muted) with optional bold
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
Sidebar Composable compound sidebar shell with icon-rail collapse mode. Sub-components: Sidebar.Header, Sidebar.Section (supports position="bottom" and maxHeight), 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 }.
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

Import Paths

Within this repo (design system development)

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'
import { AppShell } from './design-system/layout/AppShell'
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'
import { ThemeProvider, useTheme } from './design-system/providers/ThemeProvider'

From consuming apps (via npm package)

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.

Brand Assets

The design system ships logo assets as static files via the ./assets/* package export. These are not React components — they resolve to file URLs when imported via a bundler. All PNGs have transparent backgrounds.

File Size Use case
cameleer3-logo.png Original Full resolution for print/marketing
cameleer3-16.png 16×16 Browser tab favicon
cameleer3-32.png 32×32 Standard favicon, bookmarks
cameleer3-48.png 48×48 Windows taskbar
cameleer3-180.png 180×180 Apple touch icon
cameleer3-192.png 192×192 Android/PWA icon
cameleer3-512.png 512×512 PWA splash, og:image
cameleer3-logo.svg Vector High-detail SVG logo (traced from PNG, transparent)
camel-logo.svg Vector Simplified camel SVG logo

Usage

import logo from '@cameleer/design-system/assets/cameleer3-512.png'
<img src={logo} alt="Cameleer3" />
<!-- 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">

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