@odla-ai/ui
v0.3.1
Published
The odla design system: semantic CSS tokens, six themes, class-scoped styles, canvas helpers, and optional React/Preact form, navigation, and application-shell components.
Maintainers
Readme
@odla-ai/ui
⚠️ Early access — pre-1.0. Agents work from bounded runbooks; humans approve credentials, production changes, releases, and merges. APIs and exact package availability can change. Review the documented guarantees and limitations; this software is MIT-licensed and provided without warranty.
The odla design system: one semantic token contract (--ui-*), six themes,
class-scoped component CSS, canvas chart helpers, and optional React/Preact
form components. CSS-first — every odla surface can consume it, from
zero-build static sites to Vite React apps.
- Tokens: colors, text tiers, status, fonts, spacing, radius, focus,
chart and chat roles. Defaults ship at zero specificity (
:where()), so themes and app overrides always win. - Themes:
paper(the odla Studio's warm-paper dashboard look),flightline(field manual meets flight recorder), plusjuniper,salt,chalk, andclay(the blog themes —@odla-ai/blogresolves those four from this package). Each theme =styles.css(its own palette) +ui.css(mapping onto the contract) +theme.json. - Components (CSS): buttons/segmented/pills, form fields with validation
states, cards/panels/badges, data tables, container-native app chrome with a
navigation rail + sidebar, accessible in-content tabs, a persistent
bottom notification edge with Gmail-style docked cards, a sticky or contained
top bar, grouped docs left-nav, toasts/banners/dropzones, chat surfaces (message bubbles, tool-call cards,
thinking panels, composer — shaped by
@odla-ai/ai's streaming contract), chart containers. - JS helpers (buildless ESM): light/dark toggle with no-flash snippet,
a
--ui-*palette reader for canvas, and chart primitives (fitCanvas,niceTicks,bandFill,drawTip, …). /components: form controls;TopBar/TopBarLink;AppShell,NavigationRail,Sidebar; accessibleTabs;Dock/DockCardandEdgeNotificationBar;DocsNav/DocsNavGroup/DocsNavLink— authored once against thereactAPI, runs on React 18/19 natively and on Preact viapreact/compataliasing (Vite alias or a browser import map for buildless islands).
Install
npm install @odla-ai/ui60-second start (Vite + React)
// main.tsx
import "@odla-ai/ui/fonts/plex.css";
import "@odla-ai/ui/themes/paper/styles.css";
import "@odla-ai/ui/themes/paper/ui.css";
import "@odla-ai/ui/index.css";import { Button, Field, Input } from "@odla-ai/ui/components";
<div className="card">
<h4>New note</h4>
<Field label="Title" htmlFor="t">
<Input id="t" placeholder="…" />
</Field>
<div className="row">
<Button>Save</Button>
<Button variant="secondary">Cancel</Button>
</div>
</div>Static sites copy odla-ui.css (pre-flattened, no imports) plus a theme's
styles.css + ui.css and use the same classes in plain HTML.
Themes
| Theme | Look | Fonts |
| --- | --- | --- |
| paper | Warm paper dashboard (the odla Studio) | IBM Plex Sans/Mono (fonts/plex.css) |
| flightline | Technical field manual by day, flight recorder at night | IBM Plex Sans/Mono (fonts/plex.css) |
| juniper | Quiet long-form reading, violet accents | Lora + Gill Sans stack |
| salt | Warm editorial cream/moss/rust | Cormorant Garamond + Satoshi |
| chalk | Chalkboard on graph paper | Cormorant + Spectral + JetBrains Mono |
| clay | Warm light editorial, terracotta | System stacks only (zero font requests) |
Dark mode: every theme defines dark tokens on [data-theme="dark"] and the
prefers-color-scheme fallback (kept byte-identical — tested). Toggle with
toggleTheme() from the JS helpers.
The full contract — token tables, class inventory, recipes, invariants — lives in this installed README and the exported TypeScript declarations/JSDoc. The rendered public reference is at https://odla.ai/docs/packages/ui.
Development
npm test -w @odla-ai/ui # builds dist, then node --test
npm run gen:css -w @odla-ai/ui # refresh odla-ui.css after editing css/Tests enforce: theme dark-block identity across all six themes, full
--ui-* coverage per theme, class-scoped selectors (no bare elements) in
component sheets, odla-ui.css freshness, and component render output.
