Comment construire un système de design avec Claude Code
Découvrez comment construire un système de design avec Claude Code. Conseils pratiques et exemples de code inclus.
デザインシステム構築をClaude Codeで効率化する
デザインシステムの構築は、トークン設計、コンポーネント実装、ドキュメント整備と多くの作業が伴います。Claude Codeを使えば、一貫性のあるデザインシステムを体系的に構築できます。
デザイントークンの定義
まずは色、フォント、スペーシングなどのデザイントークンを定義します。
> TailwindのCSS変数ベースでデザイントークンを定義して。
> ライトモードとダークモード両対応にして。
// tokens/colors.ts
export const colors = {
primary: {
50: "oklch(0.97 0.01 250)",
100: "oklch(0.93 0.03 250)",
200: "oklch(0.86 0.06 250)",
300: "oklch(0.76 0.10 250)",
400: "oklch(0.66 0.15 250)",
500: "oklch(0.55 0.20 250)",
600: "oklch(0.47 0.20 250)",
700: "oklch(0.39 0.18 250)",
800: "oklch(0.33 0.15 250)",
900: "oklch(0.27 0.12 250)",
},
gray: {
50: "oklch(0.98 0.00 0)",
100: "oklch(0.96 0.00 0)",
200: "oklch(0.91 0.00 0)",
300: "oklch(0.83 0.00 0)",
400: "oklch(0.71 0.00 0)",
500: "oklch(0.55 0.00 0)",
600: "oklch(0.45 0.00 0)",
700: "oklch(0.37 0.00 0)",
800: "oklch(0.27 0.00 0)",
900: "oklch(0.18 0.00 0)",
},
} as const;
// tokens/spacing.ts
export const spacing = {
xs: "0.25rem", // 4px
sm: "0.5rem", // 8px
md: "1rem", // 16px
lg: "1.5rem", // 24px
xl: "2rem", // 32px
"2xl": "3rem", // 48px
"3xl": "4rem", // 64px
} as const;
// tokens/typography.ts
export const typography = {
fontFamily: {
sans: '"Noto Sans JP", system-ui, sans-serif',
mono: '"JetBrains Mono", monospace',
},
fontSize: {
xs: ["0.75rem", { lineHeight: "1rem" }],
sm: ["0.875rem", { lineHeight: "1.25rem" }],
base: ["1rem", { lineHeight: "1.5rem" }],
lg: ["1.125rem", { lineHeight: "1.75rem" }],
xl: ["1.25rem", { lineHeight: "1.75rem" }],
"2xl": ["1.5rem", { lineHeight: "2rem" }],
"3xl": ["1.875rem", { lineHeight: "2.25rem" }],
},
} as const;
基本コンポーネントの実装
Buttonコンポーネントをバリアント対応で作ります。
import { type ButtonHTMLAttributes, forwardRef } from "react";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
const buttonVariants = cva(
"inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
primary: "bg-primary-600 text-white hover:bg-primary-700",
secondary: "bg-gray-100 text-gray-900 hover:bg-gray-200",
outline: "border border-gray-300 bg-transparent hover:bg-gray-50",
ghost: "hover:bg-gray-100",
danger: "bg-red-600 text-white hover:bg-red-700",
},
size: {
sm: "h-8 px-3 text-sm",
md: "h-10 px-4 text-sm",
lg: "h-12 px-6 text-base",
},
},
defaultVariants: {
variant: "primary",
size: "md",
},
}
);
export interface ButtonProps
extends ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
isLoading?: boolean;
}
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, isLoading, children, disabled, ...props }, ref) => {
return (
<button
ref={ref}
className={cn(buttonVariants({ variant, size }), className)}
disabled={disabled || isLoading}
{...props}
>
{isLoading && (
<svg className="animate-spin -ml-1 mr-2 h-4 w-4" viewBox="0 0 24 24">
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" fill="none" />
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
</svg>
)}
{children}
</button>
);
}
);
Button.displayName = "Button";
Inputコンポーネント
import { type InputHTMLAttributes, forwardRef } from "react";
import { cn } from "@/lib/utils";
export interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
label?: string;
error?: string;
helperText?: string;
}
export const Input = forwardRef<HTMLInputElement, InputProps>(
({ className, label, error, helperText, id, ...props }, ref) => {
const inputId = id || label?.toLowerCase().replace(/\s/g, "-");
return (
<div className="space-y-1">
{label && (
<label htmlFor={inputId} className="block text-sm font-medium text-gray-700">
{label}
</label>
)}
<input
ref={ref}
id={inputId}
className={cn(
"block w-full rounded-md border px-3 py-2 text-sm shadow-sm transition-colors",
"focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-primary-500",
error ? "border-red-500" : "border-gray-300",
className
)}
aria-invalid={!!error}
aria-describedby={error ? `${inputId}-error` : undefined}
{...props}
/>
{error && (
<p id={`${inputId}-error`} className="text-sm text-red-500">{error}</p>
)}
{helperText && !error && (
<p className="text-sm text-gray-500">{helperText}</p>
)}
</div>
);
}
);
Input.displayName = "Input";
ダークモード対応についてはダークモード実装を、アニメーション追加はアニメーション実装をご覧ください。Claude Codeの効果的な使い方は生産性を3倍にする10のTipsを参照してください。
Summary
Claude Codeを使えば、デザイントークンの定義からコンポーネント実装、バリアント設計まで、デザインシステムの基盤を効率的に構築できます。CVAを使ったバリアント管理やアクセシビリティ対応も自然言語で指示するだけです。
詳しくはClaude Code公式ドキュメントを参照してください。
Passez votre flux Claude Code au niveau supérieur
50 modèles de prompts éprouvés, prêts à être copiés-collés dans Claude Code.
PDF gratuit : aide-mémoire Claude Code en 5 minutes
Commandes clés, raccourcis et exemples de prompts sur une seule page imprimable.
À propos de l'auteur
Masa
Ingénieur passionné par Claude Code. Il gère claudecode-lab.com, un média tech en 10 langues avec plus de 2 000 pages.
Articles similaires
Introduction au Claude Code Agent SDK — Construisez des agents autonomes rapidement
Apprenez à construire des agents IA autonomes avec le Claude Code Agent SDK. Configuration, définition d'outils et exécution multi-étapes avec des exemples pratiques.
Guide complet des techniques de gestion du contexte dans Claude Code
Découvrez les techniques pratiques pour maximiser la fenêtre de contexte de Claude Code. Optimisation des tokens, découpage des conversations et utilisation de CLAUDE.md.
Maîtriser les Hooks de Claude Code : Formatage automatique, tests automatiques et plus encore
Apprenez à configurer le formatage et les tests automatiques avec les hooks de Claude Code. Inclut des exemples de configuration pratiques et des cas d'utilisation concrets.