shadcn.io is not affiliated with official shadcn/ui
When the pointer arrives, the button takes keyboard focus or it's pressed, a diagonal band of light sweeps across it once, like a gleam on a polished surface. Leave and come back, and it sweeps again.
Use it on a pricing page's Upgrade button or a hero's main action, where a small reward for hovering fits. It's subtle enough for a serious product, and it doesn't loop. For light that keeps moving on its own, use the Shimmer Button. It wraps the Button, so every variant and size works. The sweep is a CSS keyframe animation the install adds to your stylesheet, with no JavaScript and no animation library; when the system asks for reduced motion, the light fades in where it stands instead of moving.
Installation
Usage
import { ShineButton } from "@/components/ui/shine-button";<ShineButton>Upgrade now</ShineButton>Demos
Color
shineColor takes any CSS color. By default the light is the label's color at a little over a third of its strength, which reads on every variant. Here an outline button shines in the primary color, and a filled one gets a brighter gleam from a stronger mix of its label color.
Duration
duration is how long one sweep takes to cross the button, in milliseconds; the default is 700. A quick sweep suits a small button, and a slow one a large hero button.
Accessibility
The light is decoration and hidden from assistive tech: the button is announced and activated as any Button. It sweeps on keyboard focus as well as on hover, so people who tab through the page see it too.
- Tab
- Move focus to the button; the light sweeps across.
- Enter
- Activate the button.
- Space
- Activate the button; the light sweeps while it's held.
FAQ
How do I make the shine stronger?
Pass a stronger color to shineColor, such as color-mix(in oklch, var(--primary-foreground) 70%, transparent). The Color demo does that on its second button.
Why doesn't the light sweep back when the pointer leaves?
On purpose: the sweep is an animation that runs while the hover lasts and ends with the band out of sight, and when the pointer leaves the band goes back unseen. So it only ever sweeps one way, the way a reflection does.
How do I change the speed?
Set duration in milliseconds, 700 by default, as in the Duration demo. It's written to a CSS variable on the button's light, --shine-button-duration, which the keyframes read.
Can it shine on a loop?
No, it sweeps once per hover or focus. For light that keeps moving on its own, use the Shimmer Button.
Does it shine on touch screens?
Touch screens have no hover, so the light sweeps while a finger presses the button: a long press shows the whole sweep, a quick tap only its start. The button works the same either way.
API Reference
ShineButton
children?ReactNode
The label, above the light.
duration?number
How long one sweep of light takes to cross the button, in milliseconds.
- Default
700
focusableWhenDisabled?boolean
Whether the button should be focusable when disabled.
- Default
false
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
shineColor?string
The light's color, any CSS color. By default it's the label's color at a little over a third of its strength, which reads on every variant.
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.
--shine-button-colorstring
The light's color.
--shine-button-durationstring
One sweep across the button (700ms).
Related
- Pro
Shimmer Button
SurfacesLight that keeps running
- Pro
Spotlight Button
Glow & lightLight that follows the cursor
- Pro
Gradient Button
SurfacesFill that keeps shifting
- Pro
Glass Button
SurfacesFrosted surface for imagery
- Pro
Glow Border Button
Glow & lightContinuous glow on the border
Magnetic Button
Motion & feedbackHover pull toward the cursor