maplibre-gl-geo-editor 0.1.0

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,499 @@
1
+ /* ============================================================================
2
+ GeoEditor Control Styles
3
+ ============================================================================ */
4
+
5
+ /* Base control container */
6
+ .geo-editor-control {
7
+ background: transparent;
8
+ box-shadow: none;
9
+ }
10
+
11
+ /* Toolbar container */
12
+ .geo-editor-toolbar {
13
+ display: inline-flex;
14
+ gap: 4px;
15
+ padding: 4px;
16
+ background: #fff;
17
+ border-radius: 4px;
18
+ box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.1);
19
+ }
20
+
21
+ /* Collapsed toolbar - minimal padding and no gap */
22
+ .geo-editor-toolbar--collapsed {
23
+ padding: 0;
24
+ gap: 0;
25
+ }
26
+
27
+ .geo-editor-toolbar--vertical {
28
+ flex-direction: column;
29
+ }
30
+
31
+ .geo-editor-toolbar--horizontal {
32
+ flex-direction: row;
33
+ }
34
+
35
+ /* Tools wrapper (for collapse/expand functionality) */
36
+ .geo-editor-tools-wrapper {
37
+ display: flex;
38
+ flex-direction: column;
39
+ gap: 4px;
40
+ }
41
+
42
+ .geo-editor-toolbar--horizontal .geo-editor-tools-wrapper {
43
+ flex-direction: row;
44
+ }
45
+
46
+ /* Collapse button */
47
+ .geo-editor-collapse-btn {
48
+ margin-bottom: 4px;
49
+ flex-shrink: 0;
50
+ width: 30px;
51
+ height: 30px;
52
+ }
53
+
54
+ .geo-editor-toolbar--horizontal .geo-editor-collapse-btn {
55
+ margin-bottom: 0;
56
+ margin-right: 4px;
57
+ }
58
+
59
+ /* No margin when collapsed */
60
+ .geo-editor-toolbar--collapsed .geo-editor-collapse-btn {
61
+ margin: 0;
62
+ }
63
+
64
+ /* Tool group */
65
+ .geo-editor-tool-group {
66
+ display: flex;
67
+ flex-direction: column;
68
+ gap: 2px;
69
+ }
70
+
71
+ .geo-editor-toolbar--horizontal .geo-editor-tool-group {
72
+ flex-direction: row;
73
+ }
74
+
75
+ .geo-editor-tool-group:not(:last-child) {
76
+ padding-bottom: 4px;
77
+ border-bottom: 1px solid #e5e5e5;
78
+ }
79
+
80
+ .geo-editor-toolbar--horizontal .geo-editor-tool-group:not(:last-child) {
81
+ padding-bottom: 0;
82
+ padding-right: 4px;
83
+ border-bottom: none;
84
+ border-right: 1px solid #e5e5e5;
85
+ }
86
+
87
+ .geo-editor-tool-group-label {
88
+ font-size: 9px;
89
+ font-weight: 600;
90
+ text-transform: uppercase;
91
+ color: #666;
92
+ padding: 2px 4px;
93
+ letter-spacing: 0.5px;
94
+ }
95
+
96
+ .geo-editor-tool-buttons {
97
+ display: flex;
98
+ flex-direction: column;
99
+ gap: 2px;
100
+ }
101
+
102
+ .geo-editor-toolbar--horizontal .geo-editor-tool-buttons {
103
+ flex-direction: row;
104
+ }
105
+
106
+ /* Tool button */
107
+ .geo-editor-tool-button {
108
+ display: flex;
109
+ align-items: center;
110
+ justify-content: center;
111
+ width: 30px;
112
+ height: 30px;
113
+ padding: 0;
114
+ border: none;
115
+ border-radius: 4px;
116
+ background: #f5f5f5;
117
+ color: #333;
118
+ cursor: pointer;
119
+ transition: all 0.15s ease;
120
+ }
121
+
122
+ .geo-editor-tool-button:hover {
123
+ background: #e8e8e8;
124
+ }
125
+
126
+ .geo-editor-tool-button:active {
127
+ background: #ddd;
128
+ }
129
+
130
+ .geo-editor-tool-button--active,
131
+ .geo-editor-tool-button.geo-editor-tool-button--active {
132
+ background: #3388ff !important;
133
+ background-color: #3388ff !important;
134
+ color: #fff !important;
135
+ }
136
+
137
+ .geo-editor-tool-button--active:hover,
138
+ .geo-editor-tool-button.geo-editor-tool-button--active:hover {
139
+ background: #2277ee !important;
140
+ background-color: #2277ee !important;
141
+ }
142
+
143
+ .geo-editor-tool-button:disabled {
144
+ opacity: 0.5;
145
+ cursor: not-allowed;
146
+ }
147
+
148
+ .geo-editor-tool-button svg {
149
+ width: 18px;
150
+ height: 18px;
151
+ }
152
+
153
+ /* Active button icons - force white color with high specificity */
154
+ .geo-editor-tool-button--active svg {
155
+ color: #fff !important;
156
+ }
157
+
158
+ .geo-editor-tool-button--active svg path,
159
+ .geo-editor-tool-button--active svg polygon,
160
+ .geo-editor-tool-button--active svg rect,
161
+ .geo-editor-tool-button--active svg circle,
162
+ .geo-editor-tool-button--active svg ellipse,
163
+ .geo-editor-tool-button--active svg line,
164
+ .geo-editor-tool-button--active svg text {
165
+ fill: #fff !important;
166
+ color: #fff !important;
167
+ }
168
+
169
+ /* For stroke-only elements - stroke white, preserve fill:none */
170
+ .geo-editor-tool-button--active svg path[fill="none"],
171
+ .geo-editor-tool-button--active svg polygon[fill="none"],
172
+ .geo-editor-tool-button--active svg rect[fill="none"],
173
+ .geo-editor-tool-button--active svg circle[fill="none"],
174
+ .geo-editor-tool-button--active svg ellipse[fill="none"],
175
+ .geo-editor-tool-button--active svg line[fill="none"] {
176
+ fill: none !important;
177
+ stroke: #fff !important;
178
+ }
179
+
180
+ /* Elements with explicit stroke attribute */
181
+ .geo-editor-tool-button--active svg [stroke],
182
+ .geo-editor-tool-button--active svg path[stroke],
183
+ .geo-editor-tool-button--active svg polygon[stroke],
184
+ .geo-editor-tool-button--active svg rect[stroke],
185
+ .geo-editor-tool-button--active svg circle[stroke],
186
+ .geo-editor-tool-button--active svg ellipse[stroke],
187
+ .geo-editor-tool-button--active svg line[stroke] {
188
+ stroke: #fff !important;
189
+ }
190
+
191
+ /* Tooltip styling */
192
+ .geo-editor-tool-button[title] {
193
+ position: relative;
194
+ }
195
+
196
+ /* ============================================================================
197
+ Dialog Styles
198
+ ============================================================================ */
199
+
200
+ .geo-editor-dialog-overlay {
201
+ position: fixed;
202
+ top: 0;
203
+ left: 0;
204
+ right: 0;
205
+ bottom: 0;
206
+ background: rgba(0, 0, 0, 0.5);
207
+ display: flex;
208
+ align-items: center;
209
+ justify-content: center;
210
+ z-index: 10000;
211
+ }
212
+
213
+ .geo-editor-dialog {
214
+ background: #fff;
215
+ border-radius: 8px;
216
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
217
+ max-width: 400px;
218
+ width: 90%;
219
+ max-height: 80vh;
220
+ overflow: auto;
221
+ }
222
+
223
+ .geo-editor-dialog-header {
224
+ display: flex;
225
+ align-items: center;
226
+ justify-content: space-between;
227
+ padding: 16px 20px;
228
+ border-bottom: 1px solid #e5e5e5;
229
+ }
230
+
231
+ .geo-editor-dialog-title {
232
+ font-size: 16px;
233
+ font-weight: 600;
234
+ color: #333;
235
+ margin: 0;
236
+ }
237
+
238
+ .geo-editor-dialog-close {
239
+ display: flex;
240
+ align-items: center;
241
+ justify-content: center;
242
+ width: 28px;
243
+ height: 28px;
244
+ padding: 0;
245
+ border: none;
246
+ border-radius: 4px;
247
+ background: transparent;
248
+ color: #666;
249
+ cursor: pointer;
250
+ transition: all 0.15s ease;
251
+ }
252
+
253
+ .geo-editor-dialog-close:hover {
254
+ background: #f5f5f5;
255
+ color: #333;
256
+ }
257
+
258
+ .geo-editor-dialog-body {
259
+ padding: 20px;
260
+ }
261
+
262
+ .geo-editor-dialog-footer {
263
+ display: flex;
264
+ gap: 8px;
265
+ justify-content: flex-end;
266
+ padding: 16px 20px;
267
+ border-top: 1px solid #e5e5e5;
268
+ }
269
+
270
+ /* ============================================================================
271
+ Form Controls
272
+ ============================================================================ */
273
+
274
+ .geo-editor-form-group {
275
+ margin-bottom: 16px;
276
+ }
277
+
278
+ .geo-editor-form-group:last-child {
279
+ margin-bottom: 0;
280
+ }
281
+
282
+ .geo-editor-label {
283
+ display: block;
284
+ font-size: 13px;
285
+ font-weight: 500;
286
+ color: #333;
287
+ margin-bottom: 6px;
288
+ }
289
+
290
+ .geo-editor-input {
291
+ width: 100%;
292
+ padding: 8px 12px;
293
+ border: 1px solid #ddd;
294
+ border-radius: 4px;
295
+ font-size: 14px;
296
+ transition: border-color 0.15s ease;
297
+ }
298
+
299
+ .geo-editor-input:focus {
300
+ outline: none;
301
+ border-color: #3388ff;
302
+ box-shadow: 0 0 0 3px rgba(51, 136, 255, 0.1);
303
+ }
304
+
305
+ .geo-editor-slider {
306
+ width: 100%;
307
+ height: 6px;
308
+ border-radius: 3px;
309
+ background: #e5e5e5;
310
+ appearance: none;
311
+ cursor: pointer;
312
+ }
313
+
314
+ .geo-editor-slider::-webkit-slider-thumb {
315
+ appearance: none;
316
+ width: 16px;
317
+ height: 16px;
318
+ border-radius: 50%;
319
+ background: #3388ff;
320
+ cursor: pointer;
321
+ transition: transform 0.15s ease;
322
+ }
323
+
324
+ .geo-editor-slider::-webkit-slider-thumb:hover {
325
+ transform: scale(1.1);
326
+ }
327
+
328
+ .geo-editor-slider::-moz-range-thumb {
329
+ width: 16px;
330
+ height: 16px;
331
+ border: none;
332
+ border-radius: 50%;
333
+ background: #3388ff;
334
+ cursor: pointer;
335
+ }
336
+
337
+ /* ============================================================================
338
+ Buttons
339
+ ============================================================================ */
340
+
341
+ .geo-editor-btn {
342
+ display: inline-flex;
343
+ align-items: center;
344
+ justify-content: center;
345
+ gap: 6px;
346
+ padding: 8px 16px;
347
+ border: none;
348
+ border-radius: 4px;
349
+ font-size: 14px;
350
+ font-weight: 500;
351
+ cursor: pointer;
352
+ transition: all 0.15s ease;
353
+ }
354
+
355
+ .geo-editor-btn--primary {
356
+ background: #3388ff;
357
+ color: #fff;
358
+ }
359
+
360
+ .geo-editor-btn--primary:hover {
361
+ background: #2277ee;
362
+ }
363
+
364
+ .geo-editor-btn--secondary {
365
+ background: #f5f5f5;
366
+ color: #333;
367
+ }
368
+
369
+ .geo-editor-btn--secondary:hover {
370
+ background: #e8e8e8;
371
+ }
372
+
373
+ .geo-editor-btn--danger {
374
+ background: #dc3545;
375
+ color: #fff;
376
+ }
377
+
378
+ .geo-editor-btn--danger:hover {
379
+ background: #c82333;
380
+ }
381
+
382
+ .geo-editor-btn:disabled {
383
+ opacity: 0.5;
384
+ cursor: not-allowed;
385
+ }
386
+
387
+ /* ============================================================================
388
+ Stats Display
389
+ ============================================================================ */
390
+
391
+ .geo-editor-stats {
392
+ display: flex;
393
+ gap: 20px;
394
+ padding: 12px;
395
+ background: #f8f9fa;
396
+ border-radius: 4px;
397
+ margin-bottom: 16px;
398
+ }
399
+
400
+ .geo-editor-stat {
401
+ display: flex;
402
+ flex-direction: column;
403
+ align-items: center;
404
+ }
405
+
406
+ .geo-editor-stat-value {
407
+ font-size: 20px;
408
+ font-weight: 600;
409
+ color: #333;
410
+ }
411
+
412
+ .geo-editor-stat-label {
413
+ font-size: 11px;
414
+ text-transform: uppercase;
415
+ color: #666;
416
+ letter-spacing: 0.5px;
417
+ }
418
+
419
+ .geo-editor-stat--highlight .geo-editor-stat-value {
420
+ color: #3388ff;
421
+ }
422
+
423
+ .geo-editor-stat--success .geo-editor-stat-value {
424
+ color: #28a745;
425
+ }
426
+
427
+ /* ============================================================================
428
+ Messages
429
+ ============================================================================ */
430
+
431
+ .geo-editor-message {
432
+ padding: 12px 16px;
433
+ border-radius: 4px;
434
+ font-size: 13px;
435
+ margin-bottom: 16px;
436
+ }
437
+
438
+ .geo-editor-message--info {
439
+ background: #e7f3ff;
440
+ color: #0056b3;
441
+ border: 1px solid #b8daff;
442
+ }
443
+
444
+ .geo-editor-message--warning {
445
+ background: #fff3cd;
446
+ color: #856404;
447
+ border: 1px solid #ffeeba;
448
+ }
449
+
450
+ .geo-editor-message--error {
451
+ background: #f8d7da;
452
+ color: #721c24;
453
+ border: 1px solid #f5c6cb;
454
+ }
455
+
456
+ .geo-editor-message--success {
457
+ background: #d4edda;
458
+ color: #155724;
459
+ border: 1px solid #c3e6cb;
460
+ }
461
+
462
+ /* ============================================================================
463
+ Selection Highlight
464
+ ============================================================================ */
465
+
466
+ .geo-editor-selection-highlight {
467
+ stroke: #3388ff;
468
+ stroke-width: 3;
469
+ stroke-dasharray: 5, 5;
470
+ fill: rgba(51, 136, 255, 0.1);
471
+ animation: geo-editor-dash 0.5s linear infinite;
472
+ }
473
+
474
+ @keyframes geo-editor-dash {
475
+ to {
476
+ stroke-dashoffset: -10;
477
+ }
478
+ }
479
+
480
+ /* ============================================================================
481
+ Responsive Adjustments
482
+ ============================================================================ */
483
+
484
+ @media (max-width: 768px) {
485
+ .geo-editor-toolbar {
486
+ padding: 2px;
487
+ }
488
+
489
+ .geo-editor-tool-button {
490
+ width: 36px;
491
+ height: 36px;
492
+ }
493
+
494
+ .geo-editor-dialog {
495
+ max-width: 95%;
496
+ margin: 10px;
497
+ }
498
+ }
499
+
package/dist/react.cjs ADDED
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const react = require("react");
4
+ const index = require("./index.cjs");
5
+ function GeoEditorReact({
6
+ map,
7
+ geoman,
8
+ position = "top-left",
9
+ ...options
10
+ }) {
11
+ const controlRef = react.useRef(null);
12
+ react.useEffect(() => {
13
+ if (!map) return;
14
+ const control = new index.GeoEditor({ ...options, position });
15
+ controlRef.current = control;
16
+ map.addControl(control, position);
17
+ if (geoman) {
18
+ control.setGeoman(geoman);
19
+ }
20
+ return () => {
21
+ if (controlRef.current) {
22
+ map.removeControl(controlRef.current);
23
+ controlRef.current = null;
24
+ }
25
+ };
26
+ }, [map, position]);
27
+ react.useEffect(() => {
28
+ if (controlRef.current && geoman) {
29
+ controlRef.current.setGeoman(geoman);
30
+ }
31
+ }, [geoman]);
32
+ return null;
33
+ }
34
+ function useGeoEditor(map, options = {}) {
35
+ const controlRef = react.useRef(null);
36
+ react.useEffect(() => {
37
+ if (!map) return;
38
+ const control = new index.GeoEditor(options);
39
+ controlRef.current = control;
40
+ map.addControl(control, options.position || "top-left");
41
+ return () => {
42
+ if (controlRef.current) {
43
+ map.removeControl(controlRef.current);
44
+ controlRef.current = null;
45
+ }
46
+ };
47
+ }, [map]);
48
+ const enableDrawMode = react.useCallback((mode) => {
49
+ var _a;
50
+ (_a = controlRef.current) == null ? void 0 : _a.enableDrawMode(mode);
51
+ }, []);
52
+ const enableEditMode = react.useCallback((mode) => {
53
+ var _a;
54
+ (_a = controlRef.current) == null ? void 0 : _a.enableEditMode(mode);
55
+ }, []);
56
+ const disableAllModes = react.useCallback(() => {
57
+ var _a;
58
+ (_a = controlRef.current) == null ? void 0 : _a.disableAllModes();
59
+ }, []);
60
+ const copySelected = react.useCallback(() => {
61
+ var _a;
62
+ (_a = controlRef.current) == null ? void 0 : _a.copySelectedFeatures();
63
+ }, []);
64
+ const pasteFeatures = react.useCallback(() => {
65
+ var _a;
66
+ (_a = controlRef.current) == null ? void 0 : _a.pasteFeatures();
67
+ }, []);
68
+ const deleteSelected = react.useCallback(() => {
69
+ var _a;
70
+ (_a = controlRef.current) == null ? void 0 : _a.deleteSelectedFeatures();
71
+ }, []);
72
+ const clearSelection = react.useCallback(() => {
73
+ var _a;
74
+ (_a = controlRef.current) == null ? void 0 : _a.clearSelection();
75
+ }, []);
76
+ return {
77
+ control: controlRef.current,
78
+ enableDrawMode,
79
+ enableEditMode,
80
+ disableAllModes,
81
+ copySelected,
82
+ pasteFeatures,
83
+ deleteSelected,
84
+ clearSelection
85
+ };
86
+ }
87
+ exports.ADVANCED_EDIT_MODES = index.ADVANCED_EDIT_MODES;
88
+ exports.CSS_PREFIX = index.CSS_PREFIX;
89
+ exports.CopyFeature = index.CopyFeature;
90
+ exports.DEFAULT_DRAW_MODES = index.DEFAULT_DRAW_MODES;
91
+ exports.DEFAULT_EDIT_MODES = index.DEFAULT_EDIT_MODES;
92
+ exports.DEFAULT_OPTIONS = index.DEFAULT_OPTIONS;
93
+ exports.DifferenceFeature = index.DifferenceFeature;
94
+ exports.GeoEditor = index.GeoEditor;
95
+ exports.LassoFeature = index.LassoFeature;
96
+ exports.ScaleFeature = index.ScaleFeature;
97
+ exports.SimplifyFeature = index.SimplifyFeature;
98
+ exports.SplitFeature = index.SplitFeature;
99
+ exports.UnionFeature = index.UnionFeature;
100
+ exports.addToSelection = index.addToSelection;
101
+ exports.bearingBetweenPoints = index.bearingBetweenPoints;
102
+ exports.calculateArea = index.calculateArea;
103
+ exports.calculateLength = index.calculateLength;
104
+ exports.calculateScaleFactor = index.calculateScaleFactor;
105
+ exports.canMergeFeatures = index.canMergeFeatures;
106
+ exports.canSubtractFeatures = index.canSubtractFeatures;
107
+ exports.clamp = index.clamp;
108
+ exports.cloneFeature = index.cloneFeature;
109
+ exports.contains = index.contains;
110
+ exports.createFeatureCollection = index.createFeatureCollection;
111
+ exports.createLine = index.createLine;
112
+ exports.createPoint = index.createPoint;
113
+ exports.createPolygon = index.createPolygon;
114
+ exports.degreesToRadians = index.degreesToRadians;
115
+ exports.distanceBetweenPoints = index.distanceBetweenPoints;
116
+ exports.ensureFeatureId = index.ensureFeatureId;
117
+ exports.filterByGeometryType = index.filterByGeometryType;
118
+ exports.fromSelectedFeatures = index.fromSelectedFeatures;
119
+ exports.generateFeatureId = index.generateFeatureId;
120
+ exports.getBBox = index.getBBox;
121
+ exports.getBBoxCenter = index.getBBoxCenter;
122
+ exports.getBBoxCorners = index.getBBoxCorners;
123
+ exports.getBBoxMidpoints = index.getBBoxMidpoints;
124
+ exports.getCenter = index.getCenter;
125
+ exports.getCoordAll = index.getCoordAll;
126
+ exports.getFeatureId = index.getFeatureId;
127
+ exports.getPolygonFeatures = index.getPolygonFeatures;
128
+ exports.getVertexCount = index.getVertexCount;
129
+ exports.intersects = index.intersects;
130
+ exports.isFeatureSelected = index.isFeatureSelected;
131
+ exports.isLine = index.isLine;
132
+ exports.isPoint = index.isPoint;
133
+ exports.isPolygon = index.isPolygon;
134
+ exports.isPolygonOnlySelection = index.isPolygonOnlySelection;
135
+ exports.isValidGeometry = index.isValidGeometry;
136
+ exports.isWithin = index.isWithin;
137
+ exports.overlaps = index.overlaps;
138
+ exports.polygonToLine = index.polygonToLine;
139
+ exports.positionsEqual = index.positionsEqual;
140
+ exports.radiansToDegrees = index.radiansToDegrees;
141
+ exports.removeFromSelection = index.removeFromSelection;
142
+ exports.roundCoordinates = index.roundCoordinates;
143
+ exports.safeCentroid = index.safeCentroid;
144
+ exports.safeClone = index.safeClone;
145
+ exports.safeDifference = index.safeDifference;
146
+ exports.safeLineIntersect = index.safeLineIntersect;
147
+ exports.safeLineSplit = index.safeLineSplit;
148
+ exports.safeScale = index.safeScale;
149
+ exports.safeSimplify = index.safeSimplify;
150
+ exports.safeTranslate = index.safeTranslate;
151
+ exports.safeUnion = index.safeUnion;
152
+ exports.selectFeaturesWithinLasso = index.selectFeaturesWithinLasso;
153
+ exports.toSelectedFeatures = index.toSelectedFeatures;
154
+ exports.toggleInSelection = index.toggleInSelection;
155
+ exports.GeoEditorReact = GeoEditorReact;
156
+ exports.useGeoEditor = useGeoEditor;
157
+ //# sourceMappingURL=react.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.cjs","sources":["../src/lib/core/GeoEditorReact.tsx"],"sourcesContent":["import { useEffect, useRef, useCallback } from 'react';\nimport type { Map as MapLibreMap } from 'maplibre-gl';\nimport { GeoEditor } from './GeoEditor';\nimport type { GeoEditorOptions, GeomanInstance, DrawMode, EditMode } from './types';\n\nexport interface GeoEditorReactProps extends GeoEditorOptions {\n /** MapLibre map instance */\n map: MapLibreMap;\n /** Geoman instance for integration */\n geoman?: GeomanInstance;\n}\n\n/**\n * React wrapper component for GeoEditor\n * This component renders nothing but manages the GeoEditor lifecycle\n */\nexport function GeoEditorReact({\n map,\n geoman,\n position = 'top-left',\n ...options\n}: GeoEditorReactProps) {\n const controlRef = useRef<GeoEditor | null>(null);\n\n useEffect(() => {\n if (!map) return;\n\n // Create and add the control\n const control = new GeoEditor({ ...options, position });\n controlRef.current = control;\n\n map.addControl(control, position);\n\n // Set geoman instance if provided\n if (geoman) {\n control.setGeoman(geoman);\n }\n\n // Cleanup on unmount\n return () => {\n if (controlRef.current) {\n map.removeControl(controlRef.current);\n controlRef.current = null;\n }\n };\n }, [map, position]);\n\n // Update geoman instance when it changes\n useEffect(() => {\n if (controlRef.current && geoman) {\n controlRef.current.setGeoman(geoman);\n }\n }, [geoman]);\n\n // This component doesn't render anything\n return null;\n}\n\n/**\n * Hook for using GeoEditor imperatively\n */\nexport function useGeoEditor(\n map: MapLibreMap | null,\n options: GeoEditorOptions = {}\n): {\n control: GeoEditor | null;\n enableDrawMode: (mode: DrawMode) => void;\n enableEditMode: (mode: EditMode) => void;\n disableAllModes: () => void;\n copySelected: () => void;\n pasteFeatures: () => void;\n deleteSelected: () => void;\n clearSelection: () => void;\n} {\n const controlRef = useRef<GeoEditor | null>(null);\n\n useEffect(() => {\n if (!map) return;\n\n const control = new GeoEditor(options);\n controlRef.current = control;\n map.addControl(control, options.position || 'top-left');\n\n return () => {\n if (controlRef.current) {\n map.removeControl(controlRef.current);\n controlRef.current = null;\n }\n };\n }, [map]);\n\n const enableDrawMode = useCallback((mode: DrawMode) => {\n controlRef.current?.enableDrawMode(mode);\n }, []);\n\n const enableEditMode = useCallback((mode: EditMode) => {\n controlRef.current?.enableEditMode(mode);\n }, []);\n\n const disableAllModes = useCallback(() => {\n controlRef.current?.disableAllModes();\n }, []);\n\n const copySelected = useCallback(() => {\n controlRef.current?.copySelectedFeatures();\n }, []);\n\n const pasteFeatures = useCallback(() => {\n controlRef.current?.pasteFeatures();\n }, []);\n\n const deleteSelected = useCallback(() => {\n controlRef.current?.deleteSelectedFeatures();\n }, []);\n\n const clearSelection = useCallback(() => {\n controlRef.current?.clearSelection();\n }, []);\n\n return {\n control: controlRef.current,\n enableDrawMode,\n enableEditMode,\n disableAllModes,\n copySelected,\n pasteFeatures,\n deleteSelected,\n clearSelection,\n };\n}\n\nexport default GeoEditorReact;\n"],"names":["useRef","useEffect","GeoEditor","useCallback"],"mappings":";;;;AAgBO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,GAAG;AACL,GAAwB;AACtB,QAAM,aAAaA,MAAAA,OAAyB,IAAI;AAEhDC,QAAAA,UAAU,MAAM;AACd,QAAI,CAAC,IAAK;AAGV,UAAM,UAAU,IAAIC,MAAAA,UAAU,EAAE,GAAG,SAAS,UAAU;AACtD,eAAW,UAAU;AAErB,QAAI,WAAW,SAAS,QAAQ;AAGhC,QAAI,QAAQ;AACV,cAAQ,UAAU,MAAM;AAAA,IAC1B;AAGA,WAAO,MAAM;AACX,UAAI,WAAW,SAAS;AACtB,YAAI,cAAc,WAAW,OAAO;AACpC,mBAAW,UAAU;AAAA,MACvB;AAAA,IACF;AAAA,EACF,GAAG,CAAC,KAAK,QAAQ,CAAC;AAGlBD,QAAAA,UAAU,MAAM;AACd,QAAI,WAAW,WAAW,QAAQ;AAChC,iBAAW,QAAQ,UAAU,MAAM;AAAA,IACrC;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAGX,SAAO;AACT;AAKO,SAAS,aACd,KACA,UAA4B,IAU5B;AACA,QAAM,aAAaD,MAAAA,OAAyB,IAAI;AAEhDC,QAAAA,UAAU,MAAM;AACd,QAAI,CAAC,IAAK;AAEV,UAAM,UAAU,IAAIC,MAAAA,UAAU,OAAO;AACrC,eAAW,UAAU;AACrB,QAAI,WAAW,SAAS,QAAQ,YAAY,UAAU;AAEtD,WAAO,MAAM;AACX,UAAI,WAAW,SAAS;AACtB,YAAI,cAAc,WAAW,OAAO;AACpC,mBAAW,UAAU;AAAA,MACvB;AAAA,IACF;AAAA,EACF,GAAG,CAAC,GAAG,CAAC;AAER,QAAM,iBAAiBC,kBAAY,CAAC,SAAmB;;AACrD,qBAAW,YAAX,mBAAoB,eAAe;AAAA,EACrC,GAAG,CAAA,CAAE;AAEL,QAAM,iBAAiBA,kBAAY,CAAC,SAAmB;;AACrD,qBAAW,YAAX,mBAAoB,eAAe;AAAA,EACrC,GAAG,CAAA,CAAE;AAEL,QAAM,kBAAkBA,MAAAA,YAAY,MAAM;;AACxC,qBAAW,YAAX,mBAAoB;AAAA,EACtB,GAAG,CAAA,CAAE;AAEL,QAAM,eAAeA,MAAAA,YAAY,MAAM;;AACrC,qBAAW,YAAX,mBAAoB;AAAA,EACtB,GAAG,CAAA,CAAE;AAEL,QAAM,gBAAgBA,MAAAA,YAAY,MAAM;;AACtC,qBAAW,YAAX,mBAAoB;AAAA,EACtB,GAAG,CAAA,CAAE;AAEL,QAAM,iBAAiBA,MAAAA,YAAY,MAAM;;AACvC,qBAAW,YAAX,mBAAoB;AAAA,EACtB,GAAG,CAAA,CAAE;AAEL,QAAM,iBAAiBA,MAAAA,YAAY,MAAM;;AACvC,qBAAW,YAAX,mBAAoB;AAAA,EACtB,GAAG,CAAA,CAAE;AAEL,SAAO;AAAA,IACL,SAAS,WAAW;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}