/install design-system-components
Design System Components
Build reusable components that leverage design tokens with Surface primitives and CVA (class-variance-authority).
When to Use
- Building component libraries with design tokens
- Need variant-based styling (size, color, state)
- Creating layered UI with consistent surfaces
- Want type-safe component APIs
Pattern 1: Surface Primitive
Single component for all layered surfaces:
import { cva, type VariantProps } from 'class-variance-authority';
import { cn } from '@/lib/utils';
const surfaceVariants = cva(
'rounded-lg backdrop-blur-sm transition-colors',
{
variants: {
layer: {
panel: 'bg-tone-cadet/40 border border-tone-jordy/10 shadow-card',
tile: 'bg-tone-midnight/60 border border-tone-jordy/5',
chip: 'bg-tone-cyan/10 border border-tone-cyan/20 rounded-full',
deep: 'bg-tone-void/80',
metric: 'bg-tone-cadet/20 border border-tone-jordy/8',
glass: 'bg-glass-bg backdrop-blur-lg border border-glass-border',
},
interactive: {
true: 'cursor-pointer hover:bg-tone-cadet/50 active:scale-[0.98]',
false: '',
},
glow: {
true: 'shadow-glow',
false: '',
},
},
defaultVariants: {
layer: 'tile',
interactive: false,
glow: false,
},
}
);
interface SurfaceProps
extends React.HTMLAttributes\x3CHTMLDivElement>,
VariantProps\x3Ctypeof surfaceVariants> {}
export function Surface({
layer,
interactive,
glow,
className,
...props
}: SurfaceProps) {
return (
\x3Cdiv
className={cn(surfaceVariants({ layer, interactive, glow }), className)}
{...props}
/>
);
}
Usage
\x3CSurface layer="panel" className="p-4">
\x3Ch2>Dashboard\x3C/h2>
\x3C/Surface>
\x3CSurface layer="chip" interactive>
\x3Cspan>Active\x3C/span>
\x3C/Surface>
\x3CSurface layer="metric" glow>
\x3Cspan className="text-2xl">$1,234.56\x3C/span>
\x3C/Surface>
Pattern 2: CVA Button Variants
const buttonVariants = cva(
'inline-flex items-center justify-center rounded-md font-medium transition-all focus-visible:outline-none focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50',
{
variants: {
variant: {
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
ghost: 'hover:bg-accent hover:text-accent-foreground',
link: 'text-primary underline-offset-4 hover:underline',
cyber: 'bg-gradient-to-r from-tone-cadet to-tone-azure text-white border border-tone-cyan/30 shadow-glow hover:shadow-glow-lg',
},
size: {
default: 'h-10 px-4 py-2',
sm: 'h-9 rounded-md px-3',
lg: 'h-11 rounded-md px-8',
icon: 'h-10 w-10',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
}
);
Pattern 3: Metric Display Component
const metricVariants = cva(
'font-mono tabular-nums',
{
variants: {
size: {
lg: 'text-3xl font-bold tracking-tight',
md: 'text-xl font-semibold',
sm: 'text-base font-medium',
},
trend: {
positive: 'text-success',
negative: 'text-destructive',
neutral: 'text-foreground',
},
},
defaultVariants: {
size: 'md',
trend: 'neutral',
},
}
);
interface MetricProps extends VariantProps\x3Ctypeof metricVariants> {
value: string | number;
label?: string;
prefix?: string;
suffix?: string;
}
export function Metric({
value,
label,
prefix = '',
suffix = '',
size,
trend,
}: MetricProps) {
return (
\x3Cdiv className="flex flex-col">
{label && (
\x3Cspan className="text-xs uppercase tracking-wider text-muted-foreground mb-1">
{label}
\x3C/span>
)}
\x3Cspan className={cn(metricVariants({ size, trend }))}>
{prefix}{value}{suffix}
\x3C/span>
\x3C/div>
);
}
Pattern 4: Card with Header
interface CardProps {
title?: string;
description?: string;
action?: React.ReactNode;
children: React.ReactNode;
}
export function Card({ title, description, action, children }: CardProps) {
return (
\x3CSurface layer="panel" className="flex flex-col">
{(title || action) && (
\x3Cdiv className="flex items-center justify-between px-4 py-3 border-b border-tone-jordy/10">
\x3Cdiv>
{title && (
\x3Ch3 className="font-display text-sm font-medium">{title}\x3C/h3>
)}
{description && (
\x3Cp className="text-xs text-muted-foreground">{description}\x3C/p>
)}
\x3C/div>
{action}
\x3C/div>
)}
\x3Cdiv className="p-4">{children}\x3C/div>
\x3C/Surface>
);
}
Pattern 5: Badge/Chip Variants
const badgeVariants = cva(
'inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium transition-colors',
{
variants: {
variant: {
default: 'bg-primary/10 text-primary border border-primary/20',
success: 'bg-success/10 text-success border border-success/20',
warning: 'bg-warning/10 text-warning border border-warning/20',
destructive: 'bg-destructive/10 text-destructive border border-destructive/20',
outline: 'border border-input text-foreground',
},
},
defaultVariants: {
variant: 'default',
},
}
);
Pattern 6: Composing Variants
Combine CVA with conditional classes:
function StatusIndicator({
status,
size = 'md'
}: {
status: 'online' | 'offline' | 'away';
size?: 'sm' | 'md' | 'lg';
}) {
const sizeClasses = {
sm: 'size-2',
md: 'size-3',
lg: 'size-4',
};
const statusClasses = {
online: 'bg-success animate-pulse',
offline: 'bg-muted-foreground',
away: 'bg-warning',
};
return (
\x3Cspan
className={cn(
'rounded-full',
sizeClasses[size],
statusClasses[status]
)}
/>
);
}
Related Skills
- Meta-skill: ai/skills/meta/design-system-creation/ — Complete design system workflow
- distinctive-design-systems — Token architecture and aesthetic foundations
- loading-state-patterns — Skeleton components for loading states
NEVER Do
- Build custom card containers — Use Surface primitive
- Hardcode colors in components — Use design tokens
- Skip variant types — CVA provides type safety
- Mix styling approaches — Pick CVA or cn(), not random inline styles
- Forget default variants — Components should work without props
Quick Reference
// 1. Define variants with CVA
const variants = cva('base-classes', {
variants: {
size: { sm: '...', md: '...', lg: '...' },
color: { primary: '...', secondary: '...' },
},
defaultVariants: { size: 'md', color: 'primary' },
});
// 2. Type props from variants
interface Props extends VariantProps\x3Ctypeof variants> {}
// 3. Apply in component
\x3Cdiv className={cn(variants({ size, color }), className)} />
- Make sure OpenClaw is installed (local or Docker)
- Run the install command in chat:
/install design-system-components - After installation, invoke the skill by name or use
/design-system-components - Provide required inputs per the skill's parameter spec and get structured output
What is Design System Components?
Patterns for building design system components using Surface primitives, CVA variants, and consistent styling. Use when building reusable UI components that follow design token architecture. Triggers on Surface component, CVA, class-variance-authority, component variants, design tokens. It is an AI Agent Skill for Claude Code / OpenClaw, with 1050 downloads so far.
How do I install Design System Components?
Run "/install design-system-components" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.
Is Design System Components free?
Yes, Design System Components is completely free (open-source). You can download, install and use it at no cost.
Which platforms does Design System Components support?
Design System Components is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).
Who created Design System Components?
It is built and maintained by wpank (@wpank); the current version is v1.0.0.