{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "wave-speed",
  "title": "Wave Speed",
  "description": "wave player with continuous playback speed control and preserve-pitch toggle.",
  "dependencies": [
    "wavesurfer.js",
    "lucide-react"
  ],
  "registryDependencies": [
    "@waves-cn/wave-cn",
    "button",
    "slider",
    "switch",
    "label"
  ],
  "files": [
    {
      "path": "src/registry/components/wave-speed.tsx",
      "content": "\"use client\";\n\nimport { useState, useId, type CSSProperties } from \"react\";\nimport { Button } from \"@/components/ui/button\";\nimport { Slider } from \"@/components/ui/slider\";\nimport { Switch } from \"@/components/ui/switch\";\nimport { Label } from \"@/components/ui/label\";\nimport { Play, Pause } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport WavesurferPlayer, { useWavePlayer } from \"@/lib/wave-cn\";\n\n/**\n * Props for the WaveSpeed component\n */\nexport type WaveSpeedProps = {\n  /** Audio source URL */\n  src?: string;\n  /** @deprecated use `src` */\n  url?: string;\n  /** Optional title shown above the waveform */\n  title?: string;\n  /** Audio bar color. Accepts any CSS value including var(--*) tokens @default \"var(--muted-foreground)\" */\n  waveColor?: string;\n  /** Progress bar color. Accepts any CSS value including var(--*) tokens @default \"var(--primary)\" */\n  progressColor?: string;\n  /** Waveform height in px @default 64 */\n  waveHeight?: number;\n  /** @deprecated use `waveHeight` */\n  audioHeight?: number;\n  /** Bar width in px @default 3 */\n  barWidth?: number;\n  /** Gap between bars in px @default 2 */\n  barGap?: number;\n  /** Bar border radius in px @default 2 */\n  barRadius?: number;\n  /** Minimum playback speed @default 0.25 */\n  minSpeed?: number;\n  /** Maximum playback speed @default 4 */\n  maxSpeed?: number;\n  /** Initial playback speed @default 1 */\n  defaultSpeed?: number;\n  /** Slider step increment @default 0.25 */\n  step?: number;\n  /** Called when playback starts */\n  onPlay?: () => void;\n  /** Called when playback pauses */\n  onPause?: () => void;\n  /** Called when playback finishes */\n  onFinish?: () => void;\n  /** Called with current time on every audio process tick */\n  onTimeUpdate?: (currentTime: number, duration: number) => void;\n  /** Root element class */\n  className?: string;\n  style?: CSSProperties;\n};\n\n/**\n * Audio player with variable playback speed control\n */\nexport function WaveSpeed({\n  src,\n  url,\n  title,\n  waveColor,\n  progressColor,\n  waveHeight,\n  audioHeight,\n  barWidth,\n  barGap,\n  barRadius,\n  minSpeed = 0.25,\n  maxSpeed = 4,\n  defaultSpeed = 1,\n  step = 0.25,\n  onPlay,\n  onPause,\n  onFinish,\n  onTimeUpdate,\n  className,\n  style,\n}: WaveSpeedProps) {\n  const source = src ?? url;\n  const height = waveHeight ?? audioHeight;\n\n  const player = useWavePlayer({ onPlay, onPause, onFinish, onTimeUpdate });\n  const pitchId = useId();\n\n  const [speed, setSpeed] = useState(defaultSpeed);\n  const [preservePitch, setPreservePitch] = useState(true);\n\n  const handleSpeedChange = ([value]: number[]) => {\n    setSpeed(value);\n    player.wavesurfer.current?.setPlaybackRate(value, preservePitch);\n  };\n\n  const handlePreservePitch = (checked: boolean) => {\n    setPreservePitch(checked);\n    player.wavesurfer.current?.setPlaybackRate(speed, checked);\n  };\n\n  return (\n    <div className={cn(\"w-full space-y-4\", className)} style={style}>\n      {title && (\n        <p className=\"text-sm font-medium text-foreground truncate\">{title}</p>\n      )}\n\n      {/* WavesurferPlayer renders the container div and wires up all events */}\n      <div className=\"w-full rounded-md overflow-hidden bg-muted/40\">\n        <WavesurferPlayer\n          url={source}\n          waveColor={waveColor}\n          progressColor={progressColor}\n          height={height}\n          barWidth={barWidth}\n          barGap={barGap}\n          barRadius={barRadius}\n          dragToSeek\n          {...player.handlers}\n        />\n      </div>\n\n      <div className=\"flex flex-wrap items-center gap-4\">\n        <Button\n          size=\"icon\"\n          onClick={player.togglePlay}\n          disabled={!player.isReady}\n          aria-label={player.isPlaying ? \"Pause\" : \"Play\"}\n        >\n          {player.isPlaying ? (\n            <Pause className=\"size-4\" />\n          ) : (\n            <Play className=\"size-4\" />\n          )}\n        </Button>\n\n        <span\n          role=\"status\"\n          aria-live=\"polite\"\n          className=\"inline-flex h-9 items-center rounded-md border bg-background px-4 text-sm text-muted-foreground tabular-nums shrink-0\"\n        >\n          Playback rate:{\" \"}\n          <span className=\"font-medium text-foreground\">\n            {speed.toFixed(2)}\n          </span>\n          x\n        </span>\n\n        <div className=\"flex items-center gap-3 flex-1 min-w-48\">\n          <span className=\"text-sm text-muted-foreground shrink-0\">\n            {minSpeed}x\n          </span>\n          <Slider\n            min={minSpeed}\n            max={maxSpeed}\n            step={step}\n            value={[speed]}\n            onValueChange={handleSpeedChange}\n            disabled={!player.isReady}\n            className=\"flex-1\"\n            aria-label=\"Playback speed\"\n          />\n          <span className=\"text-sm text-muted-foreground shrink-0\">\n            {maxSpeed}x\n          </span>\n        </div>\n\n        <div className=\"flex items-center gap-2\">\n          <Switch\n            id={pitchId}\n            checked={preservePitch}\n            onCheckedChange={handlePreservePitch}\n            disabled={!player.isReady}\n          />\n          <Label\n            htmlFor={pitchId}\n            className=\"text-sm text-muted-foreground cursor-pointer\"\n          >\n            Preserve pitch\n          </Label>\n        </div>\n      </div>\n    </div>\n  );\n}\n\nexport default WaveSpeed;\n",
      "type": "registry:component",
      "target": "components/waves-cn/wave-speed.tsx"
    }
  ],
  "type": "registry:component"
}