# ChoiceCard

카드 모양의 선택지다. 고르면 테두리가 굵어지고 체크 표시가 붙는다. 온보딩의 과목·알림 선택에 쓴다.

- 분류: 입력과 선택
- 가져오기: `import { ChoiceCard } from '@/ui/controls'`
- 코드 위치: `apps/mobile/src/ui/controls.tsx:66` (Mordy 저장소 60df633)
- 웹 페이지: https://developers.moring.co/tds/components/choice-card

## 미리보기

실제 컴포넌트를 그린 화면은 https://developers.moring.co/tds/components/choice-card 에서 볼 수 있다. 서비스 색 선택기로 Mordy, Morit 색을 바꿔 볼 수 있다.

## 언제 쓰는가

### 쓴다
- 여러 개를 고르는 선택(과목 고르기)에는 기본값 `role="checkbox"`를 쓴다.
- 하나만 고르는 선택(알림 받기/나중에)에는 `role="radio"`를 쓰고, 체크는 `check="end"`로 줄 오른쪽에 둔다.
- 선택지마다 아이콘과 두 줄 정도의 설명을 넣을 수 있다.

### 쓰지 않는다
- 퀴즈 보기에 쓰지 않는다. `OptionRow`를 쓴다.
- 선택지가 7개를 넘으면 쓰지 않는다. `OptionSheet`로 목록을 띄운다.
- 눌러도 상태가 안 바뀌는 안내 카드에 쓰지 않는다. `Card`를 쓴다.

## 종류

| 이름 | 설명 |
| --- | --- |
| corner (기본) | 체크 배지가 카드 오른쪽 위 모서리(7, 7)에 붙는다. 타일 모양에 쓴다. |
| end | 체크 배지(22)가 줄 오른쪽 끝에 놓인다. 한 줄짜리 선택지에 쓴다. |
| role | `checkbox`(여러 개) 또는 `radio`(하나). 접근성 역할만 바뀌고 모양은 같다. |

## 크기

| 이름 | 값 | 설명 |
| --- | --- | --- |
| 기본 | 안쪽 여백 14, 모서리 16 | 크기를 바꾸는 속성이 없다. 폭과 높이는 안의 내용과 `style`이 정한다. |

## 상태

| 상태 | 모습과 동작 |
| --- | --- |
| 선택 전 | `surface` 배경, 1.2px `cardBorder` 테두리. |
| 선택됨 | `selected` 배경, 1.8px `primary` 테두리, 체크 배지. |
| 누름 | 투명도 0.9. |

## 사용 방법

### 여러 개 선택

```tsx
import { ChoiceCard } from '@/ui/controls';

<ChoiceCard selected={picked.has(id)} onPress={() => toggle(id)} style={{ width: '48%' }}>
  <SubjectIcon icon="math" colorKey="blue" variant="soft" />
  <AppText variant="bodyStrong">수학</AppText>
</ChoiceCard>
```

### 하나만 선택

```tsx
<ChoiceCard role="radio" check="end" selected={choice === 'yes'} onPress={() => setChoice('yes')}>
  <AppText variant="bodyStrong">네, 알림을 받을게요</AppText>
</ChoiceCard>
```

### 속성(props)

| 이름 | 타입 | 기본값 | 필수 | 설명 |
| --- | --- | --- | --- | --- |
| `selected` | `boolean` | — | 필수 | 선택되었는지. |
| `onPress` | `() => void` | — | 필수 | 눌렀을 때 호출된다. |
| `children` | `ReactNode` | — | 필수 | 카드 안에 그릴 내용. |
| `style` | `StyleProp<ViewStyle>` | — | 선택 | 폭, 높이, 바깥 여백을 정하는 스타일. |
| `check` | `'corner' \| 'end'` | `'corner'` | 선택 | 체크 배지의 위치. `"corner"`(기본) 또는 `"end"`. |
| `role` | `'checkbox' \| 'radio'` | `'checkbox'` | 선택 | 접근성 역할. `"checkbox"`(기본) 또는 `"radio"`. |

## 치수와 토큰

| 항목 | 값 |
| --- | --- |
| 모양 | 모서리 `radius.lg`(16), 안쪽 여백 14 |
| 선택 전 | `surface` 배경, 1.2px `cardBorder` |
| 선택됨 | `selected` 배경, 1.8px `primary` |
| 체크 배지 | corner 20px(오른쪽 위 7·7), end 22px, `primary` 원, 흰 체크 12px 선 3.2 |

## 접근성

- 역할은 `checkbox` 또는 `radio`, 상태는 `checked`(checkbox) 또는 `selected`(radio)다.
- 선택은 테두리 굵기, 배경색, 체크 배지로 함께 나타내므로 색만으로 구분하지 않는다.
- 앱은 터치 화면이라 마우스 올림(hover)이 없다. 웹에서는 포커스 링(2.5px 실선, 바깥 3px)을 직접 그린다. 이 문서의 미리보기에는 포커스 링이 그려져 있다.

### 글자 색 대비

| 쓰임 | 글자색 | 바탕 | Mordy 라이트 | Mordy 다크 | Morit 라이트 | Morit 다크 | 기준 |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 체크 배지 아이콘 | `onPrimary` | `primary` | 3.93:1 통과 | 3.31:1 통과 | 4.60:1 통과 | 7.25:1 통과 | 3:1 |

## 잘한 예와 잘못한 예

- 잘한 예: 하나만 고르는 선택에는 `radio`로 지정한다.
- 잘못한 예: 선택했는지 테두리만 바뀌고 체크 배지가 없으면 색을 구분하기 어렵다. `ChoiceCard`를 직접 흉내 내지 않는다.

## 함께 보는 컴포넌트

- [OptionRow](https://developers.moring.co/tds/components/option-row.md): 퀴즈 보기 한 줄이다. 고르기 전, 고른 뒤, 채점 뒤(정답, 오답)의 모습이 정해져 있다.
- [RadioMark](https://developers.moring.co/tds/components/radio-mark.md): 선택 목록 행의 끝에 놓는 동그란 라디오 표시다. 시트의 선택 목록에서 쓴다.
- [OptionSheet](https://developers.moring.co/tds/components/option-sheet.md): 시트 안에서 목록 중 하나를 고르는 컴포넌트다. 행마다 라디오 표시가 있고, 고르면 바로 닫힌다.
