shadcn.io is not affiliated with official shadcn/ui
Music App Sidebar Block for React
A music player in a fixed-height window: four albums in Library and Discover, a now-playing card with play, shuffle and repeat and a CSS progress line, and the chosen album's drawn cover and track list.
Installation
Overview
Give a music app its shell with this music app sidebar for React with Base UI. A window framed by a hairline with a plus mark on each corner holds the Sidebar: four albums in Library and Discover, each a link named with its artist and track count, and a now-playing card in the footer with the track and artist, shuffle and repeat toggles, a play and pause button and a progress line. The line is one CSS animation that runs for the track's length while it plays and holds when you pause; it stays empty under reduced motion. The card says "No audio in this demo", because none plays. The page is the chosen album: a cover drawn in greyscale from plain shapes, its name, artist and length, and the track list, where a track's row plays it, and the top bar's Play album starts the first. It is built from Sidebar, Button, Avatar and Guides, with a CSS entrance only. Folded to icons the rail keeps the album icons with tooltips; below the medium breakpoint it is a sheet. For music, podcast and video players and any app with a persistent mini player.
FAQ
How does the progress line move?
It is a bar that slides in once over the track's length with a CSS animation (animate-in, with its duration set to the track's seconds), held at its last frame when the track ends. Play and pause switch the animation between running and paused, so pausing holds the line where it is rather than resetting it. Choosing another track remounts the bar so it starts again. Under reduced motion the bar stays empty and the play button, the status line and the track list still say what is playing. There is no timer and no audio element.
Does any audio play?
No. The card says "No audio in this demo" and the status line repeats it when you press play. The player is state: which track, whether it is playing, and the two toggles. To make it real, keep the card and attach your audio element to those states, and drive the progress line from its duration instead of the typed seconds.
What do shuffle and repeat do?
They are pressed buttons that keep their own state and say it in the status line ("Shuffle on."). With no audio there is no next track to choose, so they change nothing else here; in your app they would pick the next track and decide what happens at the end.
What stays in the page, and how do I connect it?
Everything: the four albums and their tracks are typed in ALBUMS, the chosen album and the playing track are the block's own state, and reloading starts over. The albums are links to # whose handler shows the album instead of navigating. They are SidebarMenuButtons with render set to an a element. Point them at your routes and mark the current one with isActive. The provider is set with persist={false} and shortcut={false}, so the block writes no cookie and leaves Ctrl and Command with B to the page it sits on.
How does it work on a phone?
Below the medium breakpoint the sidebar is a sheet that the menu button opens from the start edge, the right in a right-to-left layout. The now-playing card is in the sheet, so on the page the status line says what plays and the playing track is marked in the list. Choosing an album closes the sheet and focus goes back to the menu button.
Is it accessible?
The sidebar is a navigation landmark named after the product, with each group named by its label and the open album marked as the current page. The play button's name changes between Play and Pause, shuffle and repeat are pressed buttons, and the track list is an ordered list of buttons where the playing one is marked in words as well as by its icon. One polite status line reports each change, and the titles and times are isolated so they read right in a right-to-left layout.