-
Notifications
You must be signed in to change notification settings - Fork 2
Feat: 투표 작성 폼 애니메이션 추가 및 UX 개선, 커스텀 체크박스 생성 #92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
📦 번들 분석 결과📊 번들 크기 요약
🔍 주요 청크 파일 (크기순)🤖 자동 생성된 번들 분석 리포트 |
⚡ Lighthouse 성능 분석 결과📊 전체 평균 점수
📈 측정 현황
📄 페이지별 상세 분석🏠 커뮤니티 페이지:
|
| 지표 | 점수 |
|---|---|
| 🚀 Performance | 69점 |
| ♿ Accessibility | 78점 |
| ✅ Best Practices | 100점 |
| 🔍 SEO | 100점 |
📊 상세 분석 보기
👥 창업자 페이지: /main/founder
| 지표 | 점수 |
|---|---|
| 🚀 Performance | 75점 |
| ♿ Accessibility | 87점 |
| ✅ Best Practices | 100점 |
| 🔍 SEO | 100점 |
📊 상세 분석 보기
🏡 홈 페이지: /main/home
| 지표 | 점수 |
|---|---|
| 🚀 Performance | 75점 |
| ♿ Accessibility | 91점 |
| ✅ Best Practices | 100점 |
| 🔍 SEO | 100점 |
📊 상세 분석 보기
🗺️ 지도 페이지: /main/maps
| 지표 | 점수 |
|---|---|
| 🚀 Performance | 75점 |
| ♿ Accessibility | 87점 |
| ✅ Best Practices | 100점 |
| 🔍 SEO | 100점 |
📊 상세 분석 보기
👤 프로필 페이지: /main/profile
| 지표 | 점수 |
|---|---|
| 🚀 Performance | 75점 |
| ♿ Accessibility | 88점 |
| ✅ Best Practices | 100점 |
| 🔍 SEO | 100점 |
📊 상세 분석 보기
🔗 전체 상세 분석 결과
📄 측정된 페이지
- /main/community
- /main/founder
- /main/home
- /main/maps
- /main/profile
모든 페이지에서 성능 측정이 완료되었습니다.
🤖 자동 생성된 Lighthouse 성능 리포트
DreamPaste
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
고생하셨어요~
화려한 투표 컴포넌트군요
| <AnimatePresence initial={false}> | ||
| {canRemove && ( | ||
| <motion.button | ||
| key="remove" | ||
| type="button" | ||
| onClick={onRemove} | ||
| aria-label={`옵션 ${index + 1} 삭제`} | ||
| className="text-xs text-neutral-400" | ||
| initial={{ opacity: 0, x: 8 }} | ||
| animate={{ opacity: 1, x: 0 }} | ||
| exit={{ opacity: 0, x: 8 }} | ||
| transition={{ duration: 0.15 }} | ||
| > |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
접근성과 상세한 애니메이션 설정이 대단하군요
| onClick={() => { | ||
| const current = getValues('voteOptions') ?? []; | ||
| if (current.length >= MAX_OPTIONS) return; | ||
| append({ content: '' }); | ||
| }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
복잡한 클릭 이벤트 핸들러는 분리하는게 좋아보여요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
또, useCallback의 필요성도 확인해주세요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
리뷰 감사합니다.
주신 피드백 반영하여 인라인으로 있던 핸들러는 분리하였고,
useCallback에 대해서도 검토해보았습니다!
useCallback은
- 메모된 하위 컴포넌트에 props로 넘겨 렌더를 줄이고 싶을 때
- 의존성 배열에 들어가는 함수를 안정화해야 할 때
주로 사용하는데 현재는 해당하는 부분이 없어 제거하였습니다.
| onRemove={() => { | ||
| const current = getValues('voteOptions') ?? []; | ||
| if (current.length <= MIN_OPTIONS) return; | ||
| remove(index); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
여기도 동일하게 분리하는게 좋아보여요
📌 개요
투표 생성 페이지(SOS-49)에 애니메이션 기반 옵션 필드 추가/삭제 UX 개선을 적용하고,
커스텀 RoundCheckbox 컴포넌트를 새로 만들고 투표 설정 영역에 적용했습니다.
🗒 상세 설명
1. 투표 옵션 필드 애니메이션 적용
옵션 추가/삭제 시 화면이 순간적으로 튀는 문제를 해결하기 위해
motion.div,AnimatePresence를 활용하여 자연스러운 애니메이션을 추가했습니다.🔧 핵심 구현사항
layout을 사용하여 입력 필드 간 자연스러운 리플로우 제공MAX_OPTIONS,MIN_OPTIONS로 옵션 개수 제한을 명확히 선언watch+getValues기반으로 RHF와 애니메이션 충돌 없는 구조로 조정2. 옵션 개수 제한 로직 개선 (RHF watch 기반)
기존에는
fields.length만 의존해 불안정성이 있었는데→
watch('voteOptions')기반으로 변동을 안정적으로 감지하도록 수정했습니다.🔧 핵심 구현사항
watch('voteOptions')로 실시간 옵션 개수 추적canAddMore/canRemove명확하게 조건 분리MIN_OPTIONS조건 체크버튼 노출 조건 + 실제 삭제 시점 둘 다에서 길이 검사 이중 가드 처리
왜
watch를 쓰게 되었는지기존 구현은
useFieldArray에서 내려오는fields.length만 보고 판단해서,실제 폼 값(
voteOptions)과fields길이가 잠깐씩 어긋날 수 있는 문제가 있었습니다.이 때문에 옵션 추가/삭제를 빠르게 반복하면
watch('voteOptions')watch는 react-hook-form에서 특정 필드 값을 구독하는 함수watch('voteOptions')는"현재 폼에 들어있는 voteOptions 배열"을 그대로 가져옵니다.이번 PR에서는:
canRemove)canAddMore)를 모두
watch('voteOptions')기준으로 맞춰→ 애니메이션 / 버튼 노출 / 실제 데이터 상태가 한 소스에서 일관되도록 정리했습니다.
3. RoundCheckbox 컴포넌트 생성
디자인 시스템에 맞는 라운드형 체크박스 UI가 필요해
완전히 새 컴포넌트로 구현하여 투표 설정 영역에 적용했습니다.
🔧 핵심 구현사항
peer기반으로 체크/언체크 상태 스타일 처리register와 자연스럽게 연결 가능 (forwardRef적용)🧩 사용 예시
4. 전체 UI 구조 정리 및 스크롤 문제 개선
overflow-y-auto적용sticky bottom-0으로 고정해 UX 개선📸 스크린샷
AS-IS
as.mp4
TO-BE
checkbox.mp4
tobe.mp4
🔗 이슈
closes #SOS-49
✅ 체크리스트
🧪 테스트 방법
📝 추가 노트
MAX_OPTIONS,MIN_OPTIONS상수로 분리돼 있어향후 정책 변경 시 해당 상수만 조정하면 됩니다.
🚀 후속 작업