Glow Button

Pill button with a spring-tracked light inside and mirrored edge glows that crossfade as the pointer changes sides. Vue port of MicroKit UI's Cursor Edge Glow Button.

Default

Move the pointer across the button. The light follows on a spring and the edge on the pointer's side lights up, then both stay where the pointer left.

Dark previewReplay previewOpen in new tab

Usage

Import the parts you need from the component's folder.

ts
import { GlowButton } from "@/components/ui/glow-button";

Sizes

sm, default and lg. The glow keeps the same spread at every size.

Dark previewReplay previewOpen in new tab

Colors

colorVariant picks a hand-tuned palette: ember, the original, or cyan. For any other color pass color for the glow and highlight for the inner light, and every other stop is derived from those two.

Dark previewReplay previewOpen in new tab

Theme

The surface adapts to the page. auto follows the nearest dark class, light and dark pin it for a background that never changes.

Dark previewReplay previewOpen in new tab
theme="light"
theme="dark"
theme="auto"

Secondary

variant="secondary" drops the glow and keeps the height, padding, radius and type, so a second action sits level with the first.

Dark previewReplay previewOpen in new tab

Spring

frequency sets how fast the light catches the pointer and damping how far it overshoots. Below 1 it bounces, 1 and above it settles.

Dark previewReplay previewOpen in new tab

Playground

Every knob on one panel. The snippet under the preview lists only what differs from the defaults.

Dark previewReplay previewOpen in new tab
Color
Size
Theme
Frequency
Damping
Glow rise
Edge saturation
Edge brightness
Hue shift
<GlowButton>See in action</GlowButton>

API Reference

GlowButton

PropTypeDefaultDescription
variant"default" | "secondary""default"default carries the glow. secondary is a plain translucent pill with the same geometry.
size"sm" | "default" | "lg""default"Height 32, 40 or 48px, with padding to match.
theme"auto" | "light" | "dark""auto"Surface palette. auto follows the nearest dark class; light and dark pin it.
colorVariant"ember" | "cyan""ember"Hand-tuned palette. color and highlight override it.
colorstring—Glow color, any CSS color. Overrides colorVariant.
highlightstring—Inner light and rim tint. Derived from color when unset.
arrowbooleantrueTrailing arrow after the label.
frequencynumber3.4Spring frequency in Hz. Higher catches the pointer faster.
dampingnumber0.78Damping ratio. Below 1 overshoots, 1 and above settles without bouncing.
glowRisenumber0.5Exponent on the edge opacity. Lower values light the edge sooner.
edgeSaturationnumber0.55Extra saturation on the lit edge at full travel.
edgeBrightnessnumber0.12Extra brightness on the lit edge at full travel.
hueShiftnumber-5Hue rotation on both edges, in degrees.
tostring—Renders a NuxtLink. External URLs get target _blank and rel noopener.
targetstring—Link target. Overrides the external default.
asstring"button"Element to render when to is empty.
disabledbooleanfalseDisables the button, or marks the link aria-disabled.
SlotDescription
defaultThe label. The arrow follows it when arrow is on.

Accessibility

Keyboard shortcuts and ARIA behavior.

  • Renders a native button, or a link when to is set, so Enter and Space behave as usual.
  • The edges, the surface and the light are aria-hidden with pointer-events none. Only the label is read and clicked.
  • Keyboard focus pulls the light to the centre, and the focus outline sits 8px out so it clears the glow.
  • With prefers-reduced-motion: reduce the light stays parked on the right edge and the spring never runs.