docs: 반응형 설계 리뷰 피드백 반영
- 라우트 경로 수정 (/lab/music→/music, /blog-marketing→/blog-lab 등) - /realestate/property 미등록 라우트 제외, 실제 14개 뷰로 정정 - breakpoint 예외 목록 명시 (420/520/700px) - 사이드바→바텀네비 마이그레이션 상세 계획 추가 - react-swipeable 경량 라이브러리 활용 명시 - 미니플레이어+바텀네비 스태킹 사양 추가 - viewport-fit=cover, prefers-reduced-motion, 테스트 뷰포트 명시 - Phase 1을 1a(breakpoint 정리) + 1b(컴포넌트)로 세분화 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,16 +2,38 @@
|
|||||||
|
|
||||||
> 모바일에서 UI 짤림 현상 해결 + 풀 모바일 경험 적용
|
> 모바일에서 UI 짤림 현상 해결 + 풀 모바일 경험 적용
|
||||||
> 작성일: 2026-04-23
|
> 작성일: 2026-04-23
|
||||||
|
> 리뷰 반영: 2026-04-23 (라우트 경로 수정, breakpoint 예외 명시, 구현 복잡도 보완)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 1. 목표
|
## 1. 목표
|
||||||
|
|
||||||
- 모든 페이지(13개)에서 모바일 UI 짤림 현상 해결
|
- 전체 15개 뷰(12개 라우트 + 3개 서브라우트)에서 모바일 UI 짤림 현상 해결
|
||||||
- 현재 다크 네온 사이버펑크 디자인 톤 유지
|
- 현재 다크 네온 사이버펑크 디자인 톤 유지
|
||||||
- 모바일 전용 UX 패턴 추가 (바텀 네비게이션, 스와이프, 풀다운 리프레시, FAB, 바텀시트)
|
- 모바일 전용 UX 패턴 추가 (바텀 네비게이션, 스와이프, 풀다운 리프레시, FAB, 바텀시트)
|
||||||
- 기능적 손실 없이 반응형 적용
|
- 기능적 손실 없이 반응형 적용
|
||||||
|
|
||||||
|
**대상 뷰 목록 (routes.jsx 기준):**
|
||||||
|
|
||||||
|
| # | 라우트 | 컴포넌트 | 비고 |
|
||||||
|
|---|--------|---------|------|
|
||||||
|
| 1 | `/` | Home | |
|
||||||
|
| 2 | `/lotto` | Lotto | 3탭 (Briefing/Analysis/Purchase) |
|
||||||
|
| 3 | `/stock` | Stock | |
|
||||||
|
| 4 | `/stock/trade` | StockTrade | 서브라우트 |
|
||||||
|
| 5 | `/travel` | Travel | |
|
||||||
|
| 6 | `/blog` | Blog | |
|
||||||
|
| 7 | `/blog-lab` | BlogMarketing | |
|
||||||
|
| 8 | `/realestate` | Subscription | |
|
||||||
|
| 9 | `/music` | MusicStudio | |
|
||||||
|
| 10 | `/todo` | Todo | |
|
||||||
|
| 11 | `/agent-office` | AgentOffice | |
|
||||||
|
| 12 | `/lab` | EffectLab | |
|
||||||
|
| 13 | `/lab/sword-stream` | SwordStream | 서브라우트 |
|
||||||
|
| 14 | `/lab/day-calc` | DayCalc | 서브라우트 |
|
||||||
|
|
||||||
|
> Note: `RealEstate.jsx` (`/realestate/property`)는 routes.jsx에 미등록 상태. 반응형 스코프에서 제외.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 2. 접근 방식
|
## 2. 접근 방식
|
||||||
@@ -20,7 +42,7 @@
|
|||||||
|
|
||||||
1. 공통 모바일 인프라(컴포넌트, breakpoint, 앱 셸) 구축
|
1. 공통 모바일 인프라(컴포넌트, breakpoint, 앱 셸) 구축
|
||||||
2. 주요 4개 페이지 (홈, 로또, 주식, 여행) 우선 적용
|
2. 주요 4개 페이지 (홈, 로또, 주식, 여행) 우선 적용
|
||||||
3. 나머지 9개 페이지 확장 적용
|
3. 나머지 페이지 확장 적용
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -37,7 +59,17 @@
|
|||||||
| lg | 1024px | 소형 데스크톱 |
|
| lg | 1024px | 소형 데스크톱 |
|
||||||
| xl | 1280px | 대형 데스크톱 |
|
| xl | 1280px | 대형 데스크톱 |
|
||||||
|
|
||||||
기존 미디어 쿼리의 비표준 값(640px, 900px, 960px, 1100px 등)은 기능 손실 없이 가장 가까운 표준 breakpoint로 정리한다. 단, 특정 페이지에서 세밀한 조정이 반드시 필요한 경우 예외를 허용한다.
|
기존 미디어 쿼리의 비표준 값(640px, 900px, 960px, 1100px 등)은 기능 손실 없이 가장 가까운 표준 breakpoint로 정리한다.
|
||||||
|
|
||||||
|
**허용 예외 (이동 시 시각적 회귀 발생):**
|
||||||
|
|
||||||
|
| 기존 값 | 파일 | 사유 |
|
||||||
|
|---------|------|------|
|
||||||
|
| 420px | Stock.css (4곳) | 소형 폰 전용 패딩/라벨 축소, 480px로 이동 시 중간 기기에서 불필요한 축소 |
|
||||||
|
| 520px | Stock.css (1곳) | 지표 카드 특수 레이아웃 |
|
||||||
|
| 700px | Stock.css (1곳) | AI 코치 설정 그리드, 768px로 이동 시 태블릿에서 조기 축소 |
|
||||||
|
|
||||||
|
위 값들은 해당 페이지 CSS에서 기존 값을 유지한다.
|
||||||
|
|
||||||
### 3-2. 바텀 네비게이션 바 (`BottomNav`)
|
### 3-2. 바텀 네비게이션 바 (`BottomNav`)
|
||||||
|
|
||||||
@@ -47,8 +79,27 @@
|
|||||||
- 사이드바는 모바일에서 완전히 숨김 (기존 햄버거→슬라이드 방식 제거)
|
- 사이드바는 모바일에서 완전히 숨김 (기존 햄버거→슬라이드 방식 제거)
|
||||||
- 높이: 56~64px
|
- 높이: 56~64px
|
||||||
- `env(safe-area-inset-bottom)` 대응 (노치/홈 인디케이터 기기)
|
- `env(safe-area-inset-bottom)` 대응 (노치/홈 인디케이터 기기)
|
||||||
|
- `index.html`에 `viewport-fit=cover` 추가 필요: `<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">`
|
||||||
- 더보기 메뉴: 탭 시 위로 펼쳐지는 오버레이 패널
|
- 더보기 메뉴: 탭 시 위로 펼쳐지는 오버레이 패널
|
||||||
|
|
||||||
|
**사이드바→바텀네비 마이그레이션 상세:**
|
||||||
|
- `Navbar.jsx`: 768px 이하에서 사이드바 렌더링 제거, `sidebar-toggle` 버튼 제거
|
||||||
|
- `Navbar.css`: `.sidebar` transform/transition 미디어 쿼리 제거, `.sidebar__overlay` 제거
|
||||||
|
- `Navbar.jsx` useEffect: `body.overflow = 'hidden'` 토글 로직 정리
|
||||||
|
- `App.jsx`에서 `BottomNav` 컴포넌트 조건부 렌더링 (`useIsMobile()` 기반)
|
||||||
|
|
||||||
|
**더보기 메뉴 내용 (나머지 네비게이션 항목):**
|
||||||
|
|
||||||
|
| 순서 | 아이콘 | 라벨 | 경로 |
|
||||||
|
|------|--------|------|------|
|
||||||
|
| 1 | 음악 | 뮤직 | `/music` |
|
||||||
|
| 2 | 로봇 | 에이전트 | `/agent-office` |
|
||||||
|
| 3 | 블로그 | 블로그 | `/blog` |
|
||||||
|
| 4 | 마케팅 | 블로그랩 | `/blog-lab` |
|
||||||
|
| 5 | 건물 | 청약 | `/realestate` |
|
||||||
|
| 6 | 체크 | TODO | `/todo` |
|
||||||
|
| 7 | 실험 | 이펙트랩 | `/lab` |
|
||||||
|
|
||||||
**기본 5개 메뉴 구성:**
|
**기본 5개 메뉴 구성:**
|
||||||
|
|
||||||
| 순서 | 아이콘 | 라벨 | 경로 |
|
| 순서 | 아이콘 | 라벨 | 경로 |
|
||||||
@@ -69,13 +120,21 @@
|
|||||||
| `FAB` | `src/components/FAB.jsx` | 플로팅 액션 버튼 (바텀 네비 위 배치) |
|
| `FAB` | `src/components/FAB.jsx` | 플로팅 액션 버튼 (바텀 네비 위 배치) |
|
||||||
| `MobileSheet` | `src/components/MobileSheet.jsx` | 바텀시트 모달 (드래그 핸들, 스냅 포인트) |
|
| `MobileSheet` | `src/components/MobileSheet.jsx` | 바텀시트 모달 (드래그 핸들, 스냅 포인트) |
|
||||||
|
|
||||||
**공통 훅:**
|
**공통 훅 (신규 `src/hooks/` 디렉토리 생성):**
|
||||||
|
|
||||||
|
> 기존 훅은 페이지별 디렉토리에 colocate (`src/pages/lotto/hooks/` 등).
|
||||||
|
> 모바일 인프라 훅은 여러 페이지에서 공유하므로 `src/hooks/`에 배치한다.
|
||||||
|
|
||||||
| 훅 | 파일 | 역할 |
|
| 훅 | 파일 | 역할 |
|
||||||
|----|------|------|
|
|----|------|------|
|
||||||
| `useIsMobile` | `src/hooks/useIsMobile.js` | 768px 이하 감지 (matchMedia) |
|
| `useIsMobile` | `src/hooks/useIsMobile.js` | 768px 이하 감지 (matchMedia) |
|
||||||
| `useSwipe` | `src/hooks/useSwipe.js` | 터치 스와이프 방향·거리 감지 |
|
| `useSwipe` | `src/hooks/useSwipe.js` | 터치 스와이프 방향·거리 감지 |
|
||||||
|
|
||||||
|
**경량 라이브러리 활용:**
|
||||||
|
- `react-swipeable` (~3KB gzipped): SwipeableView/useSwipe 기반으로 활용 — 터치 velocity, threshold snap, 방향 판별을 직접 구현하지 않음
|
||||||
|
- PullToRefresh: 터치 이벤트 직접 구현하되, iOS Safari rubber-banding 및 `overscroll-behavior: contain` 대응 필수
|
||||||
|
- MobileSheet: CSS `transform` + `touch-action: none`으로 구현, 스냅 포인트 2단계 (50%, 90%)
|
||||||
|
|
||||||
### 3-4. 앱 셸 레이아웃 변경
|
### 3-4. 앱 셸 레이아웃 변경
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -171,7 +230,7 @@
|
|||||||
- FAB: "글 쓰기"
|
- FAB: "글 쓰기"
|
||||||
- 풀다운 리프레시: 글 목록 갱신
|
- 풀다운 리프레시: 글 목록 갱신
|
||||||
|
|
||||||
### 5-2. 블로그 마케팅 (BlogMarketing) — `/blog-marketing`
|
### 5-2. 블로그 마케팅 (BlogMarketing) — `/blog-lab`
|
||||||
|
|
||||||
| 영역 | 모바일 변경 |
|
| 영역 | 모바일 변경 |
|
||||||
|------|------------|
|
|------|------------|
|
||||||
@@ -196,28 +255,22 @@
|
|||||||
- FAB: "공고 등록"
|
- FAB: "공고 등록"
|
||||||
- 풀다운 리프레시: 공고/매칭 갱신
|
- 풀다운 리프레시: 공고/매칭 갱신
|
||||||
|
|
||||||
### 5-4. 관심 매물 (RealEstate) — `/realestate/property`
|
### 5-4. 뮤직 스튜디오 (MusicStudio) — `/music`
|
||||||
|
|
||||||
| 영역 | 모바일 변경 |
|
|
||||||
|------|------------|
|
|
||||||
| 매물 목록 | 카드형 리스트 |
|
|
||||||
| 지도 뷰 | 높이 35vh, 핀치 줌 |
|
|
||||||
|
|
||||||
### 5-5. 뮤직 스튜디오 (MusicStudio) — `/lab/music`
|
|
||||||
|
|
||||||
| 영역 | 모바일 변경 |
|
| 영역 | 모바일 변경 |
|
||||||
|------|------------|
|
|------|------------|
|
||||||
| 헤더 | 1컬럼, 타이틀 클램프 축소 |
|
| 헤더 | 1컬럼, 타이틀 클램프 축소 |
|
||||||
| 생성 폼 | 풀 너비 스택 |
|
| 생성 폼 | 풀 너비 스택 |
|
||||||
| 라이브러리 | 1컬럼 리스트 (앨범아트 + 제목) |
|
| 라이브러리 | 1컬럼 리스트 (앨범아트 + 제목) |
|
||||||
| 플레이어 | 미니 플레이어 바텀 고정 (바텀 네비 위) |
|
| 플레이어 | 미니 플레이어 바텀 고정 (높이 56px, 바텀 네비 위 = bottom: 64px) |
|
||||||
| 가사 에디터 | 풀 너비 |
|
| 가사 에디터 | 풀 너비 |
|
||||||
| 레이더 위젯 | 중앙 정렬 |
|
| 레이더 위젯 | 중앙 정렬 |
|
||||||
|
|
||||||
- FAB: "음악 생성"
|
- FAB: "음악 생성"
|
||||||
- 풀다운 리프레시: 라이브러리 갱신
|
- 풀다운 리프레시: 라이브러리 갱신
|
||||||
|
- 미니 플레이어 표시 시 콘텐츠 padding-bottom: 바텀네비(64px) + 미니플레이어(56px) = 120px
|
||||||
|
|
||||||
### 5-6. TODO — `/todo`
|
### 5-5. TODO — `/todo`
|
||||||
|
|
||||||
| 영역 | 모바일 변경 |
|
| 영역 | 모바일 변경 |
|
||||||
|------|------------|
|
|------|------------|
|
||||||
@@ -227,7 +280,7 @@
|
|||||||
|
|
||||||
- FAB: "할일 추가"
|
- FAB: "할일 추가"
|
||||||
|
|
||||||
### 5-7. 에이전트 오피스 (AgentOffice) — `/lab/agent-office`
|
### 5-6. 에이전트 오피스 (AgentOffice) — `/agent-office`
|
||||||
|
|
||||||
| 영역 | 모바일 변경 |
|
| 영역 | 모바일 변경 |
|
||||||
|------|------------|
|
|------|------------|
|
||||||
@@ -237,7 +290,7 @@
|
|||||||
| 명령 입력 | 하단 입력 바 (채팅 UX) |
|
| 명령 입력 | 하단 입력 바 (채팅 UX) |
|
||||||
| WebSocket 상태 | 탑바에 연결 상태 아이콘 |
|
| WebSocket 상태 | 탑바에 연결 상태 아이콘 |
|
||||||
|
|
||||||
### 5-8. 이펙트 랩 — `/lab`, `/lab/day-calc`, `/lab/sword-stream`
|
### 5-7. 이펙트 랩 — `/lab`, `/lab/day-calc`, `/lab/sword-stream`
|
||||||
|
|
||||||
| 페이지 | 모바일 변경 |
|
| 페이지 | 모바일 변경 |
|
||||||
|--------|------------|
|
|--------|------------|
|
||||||
@@ -263,31 +316,45 @@
|
|||||||
- 이미지: `loading="lazy"` 속성 확인
|
- 이미지: `loading="lazy"` 속성 확인
|
||||||
- 스와이프/터치 이벤트: passive listener 사용
|
- 스와이프/터치 이벤트: passive listener 사용
|
||||||
- 바텀시트 애니메이션: `transform` + `will-change` 사용 (layout thrashing 방지)
|
- 바텀시트 애니메이션: `transform` + `will-change` 사용 (layout thrashing 방지)
|
||||||
|
- 신규 애니메이션(스와이프, 바텀시트, 풀다운)은 `prefers-reduced-motion: reduce` 쿼리 존중 — Travel.css, MusicStudio.css 기존 패턴과 통일
|
||||||
|
|
||||||
|
### 주의: Stock.css / StockTrade.jsx 커플링
|
||||||
|
|
||||||
|
`StockTrade.jsx`는 `Stock.css`의 스타일을 공유한다. Stock.css의 반응형 수정은 StockTrade에도 영향을 미치므로, 반드시 두 페이지를 함께 검증해야 한다.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 8. 구현 순서
|
## 8. 구현 순서
|
||||||
|
|
||||||
### Phase 1: 글로벌 인프라
|
### Phase 1: 글로벌 인프라
|
||||||
1. Breakpoint 시스템 통일 (index.css)
|
|
||||||
2. `useIsMobile`, `useSwipe` 훅 생성
|
**Phase 1a: Breakpoint 정리 (기존 CSS만 수정, 신규 코드 없음)**
|
||||||
3. `BottomNav` 컴포넌트 구현
|
1. Breakpoint 시스템 통일 — 각 CSS 파일의 비표준 미디어 쿼리를 표준 값으로 정리
|
||||||
4. `PullToRefresh`, `SwipeableView`, `FAB`, `MobileSheet` 컴포넌트 구현
|
2. `index.html`에 `viewport-fit=cover` 추가
|
||||||
5. 앱 셸 레이아웃 수정 (App.jsx, App.css)
|
3. 회귀 테스트: 정리 후 각 페이지 데스크톱/모바일 확인
|
||||||
|
|
||||||
|
**Phase 1b: 공통 컴포넌트 & 앱 셸**
|
||||||
|
4. `react-swipeable` 패키지 설치
|
||||||
|
5. `src/hooks/` 디렉토리 생성 + `useIsMobile`, `useSwipe` 훅 구현
|
||||||
|
6. `BottomNav` 컴포넌트 구현 + 사이드바 모바일 제거 마이그레이션 (Navbar.jsx/css 수정)
|
||||||
|
7. `PullToRefresh`, `SwipeableView`, `FAB`, `MobileSheet` 컴포넌트 구현
|
||||||
|
8. 앱 셸 레이아웃 수정 (App.jsx, App.css)
|
||||||
|
|
||||||
### Phase 2: 주요 페이지 적용
|
### Phase 2: 주요 페이지 적용
|
||||||
6. 홈 페이지 반응형 개선
|
9. 홈 페이지 반응형 개선
|
||||||
7. 로또 페이지 반응형 개선
|
10. 로또 페이지 반응형 개선
|
||||||
8. 주식 페이지 (Stock + StockTrade) 반응형 개선
|
11. 주식 페이지 (Stock + StockTrade 함께 검증) 반응형 개선
|
||||||
9. 여행 페이지 반응형 개선
|
12. 여행 페이지 반응형 개선
|
||||||
|
|
||||||
### Phase 3: 나머지 페이지 확장
|
### Phase 3: 나머지 페이지 확장
|
||||||
10. 블로그 + 블로그 마케팅
|
13. 블로그 (`/blog`) + 블로그 마케팅 (`/blog-lab`)
|
||||||
11. 부동산 (Subscription + RealEstate)
|
14. 부동산 청약 (`/realestate`)
|
||||||
12. 뮤직 스튜디오
|
15. 뮤직 스튜디오 (`/music`)
|
||||||
13. TODO
|
16. TODO (`/todo`)
|
||||||
14. 에이전트 오피스
|
17. 에이전트 오피스 (`/agent-office`)
|
||||||
15. 이펙트 랩 (EffectLab + DayCalc + SwordStream)
|
18. 이펙트 랩 (`/lab` + `/lab/day-calc` + `/lab/sword-stream`)
|
||||||
|
|
||||||
### Phase 4: 검증
|
### Phase 4: 검증
|
||||||
16. 전체 페이지 모바일 UI 검증 및 수정
|
19. 전체 뷰 모바일 UI 검증 — 대상 뷰포트: 360px (Galaxy S), 390px (iPhone 14), 768px (iPad), 1024px (데스크톱)
|
||||||
|
20. `prefers-reduced-motion` 동작 확인
|
||||||
|
21. 터치 타겟 크기 검증 (44×44px 최소)
|
||||||
|
|||||||
Reference in New Issue
Block a user