magnetic-dock
componentry/magnetic-dockFreeComponent
A macOS-style magnetic dock with smooth scaling animations, spring physics, and premium micro-interactions. Supports both light and dark modes.
Live preview
live · rendered by the registry
Rendered by componentry on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://componentry.dev/r/magnetic-dock.jsonSource
1"use client"23import * as React from "react"4import { motion, useMotionValue, useSpring, useTransform, AnimatePresence, type MotionValue } from "framer-motion"5import { cn } from "@/lib/utils"67interface MagneticDockProps {8 /** Array of dock items */9 items: DockItemData[]10 /** Size of icons in pixels */11 iconSize?: number12 /** Maximum scale on hover */13 maxScale?: number14 /** Distance of magnetic effect in pixels */15 magneticDistance?: number16 /** Show labels on hover */17 showLabels?: boolean18 /** Dock position */19 position?: "bottom" | "top" | "left" | "right"20 /** Background style */21 variant?: "glass" | "solid" | "transparent"22 /** Custom class name */23 className?: string24}2526interface DockItemData {27 /** Unique identifier */28 id: string29 /** Display label */30 label: string31 /** Icon component or image URL */32 icon: React.ReactNode33 /** Click handler */34 onClick?: () => void35 /** Whether item is active */36 isActive?: boolean37 /** Badge count */38 badge?: number39}4041interface DockItemProps {42 item: DockItemData43 mouseX: MotionValue<number>44 iconSize: number45 maxScale: number46 magneticDistance: number47 showLabels: boolean48 isVertical: boolean49}5051function DockItem({52 item,53 mouseX,54 iconSize,55 maxScale,56 magneticDistance,57 showLabels,58 isVertical,59}: DockItemProps) {60 const ref = React.useRef<HTMLButtonElement>(null)61 const [isHovered, setIsHovered] = React.useState(false)6263 // Calculate distance from mouse to center of item64 const distance = useTransform(mouseX, (val: number) => {65 if (!ref.current) return magneticDistance + 166 const rect = ref.current.getBoundingClientRect()67 const center = isVertical68 ? rect.top + rect.height / 269 : rect.left + rect.width / 270 return val - center71 })7273 // Scale based on distance - closer = larger74 const scale = useTransform(distance, [-magneticDistance, 0, magneticDistance], [1, maxScale, 1])7576 // Apply spring physics for smooth animation77 const springConfig = { damping: 20, stiffness: 300, mass: 0.5 }78 const smoothScale = useSpring(scale, springConfig)7980 // Calculate the size based on scale81 const size = useTransform(smoothScale, (s) => s * iconSize)8283 // Floating effect84 const y = useTransform(smoothScale, (s) => (s - 1) * -10)85 const smoothY = useSpring(y, springConfig)8687 return (88// … truncated
More from componentry
All 59 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Animated Gradientanimated-gradient | componentry | Components | Free | no deps | |
| ASCII Effectascii-effect | componentry | Components | Free | no deps | |
| Aurora Flowaurora-flow | componentry | Components | Free | no deps | |
| auth-modalauth-modal | componentry | Components | Free | no deps | |
| border-beamborder-beam | componentry | Components | Free | no deps | |
| circuit-boardcircuit-board | componentry | Components | Free | no deps | |
| closing-plasmaclosing-plasma | componentry | Components | Free | no deps | |
| collection-surfercollection-surfer | componentry | Components | Free | no deps |
