Border Beam
A comet of light that laps the border of your content.
Usage
BorderBeam is a <div> wrapper that traces a single comet of light around its own border: a bright
head with a tail fading to transparent, looping forever. The beam is painted as a conic sweep clipped to
a hairline ring, so it follows the wrapper's own border-radius exactly, from a subtle rounded-xl card
to a fully rounded pill, with no radius prop to keep in sync.
Give the wrapper the same size and radius as the content it wraps (that's what the beam traces) and tune
the look with color, length (how much of the lap the comet spans), thickness, and speed. The beam
layer is aria-hidden and pointer-events-none, so it never reaches assistive tech or intercepts
clicks, and the wrapper forwards className, style, and any native <div> attributes.
Examples
Basic beam
The default beam is a 1px comet in the --primary color, spanning 10% of the border and taking 5
seconds per lap. Match the wrapper's radius to your content's (rounded-2xl here) so the beam hugs the
corners.
Color
color takes any CSS color - a hex, rgb(), oklch(), or a design token - and becomes the bright head
of the gradient, which always fades to transparent along the tail. The default, var(--primary), is
near-black in light mode and white in dark mode, so it reads on either surface. For an accent, reach for
a token's -emphasis step (var(--success-emphasis)): those hold up against both a light and a dark
background, which the base step doesn't. Over a colored or dark child surface, pick a color with
contrast against that surface rather than against the page.
Length, thickness, and speed
length is a percentage of one lap rather than a pixel value, so a comet keeps its proportions whatever
the element's size: a small value reads as a traveling spark, a large one as a long sweeping streak.
thickness is in px, and speed is the seconds one lap takes.
Staggering a group
A row of beams starting together looks mechanical. Pass a negative delay to start a beam mid-lap, which
spreads a group out around its own cycle.
Reveal on interaction
Set revealOn to keep the beam hidden until an interaction, then fade it in (the beam resumes from
paused, so it always starts its lap from the top). Accepts 'hover' (pointer-only, like Tailwind's
hover: variant) and 'press' (works on touch), or an array to combine them. Since 'hover' can't fire
on touch, opt into showOnTouch to keep the beam persistently visible there instead of hidden. Add
pressScale so the beam shrinks with a button's own active-press scale.
Controlled (loading state)
For event-driven states (a request in flight, a deploy running) drive the beam with the controlled
reveal boolean instead. It's OR-ed with any revealOn interaction, so you can combine "beam on hover"
with "beam while loading". Click the button to kick off a mock request.
RTL
Every Appica UI component supports right-to-left layouts out of the box. Set the dir attribute on a container (commonly your <html> element) so CSS logical properties resolve correctly, and wrap your tree in DirectionProvider so direction-aware behavior follows the same direction.
The beam is mirrored under dir="rtl", so it laps counterclockwise and still leads with its bright head,
matching the reading direction. No prop is involved; the layer follows the dir attribute. For setup
details and caveats, see the RTL guide.
جارٍ تحليل بياناتك
يمسح الشعاع حدود البطاقة عكس عقارب الساعة في التخطيط من اليمين إلى اليسار.
API reference
BorderBeam renders a <div> and forwards every remaining native <div> attribute. The beam layer is
aria-hidden and pointer-events-none.
Accessibility
- The beam layer is
aria-hiddenandpointer-events-none, so it's skipped by assistive tech and never intercepts clicks. - Content is wrapped, not replaced - your
childrenstay in the normal flow and fully accessible. - The motion honors
prefers-reduced-motion: a looping beam has no static resting state to fall back to, so the layer is hidden entirely for reduced-motion users rather than parked at one corner. Never make the beam the only signal for a state (loading, recording); pair it with text, a spinner, or a status message. - The beam is purely decorative - keep your content's own border and text contrast intact so nothing depends on it.