NowPlaying
A media now-playing card: album art, title + artist, a scrub bar, and elapsed / remaining times. A status display for playback your app tracks — audio support in the Display webview is undocumented; verify on-device.
Platform wishlist — built and waiting on documented audio playback in the webview. The UI ships today; the day Meta exposes the API, it plugs in. See the wishlist →
Installation
npx @glasskit-ui/cli add now-playingInstall the SDK (it provides GlassViewport, useDpad and the stylesheet), then copy these files into your project:
npm install @glasskit-ui/react// components/lib/utils.tsexport type ClassValue = string | number | null | undefined | false;/** * Join truthy class names. Dependency-free on purpose: the lens components * style via bespoke semantic classes (no conflicting Tailwind utilities to * de-dupe), so this needs no clsx/tailwind-merge and resolves from anywhere * the registry is vendored. */export function cn(...inputs: ClassValue[]): string { return inputs.filter(Boolean).join(" ");}/** * Accessible name from a free-form `label` prop: the label itself when it's a * plain string, otherwise undefined (a ReactNode can't become an aria-label). */export function stringLabel(label: unknown): string | undefined { return typeof label === "string" ? label : undefined;}// components/glasskit/now-playing.tsximport type { ReactNode } from "react";import { cn } from "../lib/utils";/** * <NowPlaying> — a media "now playing" card: album art, title + artist, a * scrub bar, and elapsed / remaining times. The art is a node you pass (an * <img>, or a gradient tile for podcasts/radio). `progress` is 0–100. Pure * display; wire transport controls with <Button>s in `controls`. RTL-safe. * * Platform note (2026-06): Meta has not documented `<audio>` / Web Audio * support for Display web apps, and the glasses' own media player owns the * speakers. Treat this as a status display for playback your app tracks * (e.g. a server-side or phone session) — verify on-device before shipping * an app that plays audio in the webview. */export function NowPlaying({ art, title, artist, progress = 0, elapsed, remaining, controls, className,}: { /** Album art — an <img> or a gradient tile. */ art?: ReactNode; title: ReactNode; artist?: ReactNode; /** 0–100. */ progress?: number; elapsed?: ReactNode; remaining?: ReactNode; /** Optional transport row. */ controls?: ReactNode; className?: string;}) { const pct = Math.max(0, Math.min(progress, 100)); return ( <div className={cn("gk-nowplaying", className)}> <div className="gk-nowplaying__top"> {art != null ? <span className="gk-nowplaying__art">{art}</span> : null} <div className="gk-nowplaying__meta"> <span className="gk-nowplaying__title t-readout">{title}</span> {artist != null ? ( <span className="gk-nowplaying__artist t-body">{artist}</span> ) : null} </div> </div> <progress className="gk-nowplaying__bar gk-progress__el" value={pct} max={100} aria-label="Playback position" /> {elapsed != null || remaining != null ? ( <div className="gk-nowplaying__times t-caption"> <span>{elapsed}</span> <span>{remaining}</span> </div> ) : null} {controls != null ? ( <div className="gk-nowplaying__controls">{controls}</div> ) : null} </div> );}Usage
<NowPlaying art={<img src={cover} alt="" />} title="Midnight City" artist="M83" progress={42} elapsed="1:48" remaining="-2:31"/>Props
Prop
Type
MediaThumb
A photo / reel tile (Photos, Instagram): a rounded media tile with optional duration pill and caption overlay. Compose in a grid for a gallery.
AssistantOrb
The Meta-AI presence: a glowing gradient orb that animates per state — idle breathe, listening pulse, thinking swirl, speaking. Pair with a transcript line.