cursor-status

by Nurlan Yusifli @yuskraft

A status pill that follows the pointer during a gesture, with feedback right where your eyes already are. One web component, no dependencies, under 4.5 kB gzipped.

npm i @yuskraft/cursor-status
GitHub

API

<cursor-status></cursor-status>
<script type="module">
  import '@yuskraft/cursor-status/define';
  const status = document.querySelector('cursor-status');

  status.show('Removing 3 files', { kind: 'progress', progress: 0, dots: true });
  status.progress = 0.4;              // springs smoothly
  status.success('Removed 3 files');  // ring → check, lingers, fades
</script>

With shadcn

A React wrapper and a useCursorStatus() hook, with the tokens mapped to your theme.

npx shadcn@latest add https://yuskraft.github.io/cursor-status/r/cursor-status.json

Attributes

Each one is reflected as a property of the same name.

AttributeValuesDefaultMeaning
kindinfo progress success errorinfoIcon and colour treatment
labelstring''Text shown; changes animate
progress0–10Ring fill for progress; springs
dotsbooleanfalseAnimated trailing “…”
iconnone plus ring check crossby kindOverride the icon
openbooleanfalseVisible or not; show() and hide() set it
followpointer manualpointerTrack the pointer, or position with moveTo()
scopeCSS selectordocumentOnly follow and stay visible while the pointer is inside
placementbottom-end bottom-start top-end top-startbottom-endSide of the cursor; logical, so it flips in RTL
offset"x y" px"18 20"Gap from the cursor
lingerms1100How long a success stays after the gesture ends
themelight darksystemForce a theme
motionreducesystemForce reduced motion
stiffnessnumber16Follow spring ω

Methods

MethodDoes
show(label, opts?)Show, or morph if visible. opts: kind, progress, dots, icon.
info(label, opts?)show() with kind: 'info'
error(label, opts?)show() with kind: 'error'
success(label?, opts?)Ring → check; stays until linger ms after the gesture ends, then fades
flash(label, opts?)One-shot: show, succeed, fade
hide({ delay }?)Fade out, optionally later
moveTo(x, y)Position in client px, for follow="manual" or to anchor at a drop point
announce(text)Say something through the polite live region

Events

EventWhen
cursor-status:shownThe pill appeared on screen. Bubbles.
cursor-status:hiddenThe pill started to disappear. Bubbles.

Theming

Custom properties on the element. It ships dark and light variants: the light one follows prefers-color-scheme, or force either with theme="light|dark". Style the internals with ::part(pill), ::part(icon) and ::part(label).

TokenDefault

Accessibility

  • It’s supplementary. The pill shows how a gesture is going; the real outcome must also show up in the UI (the row disappears, the file appears in the list).
  • Screen readers hear results, not ticks. The visual pill is aria-hidden; state changes and final results go to a polite live region inside the element.
  • Keyboard and touch. Every demo here also works from the keyboard. On touch, the pill sits above the finger. Use follow="manual" with moveTo() to anchor it to a focused control.
  • Reduced motion snaps position and keeps only the fade. Forced colours switch to system colours with a visible border.
  • Contrast of the text on both default surfaces is above 4.5:1, even over white or black.