{
  "title": "Swap",
  "description": "A flexible swap component that animates content changes with smooth customizable transition effects.",
  "name": "motion-swap",
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [],
  "type": "registry:ui",
  "files": [
    {
      "path": "components/paceui/motion/swap.tsx",
      "type": "registry:ui",
      "content": "import { type ComponentProps, type ReactNode, useMemo } from \"react\";\n\nimport { AnimatePresence, motion } from \"motion/react\";\n\nconst effectPresets = {\n    slideUp: { initial: { y: \"100%\" }, animate: { y: 0 }, exit: { y: \"-100%\" } },\n    slideDown: { initial: { y: \"-100%\" }, animate: { y: 0 }, exit: { y: \"100%\" } },\n    opacity: { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 } },\n    blur: { initial: { filter: \"blur(12px)\" }, animate: { filter: \"blur(0px)\" }, exit: { filter: \"blur(12px)\" } },\n    grayscale: {\n        initial: { filter: \"grayscale(100%)\" },\n        animate: { filter: \"grayscale(0%)\" },\n        exit: { filter: \"grayscale(100%)\" },\n    },\n    width: { initial: { width: 0 }, animate: { width: \"auto\" }, exit: { width: 0 } },\n} as const;\n\nexport type SwapProps<T> = Omit<ComponentProps<typeof motion.div>, \"children\"> & {\n    state: T;\n    children: (state: T) => ReactNode;\n    effects?: (keyof typeof effectPresets)[];\n    duration?: number;\n};\n\nconst combineEffects = (effects: (keyof typeof effectPresets)[]) => {\n    const result = { initial: {} as any, animate: {} as any, exit: {} as any };\n\n    for (const effect of effects) {\n        const preset = effectPresets[effect];\n        for (const phase of [\"initial\", \"animate\", \"exit\"] as const) {\n            for (const [key, value] of Object.entries(preset[phase])) {\n                if (key === \"filter\" && result[phase].filter) {\n                    result[phase].filter += ` ${value}`;\n                } else {\n                    result[phase][key] = value;\n                }\n            }\n        }\n    }\n\n    return result;\n};\n\nexport const Swap = <T extends any>({ state, children, duration = 0.4, effects = [], ...props }: SwapProps<T>) => {\n    const effectsKey = effects.join(\",\");\n    const variants = useMemo(() => combineEffects(effects), [effectsKey]);\n\n    return (\n        <motion.div\n            {...props}\n            style={{\n                display: \"inline-grid\",\n                position: \"relative\",\n                overflow: \"hidden\",\n                ...props.style,\n            }}>\n            <AnimatePresence mode=\"popLayout\" initial={false}>\n                <motion.div\n                    key={typeof state === \"object\" && state !== null ? JSON.stringify(state) : String(state)}\n                    initial={variants.initial}\n                    animate={variants.animate}\n                    exit={variants.exit}\n                    transition={{ duration, ease: \"easeInOut\" }}\n                    className=\"overflow-hidden\"\n                    style={{\n                        gridArea: \"1 / 1\",\n                        whiteSpace: \"nowrap\",\n                    }}>\n                    {children(state)}\n                </motion.div>\n            </AnimatePresence>\n        </motion.div>\n    );\n};\n"
    }
  ],
  "mcp": {
    "description": "Provides refined UI interactions and accessible controls. A flexible swap component that animates content changes with smooth customizable transition effects. Relies on motion. Optimal for building reusable interface elements and user input flows.",
    "tags": [
      "component",
      "motion",
      "animation"
    ]
  }
}