☰ 분류

컴포넌트 문서화 프롬프트

토큰 시스템, 컴포넌트명, 프레임워크를 넣으면 AI 코딩 도구가 따를 수 있는 CLAUDE.md용 컴포넌트 명세를 Markdown으로 작성합니다.

분류개발 › 기술 문서
태그초안작성개발자코드템플릿
프롬프트 (영어 본문 · 답은 한국어로 옵니다)
You are a design systems documentarian creating the component specification
for a CLAUDE.md file. This documentation will be used by AI coding assistants
(Claude, Cursor, Copilot) to generate consistent UI code.

## Context
- **Token system:** [Paste or reference Phase 2 output]
- **Component to document:** [Component name, or "all components from inventory"]
- **Framework:** [Next.js + React + Tailwind / etc.]

## For Each Component, Document:

### 1. Overview
- Component name (PascalCase)
- One-line description
- Category (Navigation / Input / Feedback / Layout / Data Display)

### 2. Anatomy
- List every visual part (e.g., Button = container + label + icon-left + icon-right)
- Which parts are optional vs required
- Nesting rules (what can/cannot go inside this component)

### 3. Props Specification
For each prop:
- Name, type, default value, required/optional
- Allowed values (if enum)
- Brief description of what it controls visually
- Example usage

### 4. Visual Variants
- Size variants with exact token values (padding, font-size, height)
- Color variants with exact token references
- State variants: default, hover, active, focus, disabled, loading, error
- For EACH state: specify which tokens change and to what values

### 5. Token Consumption Map
Component: Button
├── background → button-bg-${variant} → color-brand-${shade}
├── text-color → button-text-${variant} → color-white
├── padding-x → button-padding-x-${size} → spacing-{n}
├── padding-y → button-padding-y-${size} → spacing-{n}
├── border-radius → button-radius → radius-md
├── font-size → button-font-${size} → font-size-{n}
├── font-weight → button-font-weight → font-weight-semibold
└── transition → motion-duration-fast + motion-ease-default

### 6. Usage Guidelines
- When to use (and when NOT to use — suggest alternatives)
- Maximum instances per viewport (e.g., "only 1 primary CTA per section")
- Content guidelines (label length, capitalization, icon usage)

### 7. Accessibility
- Required ARIA attributes
- Keyboard interaction pattern
- Focus management rules
- Screen reader behavior
- Minimum contrast ratios met by default tokens

### 8. Code Example
Provide a copy-paste-ready code example using the actual codebase's
patterns (import paths, className conventions, etc.)

## Output Format

Markdown, structured with headers per section. This will be directly
inserted into the CLAUDE.md file.

어떤 프롬프트인가

디자인 시스템 컴포넌트의 사용 규칙과 구현 예시를 문서화할 때 좋다. 구조, props, 상태별 토큰, 접근성, 코드 예시를 실제 코드베이스 패턴에 맞춰 요구한다.

모델 비교

ChatGPT가 가장 완전하고 입력 토큰에도 충실하다. Gemini는 구성은 좋지만 부정확하고 미완성이며, [C]는 제출되지 않았다.

ChatGPT종합 1위
43/ 50

+ 요구된 8개 섹션과 토큰 매핑을 충실히 구현했다.

- Slot 링크에 disabled를 전달하는 코드와 일부 미정 토큰이 문제다.

Gemini
29/ 50

+ 표와 상태 매트릭스로 세부 규칙을 찾기 쉽게 구성했다.

- 코드가 중간에 끊겼고 없는 색상 토큰과 잘못된 대비값을 만들었다.

기준ChatGPTGemini앞선 모델
지시 준수95ChatGPT +80%
정확성85ChatGPT +60%
구체성97ChatGPT +29%
구성·가독성98ChatGPT +13%
분량 적정성84ChatGPT +100%

gpt-5.6-sol가 모델 이름을 가린 채 1~10점으로 채점했습니다 (2026-09-24). 측정값이 아니라 AI 심사 결과입니다.

답 전문 보기

같은 입력을 세 모델에 넣어 받은 답을 그대로 옮겼습니다. 각 CLI(에이전트 하네스)에서 실행했습니다. ChatGPT·Claude 앱이나 웹에서는 답이 다를 수 있습니다.

넣은 입력
[붙여 넣은 자료]
Token system (Phase 2 산출물):
- color-brand-500: #2563EB, color-brand-600: #1D4ED8
- spacing-1~8: 4px 단위로 4px~32px
- radius-md: 8px, radius-lg: 12px
- font-size-sm/base/lg: 14px/16px/18px

