maplibre-gl-components 0.6.0 → 0.7.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.
@@ -455,7 +455,7 @@ const GOOGLE_BASEMAPS = [
455
455
  maxZoom: 22
456
456
  }
457
457
  ];
458
- const DEFAULT_OPTIONS$7 = {
458
+ const DEFAULT_OPTIONS$8 = {
459
459
  colormap: "viridis",
460
460
  colorStops: [],
461
461
  vmin: 0,
@@ -492,7 +492,7 @@ class Colorbar {
492
492
  __publicField(this, "_map");
493
493
  __publicField(this, "_handleZoom");
494
494
  __publicField(this, "_zoomVisible", true);
495
- this._options = { ...DEFAULT_OPTIONS$7, ...options };
495
+ this._options = { ...DEFAULT_OPTIONS$8, ...options };
496
496
  this._state = {
497
497
  visible: this._options.visible,
498
498
  vmin: this._options.vmin,
@@ -790,7 +790,7 @@ class Colorbar {
790
790
  this._container.appendChild(barWrapper);
791
791
  }
792
792
  }
793
- const DEFAULT_OPTIONS$6 = {
793
+ const DEFAULT_OPTIONS$7 = {
794
794
  title: "",
795
795
  items: [],
796
796
  position: "bottom-left",
@@ -824,7 +824,7 @@ class Legend {
824
824
  __publicField(this, "_map");
825
825
  __publicField(this, "_handleZoom");
826
826
  __publicField(this, "_zoomVisible", true);
827
- this._options = { ...DEFAULT_OPTIONS$6, ...options };
827
+ this._options = { ...DEFAULT_OPTIONS$7, ...options };
828
828
  this._state = {
829
829
  visible: this._options.visible,
830
830
  collapsed: this._options.collapsed,
@@ -1179,7 +1179,7 @@ class Legend {
1179
1179
  this._container.appendChild(content);
1180
1180
  }
1181
1181
  }
1182
- const DEFAULT_OPTIONS$5 = {
1182
+ const DEFAULT_OPTIONS$6 = {
1183
1183
  html: "",
1184
1184
  element: void 0,
1185
1185
  title: "",
@@ -1214,7 +1214,7 @@ class HtmlControl {
1214
1214
  __publicField(this, "_map");
1215
1215
  __publicField(this, "_handleZoom");
1216
1216
  __publicField(this, "_zoomVisible", true);
1217
- this._options = { ...DEFAULT_OPTIONS$5, ...options };
1217
+ this._options = { ...DEFAULT_OPTIONS$6, ...options };
1218
1218
  this._state = {
1219
1219
  visible: this._options.visible,
1220
1220
  collapsed: this._options.collapsed,
@@ -1510,7 +1510,7 @@ class HtmlControl {
1510
1510
  this._container.appendChild(content);
1511
1511
  }
1512
1512
  }
1513
- const DEFAULT_OPTIONS$4 = {
1513
+ const DEFAULT_OPTIONS$5 = {
1514
1514
  basemaps: [],
1515
1515
  providersUrl: XYZSERVICES_URL,
1516
1516
  defaultBasemap: "",
@@ -1554,7 +1554,7 @@ class BasemapControl {
1554
1554
  __publicField(this, "_map");
1555
1555
  __publicField(this, "_handleZoom");
1556
1556
  __publicField(this, "_zoomVisible", true);
1557
- this._options = { ...DEFAULT_OPTIONS$4, ...options };
1557
+ this._options = { ...DEFAULT_OPTIONS$5, ...options };
1558
1558
  this._state = {
1559
1559
  visible: this._options.visible,
1560
1560
  collapsed: this._options.collapsed,
@@ -2353,7 +2353,7 @@ class BasemapControl {
2353
2353
  const DEFAULT_TERRAIN_URL = "https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png";
2354
2354
  const TERRAIN_SOURCE_ID = "maplibre-gl-terrain-dem";
2355
2355
  const HILLSHADE_LAYER_ID = "maplibre-gl-terrain-hillshade";
2356
- const DEFAULT_OPTIONS$3 = {
2356
+ const DEFAULT_OPTIONS$4 = {
2357
2357
  sourceUrl: DEFAULT_TERRAIN_URL,
2358
2358
  encoding: "terrarium",
2359
2359
  exaggeration: 1,
@@ -2389,7 +2389,7 @@ class TerrainControl {
2389
2389
  __publicField(this, "_handleZoom");
2390
2390
  __publicField(this, "_handleStyleLoad");
2391
2391
  __publicField(this, "_zoomVisible", true);
2392
- this._options = { ...DEFAULT_OPTIONS$3, ...options };
2392
+ this._options = { ...DEFAULT_OPTIONS$4, ...options };
2393
2393
  this._state = {
2394
2394
  visible: this._options.visible,
2395
2395
  enabled: this._options.enabled,
@@ -2788,7 +2788,7 @@ class TerrainControl {
2788
2788
  }
2789
2789
  }
2790
2790
  const NOMINATIM_URL = "https://nominatim.openstreetmap.org/search";
2791
- const DEFAULT_OPTIONS$2 = {
2791
+ const DEFAULT_OPTIONS$3 = {
2792
2792
  position: "top-right",
2793
2793
  className: "",
2794
2794
  visible: true,
@@ -2846,7 +2846,7 @@ class SearchControl {
2846
2846
  this.search(value);
2847
2847
  }, this._options.debounceMs);
2848
2848
  });
2849
- this._options = { ...DEFAULT_OPTIONS$2, ...options };
2849
+ this._options = { ...DEFAULT_OPTIONS$3, ...options };
2850
2850
  this._state = {
2851
2851
  visible: this._options.visible,
2852
2852
  collapsed: this._options.collapsed,
@@ -3804,7 +3804,7 @@ const DEFAULT_STYLE = {
3804
3804
  circleStrokeColor: "#ffffff",
3805
3805
  circleStrokeWidth: 2
3806
3806
  };
3807
- const DEFAULT_OPTIONS$1 = {
3807
+ const DEFAULT_OPTIONS$2 = {
3808
3808
  position: "top-right",
3809
3809
  className: "",
3810
3810
  visible: true,
@@ -3851,10 +3851,10 @@ class VectorDatasetControl {
3851
3851
  __publicField(this, "_loadingOverlay");
3852
3852
  __publicField(this, "_loadingText");
3853
3853
  __publicField(this, "_loadingProgress");
3854
- const enableAdvanced = (options == null ? void 0 : options.enableAdvancedFormats) ?? DEFAULT_OPTIONS$1.enableAdvancedFormats;
3854
+ const enableAdvanced = (options == null ? void 0 : options.enableAdvancedFormats) ?? DEFAULT_OPTIONS$2.enableAdvancedFormats;
3855
3855
  const acceptedExtensions = (options == null ? void 0 : options.acceptedExtensions) ?? getAcceptedExtensions(enableAdvanced);
3856
3856
  this._options = {
3857
- ...DEFAULT_OPTIONS$1,
3857
+ ...DEFAULT_OPTIONS$2,
3858
3858
  ...options,
3859
3859
  acceptedExtensions,
3860
3860
  defaultStyle: { ...DEFAULT_STYLE, ...options == null ? void 0 : options.defaultStyle }
@@ -4609,7 +4609,7 @@ const DEFAULT_HIGHLIGHT_STYLE = {
4609
4609
  circleRadius: 10,
4610
4610
  circleStrokeWidth: 3
4611
4611
  };
4612
- const DEFAULT_OPTIONS = {
4612
+ const DEFAULT_OPTIONS$1 = {
4613
4613
  position: "top-right",
4614
4614
  className: "",
4615
4615
  visible: true,
@@ -4653,7 +4653,7 @@ class InspectControl {
4653
4653
  // Bound event handlers for proper cleanup
4654
4654
  __publicField(this, "_boundClickHandler");
4655
4655
  this._options = {
4656
- ...DEFAULT_OPTIONS,
4656
+ ...DEFAULT_OPTIONS$1,
4657
4657
  ...options,
4658
4658
  highlightStyle: { ...DEFAULT_HIGHLIGHT_STYLE, ...options == null ? void 0 : options.highlightStyle }
4659
4659
  };
@@ -5309,6 +5309,738 @@ class InspectControl {
5309
5309
  this._container.style.display = shouldShow ? "block" : "none";
5310
5310
  }
5311
5311
  }
5312
+ const DEFAULT_OPTIONS = {
5313
+ position: "bottom-left",
5314
+ className: "",
5315
+ visible: true,
5316
+ collapsed: true,
5317
+ precision: 4,
5318
+ showCenter: true,
5319
+ showBounds: true,
5320
+ showZoom: true,
5321
+ showPitch: true,
5322
+ showBearing: true,
5323
+ enableBBox: false,
5324
+ bboxFillColor: "rgba(0, 120, 215, 0.1)",
5325
+ bboxStrokeColor: "#0078d7",
5326
+ bboxStrokeWidth: 2,
5327
+ panelWidth: 280,
5328
+ backgroundColor: "rgba(255, 255, 255, 0.95)",
5329
+ borderRadius: 4,
5330
+ opacity: 1,
5331
+ fontSize: 12,
5332
+ fontColor: "#333",
5333
+ minzoom: 0,
5334
+ maxzoom: 24
5335
+ };
5336
+ const VIEWSTATE_ICON = `<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><line x1="12" y1="2" x2="12" y2="6"/><line x1="12" y1="18" x2="12" y2="22"/><line x1="2" y1="12" x2="6" y2="12"/><line x1="18" y1="12" x2="22" y2="12"/></svg>`;
5337
+ const COPY_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>`;
5338
+ const CHECK_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#22c55e" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>`;
5339
+ const BBOX_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="1" stroke-dasharray="4 2"/></svg>`;
5340
+ class ViewStateControl {
5341
+ /**
5342
+ * Creates a new ViewStateControl instance.
5343
+ *
5344
+ * @param options - Configuration options for the control.
5345
+ */
5346
+ constructor(options) {
5347
+ __publicField(this, "_container");
5348
+ __publicField(this, "_button");
5349
+ __publicField(this, "_panel");
5350
+ __publicField(this, "_options");
5351
+ __publicField(this, "_state");
5352
+ __publicField(this, "_eventHandlers", /* @__PURE__ */ new Map());
5353
+ __publicField(this, "_map");
5354
+ __publicField(this, "_handleZoom");
5355
+ __publicField(this, "_zoomVisible", true);
5356
+ // DOM references for live updates
5357
+ __publicField(this, "_centerValueEl");
5358
+ __publicField(this, "_boundsValueEl");
5359
+ __publicField(this, "_zoomValueEl");
5360
+ __publicField(this, "_pitchValueEl");
5361
+ __publicField(this, "_bearingValueEl");
5362
+ // Move handler for live updates
5363
+ __publicField(this, "_boundMoveHandler");
5364
+ // BBox drawing state
5365
+ __publicField(this, "_bboxSourceId", "");
5366
+ __publicField(this, "_bboxLayerFillId", "");
5367
+ __publicField(this, "_bboxLayerLineId", "");
5368
+ __publicField(this, "_bboxDrawStart");
5369
+ __publicField(this, "_boundBBoxMouseDown");
5370
+ __publicField(this, "_boundBBoxMouseMove");
5371
+ __publicField(this, "_boundBBoxMouseUp");
5372
+ __publicField(this, "_boundBBoxDragStart");
5373
+ __publicField(this, "_bboxToggleBtn");
5374
+ __publicField(this, "_bboxResultEl");
5375
+ this._options = { ...DEFAULT_OPTIONS, ...options };
5376
+ this._state = {
5377
+ visible: this._options.visible,
5378
+ collapsed: this._options.collapsed,
5379
+ center: [0, 0],
5380
+ bounds: [0, 0, 0, 0],
5381
+ zoom: 0,
5382
+ pitch: 0,
5383
+ bearing: 0,
5384
+ drawingBBox: false,
5385
+ drawnBBox: null
5386
+ };
5387
+ const uid = generateId("viewstate");
5388
+ this._bboxSourceId = `${uid}-bbox-src`;
5389
+ this._bboxLayerFillId = `${uid}-bbox-fill`;
5390
+ this._bboxLayerLineId = `${uid}-bbox-line`;
5391
+ }
5392
+ /**
5393
+ * Called when the control is added to the map.
5394
+ *
5395
+ * @param map - The MapLibre GL map instance.
5396
+ * @returns The control's container element.
5397
+ */
5398
+ onAdd(map) {
5399
+ this._map = map;
5400
+ this._readMapState();
5401
+ this._container = this._createContainer();
5402
+ this._handleZoom = () => this._checkZoomVisibility();
5403
+ this._map.on("zoom", this._handleZoom);
5404
+ this._checkZoomVisibility();
5405
+ this._boundMoveHandler = () => this._onMapMove();
5406
+ this._map.on("move", this._boundMoveHandler);
5407
+ return this._container;
5408
+ }
5409
+ /**
5410
+ * Called when the control is removed from the map.
5411
+ */
5412
+ onRemove() {
5413
+ var _a, _b;
5414
+ if (this._map) {
5415
+ if (this._handleZoom) {
5416
+ this._map.off("zoom", this._handleZoom);
5417
+ this._handleZoom = void 0;
5418
+ }
5419
+ if (this._boundMoveHandler) {
5420
+ this._map.off("move", this._boundMoveHandler);
5421
+ this._boundMoveHandler = void 0;
5422
+ }
5423
+ if (this._state.drawingBBox) {
5424
+ this._stopBBoxDrawing();
5425
+ }
5426
+ this._removeBBoxLayers();
5427
+ }
5428
+ this._map = void 0;
5429
+ (_b = (_a = this._container) == null ? void 0 : _a.parentNode) == null ? void 0 : _b.removeChild(this._container);
5430
+ this._container = void 0;
5431
+ this._button = void 0;
5432
+ this._panel = void 0;
5433
+ this._centerValueEl = void 0;
5434
+ this._boundsValueEl = void 0;
5435
+ this._zoomValueEl = void 0;
5436
+ this._pitchValueEl = void 0;
5437
+ this._bearingValueEl = void 0;
5438
+ this._bboxToggleBtn = void 0;
5439
+ this._bboxResultEl = void 0;
5440
+ this._eventHandlers.clear();
5441
+ }
5442
+ /**
5443
+ * Expands the info panel.
5444
+ */
5445
+ expand() {
5446
+ if (this._state.collapsed) {
5447
+ this._state.collapsed = false;
5448
+ this._updatePanelVisibility();
5449
+ this._updateButtonState();
5450
+ this._emit("expand");
5451
+ }
5452
+ }
5453
+ /**
5454
+ * Collapses the info panel.
5455
+ */
5456
+ collapse() {
5457
+ if (!this._state.collapsed) {
5458
+ this._state.collapsed = true;
5459
+ this._updatePanelVisibility();
5460
+ this._updateButtonState();
5461
+ this._emit("collapse");
5462
+ }
5463
+ }
5464
+ /**
5465
+ * Toggles the panel expanded/collapsed state.
5466
+ */
5467
+ toggle() {
5468
+ if (this._state.collapsed) {
5469
+ this.expand();
5470
+ } else {
5471
+ this.collapse();
5472
+ }
5473
+ }
5474
+ /**
5475
+ * Returns whether the panel is collapsed.
5476
+ */
5477
+ isCollapsed() {
5478
+ return this._state.collapsed;
5479
+ }
5480
+ /**
5481
+ * Shows the control.
5482
+ */
5483
+ show() {
5484
+ if (!this._state.visible) {
5485
+ this._state.visible = true;
5486
+ this._updateDisplayState();
5487
+ this._emit("show");
5488
+ }
5489
+ }
5490
+ /**
5491
+ * Hides the control.
5492
+ */
5493
+ hide() {
5494
+ if (this._state.visible) {
5495
+ this._state.visible = false;
5496
+ this._updateDisplayState();
5497
+ this._emit("hide");
5498
+ }
5499
+ }
5500
+ /**
5501
+ * Returns a copy of the current state.
5502
+ */
5503
+ getState() {
5504
+ return { ...this._state };
5505
+ }
5506
+ /**
5507
+ * Starts bounding box drawing mode.
5508
+ */
5509
+ startBBoxDraw() {
5510
+ if (!this._options.enableBBox || this._state.drawingBBox) return;
5511
+ this._state.drawingBBox = true;
5512
+ this._setupBBoxListeners();
5513
+ this._updateBBoxToggleState();
5514
+ this._emit("drawstart");
5515
+ }
5516
+ /**
5517
+ * Stops bounding box drawing mode.
5518
+ */
5519
+ stopBBoxDraw() {
5520
+ if (!this._state.drawingBBox) return;
5521
+ this._stopBBoxDrawing();
5522
+ this._emit("drawend");
5523
+ }
5524
+ /**
5525
+ * Clears the drawn bounding box.
5526
+ */
5527
+ clearBBox() {
5528
+ this._state.drawnBBox = null;
5529
+ this._removeBBoxLayers();
5530
+ this._updateBBoxResult();
5531
+ this._emit("bboxclear");
5532
+ }
5533
+ /**
5534
+ * Updates the control options.
5535
+ */
5536
+ update(options) {
5537
+ Object.assign(this._options, options);
5538
+ if (options.visible !== void 0) {
5539
+ this._state.visible = options.visible;
5540
+ this._updateDisplayState();
5541
+ }
5542
+ if (options.collapsed !== void 0) {
5543
+ this._state.collapsed = options.collapsed;
5544
+ this._updatePanelVisibility();
5545
+ this._updateButtonState();
5546
+ }
5547
+ if (options.panelWidth !== void 0 && this._panel) {
5548
+ this._panel.style.width = `${options.panelWidth}px`;
5549
+ }
5550
+ this._emit("update");
5551
+ }
5552
+ /**
5553
+ * Registers an event handler.
5554
+ */
5555
+ on(event, handler) {
5556
+ if (!this._eventHandlers.has(event)) {
5557
+ this._eventHandlers.set(event, /* @__PURE__ */ new Set());
5558
+ }
5559
+ this._eventHandlers.get(event).add(handler);
5560
+ }
5561
+ /**
5562
+ * Removes an event handler.
5563
+ */
5564
+ off(event, handler) {
5565
+ var _a;
5566
+ (_a = this._eventHandlers.get(event)) == null ? void 0 : _a.delete(handler);
5567
+ }
5568
+ /**
5569
+ * Emits an event to all registered handlers.
5570
+ */
5571
+ _emit(event, bbox) {
5572
+ const handlers = this._eventHandlers.get(event);
5573
+ if (handlers) {
5574
+ handlers.forEach(
5575
+ (handler) => handler({
5576
+ type: event,
5577
+ state: this.getState(),
5578
+ bbox
5579
+ })
5580
+ );
5581
+ }
5582
+ }
5583
+ /**
5584
+ * Reads the current map state into internal state.
5585
+ */
5586
+ _readMapState() {
5587
+ if (!this._map) return;
5588
+ const center = this._map.getCenter();
5589
+ const bounds = this._map.getBounds();
5590
+ this._state.center = [center.lng, center.lat];
5591
+ this._state.bounds = [
5592
+ bounds.getWest(),
5593
+ bounds.getSouth(),
5594
+ bounds.getEast(),
5595
+ bounds.getNorth()
5596
+ ];
5597
+ this._state.zoom = this._map.getZoom();
5598
+ this._state.pitch = this._map.getPitch();
5599
+ this._state.bearing = this._map.getBearing();
5600
+ }
5601
+ /**
5602
+ * Handles map move events for live updates.
5603
+ */
5604
+ _onMapMove() {
5605
+ this._readMapState();
5606
+ this._updateValues();
5607
+ this._emit("viewchange");
5608
+ }
5609
+ /**
5610
+ * Updates the DOM value elements with current state.
5611
+ */
5612
+ _updateValues() {
5613
+ const p = this._options.precision;
5614
+ if (this._centerValueEl) {
5615
+ this._centerValueEl.textContent = `${this._state.center[0].toFixed(p)}, ${this._state.center[1].toFixed(p)}`;
5616
+ }
5617
+ if (this._boundsValueEl) {
5618
+ const b = this._state.bounds;
5619
+ this._boundsValueEl.textContent = `${b[0].toFixed(p)}, ${b[1].toFixed(p)}, ${b[2].toFixed(p)}, ${b[3].toFixed(p)}`;
5620
+ }
5621
+ if (this._zoomValueEl) {
5622
+ this._zoomValueEl.textContent = this._state.zoom.toFixed(2);
5623
+ }
5624
+ if (this._pitchValueEl) {
5625
+ this._pitchValueEl.textContent = `${this._state.pitch.toFixed(1)}°`;
5626
+ }
5627
+ if (this._bearingValueEl) {
5628
+ this._bearingValueEl.textContent = `${this._state.bearing.toFixed(1)}°`;
5629
+ }
5630
+ }
5631
+ /**
5632
+ * Creates the control container with button and panel.
5633
+ */
5634
+ _createContainer() {
5635
+ const container = document.createElement("div");
5636
+ container.className = `maplibregl-ctrl maplibregl-ctrl-group maplibre-gl-view-state ${this._options.className}`.trim();
5637
+ if (this._options.backgroundColor) {
5638
+ container.style.backgroundColor = this._options.backgroundColor;
5639
+ }
5640
+ if (this._options.borderRadius) {
5641
+ container.style.borderRadius = `${this._options.borderRadius}px`;
5642
+ }
5643
+ if (this._options.opacity !== void 0 && this._options.opacity !== 1) {
5644
+ container.style.opacity = String(this._options.opacity);
5645
+ }
5646
+ this._button = document.createElement("button");
5647
+ this._button.type = "button";
5648
+ this._button.className = "maplibre-gl-view-state-button";
5649
+ this._button.title = "View map state";
5650
+ this._button.innerHTML = VIEWSTATE_ICON;
5651
+ this._button.addEventListener("click", () => this.toggle());
5652
+ container.appendChild(this._button);
5653
+ this._panel = this._createPanel();
5654
+ container.appendChild(this._panel);
5655
+ container.style.display = this._state.visible ? "block" : "none";
5656
+ this._updatePanelVisibility();
5657
+ this._updateButtonState();
5658
+ return container;
5659
+ }
5660
+ /**
5661
+ * Creates the expandable info panel.
5662
+ */
5663
+ _createPanel() {
5664
+ const panel = document.createElement("div");
5665
+ panel.className = "maplibre-gl-view-state-panel";
5666
+ panel.style.width = `${this._options.panelWidth}px`;
5667
+ if (this._options.fontSize) {
5668
+ panel.style.fontSize = `${this._options.fontSize}px`;
5669
+ }
5670
+ if (this._options.fontColor) {
5671
+ panel.style.color = this._options.fontColor;
5672
+ }
5673
+ const header = document.createElement("div");
5674
+ header.className = "maplibre-gl-view-state-header";
5675
+ header.textContent = "View State";
5676
+ panel.appendChild(header);
5677
+ const p = this._options.precision;
5678
+ if (this._options.showCenter) {
5679
+ const { row, valueEl } = this._createRow(
5680
+ "Center",
5681
+ `${this._state.center[0].toFixed(p)}, ${this._state.center[1].toFixed(p)}`
5682
+ );
5683
+ this._centerValueEl = valueEl;
5684
+ panel.appendChild(row);
5685
+ }
5686
+ if (this._options.showBounds) {
5687
+ const b = this._state.bounds;
5688
+ const { row, valueEl } = this._createRow(
5689
+ "Bounds",
5690
+ `${b[0].toFixed(p)}, ${b[1].toFixed(p)}, ${b[2].toFixed(p)}, ${b[3].toFixed(p)}`
5691
+ );
5692
+ this._boundsValueEl = valueEl;
5693
+ panel.appendChild(row);
5694
+ }
5695
+ if (this._options.showZoom) {
5696
+ const { row, valueEl } = this._createRow("Zoom", this._state.zoom.toFixed(2));
5697
+ this._zoomValueEl = valueEl;
5698
+ panel.appendChild(row);
5699
+ }
5700
+ if (this._options.showPitch) {
5701
+ const { row, valueEl } = this._createRow("Pitch", `${this._state.pitch.toFixed(1)}°`);
5702
+ this._pitchValueEl = valueEl;
5703
+ panel.appendChild(row);
5704
+ }
5705
+ if (this._options.showBearing) {
5706
+ const { row, valueEl } = this._createRow("Bearing", `${this._state.bearing.toFixed(1)}°`);
5707
+ this._bearingValueEl = valueEl;
5708
+ panel.appendChild(row);
5709
+ }
5710
+ if (this._options.enableBBox) {
5711
+ panel.appendChild(this._createBBoxSection());
5712
+ }
5713
+ return panel;
5714
+ }
5715
+ /**
5716
+ * Creates a labeled data row with a copy button.
5717
+ */
5718
+ _createRow(label, value) {
5719
+ const row = document.createElement("div");
5720
+ row.className = "maplibre-gl-view-state-row";
5721
+ const labelEl = document.createElement("span");
5722
+ labelEl.className = "maplibre-gl-view-state-label";
5723
+ labelEl.textContent = label;
5724
+ const valueEl = document.createElement("span");
5725
+ valueEl.className = "maplibre-gl-view-state-value";
5726
+ valueEl.textContent = value;
5727
+ const copyBtn = document.createElement("button");
5728
+ copyBtn.type = "button";
5729
+ copyBtn.className = "maplibre-gl-view-state-copy";
5730
+ copyBtn.title = `Copy ${label.toLowerCase()}`;
5731
+ copyBtn.innerHTML = COPY_ICON;
5732
+ copyBtn.addEventListener("click", (e) => {
5733
+ e.stopPropagation();
5734
+ this._copyToClipboard(valueEl.textContent || "", copyBtn);
5735
+ });
5736
+ row.appendChild(labelEl);
5737
+ row.appendChild(valueEl);
5738
+ row.appendChild(copyBtn);
5739
+ return { row, valueEl };
5740
+ }
5741
+ /**
5742
+ * Creates the bounding box drawing section.
5743
+ */
5744
+ _createBBoxSection() {
5745
+ const section = document.createElement("div");
5746
+ section.className = "maplibre-gl-view-state-bbox-section";
5747
+ this._bboxToggleBtn = document.createElement("button");
5748
+ this._bboxToggleBtn.type = "button";
5749
+ this._bboxToggleBtn.className = "maplibre-gl-view-state-bbox-toggle";
5750
+ this._bboxToggleBtn.innerHTML = `${BBOX_ICON} Draw BBox`;
5751
+ this._bboxToggleBtn.addEventListener("click", () => {
5752
+ if (this._state.drawingBBox) {
5753
+ this.stopBBoxDraw();
5754
+ } else {
5755
+ this.startBBoxDraw();
5756
+ }
5757
+ });
5758
+ section.appendChild(this._bboxToggleBtn);
5759
+ this._bboxResultEl = document.createElement("div");
5760
+ this._bboxResultEl.className = "maplibre-gl-view-state-bbox-result";
5761
+ this._bboxResultEl.style.display = "none";
5762
+ section.appendChild(this._bboxResultEl);
5763
+ return section;
5764
+ }
5765
+ /**
5766
+ * Updates the bbox result display.
5767
+ */
5768
+ _updateBBoxResult() {
5769
+ if (!this._bboxResultEl) return;
5770
+ if (!this._state.drawnBBox) {
5771
+ this._bboxResultEl.style.display = "none";
5772
+ return;
5773
+ }
5774
+ this._bboxResultEl.style.display = "block";
5775
+ const b = this._state.drawnBBox;
5776
+ const p = this._options.precision;
5777
+ const bboxStr = `${b[0].toFixed(p)}, ${b[1].toFixed(p)}, ${b[2].toFixed(p)}, ${b[3].toFixed(p)}`;
5778
+ this._bboxResultEl.innerHTML = "";
5779
+ const valueDiv = document.createElement("div");
5780
+ valueDiv.className = "maplibre-gl-view-state-bbox-value";
5781
+ valueDiv.textContent = bboxStr;
5782
+ this._bboxResultEl.appendChild(valueDiv);
5783
+ const actionsDiv = document.createElement("div");
5784
+ actionsDiv.className = "maplibre-gl-view-state-bbox-actions";
5785
+ const copyBtn = document.createElement("button");
5786
+ copyBtn.type = "button";
5787
+ copyBtn.className = "maplibre-gl-view-state-bbox-action";
5788
+ copyBtn.innerHTML = `${COPY_ICON} Copy`;
5789
+ copyBtn.addEventListener("click", () => {
5790
+ this._copyToClipboard(bboxStr, copyBtn);
5791
+ });
5792
+ actionsDiv.appendChild(copyBtn);
5793
+ const clearBtn = document.createElement("button");
5794
+ clearBtn.type = "button";
5795
+ clearBtn.className = "maplibre-gl-view-state-bbox-action maplibre-gl-view-state-bbox-action--clear";
5796
+ clearBtn.textContent = "Clear";
5797
+ clearBtn.addEventListener("click", () => this.clearBBox());
5798
+ actionsDiv.appendChild(clearBtn);
5799
+ this._bboxResultEl.appendChild(actionsDiv);
5800
+ }
5801
+ /**
5802
+ * Copies text to clipboard and shows feedback on the button.
5803
+ */
5804
+ _copyToClipboard(text, btn) {
5805
+ navigator.clipboard.writeText(text).then(() => {
5806
+ const originalHtml = btn.innerHTML;
5807
+ btn.innerHTML = CHECK_ICON;
5808
+ setTimeout(() => {
5809
+ btn.innerHTML = originalHtml;
5810
+ }, 1e3);
5811
+ }).catch(() => {
5812
+ });
5813
+ }
5814
+ /**
5815
+ * Updates the panel visibility based on collapsed state.
5816
+ */
5817
+ _updatePanelVisibility() {
5818
+ if (this._panel) {
5819
+ if (this._state.collapsed) {
5820
+ this._panel.classList.remove("maplibre-gl-view-state-panel--visible");
5821
+ } else {
5822
+ this._panel.classList.add("maplibre-gl-view-state-panel--visible");
5823
+ }
5824
+ }
5825
+ }
5826
+ /**
5827
+ * Updates the button's active state appearance.
5828
+ */
5829
+ _updateButtonState() {
5830
+ if (this._button) {
5831
+ if (!this._state.collapsed) {
5832
+ this._button.classList.add("maplibre-gl-view-state-button--active");
5833
+ this._button.title = "Hide view state";
5834
+ } else {
5835
+ this._button.classList.remove("maplibre-gl-view-state-button--active");
5836
+ this._button.title = "View map state";
5837
+ }
5838
+ }
5839
+ }
5840
+ /**
5841
+ * Updates the bbox toggle button state.
5842
+ */
5843
+ _updateBBoxToggleState() {
5844
+ if (this._bboxToggleBtn) {
5845
+ if (this._state.drawingBBox) {
5846
+ this._bboxToggleBtn.classList.add("maplibre-gl-view-state-bbox-toggle--active");
5847
+ this._bboxToggleBtn.innerHTML = `${BBOX_ICON} Cancel Draw`;
5848
+ } else {
5849
+ this._bboxToggleBtn.classList.remove("maplibre-gl-view-state-bbox-toggle--active");
5850
+ this._bboxToggleBtn.innerHTML = `${BBOX_ICON} Draw BBox`;
5851
+ }
5852
+ }
5853
+ }
5854
+ /**
5855
+ * Converts a native MouseEvent to map lng/lat using map.unproject().
5856
+ */
5857
+ _mouseEventToLngLat(e) {
5858
+ const canvas = this._map.getCanvas();
5859
+ const rect = canvas.getBoundingClientRect();
5860
+ const x = e.clientX - rect.left;
5861
+ const y = e.clientY - rect.top;
5862
+ const lngLat = this._map.unproject([x, y]);
5863
+ return { lng: lngLat.lng, lat: lngLat.lat };
5864
+ }
5865
+ /**
5866
+ * Sets up mouse listeners for bbox drawing.
5867
+ */
5868
+ _setupBBoxListeners() {
5869
+ if (!this._map) return;
5870
+ const canvas = this._map.getCanvas();
5871
+ canvas.style.cursor = "crosshair";
5872
+ this._map.dragPan.disable();
5873
+ this._map.boxZoom.disable();
5874
+ this._boundBBoxMouseDown = (e) => this._onBBoxMouseDown(e);
5875
+ this._map.on("mousedown", this._boundBBoxMouseDown);
5876
+ this._boundBBoxDragStart = (e) => e.preventDefault();
5877
+ canvas.addEventListener("dragstart", this._boundBBoxDragStart);
5878
+ }
5879
+ /**
5880
+ * Removes bbox drawing listeners and restores map state.
5881
+ */
5882
+ _stopBBoxDrawing() {
5883
+ if (!this._map) return;
5884
+ const canvas = this._map.getCanvas();
5885
+ canvas.style.cursor = "";
5886
+ this._map.dragPan.enable();
5887
+ this._map.boxZoom.enable();
5888
+ if (this._boundBBoxMouseDown) {
5889
+ this._map.off("mousedown", this._boundBBoxMouseDown);
5890
+ this._boundBBoxMouseDown = void 0;
5891
+ }
5892
+ if (this._boundBBoxMouseMove) {
5893
+ document.removeEventListener("mousemove", this._boundBBoxMouseMove);
5894
+ this._boundBBoxMouseMove = void 0;
5895
+ }
5896
+ if (this._boundBBoxMouseUp) {
5897
+ document.removeEventListener("mouseup", this._boundBBoxMouseUp);
5898
+ this._boundBBoxMouseUp = void 0;
5899
+ }
5900
+ if (this._boundBBoxDragStart) {
5901
+ canvas.removeEventListener("dragstart", this._boundBBoxDragStart);
5902
+ this._boundBBoxDragStart = void 0;
5903
+ }
5904
+ this._bboxDrawStart = void 0;
5905
+ this._state.drawingBBox = false;
5906
+ this._updateBBoxToggleState();
5907
+ }
5908
+ /**
5909
+ * Handles mouse down for bbox drawing start.
5910
+ */
5911
+ _onBBoxMouseDown(e) {
5912
+ if (!this._map) return;
5913
+ e.preventDefault();
5914
+ e.originalEvent.preventDefault();
5915
+ e.originalEvent.stopPropagation();
5916
+ const lng = e.lngLat.lng;
5917
+ const lat = e.lngLat.lat;
5918
+ this._bboxDrawStart = { lng, lat };
5919
+ this._removeBBoxLayers();
5920
+ const pt = [lng, lat];
5921
+ this._map.addSource(this._bboxSourceId, {
5922
+ type: "geojson",
5923
+ data: {
5924
+ type: "Feature",
5925
+ geometry: { type: "Polygon", coordinates: [[pt, pt, pt, pt, pt]] },
5926
+ properties: {}
5927
+ }
5928
+ });
5929
+ this._map.addLayer({
5930
+ id: this._bboxLayerFillId,
5931
+ type: "fill",
5932
+ source: this._bboxSourceId,
5933
+ paint: {
5934
+ "fill-color": this._options.bboxFillColor,
5935
+ "fill-opacity": 1
5936
+ }
5937
+ });
5938
+ this._map.addLayer({
5939
+ id: this._bboxLayerLineId,
5940
+ type: "line",
5941
+ source: this._bboxSourceId,
5942
+ paint: {
5943
+ "line-color": this._options.bboxStrokeColor,
5944
+ "line-width": this._options.bboxStrokeWidth
5945
+ }
5946
+ });
5947
+ this._boundBBoxMouseMove = (ev) => this._onBBoxMouseMove(ev);
5948
+ this._boundBBoxMouseUp = (ev) => this._onBBoxMouseUp(ev);
5949
+ document.addEventListener("mousemove", this._boundBBoxMouseMove);
5950
+ document.addEventListener("mouseup", this._boundBBoxMouseUp);
5951
+ }
5952
+ /**
5953
+ * Handles mouse move during bbox drawing.
5954
+ */
5955
+ _onBBoxMouseMove(e) {
5956
+ if (!this._map || !this._bboxDrawStart) return;
5957
+ const start = this._bboxDrawStart;
5958
+ const current = this._mouseEventToLngLat(e);
5959
+ const coords = [
5960
+ [start.lng, start.lat],
5961
+ [current.lng, start.lat],
5962
+ [current.lng, current.lat],
5963
+ [start.lng, current.lat],
5964
+ [start.lng, start.lat]
5965
+ ];
5966
+ const source = this._map.getSource(this._bboxSourceId);
5967
+ if (source) {
5968
+ source.setData({
5969
+ type: "Feature",
5970
+ geometry: { type: "Polygon", coordinates: [coords] },
5971
+ properties: {}
5972
+ });
5973
+ }
5974
+ }
5975
+ /**
5976
+ * Handles mouse up to complete bbox drawing.
5977
+ */
5978
+ _onBBoxMouseUp(e) {
5979
+ if (!this._map || !this._bboxDrawStart) return;
5980
+ const start = this._bboxDrawStart;
5981
+ const end = this._mouseEventToLngLat(e);
5982
+ const west = Math.min(start.lng, end.lng);
5983
+ const south = Math.min(start.lat, end.lat);
5984
+ const east = Math.max(start.lng, end.lng);
5985
+ const north = Math.max(start.lat, end.lat);
5986
+ this._state.drawnBBox = [west, south, east, north];
5987
+ this._updateBBoxResult();
5988
+ const coords = [
5989
+ [west, south],
5990
+ [east, south],
5991
+ [east, north],
5992
+ [west, north],
5993
+ [west, south]
5994
+ ];
5995
+ const source = this._map.getSource(this._bboxSourceId);
5996
+ if (source) {
5997
+ source.setData({
5998
+ type: "Feature",
5999
+ geometry: { type: "Polygon", coordinates: [coords] },
6000
+ properties: {}
6001
+ });
6002
+ }
6003
+ this._stopBBoxDrawing();
6004
+ this._emit("bboxdraw", this._state.drawnBBox);
6005
+ this._emit("drawend");
6006
+ }
6007
+ /**
6008
+ * Removes bbox layers and source from the map.
6009
+ */
6010
+ _removeBBoxLayers() {
6011
+ if (!this._map) return;
6012
+ if (this._map.getLayer(this._bboxLayerFillId)) {
6013
+ this._map.removeLayer(this._bboxLayerFillId);
6014
+ }
6015
+ if (this._map.getLayer(this._bboxLayerLineId)) {
6016
+ this._map.removeLayer(this._bboxLayerLineId);
6017
+ }
6018
+ if (this._map.getSource(this._bboxSourceId)) {
6019
+ this._map.removeSource(this._bboxSourceId);
6020
+ }
6021
+ }
6022
+ /**
6023
+ * Checks zoom visibility and updates display state.
6024
+ */
6025
+ _checkZoomVisibility() {
6026
+ if (!this._map) return;
6027
+ const zoom = this._map.getZoom();
6028
+ const { minzoom, maxzoom } = this._options;
6029
+ const inRange = zoom >= minzoom && zoom <= maxzoom;
6030
+ if (inRange !== this._zoomVisible) {
6031
+ this._zoomVisible = inRange;
6032
+ this._updateDisplayState();
6033
+ }
6034
+ }
6035
+ /**
6036
+ * Updates the display state based on visibility settings.
6037
+ */
6038
+ _updateDisplayState() {
6039
+ if (!this._container) return;
6040
+ const shouldShow = this._state.visible && this._zoomVisible;
6041
+ this._container.style.display = shouldShow ? "block" : "none";
6042
+ }
6043
+ }
5312
6044
  exports.ADVANCED_EXTENSIONS = ADVANCED_EXTENSIONS;
5313
6045
  exports.ALL_EXTENSIONS = ALL_EXTENSIONS;
5314
6046
  exports.BasemapControl = BasemapControl;
@@ -5338,6 +6070,7 @@ exports.SearchControl = SearchControl;
5338
6070
  exports.TOPOJSON_EXTENSIONS = TOPOJSON_EXTENSIONS;
5339
6071
  exports.TerrainControl = TerrainControl;
5340
6072
  exports.VectorDatasetControl = VectorDatasetControl;
6073
+ exports.ViewStateControl = ViewStateControl;
5341
6074
  exports.XLSX_EXTENSIONS = XLSX_EXTENSIONS;
5342
6075
  exports.XYZSERVICES_URL = XYZSERVICES_URL;
5343
6076
  exports.bone = bone;
@@ -5382,4 +6115,4 @@ exports.terrain = terrain;
5382
6115
  exports.throttle = throttle;
5383
6116
  exports.turbo = turbo;
5384
6117
  exports.viridis = viridis;
5385
- //# sourceMappingURL=InspectControl-Dh8CfVpv.cjs.map
6118
+ //# sourceMappingURL=ViewStateControl-BZNDy3xx.cjs.map