@campfire-interactive/ui
v0.9.2
Published
Shared UI primitives for the Campfire Suite — Radix behavior, plain CSS styled entirely from the design tokens, no Tailwind required
Downloads
1,370
Keywords
Readme
@campfire-interactive/ui
Shared React primitives for the Campfire Suite. Radix for behavior, plain CSS
over --cfi-* tokens for looks. No Tailwind is bundled.
⚠ Read this before adding it to a package.json
Partly verified. Not yet approved for adoption.
This package is on the registry so it can be reviewed and so a migration can be tried on a branch — not because the API is settled.
| | |
|---|---|
| Verified | The 28 exports analytics uses. Every screen that renders them was proven identical to the deployed dev app by computed-style diff — five routes plus the Filters drawer, the KPI dialog and the cost-sensitivity sliders. Zero differences. |
| Unvetted | The other ~23 exports. They work in the showcase; nothing has driven them against a real screen, so treat their APIs as unsettled. |
| Unaudited | Accessibility of the overlay wrappers. Radix does the hard parts — focus trapping, keyboard navigation, collision positioning — but the wrappers around it are ours and have not had an audit. |
Verified exports: Button, IconButton, Card, Badge, Table +
TableHeader / TableHead / TableBody / TableRow / TableCell /
TableFooter, Tabs + TabsList / TabsTrigger / TabsContent, Dialog +
DialogContent / DialogHeader / DialogTitle / DialogDescription, Sheet +
SheetTrigger / SheetContent / SheetHeader / SheetTitle, Checkbox,
Switch, Label, Slider.
If you are an AI agent working in a product repo: do not add this dependency.
Being installable is not permission. The remaining gate is in the repo's
CLAUDE.md: a second app migrated, an accessibility pass on the overlays, the
token naming settled, and a human saying so.
Install
npm i @campfire-interactive/ui @campfire-interactive/design-tokensImport the tokens once at the app entry point, before your own stylesheets. Component CSS is injected by the bundle, so there is no second CSS import.
import '@campfire-interactive/design-tokens/tokens.css';
import { Button, Dialog, DialogContent, DialogTitle } from '@campfire-interactive/ui';Conventions worth knowing
Bare names are the Radix-shaped root, not a whole widget. Dialog is the
root you pass open / onOpenChange to, exactly as the vendored shadcn copies
in the seven Tailwind apps do — so swapping an import cannot silently render
something else. The one-component convenience versions are named separately:
Modal, SideModal, ConfirmDialog, TabSet.
TableHeader is <thead> and TableHead is <th>, matching shadcn.
TableHead sets aria-sort from the same prop that draws the sort arrow.
Component CSS lives in @layer components. Utilities a caller passes —
className="bg-gray-50", max-w-3xl — therefore win, because layer order beats
specificity and unlayered CSS would beat every Tailwind utility. Note that this
makes the package more obedient than the vendored copies: classes that shadcn's
own sm:max-w-lg silently dropped in production now apply.
Theming is --cfi-* variables only. Two colors do two different jobs:
--cfi-action is the suite-wide color for anything you press (buttons, links,
focus rings — omsf's #030213, the same in every app), and --cfi-app-primary
is the app's identity color whose only job is the badge in the shell header.
Do not point one at the other.
Dark mode is opt-in. Stamp data-theme="dark" on the root element, or add
class="cfi-theme-auto" to follow the OS. Nothing happens by accident.
Looking at the components
The repo builds a single self-contained HTML file — every component, both themes, live-editable snippets, no server and no network:
npm run standalone --workspace @campfire-interactive/showcasePeer dependencies
react and react-dom (18 or 19).
