{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "opacity-swapy",
  "dependencies": [
    "swapy"
  ],
  "devDependencies": [],
  "registryDependencies": [],
  "files": [
    {
      "path": "./registry/components/swapy/swapy-opacity.tsx",
      "content": "'use client';\nimport { DragHandle, SwapyItem, SwapyLayout, SwapySlot } from '@/components/ui/swapy';\nimport {\n  BarChart2,\n  Brain,\n  DollarSign,\n  Heart,\n  PlusCircle,\n  Sparkles,\n  Users,\n  Zap,\n} from 'lucide-react';\nimport { type ReactNode, useEffect, useMemo, useRef, useState } from 'react';\nimport { type SlotItemMapArray, Swapy, utils } from 'swapy';\n\ntype Item = {\n  id: string;\n  title: string;\n  icon: ReactNode;\n  bgColor: string;\n  className?: string;\n};\n\nconst initialItems: Item[] = [\n  {\n    id: '1',\n    icon: <Zap className='w-7 h-7 text-blue-600' />,\n    title: 'Streamline Operations',\n    bgColor: 'bg-blue-50',\n  },\n  {\n    id: '2',\n    icon: <BarChart2 className='w-7 h-7 text-pink-600' />,\n    title: 'Decision Making',\n    bgColor: 'bg-pink-50',\n  },\n  {\n    id: '3',\n    icon: <Users className='w-7 h-7 text-green-600' />,\n    title: 'Customer Experiences',\n    bgColor: 'bg-green-50',\n  },\n  {\n    id: '4',\n    icon: <Brain className='w-7 h-7 text-yellow-600' />,\n    title: 'Accelerate Innovation',\n    bgColor: 'bg-yellow-50',\n  },\n  {\n    id: '5',\n    icon: <DollarSign className='w-7 h-7 text-purple-600' />,\n    title: 'Reduce Costs',\n    bgColor: 'bg-purple-50',\n  },\n  {\n    id: '6',\n    icon: <Sparkles className='w-7 h-7 text-cyan-600' />,\n    title: 'Future-Proof',\n    bgColor: 'bg-cyan-50',\n  },\n];\n\nfunction SwapyOpacity() {\n  const [slotItemMap, setSlotItemMap] = useState<SlotItemMapArray>(\n    utils.initSlotItemMap(initialItems, 'id')\n  );\n\n  const slottedItems = useMemo(\n    () => utils.toSlottedItems(initialItems, 'id', slotItemMap),\n    [initialItems, slotItemMap]\n  );\n\n  return (\n    <SwapyLayout\n      id='swapy'\n      className='w-full'\n      config={{\n        swapMode: 'hover',\n      }}\n      onSwap={(event) => {\n        console.log('Swap detected!', event.newSlotItemMap.asArray);\n      }}\n    >\n      <div className='w-96 mx-auto  space-y-2'>\n        {slottedItems.map(({ itemId }) => {\n          const item = initialItems.find((i) => i.id === itemId);\n          return (\n            <SwapySlot\n              key={itemId}\n              className={`swapyItem rounded-lg  ${item?.className}`}\n              id={itemId}\n            >\n              <SwapyItem\n                id={itemId}\n                dragItemOpacity={50}\n                className={`relative flex p-4 w-full items-center  rounded-lg gap-5 h-full border border-dashed border-neutral-300  ${item?.bgColor}`}\n              >\n                <div className={`rounded-full flex items-center justify-center`}>{item?.icon}</div>\n                <h3 className='text-xl text-neutral-900 font-medium '>{item?.title}</h3>\n              </SwapyItem>\n            </SwapySlot>\n          );\n        })}\n      </div>\n    </SwapyLayout>\n  );\n}\n\nexport default SwapyOpacity;\n",
      "type": "registry:component"
    },
    {
      "path": "./components/ui/swapy.tsx",
      "content": "'use client';\n\nimport { cn } from '@/lib/utils';\nimport type React from 'react';\nimport { useEffect, useRef } from 'react';\nimport { type SlotItemMapArray, createSwapy } from 'swapy';\n\ntype AnimationType = 'dynamic' | 'spring' | 'none';\ntype SwapMode = 'hover' | 'drop';\n\ntype Config = {\n  animation: AnimationType;\n  continuousMode: boolean;\n  manualSwap: boolean;\n  swapMode: SwapMode;\n  autoScrollOnDrag: boolean;\n};\n\ntype SwapyLayoutProps = {\n  id: string;\n  enable?: boolean;\n  onSwap?: (event: { newSlotItemMap: { asArray: SlotItemMapArray } }) => void;\n  config?: Partial<Config>;\n  className?: string;\n  children: React.ReactNode;\n};\n\nexport const SwapyLayout = ({ id, onSwap, config = {}, className, children }: SwapyLayoutProps) => {\n  const containerRef = useRef<HTMLDivElement | null>(null);\n  const swapyRef = useRef<ReturnType<typeof createSwapy> | null>(null);\n\n  useEffect(() => {\n    const container = containerRef.current;\n    if (!container) return;\n\n    swapyRef.current = createSwapy(container, config);\n\n    if (onSwap) {\n      swapyRef.current.onSwap(onSwap);\n    }\n\n    return () => {\n      swapyRef.current?.destroy();\n    };\n  }, [config, onSwap]);\n\n  return (\n    <div id={id} ref={containerRef} className={className}>\n      {children}\n    </div>\n  );\n};\n\nexport const DragHandle = ({ className }: { className?: string }) => {\n  return (\n    <div\n      data-swapy-handle\n      className={cn(\n        'absolute top-2 left-2 cursor-grab  text-neutral-500  rounded-md bg-transparent  active:cursor-grabbing  ',\n        className\n      )}\n    >\n      <svg\n        xmlns='http://www.w3.org/2000/svg'\n        width='24'\n        height='24'\n        viewBox='0 0 24 24'\n        fill='none'\n        stroke='currentColor'\n        strokeWidth='2'\n        strokeLinecap='round'\n        strokeLinejoin='round'\n        className='lucide lucide-grip-vertical-icon lucide-grip-vertical opacity-80'\n      >\n        <circle cx='9' cy='12' r='1' />\n        <circle cx='9' cy='5' r='1' />\n        <circle cx='9' cy='19' r='1' />\n        <circle cx='15' cy='12' r='1' />\n        <circle cx='15' cy='5' r='1' />\n        <circle cx='15' cy='19' r='1' />\n      </svg>\n    </div>\n  );\n};\n\nexport const SwapySlot = ({\n  id,\n  className,\n  children,\n}: {\n  id: string;\n  className?: string;\n  children: React.ReactNode;\n}) => {\n  return (\n    <div\n      className={cn(\n        'data-swapy-highlighted:bg-neutral-200 dark:data-swapy-highlighted:bg-neutral-800',\n        className\n      )}\n      data-swapy-slot={id}\n    >\n      {children}\n    </div>\n  );\n};\n\nconst dragOpacityClassMap: Record<number, string> = {\n  10: 'data-swapy-dragging:opacity-10',\n  20: 'data-swapy-dragging:opacity-20',\n  30: 'data-swapy-dragging:opacity-30',\n  40: 'data-swapy-dragging:opacity-40',\n  50: 'data-swapy-dragging:opacity-50',\n  60: 'data-swapy-dragging:opacity-60',\n  70: 'data-swapy-dragging:opacity-70',\n  80: 'data-swapy-dragging:opacity-80',\n  90: 'data-swapy-dragging:opacity-90',\n  100: 'data-swapy-dragging:opacity-100',\n};\n\nexport const SwapyItem = ({\n  id,\n  className,\n  children,\n  dragItemOpacity = 100, // default to 100\n}: {\n  id: string;\n  className?: string;\n  children: React.ReactNode;\n  dragItemOpacity?: number;\n}) => {\n  const opacityClass = dragOpacityClassMap[dragItemOpacity] ?? 'data-swapy-dragging:opacity-50';\n  return (\n    <div className={cn(opacityClass, className)} data-swapy-item={id}>\n      {children}\n    </div>\n  );\n};\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component"
}