{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "primitive-before-after-slider",
  "type": "registry:ui",
  "title": "Before / after slider",
  "description": "Compare before and after states of the same visual with a draggable divider.",
  "dependencies": [
    "motion"
  ],
  "categories": [
    "primitive",
    "polish-effects"
  ],
  "docs": "https://motion-lexicon.pages.dev/en/primitives/before-after-slider/",
  "files": [
    {
      "path": "src/registry/primitives/before-after-slider.tsx",
      "type": "registry:ui",
      "target": "components/motion-lexicon/primitives/before-after-slider.tsx",
      "content": "\"use client\";\n\nimport { motion, useReducedMotion } from \"motion/react\";\nimport { useEffect, useState, type ReactNode } from \"react\";\n\nexport type BeforeAfterSliderPrimitiveProps = {\n  before: ReactNode;\n  after: ReactNode;\n  initialPosition?: number;\n  duration?: number;\n  beforeLabel?: string;\n  afterLabel?: string;\n  className?: string;\n};\n\nexport function BeforeAfterSliderPrimitive({\n  before,\n  after,\n  initialPosition = 50,\n  duration = 0.18,\n  beforeLabel = \"Before\",\n  afterLabel = \"After\",\n  className,\n}: BeforeAfterSliderPrimitiveProps) {\n  const reduceMotion = useReducedMotion();\n  const [position, setPosition] = useState(() => Math.max(10, Math.min(90, initialPosition)));\n\n  useEffect(() => {\n    setPosition(Math.max(10, Math.min(90, initialPosition)));\n  }, [initialPosition]);\n\n  return (\n    <div className={`relative isolate overflow-hidden ${className ?? \"\"}`}>\n      <div className=\"absolute inset-0\" aria-label={afterLabel}>{after}</div>\n      <motion.div\n        className=\"absolute inset-0 overflow-hidden\"\n        aria-label={beforeLabel}\n        animate={{ clipPath: `inset(0 ${100 - position}% 0 0)` }}\n        transition={reduceMotion ? { duration: 0 } : { duration, ease: [0.23, 1, 0.32, 1] }}\n      >\n        <div className=\"size-full\">{before}</div>\n      </motion.div>\n      <motion.div\n        aria-hidden\n        className=\"pointer-events-none absolute inset-y-0 left-0 w-full origin-left border-l border-white shadow-[-1px_0_0_rgba(0,0,0,0.16)]\"\n        animate={{ transform: `translate3d(${position}%, 0, 0)` }}\n        transition={reduceMotion ? { duration: 0 } : { duration, ease: [0.23, 1, 0.32, 1] }}\n      />\n      <input\n        className=\"absolute inset-0 size-full cursor-ew-resize opacity-0\"\n        type=\"range\"\n        min=\"10\"\n        max=\"90\"\n        value={position}\n        aria-label={`${beforeLabel} / ${afterLabel}`}\n        onChange={(event) => setPosition(Number(event.target.value))}\n      />\n    </div>\n  );\n}\n"
    }
  ]
}
