Browse docs
Browse docs
@dashforge/tw is a props-first component library that runs on top of Tailwind CSS. You bring Tailwind. We bring the components you'd otherwise hand-roll over and over — Button, TextField, Checkbox, Switch, and the rest of an opinionated app stack — already wired to a token system, dark mode, RBAC, and a reactive theme.
It is not a Tailwind alternative. It uses Tailwind, the way React uses HTML.
import { Button, TextField, Switch } from '@dashforge/tw';
export function SignIn() {
return (
<form className="space-y-3">
<TextField name="email" type="email" label="Email" required />
<TextField name="password" type="password" label="Password" required />
<Switch label="Remember me" />
<Button type="submit" color="primary">Sign in</Button>
</form>
);
}No utility-class chains. No useState for the toggle. No hand-rolled focus rings. Dark mode included.
Three packages cooperate. You usually install all three:
| Package | What it ships | Size |
|---|---|---|
@dashforge/tw-tokens | Pure TypeScript token types + defaults (colors 50–950, spacing, radii, font sizes). One source of truth. | < 5 KB |
@dashforge/tw-theme | Reactive theme runtime + <DashforgeTailwindProvider> + a Tailwind preset (dashforgePreset()) that resolves tokens to CSS vars. | < 8 KB |
@dashforge/tw | The component library (Button, TextField, Checkbox, Switch — more incoming). All Tailwind-rendered, all cn()-composable, all overridable via className + slotProps. | grows with adoption |
<DashforgeTailwindProvider> injects CSS variables on <html>, flips them on setMode('dark'). Every component reacts. No theme prop drilling.@dashforge/tw-tokens as typed constants. The Tailwind preset turns them into utility classes; the runtime turns them into CSS variables. You override one, both move in lockstep.<Button color="primary" variant="outlined" size="md" loading={isLoading}> instead of a 12-class utility chain you copy-paste from another file. The variant catalogue is tailwind-variants under the hood, so override slots (slotProps) and one-off classes (className) compose cleanly.role, aria-*, keyboard handlers, focus rings come pre-wired. Checkbox and Switch use Radix primitives; Button passes through disabled to the underlying element.access={...} prop that hides, disables or read-only's it based on the shared @dashforge/rbac context. Same prop, same semantics on the MUI side.Three things matter here:
tailwind.config.js important if you're embedding the library in a larger app that uses its own CSS.tailwind.config.js is the source of truth. Add the dashforgePreset() and your own colors/utilities sit next to ours.