[feature] 배너 로딩 중 shimmer 스켈레톤 UI 추가#1557
Conversation
isPending 상태일 때 null 대신 shimmer 애니메이션 스켈레톤을 모바일/데스크탑/랩탑 전 해상도에서 표시
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning
|
| Layer / File(s) | Summary |
|---|---|
스켈레톤 UI 스타일 정의 frontend/src/pages/MainPage/components/Banner/Banner.styles.ts |
keyframes를 통한 shimmer 애니메이션과 반응형 크기 설정을 포함한 SkeletonBannerWrapper 스타일 컴포넌트를 추가함. |
배너 컴포넌트 로딩 상태 처리 frontend/src/pages/MainPage/components/Banner/Banner.tsx |
useGetBanners 훅의 로딩 상태 판별을 isLoading에서 isPending으로 변경하고, 로딩 중 스켈레톤 UI를 렌더링하도록 조건부 반환 로직을 수정함. |
기능 문서 frontend/docs/features/main/banner.md |
배너 스켈레톤 UI 적용 방식, isPending 기반 렌더링/교체 흐름, 캐시 hit 조건, 모바일/데스크탑 반응형 사양을 설명하는 문서를 새로 추가함. |
Estimated Code Review Effort
🎯 2 (Simple) | ⏱️ ~10 minutes
Possibly Related Issues
- [feature] MOA-862 사용자는 배너 로딩 중 스켈레톤 UI를 볼 수 있다 #1556: 배너 데이터 로딩 중 스켈레톤 UI(SkeletonBannerWrapper)를 표시하는 기능을 구현하는 변경사항으로 직접 연관됨.
Possibly Related PRs
- Moadong/moadong#1331: 두 PR 모두 메인 페이지
Banner.tsx의 배너 로딩/표시 로직(React Query 상태 기반 early return 및 데이터 소스 선택)을 변경하여 동일한 코드 경로에서 충돌/연관될 가능성이 있음. - Moadong/moadong#1332: 두 PR 모두 메인 페이지
Banner기능에서useGetBannersReact Query 훅 및 로딩 상태를 활용하여 배너 데이터를 패칭/렌더링하므로, 이 PR의isPending스켈레톤 UI 변경사항이 검색된 PR의 배너 API/훅 통합과 직접 연결됨.
Suggested Labels
✨ Feature, 💻 FE
Suggested Reviewers
- lepitaaar
- oesnuj
- suhyun113
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
| Check name | Status | Explanation |
|---|---|---|
| Title check | ✅ Passed | PR 제목이 주요 변경사항인 '배너 로딩 중 shimmer 스켈레톤 UI 추가'를 명확하게 설명하고 있으며, 변경셋의 핵심 목적과 완전히 일치한다. |
| Docstring Coverage | ✅ Passed | No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. |
| Linked Issues check | ✅ Passed | Check skipped because no linked issues were found for this pull request. |
| Out of Scope Changes check | ✅ Passed | Check skipped because no linked issues were found for this pull request. |
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
✏️ Tip: You can configure your own custom pre-merge checks in the settings.
✨ Finishing Touches
📝 Generate docstrings
- Create stacked PR
- Commit on current branch
🧪 Generate unit tests (beta)
- Create PR with unit tests
- Commit unit tests in branch
feature/#1556-banner-skeleton-MOA-862
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands and usage tips.
✅ UI 변경사항 없음
전체 57개 스토리 · 22개 컴포넌트 |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
frontend/src/pages/MainPage/components/Banner/Banner.tsx (1)
84-89: ⚡ Quick win스켈레톤 로딩 분기에 보조기기용 상태 정보를 추가해주세요.
현재는 시각적으로만 로딩을 표현하므로,
role="status"/aria-live및 장식 요소aria-hidden을 같이 두는 편이 안전합니다.접근성 보완 예시(diff)
if (isPending) { return ( - <Styled.BannerContainer> - <Styled.SkeletonBannerWrapper /> + <Styled.BannerContainer role='status' aria-live='polite' aria-label='배너 로딩 중'> + <Styled.SkeletonBannerWrapper aria-hidden='true' /> </Styled.BannerContainer> ); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/pages/MainPage/components/Banner/Banner.tsx` around lines 84 - 89, The skeleton-loading branch inside the Banner component (the isPending conditional that returns <Styled.BannerContainer> and <Styled.SkeletonBannerWrapper />) should expose assistive-status attributes: add role="status" and an appropriate aria-live (e.g., "polite") to the visible loading container element (Styled.BannerContainer) and mark purely decorative DOM inside the skeleton (Styled.SkeletonBannerWrapper) as aria-hidden="true"; ensure there is no duplicate live region elsewhere and that any textual loading message is included but visually hidden for screen readers if needed.frontend/src/pages/MainPage/components/Banner/Banner.styles.ts (1)
4-17: ⚡ Quick win모션 감소 환경에서 shimmer 애니메이션을 비활성화해주세요.
현재 shimmer가 항상 재생되어
prefers-reduced-motion사용자에게 부담을 줄 수 있습니다.접근성 개선 예시(diff)
const shimmer = keyframes` 0% { background-position: -800px 0; } 100% { background-position: 800px 0; } `; export const SkeletonBannerWrapper = styled.div` width: 100%; max-width: 1180px; aspect-ratio: 1180 / 316; border-radius: 26px; background: linear-gradient(90deg, `#f0f0f0` 25%, `#e4e4e4` 50%, `#f0f0f0` 75%); background-size: 800px 100%; animation: ${shimmer} 1.5s infinite linear; + + `@media` (prefers-reduced-motion: reduce) { + animation: none; + } ${media.mobile} { aspect-ratio: 1.8; border-radius: 0; } `;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/src/pages/MainPage/components/Banner/Banner.styles.ts` around lines 4 - 17, The shimmer animation currently always runs on SkeletonBannerWrapper; update the styling so users with prefers-reduced-motion do not see it by adding a media query for prefers-reduced-motion: reduce that disables the animation (set animation to none and/or remove background-position animation) for the SkeletonBannerWrapper while keeping the keyframes (shimmer) for normal users; reference the shimmer keyframes and the SkeletonBannerWrapper styled component to locate where to add the `@media` (prefers-reduced-motion: reduce) rule.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@frontend/src/pages/MainPage/components/Banner/Banner.styles.ts`:
- Around line 4-17: The shimmer animation currently always runs on
SkeletonBannerWrapper; update the styling so users with prefers-reduced-motion
do not see it by adding a media query for prefers-reduced-motion: reduce that
disables the animation (set animation to none and/or remove background-position
animation) for the SkeletonBannerWrapper while keeping the keyframes (shimmer)
for normal users; reference the shimmer keyframes and the SkeletonBannerWrapper
styled component to locate where to add the `@media` (prefers-reduced-motion:
reduce) rule.
In `@frontend/src/pages/MainPage/components/Banner/Banner.tsx`:
- Around line 84-89: The skeleton-loading branch inside the Banner component
(the isPending conditional that returns <Styled.BannerContainer> and
<Styled.SkeletonBannerWrapper />) should expose assistive-status attributes: add
role="status" and an appropriate aria-live (e.g., "polite") to the visible
loading container element (Styled.BannerContainer) and mark purely decorative
DOM inside the skeleton (Styled.SkeletonBannerWrapper) as aria-hidden="true";
ensure there is no duplicate live region elsewhere and that any textual loading
message is included but visually hidden for screen readers if needed.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: ad023ee4-41c4-45d6-8e57-6a99720e4885
📒 Files selected for processing (3)
frontend/docs/features/main/banner.mdfrontend/src/pages/MainPage/components/Banner/Banner.styles.tsfrontend/src/pages/MainPage/components/Banner/Banner.tsx
SkeletonOverlay를 BannerWrapper 위에 절대 위치로 얹어 API 응답 후 이미지 로딩 중에도 스켈레톤이 유지되도록 처리
Summary
isPending상태일 때null대신 shimmer 애니메이션 스켈레톤 UI 표시isLoading→isPending교체 (TanStack Query v5 권장 방식)SkeletonOverlay로 스켈레톤 유지스켈레톤 노출 흐름
isPendingSkeletonBannerWrapper(단독)SkeletonOverlay(BannerWrapper 위 절대 위치)onLoad발화Test plan
Jira
MOA-861