maplibre-gl-layer-control 0.14.0 → 0.15.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.
package/dist/index.cjs CHANGED
@@ -686,9 +686,11 @@ class LayerControl {
686
686
  __publicField(this, "styleEditors");
687
687
  __publicField(this, "initialSourceIds", null);
688
688
  __publicField(this, "initialLayerIds", null);
689
+ __publicField(this, "initialLayerStates");
689
690
  // Panel width management
690
691
  __publicField(this, "minPanelWidth");
691
692
  __publicField(this, "maxPanelWidth");
693
+ __publicField(this, "initialPanelWidth");
692
694
  __publicField(this, "maxPanelHeight");
693
695
  __publicField(this, "showStyleEditor");
694
696
  __publicField(this, "showOpacitySlider");
@@ -709,6 +711,18 @@ class LayerControl {
709
711
  __publicField(this, "widthDragStartX", null);
710
712
  __publicField(this, "widthDragStartWidth", null);
711
713
  __publicField(this, "widthFrame", null);
714
+ // Exact-opacity input popup
715
+ __publicField(this, "opacityInputEl", null);
716
+ // Panel edge-drag resizing (handles on both the left and right edges)
717
+ __publicField(this, "resizeHandleEls", []);
718
+ /** Which edge is anchored to the control corner (the other edge is "free") */
719
+ __publicField(this, "panelAnchorSide", "right");
720
+ __publicField(this, "isPanelResizing", false);
721
+ /** The physical edge being dragged in the current resize gesture */
722
+ __publicField(this, "panelResizeEdge", "left");
723
+ __publicField(this, "panelResizeStartX", null);
724
+ __publicField(this, "panelResizeStartWidth", null);
725
+ __publicField(this, "panelResizeStartOffset", 0);
712
726
  // Context menu and drag-drop
713
727
  __publicField(this, "contextMenuEl", null);
714
728
  __publicField(this, "enableContextMenu");
@@ -718,22 +732,26 @@ class LayerControl {
718
732
  __publicField(this, "onLayerRemove");
719
733
  this.minPanelWidth = options.panelMinWidth || 240;
720
734
  this.maxPanelWidth = options.panelMaxWidth || 420;
735
+ this.initialPanelWidth = options.panelWidth || 350;
721
736
  this.maxPanelHeight = options.panelMaxHeight || 600;
722
737
  this.showStyleEditor = options.showStyleEditor !== false;
723
738
  this.showOpacitySlider = options.showOpacitySlider !== false;
724
739
  this.showLayerSymbol = options.showLayerSymbol !== false;
725
740
  this.excludeDrawnLayers = options.excludeDrawnLayers !== false;
726
- this.excludeLayerPatterns = this.wildcardPatternsToRegex(options.excludeLayers || []);
741
+ this.excludeLayerPatterns = this.wildcardPatternsToRegex(
742
+ options.excludeLayers || []
743
+ );
727
744
  this.enableContextMenu = options.enableContextMenu !== false;
728
745
  this.enableDragAndDrop = options.enableDragAndDrop !== false;
729
746
  this.onLayerRename = options.onLayerRename;
730
747
  this.onLayerReorder = options.onLayerReorder;
731
748
  this.onLayerRemove = options.onLayerRemove;
749
+ this.initialLayerStates = options.layerStates || {};
732
750
  this.state = {
733
751
  collapsed: options.collapsed !== false,
734
752
  panelWidth: options.panelWidth || 350,
735
753
  activeStyleEditor: null,
736
- layerStates: options.layerStates || {},
754
+ layerStates: {},
737
755
  originalStyles: /* @__PURE__ */ new Map(),
738
756
  userInteractingWithSlider: false,
739
757
  backgroundLegendOpen: false,
@@ -757,7 +775,7 @@ class LayerControl {
757
775
  },
758
776
  isStyleOperationInProgress: false
759
777
  };
760
- this.targetLayers = options.layers || Object.keys(this.state.layerStates);
778
+ this.targetLayers = options.layers || Object.keys(this.initialLayerStates);
761
779
  this.styleEditors = /* @__PURE__ */ new Map();
762
780
  if (options.customLayerAdapters && options.customLayerAdapters.length > 0) {
763
781
  this.customLayerRegistry = new CustomLayerRegistry();
@@ -802,7 +820,10 @@ class LayerControl {
802
820
  }
803
821
  this.buildLayerItems();
804
822
  }).catch((error) => {
805
- console.warn("Failed to fetch basemap style, falling back to heuristic detection:", error);
823
+ console.warn(
824
+ "Failed to fetch basemap style, falling back to heuristic detection:",
825
+ error
826
+ );
806
827
  if (Object.keys(this.state.layerStates).length === 0) {
807
828
  this.autoDetectLayers();
808
829
  }
@@ -841,7 +862,11 @@ class LayerControl {
841
862
  this.basemapLayerIds = /* @__PURE__ */ new Set();
842
863
  }
843
864
  } catch (error) {
844
- console.warn("Failed to fetch basemap style from URL:", this.basemapStyleUrl, error);
865
+ console.warn(
866
+ "Failed to fetch basemap style from URL:",
867
+ this.basemapStyleUrl,
868
+ error
869
+ );
845
870
  throw error;
846
871
  }
847
872
  }
@@ -870,6 +895,7 @@ class LayerControl {
870
895
  (_a = this.contextMenuEl.parentNode) == null ? void 0 : _a.removeChild(this.contextMenuEl);
871
896
  this.contextMenuEl = null;
872
897
  }
898
+ this.hideOpacityInput();
873
899
  this.cleanupDragState();
874
900
  (_b = this.panel.parentNode) == null ? void 0 : _b.removeChild(this.panel);
875
901
  (_c = this.container.parentNode) == null ? void 0 : _c.removeChild(this.container);
@@ -929,11 +955,11 @@ class LayerControl {
929
955
  const layerType = layer.type;
930
956
  const opacity = getLayerOpacity(this.map, layerId, layerType);
931
957
  const friendlyName = this.generateFriendlyName(layerId);
932
- this.state.layerStates[layerId] = {
958
+ this.state.layerStates[layerId] = this.mergeWithUserState(layerId, {
933
959
  visible: isVisible,
934
960
  opacity,
935
961
  name: friendlyName
936
- };
962
+ });
937
963
  });
938
964
  } else {
939
965
  const userLayers = [];
@@ -964,11 +990,11 @@ class LayerControl {
964
990
  const layerType = layer.type;
965
991
  const opacity = getLayerOpacity(this.map, layerId, layerType);
966
992
  const friendlyName = this.generateFriendlyName(layerId);
967
- this.state.layerStates[layerId] = {
993
+ this.state.layerStates[layerId] = this.mergeWithUserState(layerId, {
968
994
  visible: isVisible,
969
995
  opacity,
970
996
  name: friendlyName
971
- };
997
+ });
972
998
  });
973
999
  }
