# Pressable

React Native의 Pressable에 Android 눌림 물결(ripple)을 더한 기본 눌림 영역이다. 앱의 모든 버튼이 이것을 쓴다.

- 분류: 버튼
- 가져오기: `import { Pressable } from '@/ui/Pressable'`
- 코드 위치: `apps/mobile/src/ui/Pressable.tsx:41` (Mordy 저장소 60df633)
- 웹 페이지: https://developers.moring.co/tds/components/pressable

## 미리보기

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

## 언제 쓰는가

### 쓴다
- 직접 눌리는 새 컴포넌트를 만들 때 React Native의 `Pressable` 대신 이것을 가져와 쓴다.
- 물결을 끄고 싶은 곳(배경 가림막)에는 `ripple={false}`를 쓴다.

### 쓰지 않는다
- React Native의 `Pressable`을 직접 가져오지 않는다. Android에서 눌림 표시가 빠진다.
- 눌림 표시를 `opacity`로만 처리하지 않는다. Android에서는 이 컴포넌트가 물결로 대신하고 `opacity`와 배경색 변화를 지운다.

## 종류

| 이름 | 설명 |
| --- | --- |
| auto (기본) | 눌리는 영역 안에서만 퍼지는 물결. 아이콘만 있는 컨트롤(배경 없음, `hitSlop` 있음)은 원형으로 퍼진다. 배경이 어두운 색이면 흰 물결이다. |
| light | 흰 물결을 면 앞쪽에 그린다. 그라데이션이나 사진 위의 컨트롤에 쓴다. |
| borderless | 반지름 22의 원형 물결. 머티리얼 아이콘 버튼 모양이다. |
| false | 물결을 그리지 않는다. 화면을 덮는 배경, 감싸기용 영역에 쓴다. |

## 크기

크기는 없다. 자식과 `style`이 정한다.

## 상태

| 상태 | 모습과 동작 |
| --- | --- |
| Android | 눌리는 동안 물결이 퍼진다. 색은 흰 물결 `rgba(255,255,255,0.26)`(채운 면 위), 밝은 모드에서 `rgba(17,24,39,0.09)`, 어두운 모드에서 `rgba(255,255,255,0.14)`. |
| iOS와 웹 | 물결이 없다. `style`에 넘긴 누름 상태 스타일(`pressed`)이 그대로 쓰인다. |

## 사용 방법

### 새 눌림 영역

```tsx
import { Pressable } from '@/ui/Pressable';

<Pressable
  onPress={open}
  accessibilityRole="button"
  style={({ pressed }) => [styles.row, pressed && { backgroundColor: color.pressed }]}
>
  {/* 내용 */}
</Pressable>
```

### 물결 끄기

```tsx
<Pressable ripple={false} style={{ flex: 1 }} onPress={onClose} accessibilityLabel="닫기" />
```

### 속성(props)

| 이름 | 타입 | 기본값 | 필수 | 설명 |
| --- | --- | --- | --- | --- |
| `ripple` | `Ripple` | `'auto'` | 선택 | 물결의 종류. `"auto"`(기본), `"light"`, `"borderless"`, `false`. |
| `android_ripple` | `(React Native)` | — | 선택 | Android 물결 설정을 직접 넘긴다. 넘기면 `ripple` 설정보다 우선한다. |
| `style` | `(React Native)` | — | 선택 | React Native의 `Pressable`과 같다. 객체, 배열, 또는 `({ pressed }) => 스타일` 함수. |

나머지 속성은 `PressableProps`를 그대로 받는다.

위에 적지 않은 나머지 속성(`onPress`, `hitSlop`, `disabled`, `accessibilityRole` 등)은 React Native의 `PressableProps`를 그대로 받는다.

## 치수와 토큰

| 항목 | 값 |
| --- | --- |
| 물결(채운 면 위) | rgba(255,255,255,0.26) |
| 물결(밝은 모드) | rgba(17,24,39,0.09) |
| 물결(어두운 모드) | rgba(255,255,255,0.14) |
| 원형 물결 반지름 | 22 |
| "어두운 배경" 판정 | 배경색 밝기(0.2126R+0.7152G+0.0722B)가 0.55 미만 |

## 접근성

- `onPress`가 있고 `disabled`가 아닐 때만 물결이 켜진다.
- 눌리는 영역에는 `accessibilityRole`과 이름(`accessibilityLabel` 또는 안의 글자)을 둔다.

## 잘한 예와 잘못한 예

- 잘한 예: 눌림 표시는 배경색 변화로 쓰고, Android 물결은 이 컴포넌트에 맡긴다.
- 잘못한 예: `opacity`를 줄여 누름을 나타내면 Android에서는 지워진다. 눌림 표시가 두 번 나타나지 않게 `Pressable`을 쓴다.

## 함께 보는 컴포넌트

- [IconButton](https://developers.moring.co/tds/components/icon-button.md): 아이콘 하나만 있는 투명한 둥근 버튼이다. 헤더의 "뒤로", "검색"에 쓴다.
- [PrimaryButton](https://developers.moring.co/tds/components/primary-button.md): 서비스 주색 그라데이션으로 채운 알약 모양 버튼이다. 한 화면에서 가장 중요한 행동 하나에 쓴다.
