UI Fundamentals
Start
  • Overview
Foundations
  • Theming
    9
Components
  • Buttons
    6
  • Cards
    2
  • Progress
    3
  • Items
    3
  • Separators
    3
  • Inputs
    4
  • Badges
    6
  • Patterns
    3
  • Home
  • Docs
cmd+b

Design System

shadcn sourceBase UI trackSidebar shell

Design system fundamentals playground

The shell, previews, themes, and typography now come from the same local shadcn source system. The goal is to keep this sandbox easy to navigate, easy to extend, and close to how a real component docs surface should feel.

Read the Base button docs
Installed from

Local source files generated by the shadcn CLI.

pnpm exec shadcn add button sidebar card badge separator spinner item button-group
open code
Owned shell

The navigation, header frame, and content surfaces are all built from local shadcn source files.

sidebar.tsx, button.tsx, item.tsx, card.tsx, button-group.tsx
local
Primitive underneath

This project is on the Base UI track, so the interaction behavior comes from Base UI primitives.

@base-ui/react
Base UI
Theme system

Semantic CSS tokens define the look while the same component classes keep working across themes.

app/globals.css + next-themes
tokens
Typography system

The catalog now uses the official Geist package, with Geist Sans for interface copy and Geist Mono for code.

geist/font/sans + geist/font/mono
type

Theming

Token-based themes

The shell changes the theme class on the html element. All the color utilities below are driven by semantic tokens, so the same component classes work across every theme.

Background / Foreground

Base page shell and default text.

TokenAa
Card / Card Foreground

Panels and elevated surfaces.

TokenAa
Primary / Primary Foreground

High emphasis action surfaces.

TokenAa
Secondary / Secondary Foreground

Lower-emphasis filled actions.

TokenAa
Muted / Muted Foreground

Subtle surfaces and supporting copy.

TokenAa
Accent / Accent Foreground

Interactive hover and selected states.

TokenAa
Sidebar / Sidebar Foreground

Navigation shell surface and default sidebar text.

TokenAa
Sidebar Hover / Sidebar Hover Foreground

Low-emphasis hover state for navigation rows and sidebar controls.

TokenAa
Sidebar Active / Sidebar Active Foreground

Selected state for active sidebar rows and sub-navigation.

TokenAa

Buttons

Variants and sizing

Treat the catalog as structured documentation. Each row explains intent and shows one live preview without wrapping every example in another mini-card.

Variants
Button intent and visual weight.
Default

Primary action

Outline

Secondary action

Secondary

Muted emphasis

Ghost

Low visual weight

Destructive

Danger action

Link

Text-only action

Sizes
Scale options for dense UI and stronger CTAs.
Extra Small

Compact utility UI

Small

Dense table and form actions

Default

General product actions

Large

High-emphasis CTA

Icon-only sizes

Keep icon actions compact and grouped. Always provide an accessible label.

Use aria-label for icon-only actions.

Cards

Slots and size prop

The local Card source is composition-first. It exposes a single size prop and a set of structural slots: CardHeader, CardTitle, CardDescription, CardAction, CardContent, and CardFooter.

API notes
The actual slots and built-in behaviors exposed by card.tsx.
Default

Standard spacing for richer content blocks.

Root prop: size="default"
default
Small

Denser spacing for compact utility surfaces.

Root prop: size="sm"
sm
Header action slot

Use CardAction for controls or status content aligned to the top-right of the header.

Slot: CardAction
top-right
Image-first behavior

The root styles automatically remove top padding when the first child is an image.

Source class: has-[>img:first-child]:pt-0
built-in

Live examples

One standard card and one compact card using the local source component.

Weekly summary
A standard content card with header, description, content, and footer.
Default

Cards in this system rely on semantic tokens like bg-card and text-card-foreground, so themes restyle them automatically.

The source file exposes one size prop and a slot-based composition API instead of many visual variants.

card.tsx
Compact summary
Smaller spacing for tighter dashboards and side panels.
SM

Use this when the card should stay informative but visually light.

The source file exposes one size prop and a slot-based composition API instead of many visual variants.

card.tsx

Progress

Shared completion bar

The progress component wraps the installed Base UI primitive in one reusable atom. It keeps the numeric value inside the fill by default, which works well for course dashboards and compact status surfaces.

API notes
The shared progress atom exposes a small API focused on label, value, and token overrides.
Visible label

Use the label prop when the progress bar needs an on-screen title and an accessible name.

x
Value inside indicator

The shared component keeps the value inside the fill so even 0% still has a readable pill state.

x
Token overrides

Use trackClassName, indicatorClassName, and valueClassName to adapt the bar to shells like sidebars.

x

Live examples

Default and sidebar-style compositions built from the same shared source component.

Default

Neutral track with the current value kept inside the fill.

Launch checklist
64%
x

Sidebar treatment

The same component can be retuned for darker shells by overriding its token classes.

Progress
0%
x

Items

Rows, structure, and density

