Signal Beam
A neon tube drawn between two elements, with a pulse of light running along it. Curves, reverses, runs both ways.
New in 1.7.
- GitHubpush, pull_request
- Stripeinvoice.paid
- Postgresorders, CDC
- Linearissue.updated
- Sentrypaused
Installation
npx shadcn@latest add https://neonkit.heyaadi.com/r/signal-beam.jsonUsage
import { SignalBeam } from "@/components/ui/signal-beam"
const container = useRef(null)
const from = useRef(null)
const to = useRef(null)
<div ref={container} className="relative flex justify-between">
<span ref={from}>…</span>
<span ref={to}>…</span>
<SignalBeam containerRef={container} fromRef={from} toRef={to} curvature={30} />
</div>Examples
Reverse and both ways
A request goes out and a response comes back on the same tube, half a cycle apart.
Live, slow and dark
Glow marks a link that's carrying traffic; a dark tube is dashed and unlit.
API reference
An SVG that fills its positioned parent. Render it inside the container, after or before the nodes. Also accepts native SVG attributes.
| Prop | Type | Default |
|---|---|---|
fromRef | RefObject<HTMLElement>Where the tube starts. | None |
toRef | RefObject<HTMLElement>Where the tube ends. | None |
containerRef | RefObject<HTMLElement>Watched for resizes along with both nodes. | parent |
curvature | numberBow at the middle in pixels. Positive bends left of the direction of travel. | 0 |
duration | numberSeconds for a pulse to cross. | 2.4 |
delay | numberSeconds before the first pulse. Stagger beams with it. | 0 |
repeatDelay | numberSeconds of dark between pulses. | 0.8 |
reverse | booleanRun from | false |
bidirectional | booleanPulses both ways, half a cycle apart. | false |
pulseLength | numberPulse length as a share of the tube, 0.05 to 1. | 0.3 |
width | numberTube thickness in pixels. | 2 |
active | booleanFalse leaves a dashed, unlit tube with no pulse. | true |
gap | numberPixels between a node's edge and the tube's end. | 4 |
fromOffset | [number, number]Nudges the start point, in pixels. | None |
toOffset | [number, number]Nudges the end point, in pixels. | None |
color | NeonColorColor of the tube and its light. | inherited |
Accessibility
- Decorative: the SVG is aria-hidden. Describe the connection in text if it carries meaning.
- Ends leave each node along the tube's tangent, from the edge of a box or the rim of a round node, so the tube never starts under a card.
- The pulse is CSS animating a dash offset on a path with pathLength 1. No script runs per frame, and a resize only rewrites the path.
- Pulses pause off screen and in background tabs. With reduced motion each pulse holds still, partway along its tube.
- Inside a scaled parent (a zoomed preview) the geometry is corrected for the scale.