Component to document: Button
Framework: Next.js 14 + React + TailwindCSS (shadcn/ui 기반)
gpt-5.6-luna (codex CLI · 에이전트 하네스) · 실행일 2026-09-24

Button

1. 개요

  • 컴포넌트명: Button
  • 설명: 사용자의 작업을 실행하거나 다음 단계로 이동시키는 클릭 가능한 액션 컨트롤
  • 카테고리: Input / Navigation

기본 프레임워크는 Next.js 14, React, TailwindCSS, shadcn/ui의 cva 및 Slot 패턴을 따른다.


2. Anatomy

Button
├── interactive container
├── icon-left      optional
├── label          required, icon-only일 때는 visually hidden 가능
├── icon-right     optional
└── loading indicator optional

필수 요소

  • 클릭 가능한 컨테이너
  • 일반 버튼인 경우 visible label
  • 아이콘만 사용하는 경우 aria-label 또는 sr-only 접근성 이름

선택 요소

  • 왼쪽 아이콘
  • 오른쪽 아이콘
  • 로딩 스피너
  • 키보드 단축키 표시

Nesting rules

  • 기본적으로 텍스트, 아이콘, 로딩 인디케이터만 포함한다.
  • 버튼 안에 다른 <button>, <a>, 입력 필드 또는 인터랙티브 요소를 중첩하지 않는다.
  • 링크 이동이 목적이면 Button보다 Link를 사용한다.
  • asChild 사용 시 단일 React element만 자식으로 전달한다.

3. Props Specification

Prop Type Default Required 설명
variant "default" | "outline" | "ghost" | "destructive" "default" Optional 버튼의 색상 및 시각적 강조 수준
size "sm" | "default" | "lg" | "icon" "default" Optional 버튼의 높이, 패딩, 글자 크기
asChild boolean false Optional 자식 요소의 태그와 동작을 유지하면서 Button 스타일을 적용
loading boolean false Optional 로딩 상태 표시 및 중복 클릭 방지
disabled boolean false Optional 버튼 비활성화
className string undefined Optional 추가 Tailwind 클래스
children React.ReactNode — Required 버튼 내용
type "button" | "submit" | "reset" "button" Optional 폼 내 버튼의 동작
aria-label string undefined Conditional 아이콘 전용 버튼의 접근성 이름

사용 예시

<Button variant="default" size="default">
  저장
</Button>

<Button variant="outline" loading>
  저장 중
</Button>

<Button size="icon" aria-label="설정 열기">
  <Settings className="size-4" />
</Button>

<Button asChild>
  <Link href="/settings">설정</Link>
</Button>

4. Visual Variants

Size variants

Size Height Padding X Padding Y Font size 아이콘
sm 32px spacing-3 = 12px spacing-2 = 8px font-size-sm = 14px 16px
default 40px spacing-4 = 16px spacing-2 = 8px font-size-base = 16px 16px
lg 48px spacing-6 = 24px spacing-3 = 12px font-size-lg = 18px 20px
icon 40px 0px 0px — 16px
  • border-radius: radius-md = 8px
  • font-weight: font-weight-semibold = 600
  • gap: spacing-2 = 8px
  • transition: motion-duration-fast + motion-ease-default

Color variants

Variant Default Hover Active Text
default color-brand-500 = #2563EB color-brand-600 = #1D4ED8 color-brand-600 = #1D4ED8 color-white
outline transparent + color-brand-500 border color-brand-500 background color-brand-600 background color-brand-600
ghost transparent color-brand-500 at 10% opacity color-brand-500 at 15% opacity color-brand-600
destructive color-error-500 color-error-600 color-error-600 color-white

destructive와 ghost에 필요한 color-error-*, 투명도 토큰은 Phase 2 토큰 시스템에 추가하거나 프로젝트의 기존 semantic token으로 매핑한다.

State variants

State 변경 토큰
Default button-bg-{variant}, button-text-{variant}, button-radius, size별 padding/font
Hover 배경을 color-brand-600으로 변경. outline은 color-brand-500 배경으로 변경
Active 배경을 color-brand-600으로 변경하고 transform: translateY(1px) 적용 가능
Focus-visible ring-width-2, ring-color-brand-500, ring-offset-2 적용
Disabled opacity-50, cursor-not-allowed, hover/active 스타일 제거
Loading 기존 label의 시각적 투명도 감소, loading-indicator 표시, 클릭 방지
Error color-error-* border/background/text 및 aria-invalid="true" 적용

