Svg Defs

A drop-in <defs> block that registers the canonical arrow markers (default + highlighted) and the three glow filter tiers (subtle / medium / bright) for SVG-native nodes.

Before centralizing these, every graph renderer hand-rolled its own <marker> and <filter> with subtly different geometry. SvgDefs eliminates that drift.

glow: medium
Customize
Markers & filters
medium

Installation

npx shadcn@latest add https://craftbits.dev/r/svg-defs.json

Usage

import { SvgDefs, svgMarkers } from "@craft-bits/core";
 
const m = svgMarkers("my-graph");
 
<svg>
  <SvgDefs id="my-graph" hex="#4A7BF7" />
  <line markerEnd={m.arrow} ... />
  <line markerEnd={m.arrowHl} ... />
  <circle filter={m.glowMedium} ... />
</svg>

Understanding the component

  1. Drop inside <svg>. SvgDefs renders an SVG <defs> element. It must live inside an <svg> to register its markers and filters.
  2. Unique id prefix. Every marker / filter is prefixed with the id you provide (or a stable useId() if you omit it). Multiple SVGs on the same page can coexist without clobbering each other's defs.
  3. Two arrows, three glows. arrow (muted foreground) and arrowHl (hex accent) for directed edges; glowSubtle / glowMedium / glowBright for SVG-native node halos.
  4. Pair with svgMarkers(id). It returns url(#…) strings ready for markerStart / markerEnd / filter props — no template literals at the call site.

Props

PropTypeDefaultDescription
hexstringrequiredAccent hex for the highlighted arrow and glow tint.
idstringautoPrefix for marker / filter IDs. Auto-generated via useId() if omitted.

Accessibility

  • <defs> is non-rendered SVG content — it has no a11y surface of its own.
  • The <svg> that hosts SvgDefs should still carry role="img" and aria-label describing the visualization.

Credits

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