Now Playing Sheet
常駐底部的迷你播放列,點按後封面以共享元素放大、整層彈簧展開為全螢幕播放頁,下拉依手勢速度回收。
載入預覽⋯
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
<NowPlayingSheet />
安裝
npx shadcn@latest add https://webberui.com/r/now-playing-sheet.json或在 components.json 設定 registries 後,改用 @webberui/now-playing-sheet 安裝。
安裝依賴後,從 registry JSON(/r/now-playing-sheet.json 的 files[0].content)複製 now-playing-sheet.tsx 原始碼到你的 components/ui/ 目錄:
npm install motion lucide-react clsx tailwind-merge使用
NowPlayingSheet 自身即是一個定位容器:把應用內容以 children 傳入(會被固定在底部的迷你列覆蓋一段內距),迷你列與全螢幕播放頁共用同一份 track。
import { NowPlayingSheet } from "@/components/ui/now-playing-sheet";
<div className="relative h-[560px] w-full max-w-sm overflow-hidden rounded-3xl">
<NowPlayingSheet
className="size-full"
track={{
title: "霓虹漫遊",
artist: "夜行電流",
album: "午夜循環",
artwork: <img src="/cover.jpg" alt="" />,
duration: 214,
}}
defaultPlaying
onNext={() => {}}
onPrevious={() => {}}
>
{/* 你的應用內容 */}
</NowPlayingSheet>
</div>;展開/播放/進度皆支援受控與非受控雙模式:傳入 open、playing 或 progress 即進入受控,否則由元件內部管理;未受控且播放中時,進度會依 track.duration 自動前進。
NowPlayingTrack
| 欄位 | 型別 | 說明 |
|---|---|---|
title | string | 曲名 |
artist | string | 演出者 |
album | string | 專輯/情境標題(展開頁頂部顯示) |
artwork | React.ReactNode | 封面內容(<img>、漸層 <div> 或任意節點);省略時顯示中性漸層佔位 |
duration | number | 曲目總長度(秒),用於時間標籤與自動前進 |
Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
track | NowPlayingTrack | — | 目前播放的曲目資料 |
children | React.ReactNode | — | 迷你列上方的應用內容(可捲動區) |
open | boolean | — | 受控展開狀態 |
defaultOpen | boolean | false | 非受控初始展開狀態 |
onOpenChange | (open: boolean) => void | — | 展開狀態變更回呼 |
playing | boolean | — | 受控播放狀態 |
defaultPlaying | boolean | false | 非受控初始播放狀態 |
onPlayingChange | (playing: boolean) => void | — | 播放狀態變更回呼 |
progress | number | — | 受控播放進度(0–1);提供時停用自動前進 |
onProgressChange | (progress: number) => void | — | 進度變更回呼 |
onPrevious | () => void | — | 點按「上一首」 |
onNext | () => void | — | 點按「下一首」 |
className | string | — | 追加到最外層 stage 容器(設定尺寸/圓角/背景) |
細節
- 共享元素放大:迷你列與播放頁的封面共用同一
layoutId,展開/收合時由 Motion 執行無縫形變;整個播放列亦共用另一layoutId,從底部矩形彈簧展開為全螢幕層。 - 手勢回收:全螢幕層可向下拖曳,放開時位移超過 120px 或速度超過 600px/s 即收合,否則彈回原位。
- 進度條:可點按、拖曳,或以方向鍵 /
Home/End調整(每步 5 秒或 2%)。 - 自動前進:未受控且播放中時,進度依
track.duration每 250ms 前進,到結尾停止;計時器於卸載與狀態變更時清除。
可及性
- 迷你列封面區為
aria-expanded的展開鈕,全螢幕層為role="dialog"並以曲名aria-labelledby標記。 - 展開時
Escape收合、焦點移入播放頁;收合後焦點歸還迷你列。展開時迷你列以inert移出焦點序列。 - 進度條為
role="slider",具aria-valuenow與aria-valuetext;播放/暫停與隨機/循環按鈕皆有aria-label與aria-pressed。 - 使用者開啟「減少動態效果」時,停用形變位移與拖曳,改以短暫淡入淡出呈現。