--- name: ui description: 컴포넌트, 스크린, 네비게이션, 스타일링 type: generic --- # UI Domain ## 목적 / 책임 React Native UI 컴포넌트, 스크린, 네비게이션, 스타일링을 담당한다. ## 포함 경로 - `app/components/` - 재사용 컴포넌트 - `app/screens/` - 화면 단위 컴포넌트 - `app/hooks/` - 공통 React hooks - `app/utils/` - UI 유틸리티 - `share_extension/` - Android 공유 확장 (React Navigation 사용) ## 제외 경로 - `app/products/*/components/` (각 product 도메인) - `app/actions/` (비즈니스 로직은 messaging/product 도메인) ## 주요 구성 요소 - **Navigation**: `react-native-navigation` v7 (메인 앱), `React Navigation` (share extension) - **Components**: 60+ 재사용 컴포넌트 - **Screens**: 63+ 화면 컴포넌트 (각각 독립 등록) - **Themes**: `PREFERENCES.THEMES` 상수 사용 ## 유지할 패턴 - `Pressable` 사용 (→ `TouchableOpacity` 금지), 항상 pressed 피드백 추가 - `typography()` 사용 (→ raw `fontSize`/`fontWeight`/`fontFamily` 금지) - `makeStyleSheetFromTheme` 사용 시 `StyleSheet.create` 불필요 - `getStyleSheet` 는 파일 상단(imports 이후)에 위치 - 정적 객체(hitSlop 등)는 모듈 레벨 상수로 추출 - `FormattedText` 사용 (→ `{intl.formatMessage(...)}` 지양) - `useServerUrl()` hook 사용 (→ `serverUrl` prop 전달 지양) - `usePreventDoubleTap` hook 사용 (버튼 중복 클릭 방지) - 리스트 렌더링: 인라인 화살표 함수 금지, 자식 컴포넌트에서 ID 받아 처리 - `useDidMount` (→ `useEffect(cb, [])` 대신), `useInitialValue` (→ `useMemo(f, [])` 대신) ## 다른 도메인과의 경계 - **messaging/product 도메인**: UI는 데이터 표시만, 비즈니스 로직은 해당 도메인 - **database 도메인**: `observe*` 쿼리를 통해 반응형 데이터 구독 ## 금지 사항 - `TouchableOpacity` 사용 - raw `fontSize`, `fontWeight`, `fontFamily` 스타일 직접 사용 - `Object.hasOwn()` 사용 (ES2022+, RN 미지원 → `'key' in obj` 사용) - `Animated` API 사용 (→ `react-native-reanimated` 사용) - `new URL()` 사용 (→ `urlParse` 사용) - `Linking.openURL()` 직접 사용 (→ `tryOpenURL()` 사용) - `ActivityIndicator` 직접 사용 (→ `` 컴포넌트 사용) - 커스텀 React 컴포넌트를 Markdown 컴포넌트 내부에 인라인 삽입