fix: replace white scrollbar on artist page with chevron arrow carousel#29
Conversation
Replace the native overflow-x-auto scrollbar on the artist albums section with a hidden-scrollbar carousel matching the home page pattern. Left/right chevron arrow buttons appear dynamically based on scroll position. Closes #28 https://claude.ai/code/session_015duffePt3aymjzz7T84rEB
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Coverage Report
File Coverage
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Move the duplicated ScrollArrow component from PlaylistCarousel and ArtistDetail into a shared src/components/ui/ScrollArrow.tsx, eliminating code duplication flagged by SonarQube. https://claude.ai/code/session_015duffePt3aymjzz7T84rEB
There was a problem hiding this comment.
Pull request overview
Updates the Artist detail page’s Albums section to use a chevron-based horizontal carousel (matching the home page pattern) instead of relying on the native horizontal scrollbar.
Changes:
- Added scroll container ref + scroll/resize listeners to compute when left/right chevrons should appear.
- Introduced overlay chevron buttons that scroll the albums row smoothly by a fixed increment.
- Applied inline scrollbar-hiding styles to the albums scroll container.
Comments suppressed due to low confidence (2)
src/pages/ArtistDetail.tsx:129
scrollbarWidth: 'none'/msOverflowStyle: 'none'won’t hide the horizontal scrollbar on Chromium/WebKit browsers, so the “white scrollbar” issue will likely persist on Windows Chrome/Edge. Consider adding a CSS class that also targets::-webkit-scrollbar(e.g.,display: none/height: 0) and apply it to this scroll container.
src/pages/ArtistDetail.tsx:135- New carousel behavior (dynamic left/right chevrons + smooth scrolling) isn’t covered by the existing
ArtistDetailtests. Since this change is user-visible and stateful (scroll position -> arrow visibility), add tests asserting arrow presence/absence and that clicking the arrows callsscrollBy/updates scroll state.
);
}
| @@ -26,9 +58,6 @@ export default function ArtistDetail() { | |||
| ); | |||
| } | |||
|
|
|||
| const albums = (albumsData?.items ?? []).slice(0, 10); | |||
| const artistImage = artist.images?.[0]?.url; | |||
|
|
|||
| return ( | |||
| <div className="flex flex-col min-h-full" data-testid="artist-detail"> | |||
There was a problem hiding this comment.
The useEffect dependency is albums, but albums is created via .slice(0, 10) on every render, so this effect will re-run and rebind scroll/resize listeners on any re-render (including state updates from scrolling). Consider memoizing albums or changing the dependency to something stable (e.g., albumsData?.items or albums.length).
| const scrollRef = useRef<HTMLDivElement>(null); | ||
| const [canScrollLeft, setCanScrollLeft] = useState(false); | ||
| const [canScrollRight, setCanScrollRight] = useState(false); | ||
|
|
There was a problem hiding this comment.
This button should explicitly set type="button" to avoid defaulting to submit if the component ever ends up inside a form.
- Extract scroll state/effect logic into useCarouselScroll hook shared by PlaylistCarousel and ArtistDetail, eliminating code duplication - Fix useEffect dependency to use stable albumsData?.items instead of the albums array recreated on every render - Add type="button" to ScrollArrow button to prevent accidental form submit https://claude.ai/code/session_015duffePt3aymjzz7T84rEB
|



Summary
scrollbarWidth: none) and adds left/right chevron arrow buttons that appear dynamically based on scroll positionPlaylistCarousel)Closes #28
Test plan
ArtistDetailtests passhttps://claude.ai/code/session_015duffePt3aymjzz7T84rEB