Skip to content

Pulse Button

A button with a soft ring that keeps radiating out, to draw the eye to the one action that matters now. Builds on Button.

Motionv0.1.0experimentalWCAG 2.2 AAView spec

Optional, and kept apart.

Nothing here is included in a project unless you add it, and the plain component it builds on is unchanged. This effect is decoration: it is hidden from screen readers, stands still for visitors who prefer reduced motion, and can be paused. Use Still on a preview to see that version.

import { PulseButton } from "@rdloom/react";

export default function PulseButtonBasicExample() {
  return (
    <PulseButton>Claim offer</PulseButton>
  );
}

Installation

npx rdloom add pulse-button

Copies the source into src/components/rdloom. Edit it freely: rdloom upgrade merges later versions into your changes.

It also adds rdloom-motion.css next to your tokens and imports it from the tokens file, once: no setup, and no inline styles. The plain components you already use are untouched.

Use another registry client
npx shadcn@latest add https://rdloom.vimalbhatt.com/r/pulse-button.json

Works, but without upgrade tracking, and you import the motion CSS yourself.

Usage

import { PulseButton } from "@rdloom/react";

<PulseButton>Claim offer</PulseButton>

Custom color

import { PulseButton } from "@rdloom/react";

export default function PulseButtonCustomColorExample() {
  return (
    <div className="flex flex-wrap items-center gap-6">
      <PulseButton color="var(--rd-color-feedback-success)" variant="secondary">
        Go live
      </PulseButton>
      <PulseButton color="var(--rd-color-feedback-danger)" variant="danger" duration={1.6}>
        Stop recording
      </PulseButton>
    </div>
  );
}

API Reference

Defined by the spec. Components also accept the props of the React Aria component they wrap.

PropTypeDefault
childrenrequired

Button label. Icon-only buttons must pass aria-label instead.

nodenone
variant

Visual emphasis, as on Button.

"primary" | "secondary" | "ghost" | "danger""primary"
size

Height, padding and font size, as on Button.

"sm" | "md" | "lg""md"
color

Colour of the ring, any CSS colour. Defaults to the action colour.

stringnone
duration

Seconds for one pulse.

number2
isPaused

Stops the animation. Moving content that lasts more than five seconds should be stoppable.

booleanfalse
isDisabled

Prevents interaction and dims the button.

booleanfalse
isLoading

Shows a spinner and blocks presses; the pending state is announced.

booleanfalse
onPress

Called when the button is pressed by mouse, touch or keyboard.

() => voidnone

Accessibility

Role button, WCAG 2.2 AA. Tested with axe and keyboard tests; screen reader checks are in the audit checklist.

Keyboard

  • Tab focuses it
  • Enter or Space presses it

Screen readers announce

  • Announced exactly as a Button: its label, as a button; the effect adds nothing to what is read

What your code must do

  • Decoration only: the animated layers are hidden from assistive technology and never take focus
  • Stands still for visitors who ask for less motion (prefers-reduced-motion), and the effect can also be shown still with the rdm-still class
  • The pulse is a box shadow outside the button, so it never changes the label's contrast
  • A disabled button stops pulsing
  • Does not flash: nothing changes more than three times in a second (WCAG 2.3.1)
  • Optional: it is a separate component, so projects that do not add it carry none of its code

Guidelines

Use it when

  • A time-limited offer or a step that is waiting on the user

Avoid it when

  • Anything that stays on screen for a long time: constant motion becomes noise

Don't

  • Pulsing several buttons at once
  • Using it where people are reading

Design tokens

The semantic tokens this component uses. Change them once and every component follows; see Design tokens.

  • --rd-color-action-primary
  • --rd-color-action-on-primary
  • --rd-color-action-danger
  • --rd-color-surface-default
  • --rd-color-text-default
  • --rd-color-border-default
  • --rd-color-focus-ring
  • --rd-radius-control