{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "core-audio-clip-wave-layer",
  "type": "registry:ui",
  "title": "Audio Clip Wave Layer",
  "description": "Audio Clip Wave Layer shared by module faces and application hosts.",
  "dependencies": [
    "maruaudio@>=0.0.3 <0.1.0"
  ],
  "registryDependencies": [
    "https://pluginui.com/r/core-audio-clip-player.json"
  ],
  "files": [
    {
      "path": "components/ui/audio-clip-wave-layer.tsx",
      "content": "/**\n * Source: https://maru.audio/ui-kit/audio-clip-wave-layer\n * Copyright © [Maru](https://maru.audio)\n *\n * Maru UI Kit — https://maru.audio/ui-kit\n *\n * Installed from the Maru UI registry. This file is yours now: edit it\n * freely, it will not be overwritten unless you re-run the add command.\n *\n * Keep this item’s companion files and CSS imports together. Dependencies\n * declared by the registry are installed with the source.\n */\nimport { useState, type ComponentProps, type CSSProperties } from \"react\"\nimport {\n  AudioClipWaveform,\n  AUDIO_WAVEFORM_PRESENTATIONS,\n} from \"@/components/ui/audio-clip-player\"\nimport type {\n  AudioPreviewWaveform,\n  AudioWaveformGridLine,\n} from \"maruaudio/ui/shared/audio-clip-waveform\"\n\nexport type WaveGridLine = AudioWaveformGridLine\n/** Shared list/inspector layer. Seeking, pointer capture and keyboard input\n * stay in AudioClipWaveform; this composes hover and musical grid overlays. */\nexport function AudioClipWaveLayer({\n  label,\n  waveform,\n  durationMs,\n  gridLines = [],\n  source,\n  className,\n  style,\n  ...control\n}: Omit<ComponentProps<typeof AudioClipWaveform>, \"variant\"> & {\n  label: string\n  waveform: AudioPreviewWaveform | null\n  durationMs?: number\n  gridLines?: readonly WaveGridLine[]\n  source?: string\n  className?: string\n  style?: CSSProperties\n}) {\n  const [hover, setHover] = useState<number | null>(null)\n  const height =\n    control.height ??\n    (control.presentation\n      ? AUDIO_WAVEFORM_PRESENTATIONS[control.presentation].height\n      : 32)\n  return (\n    <div\n      data-waveform={source ?? (waveform ? \"provided\" : \"unavailable\")}\n      data-waveform-presentation={control.presentation}\n      className={className}\n      style={{\n        position: \"relative\",\n        display: \"flex\",\n        alignItems: \"center\",\n        width: \"100%\",\n        minWidth: 0,\n        height,\n        ...style,\n      }}\n      onPointerMove={(event) => {\n        if (control.disabled) return\n        const box = event.currentTarget.getBoundingClientRect()\n        if (box.width > 0)\n          setHover(\n            Math.min(1, Math.max(0, (event.clientX - box.left) / box.width))\n          )\n      }}\n      onPointerLeave={() => setHover(null)}\n    >\n      {waveform ? (\n        <AudioClipWaveform\n          {...control}\n          height={height}\n          variant={{ label, waveform, durationMs }}\n        />\n      ) : (\n        <svg\n          role=\"img\"\n          aria-label=\"Waveform unavailable\"\n          width=\"100%\"\n          height={height}\n        >\n          <line\n            x1=\"0\"\n            x2=\"100%\"\n            y1=\"50%\"\n            y2=\"50%\"\n            stroke=\"currentColor\"\n            opacity={0.3}\n          />\n        </svg>\n      )}\n      {gridLines.map((line) => (\n        <span\n          key={line.fraction}\n          aria-hidden\n          style={{\n            pointerEvents: \"none\",\n            position: \"absolute\",\n            top: 0,\n            bottom: 0,\n            width: 1,\n            left: `${line.fraction * 100}%`,\n            background: \"currentColor\",\n            opacity: line.bar ? 0.18 : 0.1,\n          }}\n        />\n      ))}\n      {hover !== null && !control.disabled && (\n        <span\n          aria-hidden\n          style={{\n            pointerEvents: \"none\",\n            position: \"absolute\",\n            top: 0,\n            bottom: 0,\n            width: 1,\n            left: `${hover * 100}%`,\n            background: \"currentColor\",\n            opacity: 0.6,\n          }}\n        />\n      )}\n    </div>\n  )\n}\n",
      "type": "registry:component",
      "target": "@ui/audio-clip-wave-layer.tsx"
    }
  ]
}
