Primitives

Button

Primary action element. 5 variants, 3 sizes. Renders as <button> or <a> when href is provided.

Variants

Sizes

States

PropTypeDefaultDescription
variant"primary" | "secondary" | "outline" | "ghost" | "danger""primary"Visual style
size"sm" | "md" | "lg""md"Height and horizontal padding
hrefstringIf set, renders as Next.js Link instead of <button>
disabledbooleanDisable interaction (button only)

Badge & Chip

Status & label indicators. Badge (semantic + variants), CountBadge (counters), PillBadge (rounded), plus domain chips SlaChip and OrderStatusChip.

Tones — soft (default)

NeutralInfoSuccessWarningDangerPrimary

Variants

SoftSolidOutlineDot

With icon

VerifiedPending review

Counters

Notifications 3Approvals 12Items 99+

Pill badges

NewTrusted vendorPremium tier

Domain chips (composed)

Excellent99.5% on-timeGood98% on-timeAt risk91% on-timeBreached78% on-timeDraftIn ApprovalApprovedShippedDeliveredRejected

Input / Textarea / Select / Label

Form primitives. Same height (40px), same focus ring. Pair with Label + FieldHelp for context.

Helper text in muted tone

Looks good

Above credit limit

Multiselect

Pick multiple options from a (possibly grouped) list with search, chips, and clear-all. Used for filtering catalogs by vendor, category, status.

With group + chips

Empty / disabled

PropTypeDefaultDescription
optionsMultiselectOption[]{ value, label, description?, group?, disabled? } array
value / onChangestring[] / (next) => voidSelected values, controlled
maxChipsnumber3How many chips to render before overflow +N
searchPlaceholderstringPlaceholder for inline search

Combobox

Single-value picker with type-ahead search. Use when a plain <Select> isn't enough (long lists, descriptions, fuzzy match).

Filtered single-select

TreeView

Hierarchical navigation with expand/collapse, optional single-select or multi-select with tristate (parent shows partial selection).

Selectable (single)

Selected: connectors

Checkable (multi w/ tristate)

Checked: 2

FileUploader

Drag-and-drop area + click-to-browse. List of attached files with remove.

Drop files here or click to browse

PDF, PNG, JPG, XLSX, CSV, DOCX up to 10 MB

  • technical_spec.pdf1.2 MB

Tabs

Two variants: underline tabs (Tabs / TabsList / TabsTrigger / TabsContent) and pill tabs (TabsPills) for filter strips.

Underline + content + counter

5 open RFQs awaiting your response.

Pill filter strip

Pagination

Numeric pagination with prev/next + ellipsis. Auto-truncates middle pages for large counts.

Showing 121140 of 1246

Stepper

Multi-step progress indicator. Horizontal for wizards, vertical for approvals.

Horizontal — wizard

  1. Items

  2. Vendor

  3. Delivery

  4. ·

    Review

  5. ·

    Submit

Vertical — approvals

  1. Submitted

    by Olivia Rhye

  2. Line Manager

    James Smith

  3. Procurement Head

    Andrew Parker · awaiting

  4. ·

    Finance

  5. ·

    Completed

Avatar

Initials-based avatars with deterministic color (hash of name). Supports group with overflow.

Sizes + status

ORORORJSAP

Group

ORJSAPSJ+2

Tooltip

Inline hover/focus hint. Use sparingly — for icon-only buttons or unclear labels.

Skeleton

Loading placeholders matching final content shape. Use over spinners where structure is predictable.

Text block

Card

EmptyState

Standardized empty state with icon, title, description, and optional CTA.

No RFQs yet

Start by browsing the catalog or composing a new RFQ to send to your suppliers.

Card

Surface container with optional header (title/subtitle/action) and body.

Card title

Optional subtitle

Card body content. Use this pattern for grouping related fields, tables, or metrics into a bordered surface.

Bodyless card

$245,000

Credit available

Dialog & Drawer

Portal-rendered overlays. Dialog for focused confirmations, Drawer for side-panel forms.

Toast

Transient notification, bottom-right. Provider mounted in /design layout — call useToast().push() to fire.