macOS Dock
Featuredby Dax · tsx · 49 lines
A macOS-style dock where icons magnify as you hover near them. Each item scales based on its distance from the cursor, creating the iconic fish-eye effect. Uses framer-motion for smooth springs.
docknavigationmagnifyframer-motion
49 lines
"use client";
import { useRef } from "react";
import { motion, useMotionValue, useSpring, useTransform } from "framer-motion";
function DockItem({ icon, label, mouseX }: {
icon: string; label: string; mouseX: any;
}) {
const ref = useRef<HTMLDivElement>(null);
const distance = useTransform(mouseX, (val: number) => {
const rect = ref.current?.getBoundingClientRect();
return val - (rect ? rect.x + rect.width / 2 : 0);
});
const size = useSpring(
useTransform(distance, [-120, 0, 120], [48, 72, 48]),
{ mass: 0.1, stiffness: 200, damping: 12 }
);
return (
<motion.div
ref={ref}
style={{ width: size, height: size }}
className="flex items-center justify-center rounded-xl bg-white/10 text-2xl backdrop-blur-sm"
title={label}
>
{icon}
</motion.div>
);
}
export function Dock({ items }: {
items: { icon: string; label: string }[];
}) {
const mouseX = useMotionValue(Infinity);
return (
<motion.div
onMouseMove={(e) => mouseX.set(e.pageX)}
onMouseLeave={() => mouseX.set(Infinity)}
className="mx-auto flex items-end gap-2 rounded-2xl border border-white/10 bg-black/50 px-3 py-2 backdrop-blur-xl"
>
{items.map((item) => (
<DockItem key={item.label} {...item} mouseX={mouseX} />
))}
</motion.div>
);
}