shadcn.io is an independent project built on shadcn/ui
Buttons
ProPulse Button for Vue
Two rings pulse out from the button's edge, drawing the eye to the one action that matters. For Vue with Ark UI, for an onboarding step or upgrade.
Two thin rings leave the button's edge and fade as they spread, one after the other, in a loop. They take the button's corners at every size, pill included.
Use it for the single action you most want taken on a screen: start a trial, take the tour, finish setup. Keep it to one per page, and turn it off once it has done its job; a pulse that never stops turns into noise. For a glow that answers the pointer instead, use the Neon Button. It wraps the Button, so variant and size work as usual. The rings are CSS keyframes the install adds to your stylesheet, with no animation library. When the system asks for reduced motion they stop and one ring stays, still and faint.
Installation
Usage
<script setup lang="ts">
import { PulseButton } from "@/components/ui/pulse-button";
</script>
<template>
<PulseButton>Start free trial</PulseButton>
</template>
Demos
Stop After a Click
pulse turns the rings on and off. Here they stop once the button has been pressed, since it has been noticed by then. Driving it from state works the same way after a timeout, or once the section has scrolled out of view.
Color
The rings follow the variant: the primary color by default and the destructive color on a destructive button. pulseColor takes any CSS color for another one, here a quiet var(--muted-foreground) ring on an outline button.
Duration
duration is one ring's spread and fade in milliseconds; the default is 2000, and the second ring always runs half a cycle behind the first. A fast pulse, 1200 here, feels urgent; a slow one, 3200, is a gentle reminder.
Accessibility
The rings are decoration and hidden from assistive tech: the button is announced and activated as any Button. They hide while the button is disabled, so a pulse never points at something that can't be pressed.
- Enter
- Activate the button.
- Space
- Activate the button.
FAQ
How do I stop the pulse once it has been seen?
Set pulse={false}. Keep it in state and turn it off after the first click, a few seconds in, or when the user scrolls past, as in the Stop After a Click demo.
How do I change the rings' color?
Pass pulseColor, any CSS color such as var(--muted-foreground) or a hex code. Without it the rings are the primary color, or the destructive color on the destructive variant.
Can I make it pulse faster or slower?
Set duration in milliseconds; 2000 is the default. The second ring always runs half a cycle behind the first, as the Duration demo shows.
Do the rings follow rounded or pill buttons?
Yes. Each ring is a line on the button's own edge, with its corners, that grows outward, so it keeps the button's shape, pill included, at every size. It grows a little more up and down than across, so a wide button gets an even margin all round.
Will a pulse that loops forever slow the page down?
No. The keyframes only change each ring's scale and opacity, which the browser can hand to the compositor: no repaint, no re-render and no JavaScript while it runs.
Why are the rings cut off?
They spread a few pixels past the button. A parent with overflow: hidden and no room around the button cuts them; give it some padding.
API Reference
PulseButton
data-slot="pulse-button-rings"
children?VNode
The label; the rings pulse out around it.
clickEffect?boolean
Apply a click effect to the button.
- Default
true
duration?number
How long one ring takes to spread and fade, in milliseconds. The second ring is always half a cycle behind the first.
- Default
2000
isLoading?boolean
Show a loading indicator.
- Default
false
pulse?boolean
Run the rings. Turn it off once the button has been noticed: after the first click, or a few seconds in.
- Default
true
pulseColor?string
The rings' color, any CSS color. By default the primary color, or the destructive color on the destructive variant.
asChild?boolean
Use the provided child element as the default rendered element, combining their props and behavior.
class?string
Merged with the part's classes.
--pulse-button-colorstring
The rings' color.
--pulse-button-durationstring
One ring's spread and fade (2s).
--pulse-button-scalestring
How far a ring grows, across and down (1.1 1.35; 1.35 on an icon button).





