Appearance
Symbol
Parameterized geometry instance resolved through the engine symbol registry.
No children allowed.
Props
| Prop | Type | Required | Description |
|---|---|---|---|
symbol | SymbolDefinition | Either | Inline symbol definition |
symbolId | string | Either | Engine registry key for a preloaded symbol |
width | number | Yes | Display width in px |
height | number | Yes | Display height in px |
fill | string | Default fill applied to emitted geometry | |
stroke | string | Default stroke applied to emitted geometry | |
strokeWidth | number | Stroke width | |
fillRule | "nonzero" | "evenodd" | Default fill rule | |
strokeLinecap | "butt" | "round" | "square" | Stroke line cap | |
strokeLinejoin | "miter" | "round" | "bevel" | Stroke line join | |
strokeDasharray | string | Stroke dash pattern | |
strokeMiterlimit | number | Stroke miter limit | |
preserveAspectRatio | "none" | "meet" | "slice" | How to fit the symbol into the display box | |
opacity | number | Opacity (0–1) | |
zIndex | number | Sibling-local paint order (integer; higher paints later) | |
meta | Record<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) | |
emitPartIds | boolean | Emit one path per addressable geometry part tagged with data-boundsvg-part-id (opt-in; overlapping parts paint separately) | |
transform | Transform2D | Static post-layout paint transform | |
animate | AnimationSpec | Declarative opacity/transform track; see Animation | |
margin | number | [number, number, number, number] | Margin | |
partPaint | Record<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 | |
layer | string | Layer 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>;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>