HelixOverviewDocsComponentsSandboxTheme builderMapsBuildingCortexDocsEngramBuildingTraceBuildingRecallDeclaredServicesInsightsGet in touchSource on GitHub
Essentials
MapsHelix Maps puts a frame around a map drawn by MapLibre, Leaflet, or a renderer of
your own. The frame adds a column of controls and a place for the map credit. You
add places, routes, areas, live positions, and data as elements inside the
frame, and @fusion.dev/helix-map connects the frame to the renderer and styles
the map with your theme.Add a mapInstall Helix, the map connector, and MapLibre:bun add @fusion.dev/helix @fusion.dev/helix-map maplibre-glAdd the map frame, an element for MapLibre to draw in, and your places:<helix-maplabel="Our stores"><divid="map"></div><helix-map-markerlabel="Flagship"lat="30.2672"lng="-97.7431"></helix-map-marker></helix-map>Create the map with a style from your theme, then connect it to the frame:import'@fusion.dev/helix'import'maplibre-gl/dist/maplibre-gl.css'import{colorsReady,connectMap}from'@fusion.dev/helix-map'import{followTheme,mapLibreDriver,mapLibreStyle}from'@fusion.dev/helix-map/maplibre'importmaplibreglfrom'maplibre-gl'constframe=document.querySelector('helix-map')conststyle=(colors)=>mapLibreStyle(colors)constmap=newmaplibregl.Map({attributionControl:false,container:'map',style:style(awaitcolorsReady(frame)),})constconnection=connectMap(frame,mapLibreDriver(map))connection.fit({animate:false})followTheme(map,frame,style)What the connector doesconnectMap links the frame to the renderer:The frame's pan, zoom, rotate, and tilt buttons and keys move the map, using
your theme's motion settings. The map moves without animation when a user has asked for
reduced motion.The renderer's own keyboard handling and zoom buttons are turned off, so the
frame's controls are the only ones.The renderer's credit is shown in the frame's footer.connection.fit() frames every place on the map.connection.disconnect() puts back everything connectMap changed.Use mapLibreDriver(map) for MapLibre GL JS 5 and leafletDriver(map, L) for
Leaflet 1.9. Neither renderer is bundled with Helix, so you can use the version
you already have. Leaflet draws routes, areas, and points only when you pass it
L.Style the map with your thememapLibreStyle(colors) builds a MapLibre style from five colors in your theme:Land uses surface.Water uses info.Parks use success.Main roads use primary, your brand color.Smaller roads, buildings, borders, and labels use foreground.It also draws landmarks, highway signs, and neighborhood names:A landmark is an icon on a disc and its name, in a color for its kind:
parks, museums, schools, hotels, hospitals, stations, and stadiums from zoom
14, and food and shops from zoom 16. Each color is a fixed hue at your brand
color's lightness, so the kinds stay apart in any theme.A highway's number is on its sign, drawn to the Federal Highway
Administration's outlines: the red and blue Interstate shield, the white US
route shield, the white circle of a state route, and a plain plate for other
roads.Neighborhoods are in spaced capitals, quieter than the towns.The same call builds a light map for a light theme and a dark map for a dark
theme. Map labels meet a contrast target of 4.5 against the land. Pass
contrast to change it, language to choose which name each place is labeled
with, and tiles and glyphs to use your own tile server.Pass font to draw the labels in your theme's typeface. MapLibre draws the
letters in the page from the font your page has loaded, so there are no glyph
files to fetch. mapFontFrom(frame) reads the typeface from your theme, and
fontReady(font) waits until its weights are loaded. Wait for it before you
create the map, because MapLibre keeps each letter as first drawn:constfont=mapFontFrom(frame)awaitfontReady(font)constmap=newmaplibregl.Map({container:'map',style:mapLibreStyle(colors,{font})})The style draws the world as a globe when the map is zoomed out. The globe turns
into the flat map as the map zooms in. connectMap hides markers on the far side
of the globe, and a keyboard user who moves to one turns the globe to show it.
Pass globe: false for a flat map at every zoom. MapLibre 4 has no globe, so
pass it there too.followTheme(map, frame, style) restyles the map when your theme changes. It
watches for a new color mode, class, or theme value on the frame or its
ancestors, and for a change in the system's light or dark setting. If your page
changes its theme another way, such as by replacing a stylesheet, call
update() on the object followTheme returns.colorsReady(frame) waits until your theme's colors can be read, which can take
a frame or two after the page loads. If the colors never become available, it
reports which one is missing.What you can add to a mapElementWhat it addshelix-map-markerA named place on the maphelix-map-routeA line, such as a delivery routehelix-map-areaA shape, such as a delivery zonehelix-map-positionA moving point or arrow, such as a vehiclehelix-map-pointsThousands of places loaded from GeoJSONhelix-map-buildingsThe map's buildings, raised to their heights in 3Dhelix-map-rasterMap tiles over the map, such as weather radar or satellite imageryhelix-map-terrainHills and mountains, shaded and raised in 3Dhelix-map-contoursContour lines, each at one heighthelix-map-landcoverWhat covers the ground: forest, grass, farmland, sand, rock, and iceEach element takes tone, such as primary or danger, for its color.Markers<helix-map-markerlabel="Texas Capitol"lat="30.2747"lng="-97.7405"shape="ring"><spanslot="icon">B</span></helix-map-marker>A marker is a button placed at its latitude and longitude. Its label appears
when you hover over or focus the marker. The icon slot holds a letter, a
number, or an icon, and shape sets the marker's form: ring, rounded,
square, diamond, or pin. Pressing a marker sends helix-activate from the
frame with the marker's name, or its label if it has no name.To show that a place has been visited, add passed. The marker is drawn in a
muted color, and screen readers hear its name followed by "passed". Use
passed-label to change that word.ClustersAdd cluster to the frame to combine markers that would overlap into one
count. The count splits apart as you zoom in, and pressing it zooms in to its
places. Places at the same location, such as two businesses at one address,
spread out around that point when you press their count. Press Escape to
combine them again.To handle a pressed cluster yourself, for example by listing its places in a
panel, pass clusterZoom: false to connectMap and listen for
helix-map-cluster.Routes and areas<helix-map-routedescription="4.2 km"label="Depot to Mission"points="37.7955,-122.3937 37.7644,-122.427"progress="0.4"></helix-map-route>Write points as lat,lng pairs separated by spaces. A route draws straight
lines between its points, so to follow streets, pass the path from a routing
service such as OSRM or Valhalla.progress, from 0 to 1, draws the part already traveled in a lighter color.variant="dotted" draws a route as dots, for a walk off the road network.distancesAlong(points) measures a route the same way the connector does, so
something you move along the route and the lighter part stay in step.Live positions<helix-map-positionaccuracy="30"description="Two stops away"heading="90"label="Van 12"lat="37.78"lng="-122.41"></helix-map-position>Update lat, lng, and heading as the position moves. heading turns it
into an arrow, and accuracy draws a ring with a radius of that many meters. Screen
readers announce its description when it changes, at most once every
announce-every milliseconds. Its movement is not announced.Thousands of points<helix-map-pointsclusterlabel="Food and drink"src="/places.geojson"></helix-map-points>Use helix-map-points for more places than markers can handle. MapLibre draws
all of them as one layer, loaded from a GeoJSON file in src or from data you
set on data. With cluster, nearby points combine into counts, and pressing a
count zooms in to it. Pressing a point sends helix-activate from the layer
with the point's id, or with the property named by name-key. Leaflet draws
each point on its own, which works for hundreds of points.Buildings in 3D<helix-map-buildings></helix-map-buildings>helix-map-buildings raises the buildings in the map's tiles to the heights the
tiles record, in your theme's raised surface color. Set tone to color them by
meaning. The buildings appear from zoom 13. To see their height, tilt the map by
setting pitch when you create it:constmap=newmaplibregl.Map({container:'map',pitch:55,style,zoom:15.5})To let users tilt the map, add tilt to the frame's controls:<helix-mapcontrols="zoom compass tilt fullscreen"label="Downtown Austin in 3D">The 3D button is a toggle. Pressed, it tilts the map 50 degrees toward the
horizon and raises the buildings. Pressed again, it makes the map flat, and the
buildings are the map's own flat footprints. Raised terrain lies flat with them,
and keeps its shading. The compass's needle points north as the map turns, and
pressing the compass turns the map back to north.Leaflet draws maps flat and does not rotate, so a Leaflet map shows no
buildings, and the compass and the 3D button do nothing.Weather and other tile overlays<helix-map-rasterattribution="Radar from Example Weather"frames="https://tiles.example/radar-50m/{z}/{x}/{y}.png https://tiles.example/radar-now/{z}/{x}/{y}.png"label="Weather radar"></helix-map-raster>helix-map-raster draws map tiles over the land and roads, and under your
routes, areas, and place names. Set src to one tile URL, or frames to
several, and set playing to show the frames in order, interval milliseconds
each. Every frame's tiles load once, so the loop plays without a blank frame.Put the tile provider's credit in attribution. The frame shows it beside
the map's credit.The frames do not play while the user has asked for reduced motion.Content that moves for more than five seconds needs a way to pause it, so
give playing a control on your page.Satellite imagery and map types<helix-map-rasterattribution="Imagery from USGS The National Map"groundlabel="Satellite imagery"max-zoom="16"opacity="1"src="https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryOnly/MapServer/tile/{z}/{y}/{x}"></helix-map-raster>Set ground on helix-map-raster to make its tiles the map's imagery. Imagery
is a map type, which the frame's map-type attribute chooses:Absent, the Standard map: your themed map, without the imagery.hybrid: the imagery in place of the map's land, under its roads and names.satellite: the imagery alone, without the roads and names.With layers in the frame's controls, the layers menu opens with a card for
each map type, showing a picture of the map in it. Set max-zoom to the deepest
zoom your provider has tiles for, and the map enlarges those tiles when a user
zooms in further.The imagery above is from the U.S. Geological Survey. It is in the public domain
and covers the United States. Some providers put {y} before {x} in their
tile URLs, as this one does.Terrain<helix-map-terrainattribution="Elevation from 3DEP and SRTM data, courtesy of the U.S. Geological Survey"max-zoom="15"raisedsrc="https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png"></helix-map-terrain>helix-map-terrain shades the land by its slopes, so hills and valleys show on a
flat map. Set raised to raise the ground to its real height as well, and tilt
the map to see it. Set exaggeration to raise it more than its real height,
such as 1.5. Routes, areas, and buildings lie on the raised ground.The elevation tiles above are Terrain Tiles on AWS, which are free to use and
cover the world. Their tiles store heights in the terrarium encoding, which is
the default. For tiles in the Mapbox encoding, set encoding="mapbox". Credit
the sources your map shows: in the United States, the U.S. Geological Survey.Leaflet draws maps flat, so a Leaflet map shows no terrain.Contour lines<helix-map-contoursmax-zoom="15"src="https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png"unit="feet"></helix-map-contours>helix-map-contours draws lines of equal height from the same elevation tiles
as terrain. The lines are closer together as the map zooms in, from 500 meters
apart over a region to 5 meters at street level. Every fifth line is heavier and
labeled with its height, in meters, or in feet with unit="feet". They show
from zoom 9, and lie on the ground when it is raised.Land cover<helix-map-landcover></helix-map-landcover>helix-map-landcover colors the ground by what covers it: forest and grass in
greens, farmland in wheat, wetland in teal, sand in tan, rock in gray, and ice
in pale blue. Each color is mixed into your theme's land color. It draws over
parks and under water and roads, so a park shows its meadows and forests.Turn layers on and off<helix-mapcontrols="zoom compass layers fullscreen"label="Downtown Austin">Add layers to the frame's controls for a layers button. It opens a menu with
a tile for each layer: a picture of what the layer draws, and its label. A
tile is lit while its layer is shown. Pressing a tile sets its layer's hidden
attribute, and connectMap does not draw a hidden layer. Write hidden on a
layer to start it turned off.Give layers the same group to show them as one tile, such as a route and the
dotted legs at its ends. The tile takes the name of the first layer in the
group, and shows or hides every layer in it. Keep labels short, such as
"Walking route", and put the rest in description, which screen readers read
after the label.Keyboard and screen readersThe frame is one tab stop. Arrow keys pan the map, and the plus and minus keys
zoom it. Shift with Left or Right rotates the map, and Shift with Up or Down
tilts it.The markers are one tab stop. Arrow keys move between them in the order you
wrote them. The map pans to show a marker that is off screen.A points layer is one tab stop over the points and counts in view. Arrow keys
move top to bottom and along each line. Enter on a count zooms in to it.Screen readers find the map's shown layers in a list inside the frame, named
by their label and description.With a pointer, dragging is the only way to move and turn the map. Where your
map has to work without dragging, as WCAG 2.2 asks at level AA, add pan and
rotate to controls for buttons around the compass that move and turn it.In the layers menu, Tab moves between the tiles, Space or Enter turns a layer
on or off, and Escape closes the menu.Write a driverTo use another renderer, write a driver: an object with two methods.panBy(x, y, motion) moves the map by a number of pixels.zoomBy(direction, motion) zooms in for 1 and out for -1.motion is your theme's { duration, easing }, or null to move without
animation. Each optional method turns on a feature:MethodTurns onproject, onViewPlacing markers and positionsshowBringing a focused marker into viewfitconnection.fit() and zooming in to clusterslayersDrawing routes, areas, and pointscreditsThe map credit in the frame's footersilenceKeyboard, focusTarget, replaceZoomUsing the frame's keys and zoom buttonsbearingArrows that stay correct when the map is rotated, and the Face north arrowrotate, tiltThe rotate, Face north, and tilt buttons and keysWithout project, markers stay hidden. To animate a move your page makes
itself, read the same motion with motionOf(element, pace).