← All components

Dot + ring

A small dot pinned to the pointer with a larger ring chasing it. The gap between the two follow durations is the whole effect — there is no spring physics, just 0.15s against 0.6s.

Live props — bound to the real component

8
36
1.5
0.4
0.6
2.5

Install

npx shadcn@latest add @pointerui/dot-ring

Usage

app/page.tsx
import { CursorProvider } from "@/components/pointerui/provider";
import { DotRing } from "@/components/pointerui/dot-ring";

export default function Page() {
  return (
    <CursorProvider>
      <DotRing />

      <button data-cursor="grow">Hover me</button>
    </CursorProvider>
  );
}

Props

Generated from dot-ring/types.ts and the component's own defaults, so this table cannot drift from the code you are about to copy.

PropTypeDefaultDescription
dotSizenumber8

Diameter of the leading dot, in px.

ringSizenumber36

Diameter of the trailing ring, in px.

ringWidthnumber1.5

Ring stroke width, in px.

ringAlphanumber0.4

Ring stroke alpha, 0–1. The ring reads as a soft halo rather than a second hard outline, so it sits below the dot in visual weight.

Applied with color-mix rather than the element's opacity, which the reveal and hide tweens already own — setting both would make them fight.

colorstring"var(--cursor-color, currentColor)"

Any CSS colour. Defaults to the --cursor-color custom property, which itself falls back to currentColor — so a copy-pasted cursor is never invisible on a light background. Never hardcode a hex here.

lagnumber0.6

Ring follow duration in seconds. The gap between this and the dot's fixed 0.15s *is* the lag effect — there is no separate spring.

growScalenumber2.5

Ring scale while over a data-cursor="grow" target.

pressScalenumber0.85

Ring scale while the pointer is held down.

easestring"power4"

GSAP ease for the follow tween. Any ease string GSAP understands works — "power3", "expo.out", "circ", "none" for a linear follow.

This is the shape of the lag, where lag is its length. Changing it changes the character of the cursor more than any other prop.

Data attributes

Mark any element with one of these and this variant responds when the pointer enters it. Values it does not understand are ignored.

data-cursor="grow"
Scales the ring up while over the target.
data-cursor="hide"
Fades both layers out.

Notes & caveats

  • The dot and ring durations must stay different. Matching them removes the lag, which is the effect.
  • Ring alpha is applied with color-mix, not the element's opacity — the reveal and hide tweens already own that property, and setting both makes them fight.