Theming
Every piece of chrome ApexMaps draws itself, the legend, tooltip, breadcrumb and attribution, reads its colors from CSS custom properties on the map's container. A host dashboard restyles the map by setting those properties, with no options tree involved at all.
#dashboard-map {
--apexmaps-surface: #1e1b4b;
--apexmaps-focus: #f472b6;
}
Dark mode
theme.mode is 'light', 'dark', or 'auto':
theme: { mode: 'dark' }
Dark mode is applied as a class (apexmaps--dark) on the container rather than only through a prefers-color-scheme media query, so a dashboard can force it independently of the operating system. 'auto' follows the OS setting via prefers-color-scheme. What changes between light and dark is the chrome, the no-data color and the text; the data palette itself (scale.palette) is unchanged, since a blues choropleth should read as the same blues choropleth in either mode.
theme.palette sets a default PaletteName for series that don't name their own, useful for keeping every series on a map consistent without repeating scale: { palette: 'x' } on each one.
The --apexmaps-* custom property surface
These are the variables the library itself reads. Override any of them on the map's container, or globally on :root, and every component that uses that variable follows.
| Variable | Used for | Light default | Dark default |
|---|---|---|---|
--apexmaps-fg | Primary text (legend, breadcrumb, tooltip title) | #1f2933 | #e5e7eb |
--apexmaps-fg-muted | Secondary text (tooltip labels, breadcrumb items) | #6b7280 | #9ca3af |
--apexmaps-bg | Container background | transparent | transparent |
--apexmaps-surface | Tooltip and card backgrounds | #ffffff | #1f2937 |
--apexmaps-border | Borders, legend item hover, swatch outlines | rgba(0,0,0,0.12) | rgba(255,255,255,0.16) |
--apexmaps-shadow | Tooltip drop shadow | 0 4px 16px rgba(15,23,42,0.14) | 0 4px 16px rgba(0,0,0,0.5) |
--apexmaps-focus | Focus ring, selection box outline, active legend accents | #2563eb | #60a5fa |
--apexmaps-radius | Tooltip and legend swatch corner radius | 6px | 6px |
--apexmaps-font-size | Base font size for legend, tooltip, breadcrumb | 12px | 12px |
--apexmaps-focus doubles as the selection box color (.apexmaps-select-box strokes and fills with it), so a rebrand that changes the accent color updates the box-selection rectangle for free.
#branded {
--apexmaps-fg: #f8fafc;
--apexmaps-fg-muted: #cbd5f5;
--apexmaps-surface: #1e1b4b;
--apexmaps-border: rgba(255, 255, 255, 0.24);
--apexmaps-focus: #f472b6;
--apexmaps-radius: 2px;
--apexmaps-font-size: 13px;
}
// No theme option set at all: the container's CSS alone drives the legend,
// tooltip and attribution.
new ApexMaps(document.getElementById('branded'), {
chart: { height: 320, background: 'transparent' },
geo: { map: 'eu/nuts0@20m' },
series: [{ name: 'Adoption', joinBy: ['nuts_id', 'key'], data, scale: { palette: 'magma' } }],
})
Two variables outside this table are written by the engine rather than meant for you to set directly: --apexmaps-anim and --apexmaps-anim-geom pace the fill and geometry transitions from chart.animations.speed, and zero out automatically under prefers-reduced-motion.
Responsive rules
responsive swaps in a different slice of options once the map's measured container width crosses a breakpoint, the same shape as ApexCharts' own responsive array:
responsive: [
{ breakpoint: 560, options: { legend: { position: 'bottom' }, dataLabels: { enabled: false } } },
{ breakpoint: 900, options: { legend: { position: 'right' } } },
]
Rules match against measured width rather than viewport width, and the narrowest matching breakpoint wins, so they can be declared in any order. This is what a map should do at that width, not a media query in disguise: a map that is half of a two-column dashboard row is "narrow" long before the browser viewport is, and responsive reacts to the box the map is actually in.
map.on('resized', () => {
console.log(map.viewport.width, map.config.legend.position)
})
An explicit width on the container (chart.width: '100%' on a sized parent, not an unconstrained flex or grid item) matters here: a resizable box that reports its intrinsic max-content width will size the map to that instead of to the page, and no breakpoint will ever fire.
See also
- Legends, Labels & Tooltips for the components most of this surface styles.
- Palettes for the data-color ramps, which theming intentionally leaves alone.
- Zoom, Pan & Camera for
prefers-reduced-motionhandling on camera moves.