Glow Node

A circular labeled node with auto-derived glow and optional sonar pulse. The atom every graph, tree, or timeline visualization composes from.

A
active
Customize
Visual
active
56px

Installation

npx shadcn@latest add https://craftbits.dev/r/glow-node.json

Usage

import { GlowNode } from "@craft-bits/core";
 
<GlowNode label="A" hex="#4A7BF7" state="active" />

Understanding the component

  1. HTML-overlaid, not SVG-native. GlowNode renders as a flex column of HTML elements (a circular div + optional subtitle / caption). This lets it sit on top of any SVG layout without inheriting SVG quirks (no text baseline issues, no foreignObject required).
  2. Four discrete visual states. state selects from hidden (undiscovered), revealed (default visible), active (current processing — adds sonar pulse + bright glow), and finished (visited / processed — muted, no glow).
  3. Colors derive from a single hex. Pass hex (a track accent color). Internally, svgNodeColors(hex) produces the full fill / stroke / text / glow palette for every state — no inline color math at the call site.
  4. Sonar pulse, only when needed. The active-state pulse ring is driven by the canonical SVG_SONAR motion variant (1s expand, 0.4s repeat-delay, 0.9→1.5 scale). All other states render zero motion elements.
  5. Smooth state transitions. Cross-state changes (e.g. revealed → active) are CSS-transitioned on box-shadow, border-color, and background over 0.3s ease.

Props

PropTypeDefaultDescription
labelstringrequiredDisplay text inside the circle.
hexstringrequiredAccent hex color (e.g. "#4A7BF7"). Drives fill, stroke, text, glow.
state'active' | 'revealed' | 'hidden' | 'finished''revealed'Visual state.
sizenumber40Diameter in pixels.
subtitlestringSmall line below the node (e.g. "t=5").
captionstringSecond small line below the subtitle.
glowstringDeprecated — pass hex + state and let the tokens resolve.
classNamestringExtra classes merged onto the outer wrapper.

Accessibility

  • The label is real text, not an icon — screen readers read it.
  • The sonar pulse ring is aria-hidden and pointer-events: none.
  • The component does not auto-add role="img"; if the node is the sole content of a meaningful container, label the parent (e.g. <svg role="img" aria-label="…">).

Credits

  • Extracted from: algoflashcards (src/lessons/primitives/graph/GlowNode.tsx).