974
1000
  if (this.customLayerRegistry) {
@@ -1028,7 +1054,9 @@ class LayerControl {
1028
1054
  }
1029
1055
  if (style.glyphs) {
1030
1056
  try {
1031
- const url = new URL(style.glyphs.replace("{fontstack}", "x").replace("{range}", "x"));
1057
+ const url = new URL(
1058
+ style.glyphs.replace("{fontstack}", "x").replace("{range}", "x")
1059
+ );
1032
1060
  basemapDomains.add(url.hostname);
1033
1061
  } catch {
1034
1062
  }
@@ -1089,6 +1117,25 @@ class LayerControl {
1089
1117
  name = name.replace(/\b\w/g, (char) => char.toUpperCase());
1090
1118
  return name || layerId;
1091
1119
  }
1120
+ /**
1121
+ * Merge auto-detected layer state with user-provided initial state.
1122
+ * User-provided values take precedence over detected values.
1123
+ */
1124
+ mergeWithUserState(layerId, detected) {
1125
+ const userState = this.initialLayerStates[layerId];
1126
+ if (!userState) return detected;
1127
+ return {
1128
+ visible: userState.visible ?? detected.visible,
1129
+ opacity: userState.opacity ?? detected.opacity,
1130
+ name: userState.name ?? detected.name,
1131
+ ...userState.isCustomLayer !== void 0 && {
1132
+ isCustomLayer: userState.isCustomLayer
1133
+ },
1134
+ ...userState.customLayerType !== void 0 && {
1135
+ customLayerType: userState.customLayerType
1136
+ }
1137
+ };
1138
+ }
1092
1139
  /**
1093
1140
  * Check if a layer ID belongs to a drawing library (Geoman, Mapbox GL Draw, etc.)
1094
1141
  * @param layerId The layer ID to check
@@ -1172,8 +1219,111 @@ class LayerControl {
1172
1219
  panel.appendChild(header);
1173
1220
  const actionButtons = this.createActionButtons();
1174
1221
  panel.appendChild(actionButtons);
1222
+ panel.appendChild(this.createResizeHandle("left"));
1223
+ panel.appendChild(this.createResizeHandle("right"));
1175
1224
  return panel;
1176
1225
  }
1226
+ /**
1227
+ * Create a draggable edge handle for resizing the panel width. A handle is
1228
+ * added on each side so the panel can be resized by dragging either edge,
1229
+ * like a conventional resizable window.
1230
+ *
1231
+ * @param side Which physical edge of the panel the handle sits on
1232
+ */
1233
+ createResizeHandle(side) {
1234
+ const handle = document.createElement("div");
1235
+ handle.className = `layer-control-resize-handle layer-control-resize-handle-${side}`;
1236
+ handle.title = "Drag to resize panel";
1237
+ handle.setAttribute("role", "separator");
1238
+ handle.setAttribute("aria-orientation", "vertical");
1239
+ this.resizeHandleEls.push(handle);
1240
+ this.setupResizeHandleEvents(handle, side);
1241
+ return handle;
1242
+ }
1243
+ /**
1244
+ * Wire pointer events for an edge resize handle.
1245
+ *
1246
+ * @param handle The handle element
1247
+ * @param side Which physical edge of the panel the handle sits on
1248
+ */
1249
+ setupResizeHandleEvents(handle, side) {
1250
+ handle.addEventListener("pointerdown", (event) => {
1251
+ event.preventDefault();
1252
+ event.stopPropagation();
1253
+ this.isPanelResizing = true;
1254
+ this.panelResizeEdge = side;
1255
+ this.panelResizeStartX = event.clientX;
1256
+ this.panelResizeStartWidth = this.state.panelWidth;
1257
+ this.panelResizeStartOffset = parseFloat(this.panel.style[this.panelAnchorSide]) || 0;
1258
+ handle.setPointerCapture(event.pointerId);
1259
+ this.panel.classList.add("resizing-active");
1260
+ });
1261
+ handle.addEventListener("pointermove", (event) => {
1262
+ if (!this.isPanelResizing) return;
1263
+ this.resizePanelFromPointer(event.clientX);
1264
+ });
1265
+ const endResize = (event) => {
1266
+ if (!this.isPanelResizing) return;
1267
+ if (event.pointerId !== void 0) {
1268
+ try {
1269
+ handle.releasePointerCapture(event.pointerId);
1270
+ } catch {
1271
+ }
1272
+ }
1273
+ this.isPanelResizing = false;
1274
+ this.panelResizeStartX = null;
1275
+ this.panelResizeStartWidth = null;
1276
+ this.panel.classList.remove("resizing-active");
1277
+ };
1278
+ handle.addEventListener("pointerup", endResize);
1279
+ handle.addEventListener("pointercancel", endResize);
1280
+ handle.addEventListener("lostpointercapture", endResize);
1281
+ handle.addEventListener("dblclick", (event) => {
1282
+ event.preventDefault();
1283
+ event.stopPropagation();
1284
+ this.applyPanelWidth(this.initialPanelWidth, true);
1285
+ });
1286
+ }
1287
+ /**
1288
+ * Compute and apply a new panel width from the pointer position during an
1289
+ * edge drag. Dragging the free edge changes the width while the anchored
1290
+ * edge stays put; dragging the anchored edge shifts the anchor so the free
1291
+ * edge stays put — both feel like resizing a normal window.
1292
+ */
1293
+ resizePanelFromPointer(clientX) {
1294
+ const dx = clientX - (this.panelResizeStartX ?? clientX);
1295
+ const startWidth = this.panelResizeStartWidth ?? this.state.panelWidth;
1296
+ const desiredWidth = this.panelResizeEdge === "left" ? startWidth - dx : startWidth + dx;
1297
+ const clamped = Math.round(
1298
+ Math.min(this.maxPanelWidth, Math.max(this.minPanelWidth, desiredWidth))
1299
+ );
1300
+ if (this.panelResizeEdge === this.panelAnchorSide) {
1301
+ let appliedDelta = clamped - startWidth;
1302
+ let newOffset = this.panelResizeStartOffset - appliedDelta;
1303
+ if (newOffset < 0) {
1304
+ newOffset = 0;
1305
+ appliedDelta = this.panelResizeStartOffset;
1306
+ }
1307
+ const finalWidth = Math.round(
1308
+ Math.min(
1309
+ this.maxPanelWidth,
1310
+ Math.max(this.minPanelWidth, startWidth + appliedDelta)
1311
+ )
1312
+ );
1313
+ this.applyPanelWidth(finalWidth, true);
1314
+ this.panel.style[this.panelAnchorSide] = `${newOffset}px`;
1315
+ } else {
1316
+ this.applyPanelWidth(clamped, true);
1317
+ }
1318
+ }
1319
+ /**
1320
+ * Record which panel edge is anchored to the control corner, based on the
1321
+ * corner the control occupies. Right corners anchor the right edge (panel
1322
+ * grows leftward); left corners anchor the left edge (panel grows rightward).
1323
+ */
1324
+ updatePanelAnchorSide(position) {
1325
+ this.panelAnchorSide = position === "top-right" || position === "bottom-right" ? "right" : "left";
1326
+ }
1177
1327
  /**
1178
1328
  * Detect which corner the control is positioned in
1179
1329
  * @returns The position: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
@@ -1181,10 +1331,14 @@ class LayerControl {
1181
1331
  getControlPosition() {
1182
1332
  const parent = this.container.parentElement;
1183
1333
  if (!parent) return "top-right";
1184
- if (parent.classList.contains("maplibregl-ctrl-top-left")) return "top-left";
1185
- if (parent.classList.contains("maplibregl-ctrl-top-right")) return "top-right";
1186
- if (parent.classList.contains("maplibregl-ctrl-bottom-left")) return "bottom-left";
1187
- if (parent.classList.contains("maplibregl-ctrl-bottom-right")) return "bottom-right";
1334
+ if (parent.classList.contains("maplibregl-ctrl-top-left"))
1335
+ return "top-left";
1336
+ if (parent.classList.contains("maplibregl-ctrl-top-right"))
1337
+ return "top-right";
1338
+ if (parent.classList.contains("maplibregl-ctrl-bottom-left"))
1339
+ return "bottom-left";
1340
+ if (parent.classList.contains("maplibregl-ctrl-bottom-right"))
1341
+ return "bottom-right";
1188
1342
  return "top-right";
1189
1343
  }
1190
1344
  /**
@@ -1196,6 +1350,7 @@ class LayerControl {
1196
1350
  const buttonRect = this.button.getBoundingClientRect();
1197
1351
  const mapRect = this.mapContainer.getBoundingClientRect();
1198
1352
  const position = this.getControlPosition();
1353
+ this.updatePanelAnchorSide(position);
1199
1354
  const buttonTop = buttonRect.top - mapRect.top;
1200
1355
  const buttonBottom = mapRect.bottom - buttonRect.bottom;
1201
1356
  const buttonLeft = buttonRect.left - mapRect.left;
@@ -1235,13 +1390,19 @@ class LayerControl {
1235
1390
  showAllBtn.className = "layer-control-action-btn";
1236
1391
  showAllBtn.textContent = "Show All";
1237
1392
  showAllBtn.title = "Show all layers";
1238
- showAllBtn.addEventListener("click", () => this.setAllLayersVisibility(true));
1393
+ showAllBtn.addEventListener(
1394
+ "click",
1395
+ () => this.setAllLayersVisibility(true)
1396
+ );
1239
1397
  const hideAllBtn = document.createElement("button");
1240
1398
  hideAllBtn.type = "button";
1241
1399
  hideAllBtn.className = "layer-control-action-btn";
1242
1400
  hideAllBtn.textContent = "Hide All";
1243
1401
  hideAllBtn.title = "Hide all layers";
1244
- hideAllBtn.addEventListener("click", () => this.setAllLayersVisibility(false));
1402
+ hideAllBtn.addEventListener(
1403
+ "click",
1404
+ () => this.setAllLayersVisibility(false)
1405
+ );
1245
1406
  container.appendChild(showAllBtn);
1246
1407
  container.appendChild(hideAllBtn);
1247
1408
  return container;
@@ -1254,7 +1415,9 @@ class LayerControl {
1254
1415
  this.toggleLayerVisibility(layerId, visible);
1255
1416
  const itemEl = this.panel.querySelector(`[data-layer-id="${layerId}"]`);
1256
1417
  if (itemEl) {
1257
- const checkbox = itemEl.querySelector(".layer-control-checkbox");
1418
+ const checkbox = itemEl.querySelector(
1419
+ ".layer-control-checkbox"
1420
+ );
1258
1421
  if (checkbox) {
1259
1422
  checkbox.checked = visible;
1260
1423
  checkbox.indeterminate = false;
@@ -1405,7 +1568,9 @@ class LayerControl {
1405
1568
  * Apply panel width (clamped to min/max)
1406
1569
  */
1407
1570
  applyPanelWidth(width, immediate = false) {
1408
- const clamped = Math.round(Math.min(this.maxPanelWidth, Math.max(this.minPanelWidth, width)));
1571
+ const clamped = Math.round(
1572
+ Math.min(this.maxPanelWidth, Math.max(this.minPanelWidth, width))
1573
+ );
1409
1574
  const applyWidth = () => {
1410
1575
  this.state.panelWidth = clamped;
1411
1576
  const px = `${clamped}px`;
@@ -1432,7 +1597,10 @@ class LayerControl {
1432
1597
  this.widthValueEl.textContent = `${this.state.panelWidth}px`;
1433
1598
  }
1434
1599
  if (this.widthSliderEl) {
1435
- this.widthSliderEl.setAttribute("aria-valuenow", String(this.state.panelWidth));
1600
+ this.widthSliderEl.setAttribute(
1601
+ "aria-valuenow",
1602
+ String(this.state.panelWidth)
1603
+ );
1436
1604
  const ratio = (this.state.panelWidth - this.minPanelWidth) / (this.maxPanelWidth - this.minPanelWidth || 1);
1437
1605
  if (this.widthThumbEl) {
1438
1606
  const sliderWidth = this.widthSliderEl.clientWidth;
@@ -1505,12 +1673,14 @@ class LayerControl {
1505
1673
  }
1506
1674
  });
1507
1675
  if (this.customLayerRegistry) {
1508
- this.customLayerUnsubscribe = this.customLayerRegistry.onChange((event, layerId) => {
1509
- if (event === "add" && layerId) {
1510
- this.removedCustomLayerIds.delete(layerId);
1676
+ this.customLayerUnsubscribe = this.customLayerRegistry.onChange(
1677
+ (event, layerId) => {
1678
+ if (event === "add" && layerId) {
1679
+ this.removedCustomLayerIds.delete(layerId);
1680
+ }
1681
+ setTimeout(() => this.checkForNewLayers(), 100);
1511
1682
  }
1512
- setTimeout(() => this.checkForNewLayers(), 100);
1513
- });
1683
+ );
1514
1684
  }
1515
1685
  }
1516
1686
  /**
@@ -1613,6 +1783,10 @@ class LayerControl {
1613
1783
  this.changeLayerOpacity(layerId, parseFloat(opacity.value));
1614
1784
  opacity.title = `Opacity: ${Math.round(parseFloat(opacity.value) * 100)}%`;
1615
1785
  });
1786
+ opacity.addEventListener("dblclick", (event) => {
1787
+ event.preventDefault();
1788
+ this.showOpacityInput(layerId, opacity);
1789
+ });
1616
1790
  row.appendChild(opacity);
1617
1791
  }
1618
1792
  if (this.showStyleEditor) {
@@ -1710,11 +1884,103 @@ class LayerControl {
1710
1884
  }, 200);
1711
1885
  return;
1712
1886
  }
1713
- this.map.setLayoutProperty(layerId, "visibility", visible ? "visible" : "none");
1887
+ this.map.setLayoutProperty(
1888
+ layerId,
1889
+ "visibility",
1890
+ visible ? "visible" : "none"
1891
+ );
1714
1892
  setTimeout(() => {
1715
1893
  this.state.isStyleOperationInProgress = false;
1716
1894
  }, 200);
1717
1895
  }
1896
+ /**
1897
+ * Show a small popup that lets the user type an exact opacity percentage
1898
+ * (0-100) for a layer. Triggered by double-clicking the opacity slider.
1899
+ *
1900
+ * @param layerId The layer ID whose opacity is being edited
1901
+ * @param slider The opacity range input associated with the layer row
1902
+ */
1903
+ showOpacityInput(layerId, slider) {
1904
+ this.hideOpacityInput();
1905
+ const popup = document.createElement("div");
1906
+ popup.className = "layer-control-opacity-input";
1907
+ const label = document.createElement("span");
1908
+ label.className = "layer-control-opacity-input-label";
1909
+ label.textContent = "Opacity";
1910
+ const field = document.createElement("div");
1911
+ field.className = "layer-control-opacity-input-field";
1912
+ const input = document.createElement("input");
1913
+ input.type = "number";
1914
+ input.min = "0";
1915
+ input.max = "100";
1916
+ input.step = "1";
1917
+ input.value = String(Math.round(parseFloat(slider.value) * 100));
1918
+ const suffix = document.createElement("span");
1919
+ suffix.className = "layer-control-opacity-input-suffix";
1920
+ suffix.textContent = "%";
1921
+ field.appendChild(input);
1922
+ field.appendChild(suffix);
1923
+ popup.appendChild(label);
1924
+ popup.appendChild(field);
1925
+ popup.addEventListener("click", (event) => event.stopPropagation());
1926
+ popup.addEventListener("pointerdown", (event) => event.stopPropagation());
1927
+ let settled = false;
1928
+ const apply = () => {
1929
+ if (settled) return;
1930
+ settled = true;
1931
+ const pct = clamp(Math.round(parseFloat(input.value)), 0, 100);
1932
+ if (!Number.isNaN(pct)) {
1933
+ const opacity = pct / 100;
1934
+ slider.value = String(opacity);
1935
+ slider.title = `Opacity: ${pct}%`;
1936
+ this.changeLayerOpacity(layerId, opacity);
1937
+ }
1938
+ this.hideOpacityInput();
1939
+ };
1940
+ const cancel = () => {
1941
+ if (settled) return;
1942
+ settled = true;
1943
+ this.hideOpacityInput();
1944
+ };
1945
+ input.addEventListener("keydown", (event) => {
1946
+ if (event.key === "Enter") {
1947
+ event.preventDefault();
1948
+ apply();
1949
+ slider.focus();
1950
+ } else if (event.key === "Escape") {
1951
+ event.preventDefault();
1952
+ cancel();
1953
+ slider.focus();
1954
+ }
1955
+ });
1956
+ input.addEventListener("blur", apply);
1957
+ this.mapContainer.appendChild(popup);
1958
+ this.opacityInputEl = popup;
1959
+ const sliderRect = slider.getBoundingClientRect();
1960
+ const mapRect = this.mapContainer.getBoundingClientRect();
1961
+ const popupRect = popup.getBoundingClientRect();
1962
+ let left = sliderRect.left - mapRect.left;
1963
+ let top = sliderRect.bottom - mapRect.top + 4;
1964
+ if (left + popupRect.width > mapRect.width) {
1965
+ left = Math.max(0, mapRect.width - popupRect.width - 5);
1966
+ }
1967
+ if (top + popupRect.height > mapRect.height) {
1968
+ top = sliderRect.top - mapRect.top - popupRect.height - 4;
1969
+ }
1970
+ popup.style.left = `${Math.max(0, left)}px`;
1971
+ popup.style.top = `${Math.max(0, top)}px`;
1972
+ input.focus();
1973
+ input.select();
1974
+ }
1975
+ /**
1976
+ * Remove the exact-opacity input popup if it is open.
1977
+ */
1978
+ hideOpacityInput() {
1979
+ if (this.opacityInputEl) {
1980
+ this.opacityInputEl.remove();
1981
+ this.opacityInputEl = null;
1982
+ }
1983
+ }
1718
1984
  /**
1719
1985
  * Change layer opacity
1720
1986
  */
@@ -1777,13 +2043,21 @@ class LayerControl {
1777
2043
  styleLayers.forEach((layer) => {
1778
2044
  if (!this.isUserAddedLayer(layer.id)) {
1779
2045
  this.state.backgroundLayerVisibility.set(layer.id, visible);
1780
- this.map.setLayoutProperty(layer.id, "visibility", visible ? "visible" : "none");
2046
+ this.map.setLayoutProperty(
2047
+ layer.id,
2048
+ "visibility",
2049
+ visible ? "visible" : "none"
2050
+ );
1781
2051
  }
1782
2052
  });
1783
2053
  if (this.state.backgroundLegendOpen) {
1784
- const legendPanel = this.panel.querySelector(".layer-control-background-legend");
2054
+ const legendPanel = this.panel.querySelector(
2055
+ ".layer-control-background-legend"
2056
+ );
1785
2057
  if (legendPanel) {
1786
- const checkboxes = legendPanel.querySelectorAll(".background-legend-checkbox");
2058
+ const checkboxes = legendPanel.querySelectorAll(
2059
+ ".background-legend-checkbox"
2060
+ );
1787
2061
  checkboxes.forEach((checkbox) => {
1788
2062
  checkbox.checked = visible;
1789
2063
  });
@@ -1816,8 +2090,14 @@ class LayerControl {
1816
2090
  button.className = "layer-control-style-button layer-control-background-legend-button";
1817
2091
  button.innerHTML = "&#9881;";
1818
2092
  button.title = "Show background layer details";
1819
- button.setAttribute("aria-label", "Show background layer visibility controls");
1820
- button.setAttribute("aria-expanded", String(this.state.backgroundLegendOpen));
2093
+ button.setAttribute(
2094
+ "aria-label",
2095
+ "Show background layer visibility controls"
2096
+ );
2097
+ button.setAttribute(
2098
+ "aria-expanded",
2099
+ String(this.state.backgroundLegendOpen)
2100
+ );
1821
2101
  button.addEventListener("click", (e) => {
1822
2102
  e.stopPropagation();
1823
2103
  this.toggleBackgroundLegend();
@@ -1845,7 +2125,9 @@ class LayerControl {
1845
2125
  if (!itemEl) return;
1846
2126
  let legendPanel = itemEl.querySelector(".layer-control-background-legend");
1847
2127
  if (legendPanel) {
1848
- const layerList = legendPanel.querySelector(".background-legend-layer-list");
2128
+ const layerList = legendPanel.querySelector(
2129
+ ".background-legend-layer-list"
2130
+ );
1849
2131
  if (layerList) {
1850
2132
  this.populateBackgroundLayerList(layerList);
1851
2133
  }
@@ -1854,7 +2136,9 @@ class LayerControl {
1854
2136
  itemEl.appendChild(legendPanel);
1855
2137
  }
1856
2138
  this.state.backgroundLegendOpen = true;
1857
- const button = itemEl.querySelector(".layer-control-background-legend-button");
2139
+ const button = itemEl.querySelector(
2140
+ ".layer-control-background-legend-button"
2141
+ );
1858
2142
  if (button) {
1859
2143
  button.setAttribute("aria-expanded", "true");
1860
2144
  button.classList.add("active");
@@ -1869,12 +2153,16 @@ class LayerControl {
1869
2153
  closeBackgroundLegend() {
1870
2154
  const itemEl = this.panel.querySelector('[data-layer-id="Background"]');
1871
2155
  if (!itemEl) return;
1872
- const legendPanel = itemEl.querySelector(".layer-control-background-legend");
2156
+ const legendPanel = itemEl.querySelector(
2157
+ ".layer-control-background-legend"
2158
+ );
1873
2159
  if (legendPanel) {
1874
2160
  legendPanel.remove();
1875
2161
  }
1876
2162
  this.state.backgroundLegendOpen = false;
1877
- const button = itemEl.querySelector(".layer-control-background-legend-button");
2163
+ const button = itemEl.querySelector(
2164
+ ".layer-control-background-legend-button"
2165
+ );
1878
2166
  if (button) {
1879
2167
  button.setAttribute("aria-expanded", "false");
1880
2168
  button.classList.remove("active");
@@ -1906,11 +2194,17 @@ class LayerControl {
1906
2194
  const showAllBtn = document.createElement("button");
1907
2195
  showAllBtn.className = "background-legend-action-btn";
1908
2196
  showAllBtn.textContent = "Show All";
1909
- showAllBtn.addEventListener("click", () => this.setAllBackgroundLayersVisibility(true));
2197
+ showAllBtn.addEventListener(
2198
+ "click",
2199
+ () => this.setAllBackgroundLayersVisibility(true)
2200
+ );
1910
2201
  const hideAllBtn = document.createElement("button");
1911
2202
  hideAllBtn.className = "background-legend-action-btn";
1912
2203
  hideAllBtn.textContent = "Hide All";
1913
- hideAllBtn.addEventListener("click", () => this.setAllBackgroundLayersVisibility(false));
2204
+ hideAllBtn.addEventListener(
2205
+ "click",
2206
+ () => this.setAllBackgroundLayersVisibility(false)
2207
+ );
1914
2208
  actionsRow.appendChild(showAllBtn);
1915
2209
  actionsRow.appendChild(hideAllBtn);
1916
2210
  const filterRow = document.createElement("div");
@@ -2024,7 +2318,11 @@ class LayerControl {
2024
2318
  */
2025
2319
  toggleIndividualBackgroundLayer(layerId, visible) {
2026
2320
  this.state.backgroundLayerVisibility.set(layerId, visible);
2027
- this.map.setLayoutProperty(layerId, "visibility", visible ? "visible" : "none");
2321
+ this.map.setLayoutProperty(
2322
+ layerId,
2323
+ "visibility",
2324
+ visible ? "visible" : "none"
2325
+ );
2028
2326
  this.updateBackgroundCheckboxState();
2029
2327
  }
2030
2328
  /**
@@ -2035,12 +2333,20 @@ class LayerControl {
2035
2333
  styleLayers.forEach((layer) => {
2036
2334
  if (!this.isUserAddedLayer(layer.id)) {
2037
2335
  this.state.backgroundLayerVisibility.set(layer.id, visible);
2038
- this.map.setLayoutProperty(layer.id, "visibility", visible ? "visible" : "none");
2336
+ this.map.setLayoutProperty(
2337
+ layer.id,
2338
+ "visibility",
2339
+ visible ? "visible" : "none"
2340
+ );
2039
2341
  }
2040
2342
  });
2041
- const legendPanel = this.panel.querySelector(".layer-control-background-legend");
2343
+ const legendPanel = this.panel.querySelector(
2344
+ ".layer-control-background-legend"
2345
+ );
2042
2346
  if (legendPanel) {
2043
- const checkboxes = legendPanel.querySelectorAll(".background-legend-checkbox");
2347
+ const checkboxes = legendPanel.querySelectorAll(
2348
+ ".background-legend-checkbox"
2349
+ );
2044
2350
  checkboxes.forEach((checkbox) => {
2045
2351
  checkbox.checked = visible;
2046
2352
  });
@@ -2061,9 +2367,13 @@ class LayerControl {
2061
2367
  if (visible === false) allVisible = false;
2062
2368
  }
2063
2369
  });
2064
- const backgroundItem = this.panel.querySelector('[data-layer-id="Background"]');
2370
+ const backgroundItem = this.panel.querySelector(
2371
+ '[data-layer-id="Background"]'
2372
+ );
2065
2373
  if (backgroundItem) {
2066
- const checkbox = backgroundItem.querySelector(".layer-control-checkbox");
2374
+ const checkbox = backgroundItem.querySelector(
2375
+ ".layer-control-checkbox"
2376
+ );
2067
2377
  if (checkbox) {
2068
2378
  checkbox.checked = anyVisible;
2069
2379
  checkbox.indeterminate = anyVisible && !allVisible;
@@ -2126,11 +2436,18 @@ class LayerControl {
2126
2436
  if (!this.state.originalStyles.has(nativeId)) {
2127
2437
  const nativeLayer = this.map.getLayer(nativeId);
2128
2438
  if (nativeLayer) {
2129
- cacheOriginalLayerStyle(this.map, nativeId, this.state.originalStyles);
2439
+ cacheOriginalLayerStyle(
2440
+ this.map,
2441
+ nativeId,
2442
+ this.state.originalStyles
2443
+ );
2130
2444
  }
2131
2445
  }
2132
2446
  }
2133
- const editor3 = this.createNativeSubLayerStyleEditor(layerId, nativeLayerIds);
2447
+ const editor3 = this.createNativeSubLayerStyleEditor(
2448
+ layerId,
2449
+ nativeLayerIds
2450
+ );
2134
2451
  if (editor3) {
2135
2452
  itemEl.appendChild(editor3);
2136
2453
  this.styleEditors.set(layerId, editor3);
@@ -2433,14 +2750,38 @@ class LayerControl {
2433
2750
  if (!fillColor) {
2434
2751
  fillColor = this.map.getPaintProperty(layerId, "fill-color");
2435
2752
  }
2436
- this.createColorControl(container, layerId, "fill-color", "Fill Color", normalizeColor(fillColor || "#088"));
2753
+ this.createColorControl(
2754
+ container,
2755
+ layerId,
2756
+ "fill-color",
2757
+ "Fill Color",
2758
+ normalizeColor(fillColor || "#088")
2759
+ );
2437
2760
  const fillOpacity = this.map.getPaintProperty(layerId, "fill-opacity");
2438
2761
  if (fillOpacity !== void 0 && typeof fillOpacity === "number") {
2439
- this.createSliderControl(container, layerId, "fill-opacity", "Fill Opacity", fillOpacity, 0, 1, 0.05);
2440
- }
2441
- const outlineColor = this.map.getPaintProperty(layerId, "fill-outline-color");
2762
+ this.createSliderControl(
2763
+ container,
2764
+ layerId,
2765
+ "fill-opacity",
2766
+ "Fill Opacity",
2767
+ fillOpacity,
2768
+ 0,
2769
+ 1,
2770
+ 0.05
2771
+ );
2772
+ }
2773
+ const outlineColor = this.map.getPaintProperty(
2774
+ layerId,
2775
+ "fill-outline-color"
2776
+ );
2442
2777
  if (outlineColor !== void 0) {
2443
- this.createColorControl(container, layerId, "fill-outline-color", "Outline Color", normalizeColor(outlineColor));
2778
+ this.createColorControl(
2779
+ container,
2780
+ layerId,
2781
+ "fill-outline-color",
2782
+ "Outline Color",
2783
+ normalizeColor(outlineColor)
2784
+ );
2444
2785
  }
2445
2786
  }
2446
2787
  /**
@@ -2457,16 +2798,49 @@ class LayerControl {
2457
2798
  if (!lineColor) {
2458
2799
  lineColor = this.map.getPaintProperty(layerId, "line-color");
2459
2800
  }
2460
- this.createColorControl(container, layerId, "line-color", "Line Color", normalizeColor(lineColor || "#000"));
2801
+ this.createColorControl(
2802
+ container,
2803
+ layerId,
2804
+ "line-color",
2805
+ "Line Color",
2806
+ normalizeColor(lineColor || "#000")
2807
+ );
2461
2808
  const lineWidth = this.map.getPaintProperty(layerId, "line-width");
2462
- this.createSliderControl(container, layerId, "line-width", "Line Width", typeof lineWidth === "number" ? lineWidth : 1, 0, 20, 0.5);
2809
+ this.createSliderControl(
2810
+ container,
2811
+ layerId,
2812
+ "line-width",
2813
+ "Line Width",
2814
+ typeof lineWidth === "number" ? lineWidth : 1,
2815
+ 0,
2816
+ 20,
2817
+ 0.5
2818
+ );
2463
2819
  const lineOpacity = this.map.getPaintProperty(layerId, "line-opacity");
2464
2820
  if (lineOpacity !== void 0 && typeof lineOpacity === "number") {
2465
- this.createSliderControl(container, layerId, "line-opacity", "Line Opacity", lineOpacity, 0, 1, 0.05);
2821
+ this.createSliderControl(
2822
+ container,
2823
+ layerId,
2824
+ "line-opacity",
2825
+ "Line Opacity",
2826
+ lineOpacity,
2827
+ 0,
2828
+ 1,
2829
+ 0.05
2830
+ );
2466
2831
  }
2467
2832
  const lineBlur = this.map.getPaintProperty(layerId, "line-blur");
2468
2833
  if (lineBlur !== void 0 && typeof lineBlur === "number") {
2469
- this.createSliderControl(container, layerId, "line-blur", "Line Blur", lineBlur, 0, 5, 0.1);
2834
+ this.createSliderControl(
2835
+ container,
2836
+ layerId,
2837
+ "line-blur",
2838
+ "Line Blur",
2839
+ lineBlur,
2840
+ 0,
2841
+ 5,
2842
+ 0.1
2843
+ );
2470
2844
  }
2471
2845
  }
2472
2846
  /**
@@ -2483,20 +2857,65 @@ class LayerControl {
2483
2857
  if (!circleColor) {
2484
2858
  circleColor = this.map.getPaintProperty(layerId, "circle-color");
2485
2859
  }
2486
- this.createColorControl(container, layerId, "circle-color", "Circle Color", normalizeColor(circleColor || "#000"));
2860
+ this.createColorControl(
2861
+ container,
2862
+ layerId,
2863
+ "circle-color",
2864
+ "Circle Color",
2865
+ normalizeColor(circleColor || "#000")
2866
+ );
2487
2867
  const circleRadius = this.map.getPaintProperty(layerId, "circle-radius");
2488
- this.createSliderControl(container, layerId, "circle-radius", "Radius", typeof circleRadius === "number" ? circleRadius : 5, 0, 40, 0.5);
2868
+ this.createSliderControl(
2869
+ container,
2870
+ layerId,
2871
+ "circle-radius",
2872
+ "Radius",
2873
+ typeof circleRadius === "number" ? circleRadius : 5,
2874
+ 0,
2875
+ 40,
2876
+ 0.5
2877
+ );
2489
2878
  const circleOpacity = this.map.getPaintProperty(layerId, "circle-opacity");
2490
2879
  if (circleOpacity !== void 0 && typeof circleOpacity === "number") {
2491
- this.createSliderControl(container, layerId, "circle-opacity", "Opacity", circleOpacity, 0, 1, 0.05);
2492
- }
2493
- const strokeColor = this.map.getPaintProperty(layerId, "circle-stroke-color");
2880
+ this.createSliderControl(
2881
+ container,
2882
+ layerId,
2883
+ "circle-opacity",
2884
+ "Opacity",
2885
+ circleOpacity,
2886
+ 0,
2887
+ 1,
2888
+ 0.05
2889
+ );
2890
+ }
2891
+ const strokeColor = this.map.getPaintProperty(
2892
+ layerId,
2893
+ "circle-stroke-color"
2894
+ );
2494
2895
  if (strokeColor !== void 0) {
2495
- this.createColorControl(container, layerId, "circle-stroke-color", "Stroke Color", normalizeColor(strokeColor));
2496
- }
2497
- const strokeWidth = this.map.getPaintProperty(layerId, "circle-stroke-width");
2896
+ this.createColorControl(
2897
+ container,
2898
+ layerId,
2899
+ "circle-stroke-color",
2900
+ "Stroke Color",
2901
+ normalizeColor(strokeColor)
2902
+ );
2903
+ }
2904
+ const strokeWidth = this.map.getPaintProperty(
2905
+ layerId,
2906
+ "circle-stroke-width"
2907
+ );
2498
2908
  if (strokeWidth !== void 0 && typeof strokeWidth === "number") {
2499
- this.createSliderControl(container, layerId, "circle-stroke-width", "Stroke Width", strokeWidth, 0, 10, 0.1);
2909
+ this.createSliderControl(
2910
+ container,
2911
+ layerId,
2912
+ "circle-stroke-width",
2913
+ "Stroke Width",
2914
+ strokeWidth,
2915
+ 0,
2916
+ 10,
2917
+ 0.1
2918
+ );
2500
2919
  }
2501
2920
  }
2502
2921
  /**
@@ -2504,17 +2923,77 @@ class LayerControl {
2504
2923
  */
2505
2924
  addRasterControls(container, layerId) {
2506
2925
  const rasterOpacity = this.map.getPaintProperty(layerId, "raster-opacity");
2507
- this.createSliderControl(container, layerId, "raster-opacity", "Opacity", typeof rasterOpacity === "number" ? rasterOpacity : 1, 0, 1, 0.05);
2508
- const brightnessMin = this.map.getPaintProperty(layerId, "raster-brightness-min");
2509
- this.createSliderControl(container, layerId, "raster-brightness-min", "Brightness Min", typeof brightnessMin === "number" ? brightnessMin : 0, -1, 1, 0.05);
2510
- const brightnessMax = this.map.getPaintProperty(layerId, "raster-brightness-max");
2511
- this.createSliderControl(container, layerId, "raster-brightness-max", "Brightness Max", typeof brightnessMax === "number" ? brightnessMax : 1, -1, 1, 0.05);
2926
+ this.createSliderControl(
2927
+ container,
2928
+ layerId,
2929
+ "raster-opacity",
2930
+ "Opacity",
2931
+ typeof rasterOpacity === "number" ? rasterOpacity : 1,
2932
+ 0,
2933
+ 1,
2934
+ 0.05
2935
+ );
2936
+ const brightnessMin = this.map.getPaintProperty(
2937
+ layerId,
2938
+ "raster-brightness-min"
2939
+ );
2940
+ this.createSliderControl(
2941
+ container,
2942
+ layerId,
2943
+ "raster-brightness-min",
2944
+ "Brightness Min",
2945
+ typeof brightnessMin === "number" ? brightnessMin : 0,
2946
+ -1,
2947
+ 1,
2948
+ 0.05
2949
+ );
2950
+ const brightnessMax = this.map.getPaintProperty(
2951
+ layerId,
2952
+ "raster-brightness-max"
2953
+ );
2954
+ this.createSliderControl(
2955
+ container,
2956
+ layerId,
2957
+ "raster-brightness-max",
2958
+ "Brightness Max",
2959
+ typeof brightnessMax === "number" ? brightnessMax : 1,
2960
+ -1,
2961
+ 1,
2962
+ 0.05
2963
+ );
2512
2964
  const saturation = this.map.getPaintProperty(layerId, "raster-saturation");
2513
- this.createSliderControl(container, layerId, "raster-saturation", "Saturation", typeof saturation === "number" ? saturation : 0, -1, 1, 0.05);
2965
+ this.createSliderControl(
2966
+ container,
2967
+ layerId,
2968
+ "raster-saturation",
2969
+ "Saturation",
2970
+ typeof saturation === "number" ? saturation : 0,
2971
+ -1,
2972
+ 1,
2973
+ 0.05
2974
+ );
2514
2975
  const contrast = this.map.getPaintProperty(layerId, "raster-contrast");
2515
- this.createSliderControl(container, layerId, "raster-contrast", "Contrast", typeof contrast === "number" ? contrast : 0, -1, 1, 0.05);
2976
+ this.createSliderControl(
2977
+ container,
2978
+ layerId,
2979
+ "raster-contrast",
2980
+ "Contrast",
2981
+ typeof contrast === "number" ? contrast : 0,
2982
+ -1,
2983
+ 1,
2984
+ 0.05
2985
+ );
2516
2986
  const hueRotate = this.map.getPaintProperty(layerId, "raster-hue-rotate");
2517
- this.createSliderControl(container, layerId, "raster-hue-rotate", "Hue Rotate", typeof hueRotate === "number" ? hueRotate : 0, 0, 350, 5);
2987
+ this.createSliderControl(
2988
+ container,
2989
+ layerId,
2990
+ "raster-hue-rotate",
2991
+ "Hue Rotate",
2992
+ typeof hueRotate === "number" ? hueRotate : 0,
2993
+ 0,
2994
+ 350,
2995
+ 5
2996
+ );
2518
2997
  }
2519
2998
  /**
2520
2999
  * Add controls for symbol layers
@@ -2522,15 +3001,39 @@ class LayerControl {
2522
3001
  addSymbolControls(container, layerId) {
2523
3002
  const textColor = this.map.getPaintProperty(layerId, "text-color");
2524
3003
  if (textColor !== void 0) {
2525
- this.createColorControl(container, layerId, "text-color", "Text Color", normalizeColor(textColor));
3004
+ this.createColorControl(
3005
+ container,
3006
+ layerId,
3007
+ "text-color",
3008
+ "Text Color",
3009
+ normalizeColor(textColor)
3010
+ );
2526
3011
  }
2527
3012
  const textOpacity = this.map.getPaintProperty(layerId, "text-opacity");
2528
3013
  if (textOpacity !== void 0 && typeof textOpacity === "number") {
2529
- this.createSliderControl(container, layerId, "text-opacity", "Text Opacity", textOpacity, 0, 1, 0.05);
3014
+ this.createSliderControl(
3015
+ container,
3016
+ layerId,
3017
+ "text-opacity",
3018
+ "Text Opacity",
3019
+ textOpacity,
3020
+ 0,
3021
+ 1,
3022
+ 0.05
3023
+ );
2530
3024
  }
2531
3025
  const iconOpacity = this.map.getPaintProperty(layerId, "icon-opacity");
2532
3026
  if (iconOpacity !== void 0 && typeof iconOpacity === "number") {
2533
- this.createSliderControl(container, layerId, "icon-opacity", "Icon Opacity", iconOpacity, 0, 1, 0.05);
3027
+ this.createSliderControl(
3028
+ container,
3029
+ layerId,
3030
+ "icon-opacity",
3031
+ "Icon Opacity",
3032
+ iconOpacity,
3033
+ 0,
3034
+ 1,
3035
+ 0.05
3036
+ );
2534
3037
  }
2535
3038
  }
2536
3039
  /**
@@ -2613,7 +3116,9 @@ class LayerControl {
2613
3116
  restoreOriginalStyle(this.map, layerId, this.state.originalStyles);
2614
3117
  const editor = this.styleEditors.get(layerId);
2615
3118
  if (editor) {
2616
- const sliders = editor.querySelectorAll(".style-control-slider");
3119
+ const sliders = editor.querySelectorAll(
3120
+ ".style-control-slider"
3121
+ );
2617
3122
  sliders.forEach((slider) => {
2618
3123
  var _a;
2619
3124
  const property = slider.dataset.property;
@@ -2621,7 +3126,9 @@ class LayerControl {
2621
3126
  const value = this.map.getPaintProperty(layerId, property);
2622
3127
  if (value !== void 0 && typeof value === "number") {
2623
3128
  slider.value = String(value);
2624
- const valueDisplay = (_a = slider.parentElement) == null ? void 0 : _a.querySelector(".style-control-value");
3129
+ const valueDisplay = (_a = slider.parentElement) == null ? void 0 : _a.querySelector(
3130
+ ".style-control-value"
3131
+ );
2625
3132
  if (valueDisplay) {
2626
3133
  const step = parseFloat(slider.step);
2627
3134
  valueDisplay.textContent = formatNumericValue(value, step);
@@ -2629,7 +3136,9 @@ class LayerControl {
2629
3136
  }
2630
3137
  }
2631
3138
  });
2632
- const colorPickers = editor.querySelectorAll(".style-control-color-picker");
3139
+ const colorPickers = editor.querySelectorAll(
3140
+ ".style-control-color-picker"
3141
+ );
2633
3142
  colorPickers.forEach((picker) => {
2634
3143
  var _a;
2635
3144
  const property = picker.dataset.property;
@@ -2638,7 +3147,9 @@ class LayerControl {
2638
3147
  if (value !== void 0) {
2639
3148
  const hexColor = normalizeColor(value);
2640
3149
  picker.value = hexColor;
2641
- const hexDisplay = (_a = picker.parentElement) == null ? void 0 : _a.querySelector(".style-control-color-value");
3150
+ const hexDisplay = (_a = picker.parentElement) == null ? void 0 : _a.querySelector(
3151
+ ".style-control-color-value"
3152
+ );
2642
3153
  if (hexDisplay) {
2643
3154
  hexDisplay.textContent = hexColor;
2644
3155
  }
@@ -2686,8 +3197,12 @@ class LayerControl {
2686
3197
  const layerItems = this.panel.querySelectorAll(".layer-control-item");
2687
3198
  layerItems.forEach((item) => {
2688
3199
  if (item.dataset.layerId === layerId) {
2689
- const checkbox = item.querySelector(".layer-control-checkbox");
2690
- const opacitySlider = item.querySelector(".layer-control-opacity");
3200
+ const checkbox = item.querySelector(
3201
+ ".layer-control-checkbox"
3202
+ );
3203
+ const opacitySlider = item.querySelector(
3204
+ ".layer-control-opacity"
3205
+ );
2691
3206
  if (checkbox) {
2692
3207
  checkbox.checked = visible;
2693
3208
  }
@@ -2711,7 +3226,9 @@ class LayerControl {
2711
3226
  return;
2712
3227
  }
2713
3228
  const currentMapLayerIds = new Set(style.layers.map((layer) => layer.id));
2714
- const isAutoDetectMode = this.targetLayers.length === 0 || this.targetLayers.length === 1 && this.targetLayers[0] === "Background" || this.targetLayers.every((id) => id === "Background" || this.state.layerStates[id]);
3229
+ const isAutoDetectMode = this.targetLayers.length === 0 || this.targetLayers.length === 1 && this.targetLayers[0] === "Background" || this.targetLayers.every(
3230
+ (id) => id === "Background" || this.state.layerStates[id]
3231
+ );
2715
3232
  const newLayers = [];
2716
3233
  const useBasemapStyleDetection = this.basemapLayerIds !== null && this.basemapLayerIds.size > 0;
2717
3234
  const useInitialLayerDetection = !useBasemapStyleDetection && this.initialLayerIds !== null && this.initialLayerIds.size > 0;
@@ -2766,7 +3283,9 @@ class LayerControl {
2766
3283
  if (removedLayers.length > 0) {
2767
3284
  removedLayers.forEach((layerId) => {
2768
3285
  delete this.state.layerStates[layerId];
2769
- const itemEl = this.panel.querySelector(`[data-layer-id="${layerId}"]`);
3286
+ const itemEl = this.panel.querySelector(
3287
+ `[data-layer-id="${layerId}"]`
3288
+ );
2770
3289
  if (itemEl) {
2771
3290
  itemEl.remove();
2772
3291
  }
@@ -2813,7 +3332,9 @@ class LayerControl {
2813
3332
  const state = this.state.layerStates[layerId];
2814
3333
  if (state.isCustomLayer && !customLayerIds.includes(layerId)) {
2815
3334
  delete this.state.layerStates[layerId];
2816
- const itemEl = this.panel.querySelector(`[data-layer-id="${layerId}"]`);
3335
+ const itemEl = this.panel.querySelector(
3336
+ `[data-layer-id="${layerId}"]`
3337
+ );
2817
3338
  if (itemEl) {
2818
3339
  itemEl.remove();
2819
3340
  }
@@ -2836,12 +3357,14 @@ class LayerControl {
2836
3357
  registerCustomAdapter(adapter) {
2837
3358
  if (!this.customLayerRegistry) {
2838
3359
  this.customLayerRegistry = new CustomLayerRegistry();
2839
- this.customLayerUnsubscribe = this.customLayerRegistry.onChange((event, layerId) => {
2840
- if (event === "add" && layerId) {
2841
- this.removedCustomLayerIds.delete(layerId);
3360
+ this.customLayerUnsubscribe = this.customLayerRegistry.onChange(
3361
+ (event, layerId) => {
3362
+ if (event === "add" && layerId) {
3363
+ this.removedCustomLayerIds.delete(layerId);
3364
+ }
3365
+ this.checkForNewLayers();
2842
3366
  }
2843
- this.checkForNewLayers();
2844
- });
3367
+ );
2845
3368
  }
2846
3369
  this.customLayerRegistry.register(adapter);
2847
3370
  if (this.panel) {
@@ -2888,20 +3411,29 @@ class LayerControl {
2888
3411
  }
2889
3412
  this.hideContextMenu();
2890
3413
  });
2891
- const moveBottomItem = this.createContextMenuItem("Move to Bottom", "⤓", () => {
2892
- if (this.state.contextMenu.targetLayerId) {
2893
- this.moveLayerToBottom(this.state.contextMenu.targetLayerId);
3414
+ const moveBottomItem = this.createContextMenuItem(
3415
+ "Move to Bottom",
3416
+ "⤓",
3417
+ () => {
3418
+ if (this.state.contextMenu.targetLayerId) {
3419
+ this.moveLayerToBottom(this.state.contextMenu.targetLayerId);
3420
+ }
3421
+ this.hideContextMenu();
2894
3422
  }
2895
- this.hideContextMenu();
2896
- });
3423
+ );
2897
3424
  const sep2 = document.createElement("div");
2898
3425
  sep2.className = "context-menu-separator";
2899
- const removeItem = this.createContextMenuItem("Remove Layer", "🗑️", () => {
2900
- if (this.state.contextMenu.targetLayerId) {
2901
- this.removeLayer(this.state.contextMenu.targetLayerId);
2902
- }
2903
- this.hideContextMenu();
2904
- }, true);
3426
+ const removeItem = this.createContextMenuItem(
3427
+ "Remove Layer",
3428
+ "🗑️",
3429
+ () => {
3430
+ if (this.state.contextMenu.targetLayerId) {
3431
+ this.removeLayer(this.state.contextMenu.targetLayerId);
3432
+ }
3433
+ this.hideContextMenu();
3434
+ },
3435
+ true
3436
+ );
2905
3437
  menu.appendChild(renameItem);
2906
3438
  menu.appendChild(zoomItem);
2907
3439
  menu.appendChild(sep1);
@@ -3031,7 +3563,9 @@ class LayerControl {
3031
3563
  if ((layerState == null ? void 0 : layerState.isCustomLayer) && this.customLayerRegistry) {
3032
3564
  const bounds = this.customLayerRegistry.getBounds(layerId);
3033
3565
  if (bounds) {
3034
- this.map.fitBounds(bounds, { padding: 50 });
3566
+ this.map.fitBounds(bounds, {
3567
+ padding: 50
3568
+ });
3035
3569
  return;
3036
3570
  }
3037
3571
  }
@@ -3063,7 +3597,9 @@ class LayerControl {
3063
3597
  } else if (feature.geometry.type === "LineString" || feature.geometry.type === "MultiPoint") {
3064
3598
  feature.geometry.coordinates.forEach(processCoords);
3065
3599
  } else if (feature.geometry.type === "Polygon" || feature.geometry.type === "MultiLineString") {
3066
- feature.geometry.coordinates.forEach((ring) => ring.forEach(processCoords));
3600
+ feature.geometry.coordinates.forEach(
3601
+ (ring) => ring.forEach(processCoords)
3602
+ );
3067
3603
  } else if (feature.geometry.type === "MultiPolygon") {
3068
3604
  feature.geometry.coordinates.forEach(
3069
3605
  (polygon) => polygon.forEach((ring) => ring.forEach(processCoords))
@@ -3071,7 +3607,13 @@ class LayerControl {
3071
3607
  }
3072
3608
  });
3073
3609
  if (minLng !== Infinity && minLat !== Infinity && maxLng !== -Infinity && maxLat !== -Infinity) {
3074
- this.map.fitBounds([[minLng, minLat], [maxLng, maxLat]], { padding: 50 });
3610
+ this.map.fitBounds(
3611
+ [
3612
+ [minLng, minLat],
3613
+ [maxLng, maxLat]
3614
+ ],
3615
+ { padding: 50 }
3616
+ );
3075
3617
  }
3076
3618
  } catch (error) {
3077
3619
  console.warn(`Failed to zoom to layer ${layerId}:`, error);
@@ -3085,15 +3627,21 @@ class LayerControl {
3085
3627
  const style = this.map.getStyle();
3086
3628
  if (!(style == null ? void 0 : style.layers)) return [];
3087
3629
  const mapLayerIds = style.layers.map((l) => l.id);
3088
- const userLayerIds = Object.keys(this.state.layerStates).filter((id) => id !== "Background");
3089
- const mapLibreLayers = userLayerIds.filter((id) => mapLayerIds.includes(id));
3630
+ const userLayerIds = Object.keys(this.state.layerStates).filter(
3631
+ (id) => id !== "Background"
3632
+ );
3633
+ const mapLibreLayers = userLayerIds.filter(
3634
+ (id) => mapLayerIds.includes(id)
3635
+ );
3090
3636
  const customLayers = userLayerIds.filter(
3091
3637
  (id) => {
3092
3638
  var _a;
3093
3639
  return ((_a = this.state.layerStates[id]) == null ? void 0 : _a.isCustomLayer) && !mapLayerIds.includes(id);
3094
3640
  }
3095
3641
  );
3096
- const sortedMapLibreLayers = mapLibreLayers.sort((a, b) => mapLayerIds.indexOf(b) - mapLayerIds.indexOf(a));
3642
+ const sortedMapLibreLayers = mapLibreLayers.sort(
3643
+ (a, b) => mapLayerIds.indexOf(b) - mapLayerIds.indexOf(a)
3644
+ );
3097
3645
  return [...customLayers, ...sortedMapLibreLayers];
3098
3646
  }
3099
3647
  /**
@@ -3135,7 +3683,10 @@ class LayerControl {
3135
3683
  }
3136
3684
  const newLayerStates = {};
3137
3685
  const orderedIds = [...layerIds];
3138
- [orderedIds[index], orderedIds[index - 1]] = [orderedIds[index - 1], orderedIds[index]];
3686
+ [orderedIds[index], orderedIds[index - 1]] = [
3687
+ orderedIds[index - 1],
3688
+ orderedIds[index]
3689
+ ];
3139
3690
  if (this.state.layerStates["Background"]) {
3140
3691
  newLayerStates["Background"] = this.state.layerStates["Background"];
3141
3692
  }
@@ -3199,7 +3750,10 @@ class LayerControl {
3199
3750
  }
3200
3751
  const newLayerStates = {};
3201
3752
  const orderedIds = [...layerIds];
3202
- [orderedIds[index], orderedIds[index + 1]] = [orderedIds[index + 1], orderedIds[index]];
3753
+ [orderedIds[index], orderedIds[index + 1]] = [
3754
+ orderedIds[index + 1],
3755
+ orderedIds[index]
3756
+ ];
3203
3757
  if (this.state.layerStates["Background"]) {
3204
3758
  newLayerStates["Background"] = this.state.layerStates["Background"];
3205
3759
  }
@@ -3223,7 +3777,11 @@ class LayerControl {
3223
3777
  if (index < 0 || index === layerIds.length - 1) return;
3224
3778
  const isCustom = (_a = this.state.layerStates[layerId]) == null ? void 0 : _a.isCustomLayer;
3225
3779
  if (!isCustom && this.isMapLibreLayer(layerId)) {
3226
- const bottomLayerId = this.findNextMapLibreLayer(layerIds, layerIds.length - 1, -1);
3780
+ const bottomLayerId = this.findNextMapLibreLayer(
3781
+ layerIds,
3782
+ layerIds.length - 1,
3783
+ -1
3784
+ );
3227
3785
  if (bottomLayerId && bottomLayerId !== layerId) {
3228
3786
  try {
3229
3787
  this.map.moveLayer(layerId, bottomLayerId);
@@ -3311,7 +3869,9 @@ class LayerControl {
3311
3869
  this.map.removeLayer(layerId);
3312
3870
  if (sourceId) {
3313
3871
  const style = this.map.getStyle();
3314
- const sourceStillUsed = (_a = style == null ? void 0 : style.layers) == null ? void 0 : _a.some((l) => l.source === sourceId);
3872
+ const sourceStillUsed = (_a = style == null ? void 0 : style.layers) == null ? void 0 : _a.some(
3873
+ (l) => l.source === sourceId
3874
+ );
3315
3875
  if (!sourceStillUsed) {
3316
3876
  try {
3317
3877
  this.map.removeSource(sourceId);
@@ -3378,7 +3938,9 @@ class LayerControl {
3378
3938
  */
3379
3939
  startDrag(layerId, e) {
3380
3940
  var _a;
3381
- const itemEl = this.panel.querySelector(`[data-layer-id="${layerId}"]`);
3941
+ const itemEl = this.panel.querySelector(
3942
+ `[data-layer-id="${layerId}"]`
3943
+ );
3382
3944
  if (!itemEl) return;
3383
3945
  const rect = itemEl.getBoundingClientRect();
3384
3946
  this.state.drag = {
@@ -3429,7 +3991,11 @@ class LayerControl {
3429
3991
  clone.style.top = `${currentTop + deltaY}px`;
3430
3992
  this.state.drag.startY = e.clientY;
3431
3993
  this.state.drag.currentY = e.clientY;
3432
- const items = Array.from(this.panel.querySelectorAll(".layer-control-item:not(.dragging)")).filter((item) => item.dataset.layerId !== "Background");
3994
+ const items = Array.from(
3995
+ this.panel.querySelectorAll(".layer-control-item:not(.dragging)")
3996
+ ).filter(
3997
+ (item) => item.dataset.layerId !== "Background"
3998
+ );
3433
3999
  for (const item of items) {
3434
4000
  const itemRect = item.getBoundingClientRect();
3435
4001
  if (e.clientY >= itemRect.top && e.clientY <= itemRect.bottom) {
@@ -3455,7 +4021,9 @@ class LayerControl {
3455
4021
  if (!this.state.drag.active) return;
3456
4022
  const layerId = this.state.drag.layerId;
3457
4023
  const placeholder = this.state.drag.placeholder;
3458
- const itemEl = this.panel.querySelector(`[data-layer-id="${layerId}"]`);
4024
+ const itemEl = this.panel.querySelector(
4025
+ `[data-layer-id="${layerId}"]`
4026
+ );
3459
4027
  if (itemEl && placeholder) {
3460
4028
  (_a = placeholder.parentNode) == null ? void 0 : _a.insertBefore(itemEl, placeholder);
3461
4029
  itemEl.classList.remove("dragging");