@rural-environmental-registry/map_component 1.2.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,512 @@
1
+ <template>
2
+ <div
3
+ class="section-menu"
4
+ :class="{ 'section-menu--editing': isEditing }"
5
+ >
6
+ <div
7
+ v-if="sections.length"
8
+ class="section-menu-selector"
9
+ role="tablist"
10
+ aria-label="Seções do menu de camadas"
11
+ >
12
+ <button
13
+ v-for="item in sections"
14
+ :key="item.key"
15
+ type="button"
16
+ role="tab"
17
+ class="section-menu-selector-item"
18
+ :class="{ 'section-menu-selector-item--active': item.key === activeSectionKey }"
19
+ :aria-selected="item.key === activeSectionKey"
20
+ @click.stop="onSelectSection(item.key)"
21
+ >
22
+ {{ item.name || item.key }}
23
+ </button>
24
+ </div>
25
+
26
+ <template v-if="section">
27
+ <template v-if="isEditing && editingLayer && editingGroup">
28
+ <div class="section-edit-panel">
29
+ <ChildMenu
30
+ :actionDefaults="section.actionDefaults"
31
+ :data="editingLayer"
32
+ :groupKey="editingGroup.key"
33
+ :hideControls="true"
34
+ :persist="persist"
35
+ :sectionKey="section.key"
36
+ :visibilityMode="visibilityMode"
37
+ @onChildLayerToggle="emit('onChildLayerToggle', $event)"
38
+ @onLayerAction="emit('onLayerAction', $event)"
39
+ />
40
+
41
+ <div
42
+ v-if="editPanelActions.length"
43
+ class="section-edit-panel-actions"
44
+ >
45
+ <button
46
+ v-for="action in editPanelActions"
47
+ :key="action.key"
48
+ type="button"
49
+ class="section-edit-action-button"
50
+ :style="actionButtonStyle(action)"
51
+ :disabled="action.disabled"
52
+ @click.stop="onEditPanelAction(action)"
53
+ >
54
+ <FontAwesomeIcon
55
+ v-if="action.icon"
56
+ :iconName="action.icon"
57
+ />
58
+ <span>{{ action.name }}</span>
59
+ </button>
60
+ </div>
61
+
62
+ <div
63
+ v-if="editingMetrics.length"
64
+ class="section-edit-metrics"
65
+ >
66
+ <div
67
+ v-for="(metric, index) in editingMetrics"
68
+ :key="`${metric.title}-${metric.type}-${index}`"
69
+ class="section-metric-row"
70
+ >
71
+ <span class="section-metric-title">{{ metric.title }} :</span>
72
+ <span
73
+ class="section-metric-value-label"
74
+ :style="metricValueLabelStyle(metric)"
75
+ >
76
+ {{ metric.value }}
77
+ </span>
78
+ <span class="section-metric-type">{{ metric.type }}</span>
79
+ </div>
80
+ </div>
81
+
82
+ <div class="section-edit-footer">
83
+ <button
84
+ v-if="cancelAction.visible !== false"
85
+ type="button"
86
+ class="section-edit-footer-button"
87
+ :style="actionButtonStyle(cancelAction)"
88
+ :disabled="cancelAction.disabled"
89
+ @click.stop="onEditControlAction(cancelAction)"
90
+ >
91
+ <FontAwesomeIcon
92
+ v-if="cancelAction.icon"
93
+ :iconName="cancelAction.icon"
94
+ />
95
+ <span>{{ cancelAction.name }}</span>
96
+ </button>
97
+
98
+ <button
99
+ v-if="concludeAction.visible !== false"
100
+ type="button"
101
+ class="section-edit-footer-button section-edit-footer-button--end"
102
+ :style="actionButtonStyle(concludeAction)"
103
+ :disabled="concludeAction.disabled"
104
+ @click.stop="onEditControlAction(concludeAction)"
105
+ >
106
+ <FontAwesomeIcon
107
+ v-if="concludeAction.icon"
108
+ :iconName="concludeAction.icon"
109
+ />
110
+ <span>{{ concludeAction.name }}</span>
111
+ </button>
112
+ </div>
113
+ </div>
114
+ </template>
115
+
116
+ <template v-else>
117
+ <ParentMenu
118
+ v-for="group in section.groups"
119
+ :key="group.key"
120
+ :actionDefaults="section.actionDefaults"
121
+ :groupData="group"
122
+ :persist="persist"
123
+ :sectionKey="section.key"
124
+ :visibilityMode="visibilityMode"
125
+ @onChildLayerToggle="emit('onChildLayerToggle', $event)"
126
+ @onGroupLayerToggle="emit('onGroupLayerToggle', $event)"
127
+ @onLayerAction="emit('onLayerAction', $event)"
128
+ />
129
+ </template>
130
+ </template>
131
+ </div>
132
+ </template>
133
+
134
+ <script lang="ts" setup>
135
+ import { computed } from 'vue'
136
+ import FontAwesomeIcon from '../fa-icon/FontAwesomeIcon.vue'
137
+ import ParentMenu from './ParentMenu.vue'
138
+ import ChildMenu from './ChildMenu.vue'
139
+ import {
140
+ GroupLayerData,
141
+ LayerActionConfig,
142
+ LayerActionPayload,
143
+ LayerActionStyle,
144
+ LayerData,
145
+ LayerMetricsConfig,
146
+ SectionConfig
147
+ } from '../../types'
148
+ import {
149
+ resolveEditControlAction,
150
+ resolveLayerActions,
151
+ resolveLayerMetrics
152
+ } from '../../utils/layersConfigNormalizer'
153
+
154
+ const DEFAULT_ACTION_STYLE: Required<LayerActionStyle> = {
155
+ backgroundColor: 'var(--mapa-base-green)',
156
+ color: 'var(--mapa-base-white)',
157
+ borderColor: 'var(--mapa-base-white)'
158
+ }
159
+
160
+ const resolveActionStyle = (style?: LayerActionStyle): Required<LayerActionStyle> => {
161
+ const color = style?.color ?? DEFAULT_ACTION_STYLE.color
162
+ return {
163
+ backgroundColor: style?.backgroundColor ?? DEFAULT_ACTION_STYLE.backgroundColor,
164
+ color,
165
+ borderColor: style?.borderColor ?? color
166
+ }
167
+ }
168
+
169
+ const actionButtonStyle = (action: LayerActionConfig): Required<LayerActionStyle> =>
170
+ resolveActionStyle(action.style)
171
+
172
+ const firstColor = (...values: Array<string | null | undefined>): string | undefined =>
173
+ values.find((value) => typeof value === 'string' && value.trim() !== '')
174
+
175
+ const metricValueLabelStyle = (
176
+ metric: LayerMetricsConfig
177
+ ): Pick<Required<LayerActionStyle>, 'backgroundColor' | 'borderColor'> => {
178
+ const style = metric.style
179
+ return {
180
+ backgroundColor: firstColor(style?.backgroundColor) ?? '#ffffff',
181
+ borderColor: firstColor(style?.borderColor, style?.color) ?? 'transparent'
182
+ }
183
+ }
184
+
185
+ type SectionMenuProps = {
186
+ sections: SectionConfig[]
187
+ selectedSectionKey?: string | null
188
+ persist: boolean
189
+ editingLayerKey?: string | null
190
+ visibilityMode?: 'switch' | 'eye'
191
+ }
192
+
193
+ const props = withDefaults(defineProps<SectionMenuProps>(), {
194
+ visibilityMode: 'switch',
195
+ editingLayerKey: null,
196
+ selectedSectionKey: null
197
+ })
198
+
199
+ const emit = defineEmits<{
200
+ onChildLayerToggle: [LayerData]
201
+ onGroupLayerToggle: [GroupLayerData]
202
+ onLayerAction: [LayerActionPayload]
203
+ onSelectedSectionChange: [string]
204
+ }>()
205
+
206
+ const activeSectionKey = computed((): string | null => {
207
+ const sections = props.sections
208
+ if (!sections.length) return null
209
+
210
+ const selected = props.selectedSectionKey
211
+ if (selected && sections.some((item) => item.key === selected)) {
212
+ return selected
213
+ }
214
+
215
+ return sections[0].key
216
+ })
217
+
218
+ const section = computed((): SectionConfig | null => {
219
+ const key = activeSectionKey.value
220
+ if (!key) return null
221
+ return props.sections.find((item) => item.key === key) ?? null
222
+ })
223
+
224
+ const findLayerContext = (
225
+ layerKey: string | null | undefined
226
+ ): { layer: LayerData; group: GroupLayerData } | null => {
227
+ if (!layerKey || !section.value) return null
228
+ for (const group of section.value.groups) {
229
+ const layer = group.layers?.find((item) => item.key === layerKey)
230
+ if (layer) return { layer, group }
231
+ }
232
+ return null
233
+ }
234
+
235
+ const editingContext = computed(() => findLayerContext(props.editingLayerKey))
236
+ const editingLayer = computed(() => editingContext.value?.layer ?? null)
237
+ const editingGroup = computed(() => editingContext.value?.group ?? null)
238
+ const isEditing = computed(() => !!editingLayer.value)
239
+
240
+ const editingMetrics = computed((): LayerMetricsConfig[] =>
241
+ resolveLayerMetrics(editingLayer.value)
242
+ )
243
+
244
+ const editPanelActions = computed((): LayerActionConfig[] => {
245
+ const layer = editingLayer.value
246
+ const currentSection = section.value
247
+ if (!layer || !currentSection) return []
248
+
249
+ const sourceActions =
250
+ Array.isArray(layer.editActions) && layer.editActions.length > 0
251
+ ? layer.editActions
252
+ : resolveLayerActions(layer, currentSection.actionDefaults)
253
+
254
+ return sourceActions.filter((action) => action.visible !== false)
255
+ })
256
+
257
+ const cancelAction = computed(() =>
258
+ resolveEditControlAction(section.value?.actionDefaults, 'cancel')
259
+ )
260
+
261
+ const concludeAction = computed(() =>
262
+ resolveEditControlAction(section.value?.actionDefaults, 'conclude')
263
+ )
264
+
265
+ const onSelectSection = (sectionKey: string): void => {
266
+ if (sectionKey === activeSectionKey.value) return
267
+ emit('onSelectedSectionChange', sectionKey)
268
+ }
269
+
270
+ const emitEditPanelAction = (action: LayerActionConfig): void => {
271
+ const layer = editingLayer.value
272
+ const currentSection = section.value
273
+ if (!layer || !currentSection || action.disabled) return
274
+
275
+ emit('onLayerAction', {
276
+ actionKey: action.key,
277
+ actionType: action.type,
278
+ sectionKey: currentSection.key,
279
+ groupKey: editingGroup.value?.key,
280
+ layerKey: layer.key,
281
+ layer,
282
+ source: 'edit-panel'
283
+ })
284
+ }
285
+
286
+ const onEditPanelAction = (action: LayerActionConfig): void => {
287
+ emitEditPanelAction(action)
288
+ }
289
+
290
+ const onEditControlAction = (action: LayerActionConfig): void => {
291
+ emitEditPanelAction(action)
292
+ }
293
+ </script>
294
+
295
+ <style>
296
+ .section-menu {
297
+ display: flex;
298
+ flex-direction: column;
299
+ gap: var(--mapa-size-base-5);
300
+ }
301
+
302
+ .section-menu--editing {
303
+ flex: 1 1 auto;
304
+ min-height: 100%;
305
+ }
306
+
307
+ .section-menu-selector {
308
+ display: flex;
309
+ flex-direction: row;
310
+ flex-wrap: nowrap;
311
+ align-items: stretch;
312
+ gap: var(--mapa-size-base-5);
313
+ width: 100%;
314
+ box-sizing: border-box;
315
+ padding: var(--mapa-size-base-5) var(--mapa-size-base-10);
316
+ border-bottom: var(--mapa-size-base-1) solid rgba(0, 0, 0, 0.08);
317
+ }
318
+
319
+ .section-menu-selector-item {
320
+ display: inline-flex;
321
+ align-items: center;
322
+ justify-content: center;
323
+ flex: 1 1 0;
324
+ min-width: 0;
325
+ min-height: var(--mapa-size-base-30);
326
+ height: auto;
327
+ padding: var(--mapa-size-base-5) var(--mapa-size-base-10);
328
+ border: none;
329
+ border-bottom: var(--mapa-size-base-2) solid transparent;
330
+ border-radius: 0;
331
+ background: transparent;
332
+ color: var(--mapa-base-gray);
333
+ font-size: var(--mapa-fs-12);
334
+ font-weight: 600;
335
+ text-align: center;
336
+ white-space: normal;
337
+ overflow-wrap: break-word;
338
+ word-break: normal;
339
+ line-height: 1.3;
340
+ cursor: pointer;
341
+ }
342
+
343
+ .section-menu-selector-item:hover {
344
+ color: var(--mapa-base-green);
345
+ }
346
+
347
+ .section-menu-selector-item--active {
348
+ color: var(--mapa-base-green);
349
+ border-bottom-color: var(--mapa-base-green);
350
+ }
351
+
352
+ .section-edit-panel {
353
+ display: flex;
354
+ flex-direction: column;
355
+ flex: 1 1 auto;
356
+ min-height: 0;
357
+ width: 100%;
358
+ }
359
+
360
+ .section-edit-panel .child-menu {
361
+ padding-left: var(--mapa-size-base-20) !important;
362
+ padding-right: var(--mapa-size-base-20) !important;
363
+ }
364
+
365
+ .section-edit-metrics {
366
+ display: flex;
367
+ flex-direction: column;
368
+ align-items: stretch;
369
+ gap: var(--mapa-size-base-5);
370
+ width: 100%;
371
+ box-sizing: border-box;
372
+ margin-top: var(--mapa-size-base-15);
373
+ padding: var(--mapa-size-base-10) var(--mapa-size-base-20);
374
+ }
375
+
376
+ .section-metric-row {
377
+ display: flex;
378
+ flex: 0 0 auto;
379
+ flex-wrap: nowrap;
380
+ align-items: center;
381
+ justify-content: flex-start;
382
+ gap: var(--mapa-size-base-5);
383
+ width: 100%;
384
+ height: var(--mapa-size-base-40);
385
+ padding: 0 var(--mapa-size-base-10);
386
+ box-sizing: border-box;
387
+ font-size: var(--mapa-fs-12);
388
+ color: #000000;
389
+ white-space: nowrap;
390
+ overflow: hidden;
391
+ text-overflow: ellipsis;
392
+ font-weight: bold;
393
+ }
394
+
395
+ .section-metric-title {
396
+ flex-shrink: 0;
397
+ color: #000000;
398
+ }
399
+
400
+ .section-metric-value-label {
401
+ display: inline-flex;
402
+ flex-shrink: 0;
403
+ align-items: center;
404
+ justify-content: center;
405
+ height: var(--mapa-size-base-20);
406
+ padding: 0 var(--mapa-size-base-8);
407
+ border: 1px solid;
408
+ border-radius: 100em;
409
+ font-size: var(--mapa-fs-12);
410
+ font-weight: 600;
411
+ line-height: 1;
412
+ color: #000000;
413
+ }
414
+
415
+ .section-metric-type {
416
+ flex-shrink: 0;
417
+ color: #000000;
418
+ }
419
+
420
+ .section-edit-panel-actions {
421
+ display: flex;
422
+ flex-direction: column;
423
+ align-items: stretch;
424
+ gap: var(--mapa-size-base-5);
425
+ width: 100%;
426
+ box-sizing: border-box;
427
+ padding: var(--mapa-size-base-10) var(--mapa-size-base-20);
428
+ }
429
+ .section-edit-action-button {
430
+ display: inline-flex;
431
+ flex: 0 0 auto;
432
+ align-items: center;
433
+ justify-content: center;
434
+ gap: var(--mapa-size-base-5);
435
+ width: 100%;
436
+ height: var(--mapa-size-base-40);
437
+ padding: 0 var(--mapa-size-base-10);
438
+ border: 1px solid;
439
+ border-radius: 100em;
440
+ font-size: var(--mapa-fs-15);
441
+ font-weight: 600;
442
+ white-space: nowrap;
443
+ overflow: hidden;
444
+ text-overflow: ellipsis;
445
+ position: relative;
446
+ text-align: center;
447
+ vertical-align: middle;
448
+ cursor: pointer;
449
+ margin-top: var(--mapa-size-base-20);
450
+ }
451
+
452
+ .section-edit-action-button:not(:disabled):hover {
453
+ background-image: linear-gradient(rgba(0, 0, 0, 0.16), rgba(0, 0, 0, 0.16));
454
+ }
455
+
456
+ .section-edit-action-button:not(:disabled):active {
457
+ background-image: linear-gradient(rgba(0, 0, 0, 0.32), rgba(0, 0, 0, 0.32));
458
+ }
459
+
460
+ .section-edit-action-button:disabled {
461
+ opacity: 0.5;
462
+ cursor: not-allowed;
463
+ }
464
+
465
+ .section-edit-footer {
466
+ display: flex;
467
+ justify-content: space-between;
468
+ align-items: center;
469
+ gap: var(--mapa-size-base-5);
470
+ width: 100%;
471
+ box-sizing: border-box;
472
+ margin-top: auto;
473
+ padding: var(--mapa-size-base-10) var(--mapa-size-base-20);
474
+ }
475
+
476
+ .section-edit-footer-button {
477
+ display: inline-flex;
478
+ align-items: center;
479
+ justify-content: center;
480
+ gap: var(--mapa-size-base-5);
481
+ height: var(--mapa-size-base-40);
482
+ padding: 0 var(--mapa-size-base-20);
483
+ border: 1px solid;
484
+ border-radius: 100em;
485
+ font-size: var(--mapa-fs-15);
486
+ font-weight: 600;
487
+ white-space: nowrap;
488
+ overflow: hidden;
489
+ text-overflow: ellipsis;
490
+ position: relative;
491
+ text-align: center;
492
+ vertical-align: middle;
493
+ cursor: pointer;
494
+ }
495
+
496
+ .section-edit-footer-button--end {
497
+ margin-left: auto;
498
+ }
499
+
500
+ .section-edit-footer-button:not(:disabled):hover {
501
+ background-image: linear-gradient(rgba(0, 0, 0, 0.16), rgba(0, 0, 0, 0.16));
502
+ }
503
+
504
+ .section-edit-footer-button:not(:disabled):active {
505
+ background-image: linear-gradient(rgba(0, 0, 0, 0.32), rgba(0, 0, 0, 0.32));
506
+ }
507
+
508
+ .section-edit-footer-button:disabled {
509
+ opacity: 0.5;
510
+ cursor: not-allowed;
511
+ }
512
+ </style>
@@ -198,7 +198,9 @@ export default class MapToolsHandler {
198
198
 
199
199
  this._control = new MapToolsControl()
200
200
  this._map.addControl(this._control)
201
- this.removeNativeZoomControl()
201
+ if (config.zoom?.show !== false) {
202
+ this.removeNativeZoomControl()
203
+ }
202
204
  this.alignTopRightControls()
203
205
  }
