Skip to main content
Install any of these with 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.
Getting fadeColor wrong is the most common mistake. The fade is a real gradient painted over your content — if it does not match the background behind it, you get a visible band at the top and bottom edges.
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.
Each key in 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.