🧩 복합 UI 컴포넌트 계층 - 여러 entities와 features를 조합한 재사용 가능한 위젯
Widgets Layer는 복합 UI 컴포넌트를 관리하는 계층입니다. 여러 entities와 features를 조합하여 완전한 기능을 가진 UI 블록을 제공하며, 여러 페이지에서 재사용 가능한 큰 단위의 컴포넌트들을 포함합니다.
src/widgets/
├── Header/ # 🧭 네비게이션 헤더
│ ├── Header.tsx # 메인 헤더 컴포넌트
│ └── index.ts # 공개 API
├── Footer/ # 🦶 페이지 푸터
│ ├── Footer.tsx # 푸터 컴포넌트
│ └── index.ts # 공개 API
├── hero/ # 🎯 히어로 섹션
│ └── ui/
│ ├── Hero.tsx # 메인 히어로 영역
│ └── HowToStartTitle.tsx # 시작 가이드 제목
└── BackToHome/ # 🏠 홈 이동 버튼
└── BackToHome.tsx # 고정 위치 홈 버튼
역할: 전체 애플리케이션의 네비게이션 허브
- 로고 & 브랜딩: 프로젝트 잼 로고 및 홈 링크
- 주요 네비게이션: 프로젝트 목록, 프로젝트 등록 링크
- 사용자 메뉴: 로그인/로그아웃, 프로필 드롭다운
- 반응형 디자인: 모바일 햄버거 메뉴
- 비로그인: 로그인/회원가입 버튼 표시
- 로그인: 사용자 아바타 및 드롭다운 메뉴
- 관리자: 추가 관리 메뉴 항목
역할: 사이트 전체 정보 및 링크 제공
- 회사 정보: 프로젝트 설명 및 연락처
- 서비스 링크: 이용약관, 개인정보처리방침
- 소셜 미디어: GitHub, Discord 등 커뮤니티 링크
- 개발자 정보: 팀 소개 및 기여자 목록
- 데스크톱: 4컬럼 레이아웃
- 태블릿: 2컬럼 스택
- 모바일: 1컬럼 세로 배치
역할: 메인 페이지의 핵심 메시지 전달
- Hero.tsx: 메인 캐치프레이즈와 CTA 버튼
- HowToStartTitle.tsx: 서비스 이용 가이드 섹션
- 임팩트 메시지: "함께 만들어가는 사이드 프로젝트"
- CTA 버튼: 프로젝트 둘러보기, 프로젝트 등록
- 애니메이션: Fade-in, Slide-up 효과
- 통계 정보: 등록된 프로젝트 수, 활성 사용자 등
역할: 어디서든 빠른 홈 이동 제공
- 고정 위치: 화면 우하단 플로팅 버튼
- 스크롤 인식: 일정 스크롤 시 표시
- 부드러운 애니메이션: 나타나기/사라지기 효과
- 접근성: 키보드 네비게이션 지원
복잡한 위젯의 내부 구조를 컴포넌트로 분리하여 유연성 확보
- Container: 비즈니스 로직과 상태 관리
- Presenter: UI 렌더링에만 집중
위젯별 커스텀 훅으로 재사용 가능한 로직 분리
- Props Interface: 유연한 설정 옵션 제공
- Theming: MUI 테마 시스템 완전 지원
- 반응형: 모든 화면 크기에서 동작
- 외부 의존성 최소화: 필수 props만 요구
- 내부 상태 관리: 위젯 내부에서 상태 완결
- 에러 바운더리: 위젯 오류가 전체에 영향 미치지 않음
- 슬롯 패턴: 내부 컴포넌트 교체 가능
- 이벤트 핸들러: 외부에서 커스텀 동작 주입
- 스타일 오버라이드: 테마를 통한 스타일 커스터마이징
- xs (0px): 모바일 세로
- sm (600px): 모바일 가로
- md (900px): 태블릿
- lg (1200px): 소형 데스크톱
- xl (1536px): 대형 데스크톱
- 기본: 모바일 레이아웃으로 설계
- 확장: 큰 화면을 위한 점진적 개선
- 터치: 터치 친화적 인터랙션
- 팔레트: 프로젝트 브랜드 컬러 시스템
- 타이포그래피: Pretendard 폰트 패밀리
- 컴포넌트: 일관된 스타일 오버라이드
- Emotion: MUI의 기본 CSS-in-JS 엔진
- sx prop: 인라인 스타일링
- styled: 재사용 컴포넌트 스타일링
- 테마 토글: Header에서 다크/라이트 모드 전환
- 자동 감지: 시스템 설정 기반 초기 테마
- 지속성: localStorage를 통한 설정 유지
- React.memo: 불필요한 리렌더링 방지
- useMemo/useCallback: 계산 비용이 큰 연산 메모이제이션
- 지연 로딩: 무거운 컴포넌트의 동적 임포트
- Tree Shaking: 사용하지 않는 코드 제거
- Code Splitting: 위젯별 청크 분할
- Dynamic Import: 조건부 위젯 로딩
- WebP 포맷: 모던 브라우저 최적화
- Lazy Loading: 뷰포트 진입 시 로딩
- 적응형 이미지: 디바이스별 최적 해상도
- 역할 정의: role 속성을 통한 의미 전달
- 상태 관리: aria-expanded, aria-selected 등
- 레이블링: aria-label, aria-describedby 활용
- Tab 순서: 논리적인 포커스 흐름
- 단축키: 주요 액션에 대한 키보드 단축키
- 포커스 표시: 명확한 포커스 인디케이터
- 의미 있는 텍스트: alt 텍스트, 버튼 레이블
- 구조 정보: 헤딩 계층, 랜드마크 역할
- 상태 알림: 동적 콘텐츠 변경 알림
- 컴포넌트 렌더링: 기본 렌더링 확인
- Props 전달: 다양한 props 조합 테스트
- 이벤트 핸들링: 사용자 인터랙션 시뮬레이션
- 위젯 간 상호작용: Header와 다른 컴포넌트 연동
- 라우팅 테스트: 네비게이션 동작 확인
- 반응형 테스트: 다양한 화면 크기 검증
- Storybook: 위젯 스토리 작성
- 스냅샷 테스트: UI 변경 감지
- 크로스 브라우저: 주요 브라우저 호환성
- 디렉토리 구조:
src/widgets/WidgetName/ - 인덱스 파일: 공개 API 정의
- 타입스크립트: Props 인터페이스 정의
- 스토리북: 개발 및 테스트용 스토리
- 문서화: README 또는 JSDoc 주석
- 영향도 분석: 사용하는 페이지 확인
- 하위 호환성: Props 변경 시 기존 사용법 유지
- 테스트 업데이트: 변경사항에 맞는 테스트 수정
- 문서 갱신: 변경된 API 문서화
- 렌더링 최적화: 불필요한 리렌더링 방지
- 메모리 누수: 이벤트 리스너 정리
- 번들 크기: 큰 의존성 동적 임포트
- 로딩 시간: 초기 렌더링 최적화
💡 개발 팁: 위젯은 큰 단위의 UI 블록입니다. 단순한 버튼이나 입력 필드보다는 Header, Footer 같은 완전한 기능을 가진 컴포넌트를 만드세요!