shadcn.io is not affiliated with official shadcn/ui
When you trigger it, the button swings left and right a few times, smaller each time, and settles in half a second. It's the same signal a phone gives for a wrong passcode.
Use it for a failed submit, a wrong password, or a step that can't go ahead yet, together with a message that says what went wrong. Don't use it as the only error signal: the shake is easy to miss and says nothing about the cause. For a press that should be confirmed rather than refused, use the Confetti Button. It wraps the Button, so variant and size work as usual. The shake is CSS keyframes, which the install adds to your stylesheet; each trigger swaps the button between two names of them, which restarts the shake. When the system asks for reduced motion, the button doesn't move: it flashes an outline in the destructive color instead.
Installation
Usage
import { ShakeButton } from "@/components/ui/shake-button";<ShakeButton shakeKey={failedAttempts}>Sign in</ShakeButton>Demos
Intensity
intensity sets how far the button swings each way: subtle is 2px, medium 4px and strong 7px, with medium by default. Press each one to compare. A subtle shake suits a small, inline button; a strong one suits a blocked, serious action.
Controlled
shake shakes the button once each time it turns true, and onShakeEnd is called when the shake is over, so you can set it back to false. Here a destructive button shakes when the action is refused, and a message under it says why. For repeated failures, shakeKey is simpler: it needs no reset.
Accessibility
The shake is visual only, and it isn't announced. Put the reason in text, near the button, in a live region such as aria-live="polite", so screen readers say it too, as the demos do. Enter and Space press the button as usual, and a shake started from the keyboard looks the same as one started by a pointer.
- Enter
- Activate the button.
- Space
- Activate the button.
FAQ
How do I trigger the shake?
Two ways. Change shakeKey, such as a count of failed attempts, and it shakes once per change, with nothing to reset. Or set shake to true, and set it back to false in onShakeEnd.
Can it shake again while it's still shaking?
Yes. A new shakeKey, or shake turning true again, restarts the shake from the beginning, so a quick second failure is never lost.
How do I make it shake harder or softer?
Set intensity to subtle (2px), medium (4px, the default) or strong (7px). The Intensity demo shows all three.
How long does a shake last?
Half a second, long enough to notice and short enough not to get in the way. onShakeEnd is called when the animation ends, not after a timer, so it's always in step with what's on screen.
API Reference
ShakeButton
focusableWhenDisabled?boolean
Whether the button should be focusable when disabled.
- Default
false
intensity?"subtle" | "medium" | "strong"
How far the button swings each way: subtle is 2px, medium 4px,
strong 7px.
- Type
"subtle" | "medium" | "strong"- Default
"medium"
nativeButton?boolean
Whether the component renders a native <button> element when replacing it
via the render prop.
Set to false if the rendered element is not a button (for example, <div>).
- Default
true
onShakeEnd?() → void
Called each time a shake has finished.
- Returns
void
shake?boolean
Shake once each time this turns true. Set it back to false in
onShakeEnd, or use shakeKey, which needs no reset.
- Default
false
shakeKey?number | string
Shake once each time this value changes, such as a count of failed attempts. The first value doesn't shake.
- Type
number | string
render?ReactElement | ((props: object, state: object) => ReactElement)
Replace the host element or compose it with another component.
- Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string
Merged with the part's classes.
data-shake?string
Mirrors wave.
--shake-button-distancestring
How far the button swings each way (4px).
Related
- Pro
Success Button
Progress & resultsThe opposite signal: it worked
Loading Button
Progress & resultsShow the wait before the result
- Pro
Long Press Button
ControlsGuard actions instead of refusing
- Pro
Confetti Button
Motion & feedbackCelebrate when it does go through
- Pro
Slide To Confirm Button
ControlsConfirm a risky action first
- Pro
Pulse Button
Motion & feedbackAnother attention signal