OPERATOR

MapControls

This demo supplies local zoom and bearing. A map adapter performs navigation in an application.

Map controls

Zoom 8

Bearing 45°

<MapControls
  zoom={frame.zoom}
  bearing={frame.bearing}
  minZoom={2}
  maxZoom={20}
  onAction={requestMapAction}
  disabled={!mapReady}
/>

MapAction is zoom-in, zoom-out, pan-north, pan-east, pan-south, pan-west, reset-north, or fit. The caller performs the action and supplies the resulting view. A declined request leaves the readouts intact.

The control has no engine dependency. The adapter defines pan distance, fit extent, animation and supported projection. Zoom limits default to 2 and 20. Known zoom must be finite and within those limits; bearing is clockwise degrees from north in [0, 360). Readouts round to two decimals and group digits in the application's locale (React Aria's I18nProvider, as DatePicker does); a bearing that rounds to 360 shows 0. Unknown or invalid readouts are explicit; affected numeric actions are unavailable. Omitting onAction or supplying disabled disables every action.

Props

PROPTYPEDEFAULTREQUIRED
labelstring"Map controls"no
zoom

Supplied finite zoom within minZoom/maxZoom; null or missing is unknown. Readouts round to two decimals without changing the supplied value.

number—no
bearing

Supplied clockwise degrees from north in [0,360). Null, missing or invalid values remain unknown. Display rounds to two decimals, so a bearing that rounds to 360 shows 0.

number—no
minZoomnumber2no
maxZoomnumber20no
onAction

(action: MapAction) => void. Requests zoom-in, zoom-out, pan-north/east/south/west, reset-north or fit; no internal viewport change. Omission disables actions.

function—no
disabledbooleanfalseno
classNamestring—no

Accessibility

  • Native buttons have visible names and support Enter/Space without map shortcuts.
  • Readouts are not live regions, so renderer updates do not announce every frame.
  • Buttons wrap with long text and retain the existing minimum target and focus style.
  • When an accepted request disables the focused zoom button at a limit, focus moves to the other zoom button; when every action becomes unavailable, focus moves to the named group.
  • The root forwards a div ref and native attributes. Use distinct label values when showing multiple maps.

Manifest entry

<MapControls zoom={view.zoom} bearing={view.bearing} onAction={requestMapAction} />
View agent manifest
{
  "description": "Engine-independent map navigation requests with supplied zoom and north-bearing readouts.",
  "props": {
    "label": {
      "type": "string",
      "default": "Map controls"
    },
    "zoom": {
      "type": "number",
      "description": "Supplied finite zoom within minZoom/maxZoom; null or missing is unknown. Readouts round to two decimals without changing the supplied value."
    },
    "bearing": {
      "type": "number",
      "description": "Supplied clockwise degrees from north in [0,360). Null, missing or invalid values remain unknown. Display rounds to two decimals, so a bearing that rounds to 360 shows 0."
    },
    "minZoom": {
      "type": "number",
      "default": 2
    },
    "maxZoom": {
      "type": "number",
      "default": 20
    },
    "onAction": {
      "type": "function",
      "description": "(action: MapAction) => void. Requests zoom-in, zoom-out, pan-north/east/south/west, reset-north or fit; no internal viewport change. Omission disables actions."
    },
    "disabled": {
      "type": "boolean",
      "default": false
    },
    "className": {
      "type": "string"
    }
  },
  "composable_with": [
    "MapScale",
    "LayerControl",
    "MapLegend",
    "CoordinateInput",
    "AppShell"
  ],
  "never_inside": [
    "Button"
  ],
  "example": "<MapControls zoom={view.zoom} bearing={view.bearing} onAction={requestMapAction} />"
}

On this page