Magnetic Button
Pulled toward the cursor, with a label that leads.
Have something in mind?
Taking on two projects for July through September.
Installation
npx shadcn@latest add https://neonkit.heyaadi.com/r/magnetic-button.jsonUsage
import { MagneticButton } from "@/components/ui/magnetic-button"
<MagneticButton variant="solid" size="lg">Start a conversation</MagneticButton>Examples
Icon links
Round icon buttons rendered as links with asChild.
Strength and reach
radius is how far beyond the edge the pull starts; strength is how much of the pointer's offset the button follows.
As a link
API reference
Also accepts every native button attribute. The ref points at the button (or the asChild element).
| Prop | Type | Default |
|---|---|---|
radius | numberPixels beyond the button's edge where the pull begins. It eases in from zero at that distance. | 56 |
strength | numberShare of the pointer's offset from center the button follows, capped at about a third of its height. | 0.2 |
labelStrength | numberHow much further the label travels than the button, as a share of the button's offset. | 0.3 |
variant | "outline"The same faces as Button. | "outline" |
size | "sm"32, 40 or 48px tall like Button; icon is a 40px circle. | "md" |
color | NeonColorPalette name or hex. Falls back to --neon-accent, then cyan. | inherited |
asChild | booleanRender the child element (a link, say) as the magnet and merge props onto it. | false |
disabled | booleanDims the button, blocks clicks and switches the pull off. | false |
Accessibility
- The pull only runs for a mouse or pen on devices that can hover. Touch gets a plain button.
- Under prefers-reduced-motion the button stays put.
- The offset uses the CSS translate property, so it never fights the press scale or your own transforms.
- Motion runs on a small spring in requestAnimationFrame with direct style writes; React does not re-render while it moves.