Octonode Playbook

Octonode Design System

Canonical Octonode repository documentation.

Octonode Design System

@octonode/design-system owns shared visual tokens and shadcn-style React primitives. Studio and future Octonode apps import primitives from the package root and load styles.css once at their entry stylesheet.

Rules

  • Keep primitives product-neutral and accessible; product components remain in their app.
  • Reuse Radix behavior and the existing dependencies before adding another UI dependency.
  • Style with semantic theme tokens, never app-specific colors inside a primitive.
  • Preserve className, refs, and native/Radix props so consumers can compose instead of fork.
  • Add a primitive only after a second real consumer exists.
  • Use SearchInput for standard searchable controls and Surface for recurring bordered panels, empty states, and error states. Keep product-specific behavior in the app.
  • Use Choice for clickable radio or checkbox containers. Its card, segment, and row variants keep selection, hover, disabled, and keyboard-focus states consistent.
  • Use FormField with Input, Textarea, or a select for labeled form controls. Use Checkbox for compact standalone cells, Switch for immediately applied on/off settings, and Choice when the label and description form the whole selection target.
  • Use Callout for contextual status or errors, EmptyState for actionable blank views, and Toolbar variant="filter" for search/filter groups. Do not recreate their borders and spacing.
  • Use Surface as the shared box primitive, Container for page width and gutters, and CardGrid for responsive card collections such as Marketplace results.
  • Build data views from TableFrame, Table, TableHeader, TableBody, TableRow, TableHead, TableCell, and TableCaption so spacing, hierarchy, hover, and borders stay consistent. Use Table variant="sql" for dense query results with monospaced values and cell gridlines.
  • Use CSS Grid and Flexbox directly for page layout. Do not add Grid or Box wrappers that only rename a div; shared primitives should own a visual identity or interaction behavior.

Dynamic patterns

The default token values preserve Studio's original dark and light views. An app can set data-density="compact|comfortable" and data-radius="sharp|soft" on any ancestor. Theme colors remain CSS variables, so a product can override them at the same boundary without React state or a design-system provider.

Migration

Shared shadcn primitives live only in packages/design-system/src. Studio stories exercise the published package API. Native selects use NativeSelect when HTML form semantics or multiple are required; use the Radix Select composition for richer interactive menus.

On this page