Axon 911 Frontend Docs
    Loading navigation…
U
User
Switch to light mode
  1. Components
  2. Shape
  3. Usage

Shape

Usage

Overview
Shape renders a single-path vector graphic inside a root svg. Paint flows through design tokens, ChartColor, or DataColor; there is no className, style, or as. Use it for map pins, cluster badges, and other marks you author as path data rather than as a fixed glyph or raster asset.
When to use
  • Custom silhouettes defined in user space (pins, polygons, irregular GIS symbols) where Icon has no glyph.
  • Legend or map marks that need strokeAlignment inside or outside a closed path.
  • Marks that must show a third-party color via DataColor on fill or stroke.
When not to use
NeedUse instead
Standard UI glyph from the design systemIcon
Trusted logo or illustration as an SVGR componentImage inline svg mode
Fixed 12×12 legend dot, line, or hatchSwatch (when documented)
Raster or URL imageryImage src mode
Arbitrary styling escape hatchesNot supported on Shape
Authoring path data
toSvgPathData
Path strings are developer-owned. Validate and brand them with toSvgPathData from @prepared911/ui/shape (the helper throws with a clear message when the microsyntax is invalid). Rules enforced at authoring time:
  • Must start with M or m.
  • Only path commands MmLlHhVvCcSsQqTtAaZz and numeric arguments.
  • Do not cast raw strings to SvgPathData at call sites.
Store branded SvgPathData in module scope next to your asset constants, as map fixtures do, so invalid paths fail at load time rather than in the tree.
SvgViewBox
Pass a SvgViewBox object with positive width and height (import the type from @prepared911/ui/shape):
Shape renders it as "minX minY width height" on the root svg. The view box defines user units for the path; it is independent of the on-screen box (see size below).
Size
Optional size sets inline-size and block-size from the space scale (--space-*), mirroring inline SVG sizing on Image. Each axis is a SpaceOption step (0, 4, 8, … 128). Omit an axis to keep the intrinsic aspect ratio from viewBox.
Stroke width and alignment
strokeWidth is a ShapeStrokeWidth enum value in viewBox user units, not screen pixels: Hairline = 1, Thin = 2, Regular = 3, Thick = 4. Alignment math runs in user space; the component does not use vector-effect. The root svg is overflow: visible, so an Outside stroke or a Center stroke on a path that touches the viewBox edge is not cut off. strokeAlignment defaults to Center. Inside and Outside are meaningful only for closed paths; open paths should use Center.
AlignmentWhat is drawn
CenterOne path with fill and stroke centered on the path centerline at strokeWidth.
InsideFill on the path; then a clip path matching the shape (clipPathUnits="userSpaceOnUse") and a stroke at 2× strokeWidth clipped to the interior.
OutsideFill on the path; then a mask (maskUnits="userSpaceOnUse") with a padded white rect and a black shape cutout, and a stroke at 2× strokeWidth visible only outside the fill.
Clip and mask ids are generated with useId and stay internal.
Paint
fill and stroke accept VectorPaint:
  • Tokens: Foreground values used for Text and Icon paint, except Foreground.Inherit.
  • ChartColor: palette CSS variables for series you control.
  • DataColor: pass-through colors from third-party data; see Data color. Prefer tokens or ChartColor for anything Axon 911 owns; use DataColor only when the payload cannot be mapped (for example ESRI layer styles).
Omitted fill or stroke paints none for that side.
Meaningful vs decorative
Same union as Image inline SVG:
  • Meaningful: label (LocalizedMessage) → role="img" and aria-label on the root svg.
  • Decorative: decorative: true → aria-hidden="true" and focusable="false".
  • Passing neither or both is a type error.
Related
  • Data color
  • Image
  • Icon
Previous
Send Button / Accessibility
Next
Shape / API and Development
On this page
Overview
When to use
When not to use
Authoring path data
toSvgPathData
SvgViewBox
Size
Stroke width and alignment
Paint
Meaningful vs decorative
Related