Skip to content
Docs version
@hungpvq/vue-map@1.2.0@hungpvq/vue-map-core@1.2.0@hungpvq/vue-map-dataset@1.2.0@hungpvq/vue-map-draw@1.2.0@hungpvq/map-draw@1.2.0@hungpvq/react-map@1.2.0@hungpvq/react-map-core@1.2.0@hungpvq/react-map-dataset@1.2.0@hungpvq/react-map-draw@1.2.0

DrawControl ​

Toolbar that mounts @mapbox/mapbox-gl-draw (MapDraw) on the map and drives save/edit via MapDrawOption / useMapDraw().start().

Usecase ​

  • Sketch points, lines, or polygons for annotation or data entry.
  • Persist geometry through CRUD hooks on MapDrawOption.

Props ​

Shared map control layout props (position, visibility, order) match other map controls.

PropDescriptionTypeRequiredDefault
drawOptionsOptional initial / bound draw session configMapDrawOptionfalseundefined

Prefer starting a session with useMapDraw(mapId).start(config) so CRUD and drawSupports stay in sync. See protocol.

Usage Notes ​

  • Place inside <Map> from @hungpvq/vue-map-core or @hungpvq/react-map-core.
  • Import package style.css.
  • Draft list registers as control id mapDrawDraftList when draft mode is enabled.

Lifecycle ​

  • On unmount (Vue onBeforeUnmount / React effect cleanup), DrawControl calls close(): removes Mapbox Draw listeners/control and hides the toolbar.
  • Domain store cleanup on removeMap ends an open draw session (config cleared + MAP_DRAW_EVENT.END) via ensureMapDrawStore factory cleanup — do not call useMapDrawStore from inside a custom cleanup callback (circular inference).
  • Shared draw modes / styles / create-mode effects live in @hungpvq/map-draw (getDrawCreateModeEffects, getDrawStyles, isDraftOption).

Thin host / createDrawSession ​

Vue and React useDrawEvents wrap Experimental createDrawSession (@hungpvq/map-draw):

Host actionSession API
draw.create / update / delete + map-click select/deletegetMapDrawHandlers / handleMapClick / selectMethod / startCreate
Toolbar Save (before store persist)prepareSave() — select mode + clear isDraw / current feature
Toolbar CancelfinishCancel(onCancel?) — optional feature callback, select reset, then redrawNonDraft() once
Non-draft redraw after delete/cancelredrawNonDraft() (no-op when option is draft)

Hosts still own save(...) / draft list UI, and cleanAfterDone deleteAll. Prefer Experimental createMapDrawControl for MapDraw construct + mount instead of inlining new MapDraw in adapters.

Vue ​

vue
<script setup lang="ts">
import type { MapSimple } from '@hungpvq/map-core';
import { DrawingType, type MapDrawOption } from '@hungpvq/map-draw';
import { Map } from '@hungpvq/vue-map-core';
import { DrawControl, useMapDraw } from '@hungpvq/vue-map-draw';
import '@hungpvq/vue-map-core/style.css';
import '@hungpvq/vue-map-draw/style.css';

const { start } = useMapDraw('demo');

function onMapLoaded(_map: MapSimple) {
  start({
    drawSupports: [DrawingType.POINT, DrawingType.LINE_STRING],
    cleanAfterDone: true,
    addFeature: async () => undefined,
    updateFeature: async () => undefined,
    deleteFeature: async () => undefined,
    selectFeature: async () => undefined,
    redraw: () => undefined,
  } satisfies MapDrawOption);
}
</script>

<template>
  <Map
    map-id="demo"
    @mapLoaded="onMapLoaded"
  >
    <DrawControl position="top-right" />
  </Map>
</template>

React ​

tsx
import type { MapSimple } from '@hungpvq/map-core';
import { DrawingType, type MapDrawOption } from '@hungpvq/map-draw';
import { Map } from '@hungpvq/react-map-core';
import { DrawControl, useMapDraw } from '@hungpvq/react-map-draw';
import '@hungpvq/react-map-core/style.css';
import '@hungpvq/react-map-draw/style.css';

export function Example() {
  const { start } = useMapDraw('demo');

  function onMapLoaded(_map: MapSimple) {
    const config: MapDrawOption = {
      drawSupports: [DrawingType.POINT, DrawingType.LINE_STRING],
      cleanAfterDone: true,
      addFeature: async () => undefined,
      updateFeature: async () => undefined,
      deleteFeature: async () => undefined,
      selectFeature: async () => undefined,
      redraw: () => undefined,
    };
    start(config);
  }

  return (
    <Map
      mapId="demo"
      onMapLoaded={onMapLoaded}
    >
      <DrawControl position="top-right" />
    </Map>
  );
}

Inspect (same package) ​

Export InspectControl from vue/react-map-draw with control id mapInspectControl. Both use shared InspectController from @hungpvq/map-draw (style toggle + popup/hover). See hub Inspect.

Accessibility ​

SurfaceContract
Draw toolbarrole="toolbar" + aria-label="Draw tools"
Mode / action buttonsMapControlButton title → accessible name (Cancel, Save, Close, Draw, Select, Delete, draft actions)
EscapeWhen focus is inside the draw toolbar and a draw is in progress (isDraw), Escape emits cancel (same as Cancel)

Document-level Escape for open panels remains on bindMapKeyboardShortcuts / the draggable shell; toolbar Escape only cancels an active draw when the toolbar chrome has focus.