로딩 상태에서는 disabled와 동일하게 키보드 및 포인터 입력을 차단한다.


5. Token Consumption Map

Button
├── background
│   └── button-bg-${variant}
│       ├── default → color-brand-500
│       └── hover/active → color-brand-600
├── text-color
│   └── button-text-${variant}
│       ├── default → color-white
│       └── outline/ghost → color-brand-600
├── border-color
│   └── button-border-${variant}
│       └── outline → color-brand-500
├── padding-x
│   └── button-padding-x-${size}
│       ├── sm → spacing-3
│       ├── default → spacing-4
│       └── lg → spacing-6
├── padding-y
│   └── button-padding-y-${size}
│       ├── sm/default → spacing-2
│       └── lg → spacing-3
├── height
│   ├── sm → 32px
│   ├── default/icon → 40px
│   └── lg → 48px
├── border-radius
│   └── button-radius → radius-md
├── font-size
│   ├── sm → font-size-sm
│   ├── default → font-size-base
│   └── lg → font-size-lg
├── font-weight
│   └── button-font-weight → font-weight-semibold
├── icon-size
│   ├── sm/default → 16px
│   └── lg → 20px
└── transition
    └── motion-duration-fast + motion-ease-default

6. Usage Guidelines

사용해야 하는 경우

  • 저장, 제출, 삭제, 추가, 확인 등 명확한 액션
  • 모달의 확인/취소 동작
  • 사용자를 다음 화면으로 이동시키는 주요 CTA

사용하지 않아야 하는 경우

  • 단순 페이지 이동: Link 사용
  • 여러 옵션 중 하나를 선택: Select, RadioGroup, Tabs 사용
  • 즉시 실행이 아닌 메뉴 열기: DropdownMenuTrigger 사용
  • 긴 설명이나 문장이 필요한 경우: 버튼 라벨을 짧게 유지하고 설명은 주변 텍스트로 분리

인스턴스 제한

  • 한 화면 또는 주요 섹션에는 default 스타일의 Primary CTA를 최대 1개만 둔다.
  • 모달에는 Primary CTA 1개와 Secondary/Cancel 액션 1개를 권장한다.
  • 같은 영역에 동일한 강조도의 버튼을 3개 이상 배치하지 않는다.

콘텐츠 가이드

  • 라벨은 동사 중심으로 작성한다: 저장, 계속, 초대 보내기
  • 문장 첫 글자만 대문자로 처리하고, 전체 대문자는 사용하지 않는다.
  • 기본 라벨은 1~3단어, 최대 20자 이내를 권장한다.
  • 아이콘만 사용하는 버튼에는 반드시 aria-label을 제공한다.
  • 아이콘은 의미를 보조할 때만 사용하며, 텍스트보다 크게 만들지 않는다.
  • 삭제, 결제, 전송처럼 결과가 중요한 작업은 명확한 동사를 사용한다.

7. Accessibility

ARIA attributes

  • 일반 버튼은 native <button>을 사용하므로 별도의 role="button"을 추가하지 않는다.
  • 아이콘 전용 버튼은 aria-label을 필수로 제공한다.
  • 로딩 중에는 aria-busy="true"를 제공한다.
  • 오류 상태인 경우 aria-invalid="true"를 제공할 수 있다.
  • 버튼이 특정 영역을 열거나 닫으면 aria-expanded 및 aria-controls를 사용한다.
  • disabled 상태는 native disabled 속성을 우선 사용한다.

Keyboard interaction

  • Tab: 버튼으로 이동
  • Enter 또는 Space: 버튼 실행
  • Shift + Tab: 이전 포커스 가능 요소로 이동
  • disabled 버튼은 포커스 및 실행 대상에서 제외한다.
  • asChild로 링크를 렌더링하는 경우 링크의 기본 키보드 동작을 유지한다.

Focus management

  • :focus-visible에서만 focus ring을 표시한다.
  • 기본 focus ring은 ring-width-2, ring-color-brand-500, ring-offset-2를 사용한다.
  • 모달 내부 버튼을 클릭한 뒤 모달이 닫히면 트리거 버튼으로 포커스를 반환한다.
  • 버튼을 클릭해 새 콘텐츠가 표시되는 경우 새 콘텐츠의 첫 번째 의미 있는 요소로 포커스를 이동한다.

