Design System
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.
Local source files generated by the shadcn CLI.
pnpm exec shadcn add button sidebar card badge separator spinner item button-groupThe navigation, header frame, and content surfaces are all built from local shadcn source files.
sidebar.tsx, button.tsx, item.tsx, card.tsx, button-group.tsxThis project is on the Base UI track, so the interaction behavior comes from Base UI primitives.
@base-ui/reactSemantic CSS tokens define the look while the same component classes keep working across themes.
app/globals.css + next-themesThe catalog now uses the official Geist package, with Geist Sans for interface copy and Geist Mono for code.
geist/font/sans + geist/font/monoTheming
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.
Base page shell and default text.
Panels and elevated surfaces.
High emphasis action surfaces.
Lower-emphasis filled actions.
Subtle surfaces and supporting copy.
Interactive hover and selected states.
Navigation shell surface and default sidebar text.
Low-emphasis hover state for navigation rows and sidebar controls.
Selected state for active sidebar rows and sub-navigation.
Buttons
Treat the catalog as structured documentation. Each row explains intent and shows one live preview without wrapping every example in another mini-card.
Primary action
Secondary action
Muted emphasis
Low visual weight
Danger action
Text-only action
Compact utility UI
Dense table and form actions
General product actions
High-emphasis CTA
Keep icon actions compact and grouped. Always provide an accessible label.
aria-label for icon-only actions.Cards
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.
Standard spacing for richer content blocks.
size="default"Denser spacing for compact utility surfaces.
size="sm"Use CardAction for controls or status content aligned to the top-right of the header.
CardActionThe root styles automatically remove top padding when the first child is an image.
has-[>img:first-child]:pt-0One standard card and one compact card using the local source component.
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.
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.
Progress
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.
Use the label prop when the progress bar needs an on-screen title and an accessible name.
The shared component keeps the value inside the fill so even 0% still has a readable pill state.
Use trackClassName, indicatorClassName, and valueClassName to adapt the bar to shells like sidebars.
Default and sidebar-style compositions built from the same shared source component.
Neutral track with the current value kept inside the fill.
The same component can be retuned for darker shells by overriding its token classes.
Items
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.
No visible border. Best for embedded list rows.
variant="default"Adds a visible border for standalone rows.
variant="outline"Adds a muted surface for supporting content.
variant="muted"Standard spacing for most rows.
size="default"Compact spacing for denser lists.
size="sm"The tightest layout for menus and utility surfaces.
size="xs"Use ItemMedia, ItemHeader, ItemContent, ItemActions, and ItemFooter to compose richer rows.
default, icon, imageUse the render prop to apply item hover and focus states to an anchor.
renderExamples built with the same local item.tsx source the catalog already uses.
The default pattern used throughout this catalog.
Use Item for readable title, description, and action rows.
Header and footer slots let one row carry a little more structure.
ItemHeader and ItemFooter are useful when the row needs metadata above or below the main content.
render turns the whole row into a link while keeping item states.
A linked row with image media and muted surface treatment.
size="xs" works well for denser utility surfaces.
Separators
The local Separator source is intentionally minimal. It exposes a single orientation prop and applies the border token consistently across horizontal and vertical dividers.
Default orientation for section and list dividers.
orientation="horizontal" (default)Use between inline controls or metadata blocks.
orientation="vertical"ItemSeparator, SidebarSeparator, and ButtonGroupSeparator all build on this component.
ItemSeparator, SidebarSeparator, and ButtonGroupSeparatorSimple dividers using the same local separator.tsx source.
Use the default separator to divide stacked content.
Workspace
Manage branding, billing, and access.
Team
Invite members and adjust roles.
Use orientation=vertical to separate inline actions or metadata.
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
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.
Uses standard input props instead of custom variants.
React.ComponentProps<"input">Use aria-invalid to trigger the error styling in input.tsx.
aria-invalidUse disabled for non-interactive inputs and muted treatment.
disabledUse type=file to reuse the built-in file styles.
type="file"The official shadcn docs pair Input with Field, FieldLabel, and FieldDescription for production forms.
/docs/components/base/input and Field.Real states and compositions using the installed Input component.
Default text input with placeholder text.
The component styles standard form states without extra variants.
type=file picks up the built-in file button styling from input.tsx.
ButtonGroup supports direct child inputs, so search-style rows can stay visually grouped.
Badges
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.
Primary status emphasis
Muted supportive label
Error or risky state
Neutral status chip
Low-emphasis inline label
Text-like badge treatment
Use inline start and end markers to keep icon placement predictable.
data-icon="inline-start" or data-icon="inline-end" on the icon.Loading states can stay compact when you use the shared Spinner inside the badge.
Use the Badge render prop when the badge itself should behave like a link.
Patterns
A design system is more than one component file. It also defines how the component should be used in real product situations.
The generated button styles already support inline start and end content.
Use the same source components for loading, disabled, and destructive actions too.
In the Base UI version, use buttonVariants on a plain anchor for navigation instead of rendering an anchor through the Button primitive.