The local Item source is a composition-first row component. It exposes visual variants, density sizes, media slots, and a render prop for link-style rows.

API notes
The actual local API used to build rows across this catalog.
Default variant

No visible border. Best for embedded list rows.

Prop: variant="default"
default
Outline variant

Adds a visible border for standalone rows.

Prop: variant="outline"
outline
Muted variant

Adds a muted surface for supporting content.

Prop: variant="muted"
muted
Default size

Standard spacing for most rows.

Prop: size="default"
default
Small size

Compact spacing for denser lists.

Prop: size="sm"
sm
Extra Small size

The tightest layout for menus and utility surfaces.

Prop: size="xs"
xs
Media and layout slots

Use ItemMedia, ItemHeader, ItemContent, ItemActions, and ItemFooter to compose richer rows.

Media variants: default, icon, image
slots
Link rendering

Use the render prop to apply item hover and focus states to an anchor.

Prop: render

Live examples

Examples built with the same local item.tsx source the catalog already uses.

Basic action row

The default pattern used throughout this catalog.

+
Account verified

Use Item for readable title, description, and action rows.

Outline with header and footer

Header and footer slots let one row carry a little more structure.

Pro planNew
Workspace billing

ItemHeader and ItemFooter are useful when the row needs metadata above or below the main content.

Updated today

Link and compact media

render turns the whole row into a link while keeping item states.

Official Item docs

A linked row with image media and muted surface treatment.

Docs
s
Compact row

size="xs" works well for denser utility surfaces.

xs

Separators

Orientation and divider usage

The local Separator source is intentionally minimal. It exposes a single orientation prop and applies the border token consistently across horizontal and vertical dividers.

API notes
The actual local separator surface is very small.
Horizontal

Default orientation for section and list dividers.

Prop: orientation="horizontal" (default)
Vertical

Use between inline controls or metadata blocks.

Prop: orientation="vertical"
Local wrappers

ItemSeparator, SidebarSeparator, and ButtonGroupSeparator all build on this component.

Used by ItemSeparator, SidebarSeparator, and ButtonGroupSeparator
shared

Live examples

Simple dividers using the same local separator.tsx source.

Horizontal content split

Use the default separator to divide stacked content.

Workspace

Manage branding, billing, and access.

Team

Invite members and adjust roles.

Vertical inline split

Use orientation=vertical to separate inline actions or metadata.

Status
Draft

Why it matters

The same primitive keeps spacing and color treatment consistent across the catalog.

This project already reuses Separator in Item rows, the sidebar shell, and button groups.

Documenting it makes those patterns easier to understand and reuse without hand-drawing borders.

Inputs

Native props and state styling

The local Input source does not expose size or variant props. It styles a native input and relies on standard props like placeholder, disabled, type, and aria-invalid.

API notes
What the local input source supports without custom variants.
Native props

Uses standard input props instead of custom variants.

Local type: React.ComponentProps<"input">
Invalid state

Use aria-invalid to trigger the error styling in input.tsx.

Flag: aria-invalid
Disabled state

Use disabled for non-interactive inputs and muted treatment.

Flag: disabled
File input

Use type=file to reuse the built-in file styles.

Flag: type="file"
Official composition

The official shadcn docs pair Input with Field, FieldLabel, and FieldDescription for production forms.

See /docs/components/base/input and Field.

Live examples

Real states and compositions using the installed Input component.

Basic

Default text input with placeholder text.

Disabled and invalid

The component styles standard form states without extra variants.

File input

type=file picks up the built-in file button styling from input.tsx.

Input + action

ButtonGroup supports direct child inputs, so search-style rows can stay visually grouped.

Badges

Status chips and inline labels

Badges are good for compact status, lightweight categorization, and inline metadata. This section uses the local shadcn Badge source component and follows the current Base UI docs patterns.

Variants
Status styles available in the local badge source.
Default

Primary status emphasis

Default
Secondary

Muted supportive label

Secondary
Destructive

Error or risky state

Destructive
Outline

Neutral status chip

Outline
Ghost

Low-emphasis inline label

Ghost
Link

Text-like badge treatment

Link
Usage patterns
Common inline compositions from the Base UI docs.
With icon

Use inline start and end markers to keep icon placement predictable.

Add data-icon="inline-start" or data-icon="inline-end" on the icon.
VerifiedSaved
With spinner

Loading states can stay compact when you use the shared Spinner inside the badge.

SyncingRemoving
Rendered as link

Use the Badge render prop when the badge itself should behave like a link.

This matches the current Base UI badge docs for link rendering.
Open docs

Patterns

Common button usage patterns

A design system is more than one component file. It also defines how the component should be used in real product situations.

Leading and trailing content

The generated button styles already support inline start and end content.

State examples

Use the same source components for loading, disabled, and destructive actions too.

Semantic link styling

In the Base UI version, use buttonVariants on a plain anchor for navigation instead of rendering an anchor through the Button primitive.

Open button docsOpen Base UI