Screen reader behavior

  • visible label이 있으면 해당 텍스트를 accessible name으로 사용한다.
  • 아이콘 전용 버튼의 아이콘에 aria-hidden="true"를 설정하고 버튼에 aria-label을 지정한다.
  • 로딩 상태에서도 accessible name은 유지한다. 예: 저장 → 저장 중.
  • 스피너만으로 상태를 전달하지 않는다.

Contrast

  • color-brand-500(#2563EB) + color-white: 약 5.17:1
  • color-brand-600(#1D4ED8) + color-white: 약 6.70:1
  • 일반 텍스트 및 버튼 라벨은 WCAG AA 기준 4.5:1 이상을 충족한다.
  • 큰 텍스트 기준은 3:1 이상을 충족해야 한다.
  • disabled 상태는 WCAG 대비 요구사항의 예외가 될 수 있으나, 상태 구분을 opacity만으로 전달하지 않는다.

8. Code Example

프로젝트의 일반적인 shadcn/ui 구조에서는 @/components/ui/button 경로를 사용한다.

// components/ui/button.tsx
"use client"

import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"
import { Loader2 } from "lucide-react"

import { cn } from "@/lib/utils"

const buttonVariants = cva(
  [
    "inline-flex items-center justify-center gap-2 whitespace-nowrap",
    "rounded-[8px] text-center font-semibold",
    "transition-colors duration-150 ease-out",
    "focus-visible:outline-none focus-visible:ring-2",
    "focus-visible:ring-[#2563EB] focus-visible:ring-offset-2",
    "disabled:pointer-events-none disabled:opacity-50",
    "[&_svg]:pointer-events-none [&_svg]:shrink-0",
  ],
  {
    variants: {
      variant: {
        default:
          "bg-[#2563EB] text-white hover:bg-[#1D4ED8] active:bg-[#1D4ED8]",
        outline:
          "border border-[#2563EB] bg-transparent text-[#1D4ED8] hover:bg-[#2563EB] hover:text-white",
        ghost:
          "bg-transparent text-[#1D4ED8] hover:bg-[#2563EB]/10 active:bg-[#2563EB]/15",
        destructive:
          "bg-error-500 text-white hover:bg-error-600 active:bg-error-600",
      },
      size: {
        sm: "h-8 px-3 py-2 text-sm [&_svg]:size-4",
        default: "h-10 px-4 py-2 text-base [&_svg]:size-4",
        lg: "h-12 px-6 py-3 text-lg [&_svg]:size-5",
        icon: "size-10 [&_svg]:size-4",
      },
    },
    defaultVariants: {
      variant: "default",
      size: "default",
    },
  }
)

type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> &
  VariantProps<typeof buttonVariants> & {
    asChild?: boolean
    loading?: boolean
  }

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
  (
    {
      className,
      variant,
      size,
      asChild = false,
      loading = false,
      disabled,
      children,
      ...props
    },
    ref
  ) => {
    const Comp = asChild ? Slot : "button"

    return (
      <Comp
        ref={ref}
        className={cn(buttonVariants({ variant, size, className }))}
        disabled={disabled || loading}
        aria-busy={loading || undefined}
        {...props}
      >
        {loading && <Loader2 className="size-4 animate-spin" aria-hidden="true" />}
        <span className={loading ? "opacity-80" : undefined}>{children}</span>
      </Comp>
    )
  }
)

Button.displayName = "Button"

export { Button, buttonVariants }

사용 예시

import Link from "next/link"
import { Settings } from "lucide-react"

import { Button } from "@/components/ui/button"

export function ExampleActions() {
  return (
    <div className="flex items-center gap-2">
      <Button>저장</Button>

      <Button variant="outline">취소</Button>

      <Button variant="ghost" size="icon" aria-label="설정 열기">
        <Settings aria-hidden="true" />
      </Button>

      <Button asChild>
        <Link href="/dashboard">대시보드로 이동</Link>
      </Button>
    </div>
  )
}

color-error-500, color-error-600, motion-duration-fast, motion-ease-default가 아직 토큰 시스템에 없다면 프로젝트의 기존 semantic token으로 연결하거나 Phase 2 토큰에 추가한다.

같은 분류의 프롬프트

FTTH 통신 전문가 역할을 맡기는 프롬프트
개발자 아키텍처 안내 프롬프트
LLM 입문서 작성 프롬프트
프로그래밍 팀 구성 프롬프트
CLAUDE.md 조립 프롬프트