Flab UIv0.0.2
MobileA2UI

Map

A route-and-fleet tracking map — Leaflet under a Flab skin. A slippy map genuinely needs an engine for tiled basemaps, projection and pan/zoom, so Map lazy-loads Leaflet in an effect (it never runs on the server) and disposes it on unmount. The chrome, though, is Flab's: markers are token-styled pins with a pulsing dot for a live vehicle, routes are polylines drawn in resolved token colours, and the zoom / recenter / layers cluster matches the rest of the library. Basemap tiles come from Esri's open light/dark gray-canvas styles (no API key), so the map reads as light or dark alongside the page — pass the resolved theme from useTheme. Because a canvas is opaque to assistive tech, every marker is also a button in a visually-hidden list, giving keyboard users the same reach as a click. The live version is on the Live Tracking showcase.

RouteOriginVehicleStop
const route = {  id: 'trip',  tone: 'info',  emphasis: true,  points: [    [31.2304, 121.4737],    [31.2712, 121.0],    [31.2905, 120.8],    [31.2989, 120.5853],  ],};
const markers = [  { id: 'warehouse', position: [31.2304, 121.4737], kind: 'origin', tone: 'success', label: 'Shanghai Depot', sublabel: '2.4 km' },  { id: 'trk-024', position: [31.2712, 121.0], kind: 'vehicle', label: 'TRK-024', sublabel: '65 km/h' },  { id: 'destination', position: [31.2989, 120.5853], kind: 'destination', label: 'Suzhou Hub', sublabel: '12.8 km' },];
const [selectedId, setSelectedId] = useState('trk-024');
// Import the Leaflet base CSS once in your app: 'leaflet/dist/leaflet.css'.<Map  theme={resolvedTheme}  center={[31.2712, 121.0]}  zoom={10}  markers={markers}  routes={[route]}  selectedId={selectedId}  onMarkerSelect={setSelectedId}  ariaLabel="Delivery route from the Shanghai depot to the Suzhou hub"  height={360}  className="rounded-xl border border-hairline"/>

Setup

Leaflet ships a base stylesheet that positions the map panes, tiles and zoom animation. Map relies on it but does not import global CSS itself, so import it once in your app — for example in your root stylesheet:

@import 'leaflet/dist/leaflet.css';

Props

PropTypeDefaultNotes
centerMapLatLng—Initial [lat, lng]; superseded by fitOnMount when there is content.
zoomnumber12Initial zoom level.
minZoomnumber3Lower zoom bound.
maxZoomnumber19Upper zoom bound.
theme'light' | 'dark''light'Selects the light/dark basemap. Pass the resolved theme from useTheme.
markersMapMarker[][]Pins drawn on the map.
routesMapRoute[][]Polylines drawn beneath the markers.
selectedIdstring | null—Controlled selection; sets the enlarged pin. Omit for per-marker selected.
onMarkerSelect(id: string | null) => void—Fires on pin click or the sr-only marker button.
controlsbooleantrueShow the recenter / zoom / layers cluster.
interactivebooleantrueAllow pan and zoom; false renders a static frame.
fitOnMountbooleantrueFrame all markers and routes once, on mount.
attributionbooleantrueShow the tile attribution (required by most tile terms).
ariaLabelstring—Accessible name describing what the map shows. Required.
heightnumber | string360Map height; the container fills its width.

MapMarker

PropTypeDefaultNotes
idstring—Stable marker id, reported on selection.
positionMapLatLng—[lat, lng] of the pin.
kind'origin' | 'destination' | 'vehicle' | 'stop' | 'point''point'Sets the default tone and the pin vs. live-dot treatment.
labelstring—Chip shown above the pin.
sublabelstring—Quiet second line in the chip.
toneBadgeTone—Overrides the tone implied by kind.
selectedbooleanfalseEnlarges the pin and adds a ring (uncontrolled).
pulseboolean—Adds the pulsing ring; on by default for vehicle.

MapRoute

PropTypeDefaultNotes
pointsMapLatLng[]—Ordered [lat, lng] points.
toneBadgeTone'info'Colours the polyline from the token palette.
variant'solid' | 'dashed''solid'Dashed reads as a planned or secondary segment.
emphasisbooleanfalseDraws the line heavier, for the primary route.
idstring—Stable key for the route.

MapLegend

PropTypeDefaultNotes
itemsMapLegendItem[]—Each names a dot (tone) or a line sample (line) in text.