{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "primitive-swipe-to-dismiss",
  "type": "registry:ui",
  "title": "Swipe to dismiss",
  "description": "Map swipe distance to travel and opacity with resistance before the threshold.",
  "dependencies": [
    "motion"
  ],
  "categories": [
    "primitive",
    "feedback"
  ],
  "docs": "https://motion-lexicon.pages.dev/en/primitives/swipe-to-dismiss/",
  "files": [
    {
      "path": "src/registry/primitives/swipe-to-dismiss.tsx",
      "type": "registry:ui",
      "target": "components/motion-lexicon/primitives/swipe-to-dismiss.tsx",
      "content": "\"use client\";\n\nimport { AnimatePresence, motion, useMotionValue, useReducedMotion, useTransform, type PanInfo } from \"motion/react\";\nimport { useState, type ReactNode } from \"react\";\n\nexport type SwipeToDismissPrimitiveProps = {\n  children: ReactNode;\n  onDismiss?: () => void;\n  threshold?: number;\n  resistance?: number;\n  className?: string;\n};\n\nexport function SwipeToDismissPrimitive({\n  children,\n  onDismiss,\n  threshold = 96,\n  resistance = 0.65,\n  className,\n}: SwipeToDismissPrimitiveProps) {\n  const reduceMotion = useReducedMotion();\n  const x = useMotionValue(0);\n  const opacity = useTransform(x, [-threshold, 0, threshold], [0.15, 1, 0.15]);\n  const [present, setPresent] = useState(true);\n\n  const finish = (_event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => {\n    const dismiss = Math.abs(info.offset.x) >= threshold || Math.abs(info.velocity.x) > 520;\n    if (dismiss) {\n      setPresent(false);\n    }\n  };\n\n  return (\n    <AnimatePresence initial={false} onExitComplete={() => onDismiss?.()}>\n      {present ? (\n        <motion.div\n          className={className}\n          drag=\"x\"\n          dragConstraints={{ left: 0, right: 0 }}\n          dragElastic={Math.max(0.05, Math.min(0.9, 1 - resistance))}\n          dragMomentum={false}\n          style={{ x, opacity, touchAction: \"pan-y\" }}\n          onDragEnd={finish}\n          exit={reduceMotion\n            ? { opacity: 0 }\n            : { opacity: 0, transform: `translate3d(${x.get() < 0 ? -threshold : threshold}px, 0, 0)` }}\n          transition={reduceMotion ? { duration: 0 } : { type: \"spring\", stiffness: 360, damping: 32 }}\n        >\n          {children}\n        </motion.div>\n      ) : null}\n    </AnimatePresence>\n  );\n}\n"
    }
  ]
}
