Xzero UI
Pro library

Now playingPro

Grow a mini player into the full player in one continuous morph.

$ pnpm dlx shadcn@4.23.0 add @xzero-ui-pro/now-playing
Live · keyboard ready

When to use

When not to use

Installation

Register both Xzero UI namespaces in your project's components.json:

{
  "registries": {
    "@xzero-ui": "https://mcp.xzero.co.uk/r/{name}.json",
    "@xzero-ui-pro": "https://mcp.xzero.co.uk/r/pro/{name}.json"
  }
}
npx shadcn@4.23.0 add @xzero-ui-pro/now-playing

Install xzero-foundation once, and import @/components/xzero/foundation.css in your app root. No Xzero token is used by this snapshot. For sample portraits, photos, fonts, or logos, download https://mcp.xzero.co.uk/install-assets.mjs and run node xzero-install-assets.mjs <receiving-project>.

Usage

import { useRef, useState } from "react";
import { NowPlaying } from "@/components/xzero/now-playing/now-playing";

const tracks = [
  { id: "1", title: "Night Drive", artist: "Xzero Ensemble", duration: 212, artwork: "/covers/night-drive.jpg", src: "/audio/night-drive.mp3" },
  { id: "2", title: "Low Tide", artist: "Harbor", duration: 185, artwork: "/covers/low-tide.jpg", src: "/audio/low-tide.mp3" },
];

export function Player() {
  const audio = useRef<HTMLAudioElement>(null);
  const [index, setIndex] = useState(0);
  const [playing, setPlaying] = useState(false);
  const [time, setTime] = useState(0);

  return (
    <>
      <audio ref={audio} src={tracks[index].src} autoPlay={playing} onTimeUpdate={event => setTime(event.currentTarget.currentTime)} />
      <NowPlaying
        tracks={tracks}
        index={index}
        onIndexChange={setIndex}
        playing={playing}
        onPlayingChange={next => { setPlaying(next); if (next) audio.current?.play(); else audio.current?.pause(); }}
        currentTime={time}
        onSeek={seconds => { if (audio.current) audio.current.currentTime = seconds; }}
      />
    </>
  );
}

API reference

NowPlaying

A compact player that grows from a mini bar into a full player in one continuous morph, with a waveform scrubber and artwork that slides in the direction you skip.

PropTypeDefaultDescription
tracks (required){ id: string; title: string; artist: string; duration: number; artwork: string; artworkAlt?: string }[]–The queue. duration is in seconds.
indexnumber–Controlled position in the queue.
defaultIndexnumber0Initial position when uncontrolled.
onIndexChange(index: number) => void–Called when the track changes by skip or when a track ends. The queue wraps at both ends.
playingboolean–Controlled playback state.
defaultPlayingbooleanfalseInitial playback state when uncontrolled.
onPlayingChange(playing: boolean) => void–Called on play and pause.
currentTimenumber–Position in seconds from real audio, such as audio.currentTime on timeupdate. The built-in clock keeps the waveform moving between updates, and each new value corrects it. Ignored while the waveform is being dragged.
onSeek(seconds: number) => void–Called with the new position in seconds when a waveform drag ends, on each keyboard seek, and when Previous restarts the track. Set audio.currentTime here.
defaultExpandedbooleanfalseStarts as the full player.
labelstring"Now playing"Accessible name of the player section.
classNamestring–Extra class on the root.

NowPlayingLevels

Three small level bars that dance while a track plays and rest while paused.

PropTypeDefaultDescription
playing (required)boolean–Bars move only while true.
classNamestring–Extra class on the bars.

Keyboard interactions

KeysAction
Enter / SpaceExpands or collapses the player and activates play, pause, and skip.
ArrowLeft / ArrowRight / ArrowUp / ArrowDownOn the waveform, seeks 5 seconds back or forward.
PageUp / PageDownOn the waveform, seeks 30 seconds.
Home / EndOn the waveform, jumps to the start or end.
EscapeCollapses the full player.

Accessibility

Motion

Responsive behavior

Performance

Notes for AI

Also in audio and video

Guidance for AI tools

Now playing: Grow a mini player into the full player in one continuous morph. Follow the declared prop types and do not invent props. Keep keyboard access, reduced motion support, and both light and dark themes intact when adapting it.

Full library index: https://ui.xzero.co.uk/llms.txt

Browse all components