Motion UIComponentsComponent

Magnetic pull

An element that gently chases the pointer within a magnetic field, then springs back.

npx shadcn@latest add @motion/magnetic-pull

API reference

Components

<Magnetic />

Drop-in magnetic wrapper with padded field zone.

children?

ReactNode

Element to pull.

className?

string

Merged onto the field-zone wrapper.

<MagneticButton />

Styled compact-pill trigger for use inside Magnetic.

children?

ReactNode = "Get started"

Button label.

className?

string

Merged onto the button.

onClick?

() => void

Click handler.

type?

"button" | "submit" | "reset" = "button"

Button type. Default "button".

Hooks

useMagnetic

Magnetic-pull hook: springs, field handlers, reduced-motion gate.

useMagnetic(options: UseMagneticOptions): UseMagneticResult<T>

pullStrength?

number = DEFAULT_PULL_STRENGTH

Fraction of pointer offset applied as translate. Default 0.35.

maxPull?

number = DEFAULT_MAX_PULL

Hard clamp on displacement in px. Default 26.

Returns

ref

RefObject<T | null>

Ref for the pulled element.

style

{ x: MotionValue<number>; y: MotionValue<number> }

Motion style with smoothed x/y springs.

fieldProps

{ onPointerMove: (event: ReactPointerEvent<HTMLElement>) => void onPointerLeave: () => void }

Pointer handlers for the field zone wrapper.

motionAllowed

boolean

Whether pull is live (false under reduced motion).

Functions

magneticPull

Pure clamped magnetic displacement for one pointer move.

magneticPull(options: MagneticPullInput): { x: number; y: number }

pointer

{ x: number; y: number }

Pointer position in client coordinates.

rect

{ left: number; top: number; width: number; height: number }

Element bounding rect including current transform.

current

{ x: number; y: number }

Current translate so rest centre can be recovered from the live rect.

pullStrength

number

Fraction of offset from rest centre applied as translate.

maxPull

number

Hard clamp on displacement in px.