bunx shadcn@latest add @9am/<name>. They land in src/components/ui/.
Viewport
The house scroll container, and the piece worth understanding properly. It is not a card — it is a scroller with three behaviours layered on:- A custom scrollbar thumb you can drag, which fades in on hover and disappears entirely when the content does not overflow.
- Layered glass edges — a gradient blur at the top and bottom that content dissolves into.
- A pinning header. Scroll down and the real header blurs out while a sticky copy animates in above the content.
Plus every standard
div prop.
ViewportAction is detected at the React level rather than with CSS :has(), because Chromium 103 does not support it. Put it inside ViewportHeader and the header switches to a two-column grid automatically.
Button
Supports
asChild for rendering as a different element.
DataTable
A TanStack-backed table with search, sorting, and pagination already wired up.
Pass
countLabel whenever a domain word reads better than “rows” — that is what stops a coupons table from saying “12 rows”.
Pagination is ten rows per page.
MultiSelect
Tabs
Two variants.default is a segmented control; line is the underlined style the dashboard header uses, where the active tab turns gold and grows an underline.
Tabs also accepts orientation="vertical".
Field
Composable form-row primitives. Use these instead of hand-rolling label and helper-text layout.Field takes orientation="vertical" (default) or "horizontal". FieldError renders nothing when it has no children, so you can leave it in unconditionally.
Also exported: FieldSet, FieldLegend, FieldGroup, FieldContent, FieldTitle, FieldSeparator.
Dialog
InfoTip
A small? glyph that reveals an explanation on hover. Use it instead of cramming caveats into a label.
Chart
A Recharts wrapper that maps series to theme tokens.config produces a --color-<key> custom property. Also exported: ChartLegend, ChartLegendContent, ChartStyle.
Five chart tokens are defined per palette: --chart-1 through --chart-5.
Everything else
These follow their shadcn equivalents, restyled to the 9AM surface language.Tooltip and InfoTip need a TooltipProvider above them in the tree. Put one at the root of your app.