Advanced

Cara Build a Design System dengan Claude Code

Pelajari cara build a design system menggunakan Claude Code. Dilengkapi contoh kode praktis dan panduan langkah demi langkah.

デザインsistempembangunan dengan Claude Code: efisiensi

デザインsistem pembangunan 、token設計、komponenimplementasi、dokumen整備 dan 多く 作業 伴い.Claude Code 使えば、一貫性 adaデザインsistem 体系的 pembangunan bisa dilakukan.

Definisi Design Token

Pertama-tama 色、font、スペーシング dll. デザインtoken definisi.

> Tailwind CSSvariabelベース dengan デザインtoken definisiして。
> ライトモード dan ダークモード両dukungan.
// 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;

implementasi dasarkomponen

Buttonkomponen variantdukungan 作り.

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";

Inputkomponen

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";

Untuk ダークモードdukunganについてはダークモードimplementasiを、animasipenambahanはanimasiimplementasiをご覧ください。Claude Codeの効果的な使い方, lihat 生産性を3倍にする10のTips.

Summary

Dengan Claude Code, デザインtoken definisi dari komponenimplementasi、variant設計ま 、デザインsistem fondasi efisien pembangunan bisa dilakukan.CVA 使ったvariantmanajemenやアクセシビリティdukungan juga 自然言語 指示 だけ.

Untuk detail lebih lanjut, lihat Dokumentasi Resmi Claude Code.

#Claude Code #design system #components #Storybook #UI