Skip to content

Symbol ​

Parameterized geometry instance resolved through the engine symbol registry.

No children allowed.

Props ​

PropTypeRequiredDescription
symbolSymbolDefinitionEitherInline symbol definition
symbolIdstringEitherEngine registry key for a preloaded symbol
widthnumberYesDisplay width in px
heightnumberYesDisplay height in px
fillstringDefault fill applied to emitted geometry
strokestringDefault stroke applied to emitted geometry
strokeWidthnumberStroke width
fillRule"nonzero" | "evenodd"Default fill rule
strokeLinecap"butt" | "round" | "square"Stroke line cap
strokeLinejoin"miter" | "round" | "bevel"Stroke line join
strokeDasharraystringStroke dash pattern
strokeMiterlimitnumberStroke miter limit
preserveAspectRatio"none" | "meet" | "slice"How to fit the symbol into the display box
opacitynumberOpacity (0–1)
zIndexnumberSibling-local paint order (integer; higher paints later)
metaRecord<string, string>Metadata emitted as data-boundsvg-meta-* attributes and into the layered manifest (max 16 keys, [a-z][a-z0-9-]{0,31} keys, 256-char values)
emitPartIdsbooleanEmit one path per addressable geometry part tagged with data-boundsvg-part-id (opt-in; overlapping parts paint separately)
transformTransform2DStatic post-layout paint transform
animateAnimationSpecDeclarative opacity/transform track; see Animation
marginnumber | [number, number, number, number]Margin
partPaintRecord<string, PartPaintOverride>Per-part fill/stroke overrides keyed by part id. Splits the geometry into parts on its own; emitPartIds is only needed to also emit the data-boundsvg-part-id attributes
layerstringLayer id for Layered Export. Always rendered as an atomic island

Also accepts the same positioning, flex item, grid item, event, and id props as Svg.

Example ​

tsx
import {
  Canvas,
  Symbol,
  createEngineAsync,
  type SymbolDefinition,
} from "@boundsvg/core";

const arrow: SymbolDefinition = {
  geometry: {
    viewBox: { width: 100, height: 20 },
    root: {
      kind: "group",
      children: [
        { kind: "path", nodeId: "tail", d: "M0 8H10V12H0Z" },
        { kind: "path", nodeId: "shaft", d: "M10 8H70V12H10Z" },
        { kind: "path", nodeId: "head", d: "M70 4L100 10L70 16Z" },
      ],
    },
  },
  elasticSegments: [
    {
      nodeId: "tail",
      axis: "x",
      role: "fixed-start",
      frame: { x: 0, y: 0, width: 10, height: 20 },
    },
    {
      nodeId: "shaft",
      axis: "x",
      role: "stretch",
      frame: { x: 10, y: 0, width: 60, height: 20 },
    },
    {
      nodeId: "head",
      axis: "x",
      role: "fixed-end",
      frame: { x: 70, y: 0, width: 30, height: 20 },
    },
  ],
};

const engine = await createEngineAsync({});
engine.registerSymbol("arrow", arrow);

<Canvas width={280} height={120} background="#111827">
  <Symbol symbolId="arrow" width={220} height={24} fill="#f8fafc" />
</Canvas>;
symbol-registered example
Generated SVG
xml
<svg xmlns="http://www.w3.org/2000/svg" data-boundsvg-node-id="auto:0" viewBox="0 0 280 120" width="280" height="120">
  <rect x="0" y="0" width="280" height="120" fill="#111827"/>
  <g data-boundsvg-node-id="auto:0.0">
    <svg data-boundsvg-node-id="auto:0.0" x="0" y="0" width="220" height="24" overflow="hidden">
      <path d="M0,9.6L10,9.6L10,14.4L0,14.4Z M10,9.6L190,9.6L190,14.4L10,14.4Z M190,4.8L220,12L190,19.2Z" fill="#f8fafc"/>
    </svg>
  </g>
</svg>