Appica UIUI 1.1.0

Border Beam

A comet of light that laps the border of your content.

Deploying to production

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-hidden and pointer-events-none, so it's skipped by assistive tech and never intercepts clicks.
  • Content is wrapped, not replaced - your children stay 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.

© 2026 Appica UI. A free component library, crafted by the Appica team.