{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "primitive-origin-aware-animation",
  "type": "registry:ui",
  "title": "Origin-aware animation",
  "description": "Expand or scale from the trigger point to preserve spatial continuity.",
  "dependencies": [
    "motion"
  ],
  "categories": [
    "primitive",
    "transforms"
  ],
  "docs": "https://motion-lexicon.pages.dev/en/primitives/origin-aware-animation/",
  "files": [
    {
      "path": "src/registry/primitives/origin-aware-animation.tsx",
      "type": "registry:ui",
      "target": "components/motion-lexicon/primitives/origin-aware-animation.tsx",
      "content": "\"use client\";\n\nimport { AnimatePresence, motion, useReducedMotion, type Transition } from \"motion/react\";\nimport type { ReactNode } from \"react\";\n\nconst EASE_OUT = [0.23, 1, 0.32, 1] as const;\n\nexport type MotionOrigin = \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\" | \"center\";\n\nexport type OriginAwareAnimationPrimitiveProps = {\n  open: boolean;\n  children: ReactNode;\n  origin?: MotionOrigin;\n  startScale?: number;\n  duration?: number;\n  easing?: Transition[\"ease\"];\n  className?: string;\n};\n\nconst origins: Record<MotionOrigin, string> = {\n  \"top-left\": \"top left\",\n  \"top-right\": \"top right\",\n  \"bottom-left\": \"bottom left\",\n  \"bottom-right\": \"bottom right\",\n  center: \"center\",\n};\n\nexport function OriginAwareAnimationPrimitive({\n  open,\n  children,\n  origin = \"top-left\",\n  startScale = 0.88,\n  duration = 0.22,\n  easing = EASE_OUT,\n  className,\n}: OriginAwareAnimationPrimitiveProps) {\n  const reduceMotion = useReducedMotion();\n\n  return (\n    <AnimatePresence initial={false}>\n      {open ? (\n        <motion.div\n          className={className}\n          style={{ transformOrigin: origins[origin] }}\n          initial={reduceMotion ? { opacity: 0 } : { opacity: 0, transform: `scale(${startScale})` }}\n          animate={{ opacity: 1, transform: \"scale(1)\" }}\n          exit={reduceMotion ? { opacity: 0 } : { opacity: 0, transform: `scale(${startScale})` }}\n          transition={reduceMotion ? { duration: 0.12 } : { duration, ease: easing }}\n        >\n          {children}\n        </motion.div>\n      ) : null}\n    </AnimatePresence>\n  );\n}\n"
    }
  ]
}
