{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "compare",
  "type": "registry:component",
  "title": "Compare",
  "description": "Before/after clip-path wipe with pointer, keyboard, and slider-role support.",
  "dependencies": [],
  "registryDependencies": [
    "https://mocoui.site/r/tokens.json"
  ],
  "files": [
    {
      "path": "registry/compare/compare.tsx",
      "type": "registry:component",
      "target": "components/moco/compare.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport \"./compare.css\";\n\nexport interface CompareProps {\n  before: React.ReactNode;\n  after: React.ReactNode;\n  height?: number;\n  beforeLabel?: string;\n  afterLabel?: string;\n}\n\n/**\n * Before/after wipe. Works for images and for live DOM. Drag the handle,\n * click anywhere to position it, or focus it and use the arrow keys.\n */\nexport function Compare({\n  before,\n  after,\n  height = 300,\n  beforeLabel = \"before\",\n  afterLabel = \"after\",\n}: CompareProps) {\n  const [pct, setPct] = React.useState(50);\n  const box = React.useRef<HTMLDivElement>(null);\n  const dragging = React.useRef(false);\n\n  const setFromClientX = (x: number) => {\n    const el = box.current;\n    if (!el) return;\n    const r = el.getBoundingClientRect();\n    setPct(Math.min(100, Math.max(0, ((x - r.left) / r.width) * 100)));\n  };\n\n  return (\n    <div\n      ref={box}\n      className=\"moco-cmp\"\n      style={{ height }}\n      onPointerDown={(e) => {\n        dragging.current = true;\n        (e.currentTarget as HTMLElement).setPointerCapture(e.pointerId);\n        setFromClientX(e.clientX);\n      }}\n      onPointerMove={(e) => dragging.current && setFromClientX(e.clientX)}\n      onPointerUp={() => (dragging.current = false)}\n      onPointerCancel={() => (dragging.current = false)}\n    >\n      <span className=\"moco-cmp-label\" style={{ left: 12 }}>\n        {beforeLabel}\n      </span>\n      <span className=\"moco-cmp-label\" style={{ right: 12 }}>\n        {afterLabel}\n      </span>\n\n      <div style={{ position: \"absolute\", inset: 0 }}>{before}</div>\n      <div className=\"moco-cmp-after\" style={{ clipPath: `inset(0 0 0 ${pct}%)` }}>\n        {after}\n      </div>\n\n      <div className=\"moco-cmp-handle\" style={{ left: `${pct}%` }}>\n        <button\n          type=\"button\"\n          className=\"moco-cmp-grab\"\n          role=\"slider\"\n          aria-label={`Reveal ${afterLabel} over ${beforeLabel}`}\n          aria-valuemin={0}\n          aria-valuemax={100}\n          aria-valuenow={Math.round(pct)}\n          aria-valuetext={`${Math.round(pct)} percent`}\n          onKeyDown={(e) => {\n            if (e.key === \"ArrowLeft\") setPct((v) => Math.max(0, v - 4));\n            if (e.key === \"ArrowRight\") setPct((v) => Math.min(100, v + 4));\n            if (e.key === \"Home\") setPct(0);\n            if (e.key === \"End\") setPct(100);\n          }}\n        >\n          ⇄\n        </button>\n      </div>\n    </div>\n  );\n}\n"
    },
    {
      "path": "registry/compare/compare.css",
      "type": "registry:file",
      "target": "components/moco/compare.css",
      "content": ".moco-cmp {\n  position: relative;\n  overflow: hidden;\n  user-select: none;\n  touch-action: pan-y;\n  border: 1px solid var(--moco-line);\n  border-radius: 2px;\n  background: var(--moco-bg);\n}\n\n.moco-cmp-after {\n  position: absolute;\n  inset: 0;\n  overflow: hidden;\n  /* Opaque ground: without it, translucent `after` content lets the before\n     layer (and its text) bleed through the revealed side. */\n  background: var(--moco-bg);\n}\n\n.moco-cmp-handle {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  width: 1px;\n  background: var(--moco-accent-dk);\n  z-index: 4;\n}\n\n.moco-cmp-grab {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  transform: translate(-50%, -50%);\n  width: 22px;\n  height: 34px;\n  border: 1px solid var(--moco-accent-dk);\n  border-radius: 2px;\n  background: var(--moco-bg);\n  cursor: ew-resize;\n  display: grid;\n  place-items: center;\n  color: var(--moco-accent-dk);\n  font-size: 10px;\n}\n\n.moco-cmp-label {\n  position: absolute;\n  top: 8px;\n  font-size: 11px;\n  letter-spacing: 0.08em;\n  text-transform: uppercase;\n  color: var(--moco-faint);\n  z-index: 3;\n}\n"
    }
  ],
  "docs": "import { Compare } from \"./compare\";\n\nexport default function CompareDemo() {\n  return (\n    <Compare\n      height={220}\n      beforeLabel=\"draft\"\n      afterLabel=\"final\"\n      before={\n        <div\n          style={{\n            position: \"absolute\",\n            inset: 0,\n            display: \"grid\",\n            placeItems: \"center\",\n            background: \"var(--moco-panel)\",\n            color: \"var(--moco-muted)\",\n            fontFamily: \"var(--moco-mono)\",\n          }}\n        >\n          before\n        </div>\n      }\n      after={\n        <div\n          style={{\n            position: \"absolute\",\n            inset: 0,\n            display: \"grid\",\n            placeItems: \"center\",\n            background: \"var(--moco-accent-wash)\",\n            color: \"var(--moco-ink)\",\n            fontFamily: \"var(--moco-mono)\",\n          }}\n        >\n          after\n        </div>\n      }\n    />\n  );\n}\n",
  "meta": {
    "tags": [
      "figure",
      "interactive",
      "slider"
    ]
  }
}