@dimora/atrium-ui
v0.2.0
Published
Atrium primitive kit: typed, dual-surface-aware portal building blocks (board, table, timeline, timer, chat, consolidation pane) so agents compose rich views instead of rebuilding widgets.
Readme
@dimora/atrium-ui
Atrium's primitive kit: pure prop-logic (board grouping, table sort/filter, surface-form
helpers) on the root barrel, plus a small, token-styled React component set on the
@dimora/atrium-ui/react subpath so a plugin composes rich views instead of hand-rolling
table/tile/badge/card/modal against raw CSS.
Two import surfaces — the root barrel is React-free (import it from logic-only code without
pulling React); the components live on /react. React is a peer dependency — the consuming
plugin bundles its own copy.
// Pure logic (no React) — the root barrel:
import { sortRows, filterRows, groupCardsByColumn, isCompact } from "@dimora/atrium-ui";// React components — the /react subpath:
import { DataTable, KpiTile, Badge, SectionCard, Modal, EmptyState, ErrorBanner } from "@dimora/atrium-ui/react";The React components (a starter kit, not a design system)
| Component | What it is |
|---|---|
| DataTable | Sortable-header table with row-click and an optional per-row expansion slot. Sort is uncontrolled (asc → desc → cleared); reuses the package's pure sortRows. |
| KpiTile | A single metric: uppercase label, large intent-tinted value, optional hint. Clickable tiles are keyboard-operable. |
| Badge | A status pill. Filled (neutral/primary/danger) or outlined (success/warning). |
| SectionCard | A titled card panel — the standard container a view stacks. |
| Modal | A centered dialog: focus-trapped, Escape-to-close, overlay-click-to-close. |
| EmptyState | The "nothing here yet" placeholder — message + optional hint/action. |
| ErrorBanner | A danger-accented error strip. recoveryHint pairs directly with a connector's classified { error, recoveryHint }. |
Intent is the shared vocabulary: "neutral" | "primary" | "success" | "warning" | "danger".
Styling — the --atrium-* token seam (the ONLY colors)
Every component paints with --atrium-* CSS custom properties — never a raw palette or hex.
The host propagates the container's theme to these tokens (--vscode-* → --atrium-*; on the
browser surface the fallbacks follow the browser's prefers-color-scheme), so a view built from
this kit follows the user's light/dark theme in both surfaces with no extra work. A plugin
bundle gets no host Tailwind — style your own elements with these tokens too.
Token reference
| Token | Role |
|---|---|
| --atrium-background | The page/surface behind cards (the container owns it — views don't paint it). |
| --atrium-foreground | Default text. |
| --atrium-muted-foreground | Secondary / de-emphasized text (labels, hints). |
| --atrium-card | A card/panel background (SectionCard, KpiTile, Modal, ErrorBanner). |
| --atrium-border | Hairline borders and table row dividers. |
| --atrium-input / --atrium-input-foreground | Form input surface + its text. |
| --atrium-primary / --atrium-primary-foreground | Primary accent fill + its matched text. |
| --atrium-secondary / --atrium-secondary-foreground | Secondary accent fill + its matched text. |
| --atrium-danger / --atrium-danger-foreground | Error/destructive fill + its matched text. |
| --atrium-badge / --atrium-badge-foreground | Neutral badge fill + its matched text. |
| --atrium-success | Success accent (text/outline — no dedicated foreground token). |
| --atrium-warning | Warning accent (text/outline — no dedicated foreground token). |
| --atrium-accent | A general accent color. |
| --atrium-muted | A muted fill. |
Keep the pairs matched. A colored background always takes its own *-foreground
(--atrium-primary with --atrium-primary-foreground, --atrium-badge with
--atrium-badge-foreground, …). success/warning have no *-foreground token, so use them
as text or outline accents (as Badge's success/warning variants and KpiTile's intent
tinting do), not as a filled background.
The one deliberate non-token color in the kit is the Modal scrim (a theme-neutral darkening
layer): there is no scrim token, and a scrim must darken content in either theme.
Pure logic (no React)
groupCardsByColumn / moveCard (board), filterRows / sortRows (table), isCompact /
SurfaceContext (surface form) — testable in isolation, DOM-free.
