# Design System 개발 가이드

> `/gen-html` 에서 필요할 때 참고할 수 있는 디자인 시스템 컴포넌트 개발 규칙이다.

`packages/design-system/` 패키지 전용 규칙. 이 모노레포에서 디자인 시스템 컴포넌트를 개발할 때 적용한다.

패키지: `packages/design-system/`
Import: `sales-frontend-design-system`

---

## 파일 구성 세트

### 단순 컴포넌트

```
components/<name>/
├── index.ts               # public export
├── <name>.tsx             # 컴포넌트 구현
├── <name>.types.ts        # Props 타입 정의
└── <name>.module.scss     # 스타일
```

### 복합(Compound) 컴포넌트

```
components/<name>/
├── index.ts
├── <name>.tsx             # 네임스페이스 객체 export (Root, Item 등 조합)
├── <name>.types.ts
├── <name>.module.scss
├── elements/              # 서브 컴포넌트 (.tsx)
├── context/               # React Context + useContext 훅
└── hooks/                 # 상태/동작 커스텀 훅
```

### index.ts export 규칙

```typescript
// 타입과 컴포넌트 모두 named export
export * from './<name>.types';
export * from './<name>';
```

---

## TypeScript 타입 작성 규칙

### Props 정의

- Props 타입명은 `컴포넌트명 + Props` 접미사를 사용한다.
- 모든 타입/인터페이스 필드에 JSDoc 주석 필수
- `any` 금지

```typescript
/** Button 컴포넌트 Props */
export interface ButtonProps {
  /** button 종류 */
  variant: ButtonVariant;
  /** button 크기 */
  size: ButtonSize;
  /** 비활성화 여부 */
  disabled?: boolean;
}

const Button = ({ variant, size, disabled }: ButtonProps) => { ... }
```

---

## 컴포넌트 구현 규칙

### classnames/bind — className 적용 필수 패턴

```typescript
import classNames from 'classnames/bind';
import styles from './button.module.scss';

const cx = classNames.bind(styles);

// 정적
<div className={cx('button')} />

// 동적 (조건부 클래스)
<div className={cx('button', `button-${size}`, `button-${variant}`, disabled && 'is-disabled')} />

// 외부 className 병합
<div className={cx('button', className)} />
```

### Compound 컴포넌트 패턴

- 단일 컴포넌트가 여러 역할을 하는 경우 네임스페이스 객체로 export

```typescript
// 네임스페이스 객체로 export
const Accordion = {
  Root: AccordionRoot,
  Item: AccordionItem,
  HeaderButton: AccordionHeaderButton,
  Content: AccordionContent
};
export { Accordion };
```

---

## SCSS 작성 규칙

### 기본 설정

```scss
// 반드시 첫 줄에 선언
@use '../../styles/design-system-context.scss' as *;
```

### 클래스 네이밍

```
.{컴포넌트}                          // root
.{컴포넌트}-{property}-{value}       // modifier
.is-{state}                          // 상태 클래스
.ds-{컴포넌트}                       // 외부 참조용 네임스페이스
```

```scss
// 예시
.button { ... }
.button-appearance-filled { ... }
.button-size-large { ... }
.button-variant-primary { ... }
.is-disabled { cursor: not-allowed; }
```

### 토큰 함수 — 하드코딩 금지

```scss
// 색상
color: colors(text-body_1);
background-color: colors(surface-primary);

// 간격
padding: padding(large);
margin: margin(button-medium);

// 보더 라디우스
border-radius: radius-basic(medium);

// 타이포그래피
@include apply-typography(input_large);

// hover
@include hover {
  &:not(.is-disabled) {
    box-shadow: inset 100rem 100rem colors(states-dark_2);
  }
}
```

---

## 새 컴포넌트 추가 체크리스트

1. `packages/design-system/src/components/<name>/` 디렉토리 생성
2. 파일 세트 생성: `index.ts`, `<name>.tsx`, `<name>.types.ts`, `<name>.module.scss`
3. SCSS: `design-system-context.scss` import 후 토큰 함수만 사용
4. `packages/design-system/src/components/index.ts`에 `export * from './<name>'` 추가
