"use client";
import { motion } from "framer-motion";
import { Icon } from "@iconify/react";
interface IconWheelProps {
icons?: string[];
/** Wheel radius in px. Default: 110 */
radius?: number;
/** Rotation speed in seconds per full revolution. Default: 20 */
speed?: number;
centerIcon?: string;
}
const DEFAULT_ICONS = [
"solar:home-2-linear",
"solar:camera-linear",
"solar:settings-linear",
"solar:user-linear",
"solar:chart-linear",
"solar:messages-linear",
"solar:bell-linear",
"solar:star-linear",
];
export function IconWheel({
icons = DEFAULT_ICONS,
radius = 110,
speed = 20,
centerIcon = "solar:infinity-linear",
}: IconWheelProps) {
const angleStep = (2 * Math.PI) / icons.length;
return (
<div
className="relative flex items-center justify-center"
style={{ width: radius * 2 + 80, height: radius * 2 + 80 }}
aria-hidden="true"
>
{/* Orbit ring */}
<div
className="absolute rounded-full border border-dashed border-white/10"
style={{ width: radius * 2, height: radius * 2 }}
/>
{/* Rotating icons */}
<motion.div
animate={{ rotate: 360 }}
transition={{ duration: speed, repeat: Infinity, ease: "linear" }}
className="absolute"
style={{ width: radius * 2, height: radius * 2 }}
>
{icons.map((icon, i) => {
const angle = angleStep * i;
const x = radius + Math.cos(angle) * radius - 20;
const y = radius + Math.sin(angle) * radius - 20;
return (
<motion.div
key={icon}
className="absolute w-10 h-10 rounded-full bg-zinc-900 border border-white/10 flex items-center justify-center text-zinc-400 hover:text-indigo-400 hover:border-indigo-500/50 transition-colors cursor-pointer"
style={{ left: x, top: y }}
animate={{ rotate: -360 }} // Counter-rotate so icons stay upright
transition={{ duration: speed, repeat: Infinity, ease: "linear" }}
>
<Icon icon={icon} fontSize={18} />
</motion.div>
);
})}
</motion.div>
{/* Center */}
<div className="relative z-10 w-14 h-14 rounded-full bg-zinc-900 border border-white/20 flex items-center justify-center text-indigo-400 shadow-[0_0_30px_rgba(99,102,241,0.2)]">
<Icon icon={centerIcon} fontSize={24} />
</div>
</div>
);
}