Skip to main content

Theming

The SDK's DOM (default marker pins, cluster bubbles, the user-location dot and cone) is styled from a small set of design tokens defined in @wemap/core. Set them once at init — unset fields keep their defaults:

await core.init({
emmid,
token,
theme: {
colorPrimary: '#e91e63', // markers, clusters, route, user location, highlights
colorOnPrimary: '#ffffff',
colorSurface: '#ffffff',
colorOnSurface: '#1a1a1a',
},
});

WemapMap applies the resolved theme to its container as CSS custom properties (--wemap-color-*) and adds a wemap-map class. Import the stylesheet once for the defaults to take effect — alongside maplibre's own base stylesheet, which the map renders on top of:

import 'maplibre-gl/dist/maplibre-gl.css'; // maplibre base styles
import '@wemap/map/style.css'; // SDK marker / cluster / user-location styles

Rebranding with CSS

Because it's all CSS variables + classes, you can rebrand — or restyle a single surface — with your own CSS, no JS. Per-surface variables fall back to --wemap-color-primary:

.wemap-map {
--wemap-color-primary: #e91e63; /* everything */
--wemap-color-cluster: #6200ea; /* just cluster bubbles */
}
/* or target an element directly (SDK selectors are zero-specificity :where()) */
.wemap-cluster { border-radius: 8px; }

CSS variables

Two tiers. Theme-driven variables are set on the .wemap-map container from core.init({ theme }). Override hooks are not emitted — the stylesheet reads them and falls back to --wemap-color-primary, so set one to restyle a single surface. Both are part of the public contract (semver-governed).

VariableTierStylesDefault
--wemap-color-primarytheme-drivenmarker pin, cluster bubble, user location, route line#2f7de1
--wemap-color-on-primarytheme-drivencontent on primary (cluster count text)#ffffff
--wemap-color-surfacetheme-drivencontrols / popups background (reserved — not yet consumed)#ffffff
--wemap-color-on-surfacetheme-drivencontent on surface (reserved)#1a1a1a
--wemap-color-markeroverride hookdefault marker pin fill--wemap-color-primary
--wemap-color-clusteroverride hookcluster bubble fill--wemap-color-primary
--wemap-color-useroverride hookuser-location dot + heading cone--wemap-color-primary

CSS classes

SDK selectors use zero-specificity :where(), so your own rules always win.

ClassElement
.wemap-mapmap container (carries the theme variables)
.wemap-marker / .wemap-marker__shapedefault pin root SVG / its fillable shape
.wemap-clustercluster bubble (circle + count)
.wemap-cluster--iconcluster rendered from a custom icon image
.wemap-user-location / .wemap-user-location__dot / .wemap-user-location__coneuser-location container / dot / heading cone

Per-element options still win locally: DomMarkerLayer's color, cluster color, and ShapeLayer simplestyle fill / stroke override the theme for that layer. The route line (ItineraryLayer) can't be styled with CSS variables — set its colour through colorPrimary in the theme, or per route via ItineraryLayer's color option.