{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "barswave",
  "type": "registry:ui",
  "title": "BarsWave",
  "description": "Vertical wave bars animate in symmetry, forming a subtle motion-driven background layer.",
  "author": "Ahdeetai <https://aditya.is-cool.dev>",
  "registryDependencies": [],
  "dependencies": ["motion", "clsx", "tailwind-merge"],
  "files": [
    {
      "type": "registry:ui",
      "path": "components/ui/barswave.tsx",
      "content": "'use client';\nimport React, { useState } from 'react';\nimport { motion } from 'motion/react';\nimport { cn } from '@/lib/utils';\n\ninterface BarsWaveProps {\n  barCount?: number;\n  minHeight?: number;\n  maxHeight?: number;\n  fillColor?: string;\n  borderColor?: string;\n  barOpacity?: number;\n  animationDuration?: number;\n  variant?: 'filled' | 'outlined';\n  className?: string;\n  children?: React.ReactNode;\n}\n\nexport function BarsWave({\n  barCount = 15,\n  minHeight = 15,\n  maxHeight = 85,\n  fillColor,\n  borderColor,\n  barOpacity = 1,\n  animationDuration = 3,\n  variant = 'outlined',\n  className,\n  children,\n}: BarsWaveProps) {\n  const halfCount = Math.ceil(barCount / 2);\n\n  const [barAnimations] = useState(() => {\n    return Array.from({ length: halfCount }, (_, i) => {\n      const heights = [\n        Math.random() * (maxHeight - minHeight) + minHeight,\n        Math.random() * (maxHeight - minHeight) + minHeight,\n        Math.random() * (maxHeight - minHeight) + minHeight,\n      ];\n\n      return {\n        id: i,\n        heights: [...heights, heights[0]],\n        delay: Math.random() * 2,\n        duration: animationDuration + Math.random() * 2,\n      };\n    });\n  });\n\n  const allBars = React.useMemo(() => {\n    const leftBars = barAnimations.map((bar, i) => ({\n      ...bar,\n      id: `left-${i}`,\n      position: i,\n    }));\n\n    const rightBars = [...barAnimations].reverse().map((bar, i) => ({\n      ...bar,\n      id: `right-${i}`,\n      position: halfCount + i,\n    }));\n\n    return [...leftBars, ...rightBars].slice(0, barCount);\n  }, [barAnimations, halfCount, barCount]);\n\n  return (\n    <div className={cn('relative overflow-hidden', className)}>\n      <div className='absolute inset-0 flex items-end justify-around gap-1 px-4'>\n        {allBars.map((bar) => (\n          <motion.div\n            key={bar.id}\n            className={cn(\n              'w-full max-w-20 rounded-t-md',\n              variant === 'filled'\n                ? 'bg-gray-900/10 dark:bg-white/10'\n                : 'bg-transparent border-2 border-gray-900/20 dark:border-white/20',\n            )}\n            style={{\n              ...(fillColor &&\n                variant === 'filled' && { backgroundColor: fillColor }),\n              ...(borderColor &&\n                variant === 'outlined' && { borderColor: borderColor }),\n              opacity: barOpacity,\n            }}\n            initial={{ height: `${bar.heights[0]}%` }}\n            animate={{\n              height: bar.heights.map((h) => `${h}%`),\n            }}\n            transition={{\n              duration: bar.duration,\n              delay: bar.delay,\n              repeat: Infinity,\n              ease: 'easeInOut',\n            }}\n          />\n        ))}\n      </div>\n\n      {children && <div className='relative z-10'>{children}</div>}\n    </div>\n  );\n}\n"
    },
    {
      "type": "registry:lib",
      "path": "lib/utils.ts",
      "content": "import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs));\n}"
    }
  ]
}
