@tronvercel/ui
v0.2.0
Published
Tronvercel UI — shared React component library (shadcn/ui + Tailwind) with the restrained-Tron/Vercel theme
Readme
@tronvercel/ui
Shared React component library with the restrained Tron/Vercel theme — dark, geometric, precise. Built on shadcn/ui primitives (Radix UI + Tailwind CSS).
Components
| Component | Description |
|-----------|-------------|
| Button | Primary, default, ghost, danger variants + sm/md/icon sizes |
| Input | Single-line text input |
| Textarea | Resizable multi-line text |
| Label | Form label (pairs with any form control) |
| Select | Dropdown select (Radix-based) |
| Checkbox | Tri-state checkbox (checked / indeterminate / unchecked) |
| Switch | Toggle switch |
| RadioGroup / RadioItem | Radio group |
| Badge | Tone-aware badge (neutral/accent/ok/warn/danger/info) |
| StatusDot | Inline status indicator dot |
| StatusPill | Status dot + label pill |
| Panel / PanelHeader / PanelBody | Card/panel surface with optional structured header |
| Card / CardHeader / CardBody / CardFooter | Content card (default / flush / ghost variants) |
| TableRoot / TableHead / TableBody / TableRow / TableTh / TableTd | Data table |
| ListRow / ListGroup | List with optional leading/trailing slots |
| Pagination | Page navigation control |
| Toast / ToastTitle / ToastDescription / ToastClose / ToastAction | Radix-based toast notifications |
| Skeleton / SkeletonText | Shimmer loading placeholders |
| Kbd | Keyboard key glyph |
| Spinner | Loading spinner |
Installation
npm install @tronvercel/uiPeer dependencies
npm install react react-dom \
@radix-ui/react-checkbox @radix-ui/react-radio-group \
@radix-ui/react-select @radix-ui/react-switch @radix-ui/react-toast \
lucide-react clsx tailwind-mergeOnly install the Radix packages for components you actually use. lucide-react, clsx, and tailwind-merge are required for core utilities.
CSS
Import the stylesheet once at your app entry point:
// main.tsx
import '@tronvercel/ui/styles';The stylesheet injects the CSS custom properties (design tokens). Without it, components render but without theme colors.
Usage
import { Button, Badge, Input, Panel, PanelHeader, PanelBody } from '@tronvercel/ui';
function MyPage() {
return (
<Panel flush>
<PanelHeader title="Deployments" hint="3 active" actions={<Button size="sm">Deploy</Button>} />
<PanelBody>
<Badge tone="ok">running</Badge>
</PanelBody>
</Panel>
);
}Theming
The theme is defined entirely through CSS custom properties (channel triples — R G B without the rgb() wrapper so Tailwind's opacity modifier works):
/* surfaces */
--c-ink: 6 8 10; /* deepest background */
--c-base: 10 13 15; /* app background */
--c-surface: 16 20 23; /* panels, cards */
--c-raised: 22 27 31; /* hover / lifted state */
--c-overlay: 20 25 29; /* dialogs, popovers */
/* lines */
--c-line: 33 41 46; /* hairline borders */
--c-line-strong: 46 57 64; /* emphasized edges */
/* text */
--c-fg: 226 231 233; /* primary text */
--c-muted: 138 150 155; /* secondary text */
--c-faint: 92 103 108; /* tertiary / disabled */
/* accent — restrained technical cyan, never glowing */
--c-accent: 52 192 212;
--c-accent-fg: 6 8 10;
--c-accent-dim: 38 110 122;
/* status */
--c-ok: 63 185 80;
--c-warn: 210 153 34;
--c-danger: 248 81 73;
--c-info: 88 166 255;Overriding tokens
Wrap your app (or a subtree) in a container that overrides the CSS variables:
/* my-app.css */
:root {
--c-accent: 120 80 255; /* purple accent instead of cyan */
}Tailwind integration
If you use Tailwind in your app, copy the theme.colors block from tailwind.config.ts into your project config to get autocomplete and use the same token names (bg-surface, text-muted, etc.).
Storybook
npm run storybook # dev server on :6006
npm run build-storybook # static build → storybook-static/Stories live in stories/ and cover every component with its variants and states:
| Story group | Contents | |-------------|----------| | Design/Tokens | Color token swatches | | UI/Button | Variants, sizes, disabled | | UI/Badge | Tones, StatusDot, StatusPill | | UI/Primitives | Input, Spinner, Panel, Kbd | | UI/FormControls | Label, Textarea, Checkbox, Switch, Select, RadioGroup, composite form | | UI/DataDisplay | Card, Skeleton, Table, ListRow, Pagination, Toast |
Migration guide
From Gas Town's gastown theme (first consumer)
gastown ships its own Tailwind token set. tronvercel-ui is a port of that token set into a standalone library. CSS variable names are identical so the visual output is the same.
Step 1 — install
npm install @tronvercel/ui
npm install @radix-ui/react-checkbox @radix-ui/react-radio-group \
@radix-ui/react-select @radix-ui/react-switch @radix-ui/react-toast \
lucide-react clsx tailwind-mergeStep 2 — swap the stylesheet import
- import '@/styles/globals.css'; // local token file
+ import '@tronvercel/ui/styles';Step 3 — replace local component imports
- import { Button } from '@/components/ui/button';
+ import { Button } from '@tronvercel/ui';Component APIs are identical — no prop changes needed.
Step 4 — remove the shadowed files
Delete the local src/components/ui/ copies you've replaced. Keep any project-specific components that extend or compose library components.
From a different design system (Newel and others)
- Import
@tronvercel/ui/stylesto inject the token layer. - Replace your button/input/badge/etc. imports one component at a time.
- Use
npm run storybookto visually verify each component after migration. - Token overrides (see Theming above) let you adjust specific colors without forking.
Development
npm install
npm run build # compile to dist/
npm run typecheck # tsc --noEmit
npm run lint # eslint
npm run storybook # interactive component explorerThe library is built with Vite in library mode. src/index.ts is the public API surface — add new component exports there.