204
206
 
@@ -16,7 +16,7 @@ type MeasureToolsCallbacks = {
16
16
  type MeasureMode = 'line' | 'polygon'
17
17
 
18
18
  const LINE_ICON =
19
- '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 20L20 4"/><circle cx="6" cy="18" r="1.5" fill="currentColor" stroke="none"/><circle cx="18" cy="6" r="1.5" fill="currentColor" stroke="none"/></svg>'
19
+ '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21.3 15.3a2.4 2.4 0 0 1 0 3.4l-2.6 2.6a2.4 2.4 0 0 1-3.4 0L2.7 8.7a2.41 2.41 0 0 1 0-3.4l2.6-2.6a2.41 2.41 0 0 1 3.4 0Z"/><path d="m14.5 12.5 2-2"/><path d="m11.5 9.5 2-2"/><path d="m8.5 6.5 2-2"/><path d="m17.5 15.5 2-2"/></svg>'
20
20
 
21
21
  const POLYGON_ICON =
22
22
  '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2l8 5v10l-8 5-8-5V7z"/></svg>'
@@ -135,28 +135,34 @@ export default class MeasureToolsHandler {
135
135
  )
136
136
  }
137
137
 
138
- handler._interactionPanel = L.DomUtil.create('div', 'measure-tools-interaction js-measure-interaction', container)
139
- handler._interactionPanel.style.display = 'none'
140
- handler._interactionPanel.innerHTML = handler.buildInteractionHtml(config)
141
-
142
- handler._resultsEl = handler._interactionPanel.querySelector('.js-results')
143
- handler._helpEl = handler._interactionPanel.querySelector('.js-measure-help')
144
-
145
- const cancelBtn = handler._interactionPanel.querySelector('.js-cancel')
146
- const finishBtn = handler._interactionPanel.querySelector('.js-finish')
147
-
148
- if (cancelBtn instanceof HTMLElement) {
149
- L.DomEvent.on(cancelBtn, 'click', (e) => {
150
- L.DomEvent.stop(e)
151
- handler.cancel()
152
- })
153
- }
154
-
155
- if (finishBtn instanceof HTMLElement) {
156
- L.DomEvent.on(finishBtn, 'click', (e) => {
157
- L.DomEvent.stop(e)
158
- handler.finishDrawing()
159
- })
138
+ if (handler.isInteractionPanelEnabled()) {
139
+ handler._interactionPanel = L.DomUtil.create(
140
+ 'div',
141
+ 'measure-tools-interaction js-measure-interaction',
142
+ container
143
+ )
144
+ handler._interactionPanel.style.display = 'none'
145
+ handler._interactionPanel.innerHTML = handler.buildInteractionHtml(config)
146
+
147
+ handler._resultsEl = handler._interactionPanel.querySelector('.js-results')
148
+ handler._helpEl = handler._interactionPanel.querySelector('.js-measure-help')
149
+
150
+ const cancelBtn = handler._interactionPanel.querySelector('.js-cancel')
151
+ const finishBtn = handler._interactionPanel.querySelector('.js-finish')
152
+
153
+ if (cancelBtn instanceof HTMLElement) {
154
+ L.DomEvent.on(cancelBtn, 'click', (e) => {
155
+ L.DomEvent.stop(e)
156
+ handler.cancel()
157
+ })
158
+ }
159
+
160
+ if (finishBtn instanceof HTMLElement) {
161
+ L.DomEvent.on(finishBtn, 'click', (e) => {
162
+ L.DomEvent.stop(e)
163
+ handler.finishDrawing()
164
+ })
165
+ }
160
166
  }
161
167
 
162
168
  L.DomEvent.disableClickPropagation(container)
@@ -170,6 +176,10 @@ export default class MeasureToolsHandler {
170
176
  this._control.addTo(this._map)
171
177
  }
172
178
 
179
+ private isInteractionPanelEnabled(): boolean {
180
+ return this._config.showInteractionPanel !== false
181
+ }
182
+
173
183
  private buildInteractionHtml(config: MapToolsConfig): string {
174
184
  const title = config.texts?.measurePanelTitle ?? 'Measure distances and areas'
175
185
  const cancel = config.texts?.measureCancel ?? 'Cancel'
@@ -228,6 +238,7 @@ export default class MeasureToolsHandler {
228
238
  this.setMeasureActive(true)
229
239
  this.updateButtons()
230
240
  this.showInteractionPanel(mode)
241
+ document.addEventListener('keydown', this._boundEscapeKey)
231
242
 
232
243
  if (this._map.doubleClickZoom.enabled()) {
233
244
  this._map.doubleClickZoom.disable()
@@ -271,6 +282,7 @@ export default class MeasureToolsHandler {
271
282
  this._map.options.zoomAnimation = this._restoreZoomAnimation
272
283
  this.updateButtons()
273
284
  this.hideInteractionPanel()
285
+ document.removeEventListener('keydown', this._boundEscapeKey)
274
286
 
275
287
  if (!this._map.doubleClickZoom.enabled()) {
276
288
  this._map.doubleClickZoom.enable()
@@ -377,7 +389,7 @@ export default class MeasureToolsHandler {
377
389
  }
378
390
 
379
391
  private showInteractionPanel(mode: MeasureMode): void {
380
- if (!this._interactionPanel || !this._helpEl) return
392
+ if (!this.isInteractionPanelEnabled() || !this._interactionPanel || !this._helpEl) return
381
393
 
382
394
  this._interactionPanel.style.removeProperty('display')
383
395
  this._interactionPanel.closest('.leaflet-control-measure-tools')?.classList.add('measure-tools-expanded')
@@ -395,8 +407,6 @@ export default class MeasureToolsHandler {
395
407
  if (this._resultsEl) {
396
408
  this._resultsEl.innerHTML = ''
397
409
  }
398
-
399
- document.addEventListener('keydown', this._boundEscapeKey)
400
410
  }
401
411
 
402
412
  private hideInteractionPanel(): void {
@@ -404,7 +414,6 @@ export default class MeasureToolsHandler {
404
414
 
405
415
  this._interactionPanel.style.display = 'none'
406
416
  this._interactionPanel.closest('.leaflet-control-measure-tools')?.classList.remove('measure-tools-expanded')
407
- document.removeEventListener('keydown', this._boundEscapeKey)
408
417
  }
409
418
 
410
419
  private updateButtons(): void {
@@ -36,6 +36,7 @@ export const DEFAULT_MAP_TOOLS: MapToolsConfig = {
36
36
  show: true,
37
37
  title: 'Measure polygon'
38
38
  },
39
+ showInteractionPanel: true,
39
40
  texts: {
40
41
  measureResult: 'Measurement',
41
42
  measureLength: 'Distance',
package/src/index.ts CHANGED
@@ -3,4 +3,51 @@ import MapaDPG from './components/MapDPG.vue'
3
3
  export { createStableMarker, bindMarkerZoomStability, STABLE_MARKER_DEFAULTS } from './utils/stableMarker'
4
4
  export type { StableMarkerOptions } from './utils/stableMarker'
5
5
 
6
+ export type {
7
+ FaIconName,
8
+ SectionConfig,
9
+ SectionData,
10
+ SectionEditStatePayload,
11
+ SectionSelectPayload,
12
+ LayerActionConfig,
13
+ LayerActionStyle,
14
+ LayerActionDefaultItem,
15
+ LayerActionDefaults,
16
+ LayerActionPayload,
17
+ LayerMetricsConfig,
18
+ LayerMetrics,
19
+ LayerMetricsMap,
20
+ LayerInfoIconConfig,
21
+ LayerInfoIconsMap,
22
+ GroupActionConfig,
23
+ GroupActionsMap,
24
+ LayerData,
25
+ GroupLayerData,
26
+ LayersConfig,
27
+ LayersMenuConfig,
28
+ MapLayers,
29
+ MapOptionsConfig,
30
+ DrawingEvent,
31
+ MeasureCompleteEvent,
32
+ DescriptiveMemorial
33
+ } from './types'
34
+
35
+ export {
36
+ normalizeLayersConfig,
37
+ isSectionConfig,
38
+ isGroupConfig,
39
+ resolveLayerActions,
40
+ resolveEditControlAction,
41
+ shouldApplyMapOverlay,
42
+ isMenuSeparator,
43
+ collectLayerMetricsMap,
44
+ resolveLayerMetrics,
45
+ collectLayerInfoIconsMap,
46
+ resolveActiveLayerInfoIcons,
47
+ collectGroupActionsMap,
48
+ resolveActiveGroupActions,
49
+ withLayerInfoIconActive,
50
+ withGroupActionActive
51
+ } from './utils/layersConfigNormalizer'
52
+
6
53
  export default MapaDPG