Skip to content
16Reference

Spatly Marks

The first-party visual kit: UI icons, map markers, ornaments, chart marks and live affordances, and how to use it in Studio, on the map, and in your own apps via the export package.

What it is

Spatly Marks is an original SVG kit, not a Lucide clone: 128 UI icons on a 24 px grid with a 1.5 px stroke and a recurring diagonal survey tick, 22 map markers on a 32 px grid that load into MapLibre as SDF images, atlas ornaments (north arrow, scale bar, neatline, corner ticks, graticule, legend frame, title block), chart marks that match the map language, and animated live affordances (pulse, scan, flow, stale, offline). The Spatly logo, a square neatline with corner ticks and an offset bead with a short tick, "a beat on a plate", is part of the set.

Marks follow your theme tokens: stroke colour is currentColor, the bead and highlights use --sp-color-accent, and the night and ops variants change nothing but the tokens.

The Marks gallery with a mark selected: fill, stroke, size, badge, tags and the export buttons.
  1. Search: by name or tag (incident, facility, chevron, cluster…).
  2. Categories: All · UI · Markers · Ornaments · Chart · Live.
  3. Grid: 167 marks in this workspace's set, named.
  4. Fill and stroke: recolour the selected mark from the workspace palette or a hex value.
  5. Badge: one or two characters drawn as a small corner plate: a number for a tour stop, a letter for a site.
  6. Copy SVG · Download: the edited mark, ready to paste or drop into a repository.
  7. Brand kit: the workspace logo, accent, watermark and fonts.

In Studio

  • Every rail, panel and map control uses Marks.
  • Layer symbols, annotation pins, tour stops and chart marks are picked from the same catalog in the style editor (search by name or tag: incident, facility, chevron, cluster …).
  • The Mark editor (the right-hand panel of the gallery) recolours a mark, adds a one- or two-character badge, resizes it, and hands it back as SVG: Copy SVG to the clipboard, or Download as a file.

Names

UI icons (excerpt): layers layer-add beat beat-save camera compass crs live filter geofence elevation terrain routing pin line area callout tour north scale legend pitch bearing globe map marks insight publish share embed story slides dashboard chapter widget kpi template presenter laser notes bookmark time play pause refresh upload download link database api webhook mcp agent history stale offline warning info password lock-domain search zoom-in zoom-out fit fullscreen expand collapse external code settings spark magic user workspace mobile tablet desktop wall sun moon ops.

Map markers (22): pin pin-solid pin-numbered pin-lettered cluster chevron dot dot-ring facility incident chapter tour-stop camera station vehicle warning home flag cross square triangle diamond.

The full list with tags lives in MARK_CATALOG and in the gallery at /app/marks.

The package

bash
npm i @spatly/marks
tsx
import { Mark, SpatlyLogo, ORNAMENTS, LiveAffordance, markSvg, loadMarkImages } from "@spatly/marks";

<Mark name="beat" size={16} />                       // inline SVG, currentColor
<Mark name="marker:pin-numbered" label={3} size={32} />
<SpatlyLogo size={22} wordmark accent="var(--sp-color-accent)" />
<LiveAffordance kind="pulse" size={16} />
<ORNAMENTS.NorthArrow size={48} bearing={-18} />
<ORNAMENTS.ScaleBar metersPerPixel={38} maxWidth={160} />
strings and MapLibre
markSvg("marker:incident", { size: 32, fill: "#b91c1c" });          // full <svg> string
markDataUrl("kpi");                                                  // data: URI for CSS
await loadMarkImages(map);                                           // registers "mark:<name>" images (SDF)
map.addLayer({ type: "symbol", layout: { "icon-image": "mark:pin-solid" }, paint: { "icon-color": "#0891b2" } });
ExportWhat
Mark, MarkSprite, MarkUseReact components; <MarkSprite> once at the root, <MarkUse> references it
UI_ICONS, MAP_MARKERS, CHART_MARKSraw inner markup keyed by name
ORNAMENTSNorthArrow ScaleBar Neatline CornerTicks Graticule LegendFrame TitleBlock
LiveAffordance, LIVE_CSSanimated states; honours prefers-reduced-motion
SpatlyLogo, spatlyLogoSvg, faviconSvgthe mark, with or without wordmark
markSvg, markDataUrl, buildSprite, loadMarkImages, exportPackageruntime helpers
MARK_CATALOG, searchCatalognames, categories and tags for pickers

Export for your own app

Marks → Export in the app (or exportPackage() in code) produces a zip with:

  • sprite.svg: one <symbol> per mark, <use href="sprite.svg#icon-beat">
  • marks.tsx: typed React components, no runtime dependency
  • maplibre-images.json: name → SDF PNG data for map.addImage
  • tokens.css: the colour tokens the marks reference

Marks exported from your workspace may be used in your own products, including commercial ones; the kit itself may not be resold as a standalone icon set. See Terms.

Design rules, if you extend the set

  • 24 grid, 1.5 stroke, round caps and joins, square-ish geometry, one diagonal tick where the concept allows.
  • Markers: 32 grid, a single filled path where possible so the SDF stays crisp at any colour; anchor at the tip for pins, centre for dots.
  • Ornaments use hairlines (--sp-color-line, --sp-color-lineStrong), never drop shadows.
  • Live affordances animate transform and opacity only; nothing moves under prefers-reduced-motion.

Verified on 2026-09-02 against the local development build (gallery, search, category filter, recolour, badge and Copy SVG on /app/marks).

Was this page helpful?

Something wrong or missing? Write to hello@spatly.io.