maplibre-gl-layer-control 0.16.0 → 0.17.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/README.md +5 -5
- package/dist/index.cjs +38 -175
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +38 -175
- package/dist/index.mjs.map +1 -1
- package/dist/maplibre-gl-layer-control.css +0 -57
- package/dist/types/index.d.ts +10 -26
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -689,6 +689,7 @@ class LayerControl {
|
|
|
689
689
|
__publicField(this, "minPanelWidth");
|
|
690
690
|
__publicField(this, "maxPanelWidth");
|
|
691
691
|
__publicField(this, "initialPanelWidth");
|
|
692
|
+
/** Explicit max panel height; null means fill available vertical space */
|
|
692
693
|
__publicField(this, "maxPanelHeight");
|
|
693
694
|
__publicField(this, "showStyleEditor");
|
|
694
695
|
__publicField(this, "showOpacitySlider");
|
|
@@ -701,13 +702,6 @@ class LayerControl {
|
|
|
701
702
|
__publicField(this, "nativeLayerGroups", /* @__PURE__ */ new Map());
|
|
702
703
|
__publicField(this, "basemapStyleUrl", null);
|
|
703
704
|
__publicField(this, "basemapLayerIds", null);
|
|
704
|
-
__publicField(this, "widthSliderEl", null);
|
|
705
|
-
__publicField(this, "widthThumbEl", null);
|
|
706
|
-
__publicField(this, "widthValueEl", null);
|
|
707
|
-
__publicField(this, "isWidthSliderActive", false);
|
|
708
|
-
__publicField(this, "widthDragRectWidth", null);
|
|
709
|
-
__publicField(this, "widthDragStartX", null);
|
|
710
|
-
__publicField(this, "widthDragStartWidth", null);
|
|
711
705
|
__publicField(this, "widthFrame", null);
|
|
712
706
|
// Exact-opacity input popup
|
|
713
707
|
__publicField(this, "opacityInputEl", null);
|
|
@@ -733,9 +727,9 @@ class LayerControl {
|
|
|
733
727
|
__publicField(this, "backgroundPresetStorageKey");
|
|
734
728
|
__publicField(this, "onBackgroundPresetsChange");
|
|
735
729
|
this.minPanelWidth = options.panelMinWidth || 240;
|
|
736
|
-
this.maxPanelWidth = options.panelMaxWidth ||
|
|
730
|
+
this.maxPanelWidth = options.panelMaxWidth || 960;
|
|
737
731
|
this.initialPanelWidth = options.panelWidth || 350;
|
|
738
|
-
this.maxPanelHeight = options.panelMaxHeight
|
|
732
|
+
this.maxPanelHeight = options.panelMaxHeight ?? null;
|
|
739
733
|
this.showStyleEditor = options.showStyleEditor !== false;
|
|
740
734
|
this.showOpacitySlider = options.showOpacitySlider !== false;
|
|
741
735
|
this.showLayerSymbol = options.showLayerSymbol !== false;
|
|
@@ -816,7 +810,6 @@ class LayerControl {
|
|
|
816
810
|
this.contextMenuEl = this.createContextMenu();
|
|
817
811
|
this.mapContainer.appendChild(this.contextMenuEl);
|
|
818
812
|
}
|
|
819
|
-
this.updateWidthDisplay();
|
|
820
813
|
this.setupEventListeners();
|
|
821
814
|
if (this.basemapStyleUrl && !this.basemapLayerIds) {
|
|
822
815
|
this.fetchBasemapStyle().then(() => {
|
|
@@ -1216,7 +1209,9 @@ class LayerControl {
|
|
|
1216
1209
|
const panel = document.createElement("div");
|
|
1217
1210
|
panel.className = "layer-control-panel";
|
|
1218
1211
|
panel.style.width = `${this.state.panelWidth}px`;
|
|
1219
|
-
|
|
1212
|
+
if (this.maxPanelHeight != null) {
|
|
1213
|
+
panel.style.maxHeight = `${this.maxPanelHeight}px`;
|
|
1214
|
+
}
|
|
1220
1215
|
if (!this.state.collapsed) {
|
|
1221
1216
|
panel.classList.add("expanded");
|
|
1222
1217
|
}
|
|
@@ -1383,6 +1378,15 @@ class LayerControl {
|
|
|
1383
1378
|
this.panel.style.right = `${buttonRight}px`;
|
|
1384
1379
|
break;
|
|
1385
1380
|
}
|
|
1381
|
+
const edgeMargin = 8;
|
|
1382
|
+
const isTopAnchored = position === "top-left" || position === "top-right";
|
|
1383
|
+
const occupiedFromEdge = isTopAnchored ? buttonTop + buttonRect.height + panelGap : buttonBottom + buttonRect.height + panelGap;
|
|
1384
|
+
const availableHeight = Math.max(
|
|
1385
|
+
120,
|
|
1386
|
+
Math.round(mapRect.height - occupiedFromEdge - edgeMargin)
|
|
1387
|
+
);
|
|
1388
|
+
const maxHeight = this.maxPanelHeight != null ? Math.min(this.maxPanelHeight, availableHeight) : availableHeight;
|
|
1389
|
+
this.panel.style.maxHeight = `${maxHeight}px`;
|
|
1386
1390
|
}
|
|
1387
1391
|
/**
|
|
1388
1392
|
* Create action buttons for Show All / Hide All
|
|
@@ -1431,7 +1435,8 @@ class LayerControl {
|
|
|
1431
1435
|
});
|
|
1432
1436
|
}
|
|
1433
1437
|
/**
|
|
1434
|
-
* Create the panel header with title
|
|
1438
|
+
* Create the panel header with the title. Panel width is adjusted by
|
|
1439
|
+
* dragging either edge of the panel (see createResizeHandle).
|
|
1435
1440
|
*/
|
|
1436
1441
|
createPanelHeader() {
|
|
1437
1442
|
const header = document.createElement("div");
|
|
@@ -1440,135 +1445,8 @@ class LayerControl {
|
|
|
1440
1445
|
title.className = "layer-control-panel-title";
|
|
1441
1446
|
title.textContent = "Layers";
|
|
1442
1447
|
header.appendChild(title);
|
|
1443
|
-
const widthControl = this.createWidthControl();
|
|
1444
|
-
header.appendChild(widthControl);
|
|
1445
1448
|
return header;
|
|
1446
1449
|
}
|
|
1447
|
-
/**
|
|
1448
|
-
* Create the width control slider
|
|
1449
|
-
*/
|
|
1450
|
-
createWidthControl() {
|
|
1451
|
-
const widthControl = document.createElement("label");
|
|
1452
|
-
widthControl.className = "layer-control-width-control";
|
|
1453
|
-
widthControl.title = "Adjust layer panel width";
|
|
1454
|
-
const widthLabel = document.createElement("span");
|
|
1455
|
-
widthLabel.textContent = "Width";
|
|
1456
|
-
widthControl.appendChild(widthLabel);
|
|
1457
|
-
const widthSlider = document.createElement("div");
|
|
1458
|
-
widthSlider.className = "layer-control-width-slider";
|
|
1459
|
-
widthSlider.setAttribute("role", "slider");
|
|
1460
|
-
widthSlider.setAttribute("aria-valuemin", String(this.minPanelWidth));
|
|
1461
|
-
widthSlider.setAttribute("aria-valuemax", String(this.maxPanelWidth));
|
|
1462
|
-
widthSlider.setAttribute("aria-valuenow", String(this.state.panelWidth));
|
|
1463
|
-
widthSlider.setAttribute("aria-valuestep", "10");
|
|
1464
|
-
widthSlider.setAttribute("aria-label", "Layer panel width");
|
|
1465
|
-
widthSlider.tabIndex = 0;
|
|
1466
|
-
const widthTrack = document.createElement("div");
|
|
1467
|
-
widthTrack.className = "layer-control-width-track";
|
|
1468
|
-
const widthThumb = document.createElement("div");
|
|
1469
|
-
widthThumb.className = "layer-control-width-thumb";
|
|
1470
|
-
widthSlider.appendChild(widthTrack);
|
|
1471
|
-
widthSlider.appendChild(widthThumb);
|
|
1472
|
-
this.widthSliderEl = widthSlider;
|
|
1473
|
-
this.widthThumbEl = widthThumb;
|
|
1474
|
-
const widthValue = document.createElement("span");
|
|
1475
|
-
widthValue.className = "layer-control-width-value";
|
|
1476
|
-
this.widthValueEl = widthValue;
|
|
1477
|
-
widthControl.appendChild(widthSlider);
|
|
1478
|
-
widthControl.appendChild(widthValue);
|
|
1479
|
-
this.updateWidthDisplay();
|
|
1480
|
-
this.setupWidthSliderEvents(widthSlider);
|
|
1481
|
-
return widthControl;
|
|
1482
|
-
}
|
|
1483
|
-
/**
|
|
1484
|
-
* Setup event listeners for width slider
|
|
1485
|
-
*/
|
|
1486
|
-
setupWidthSliderEvents(widthSlider) {
|
|
1487
|
-
widthSlider.addEventListener("pointerdown", (event) => {
|
|
1488
|
-
event.preventDefault();
|
|
1489
|
-
const rect = widthSlider.getBoundingClientRect();
|
|
1490
|
-
this.widthDragRectWidth = rect.width || 1;
|
|
1491
|
-
this.widthDragStartX = event.clientX;
|
|
1492
|
-
this.widthDragStartWidth = this.state.panelWidth;
|
|
1493
|
-
this.isWidthSliderActive = true;
|
|
1494
|
-
widthSlider.setPointerCapture(event.pointerId);
|
|
1495
|
-
this.updateWidthFromPointer(event, true);
|
|
1496
|
-
});
|
|
1497
|
-
widthSlider.addEventListener("pointermove", (event) => {
|
|
1498
|
-
if (!this.isWidthSliderActive) return;
|
|
1499
|
-
this.updateWidthFromPointer(event);
|
|
1500
|
-
});
|
|
1501
|
-
const endPointerDrag = (event) => {
|
|
1502
|
-
if (!this.isWidthSliderActive) return;
|
|
1503
|
-
if (event.pointerId !== void 0) {
|
|
1504
|
-
try {
|
|
1505
|
-
widthSlider.releasePointerCapture(event.pointerId);
|
|
1506
|
-
} catch (error) {
|
|
1507
|
-
}
|
|
1508
|
-
}
|
|
1509
|
-
this.isWidthSliderActive = false;
|
|
1510
|
-
this.widthDragRectWidth = null;
|
|
1511
|
-
this.widthDragStartX = null;
|
|
1512
|
-
this.widthDragStartWidth = null;
|
|
1513
|
-
this.updateWidthDisplay();
|
|
1514
|
-
};
|
|
1515
|
-
widthSlider.addEventListener("pointerup", endPointerDrag);
|
|
1516
|
-
widthSlider.addEventListener("pointercancel", endPointerDrag);
|
|
1517
|
-
widthSlider.addEventListener("lostpointercapture", endPointerDrag);
|
|
1518
|
-
widthSlider.addEventListener("keydown", (event) => {
|
|
1519
|
-
let handled = true;
|
|
1520
|
-
const step = event.shiftKey ? 20 : 10;
|
|
1521
|
-
switch (event.key) {
|
|
1522
|
-
case "ArrowLeft":
|
|
1523
|
-
case "ArrowDown":
|
|
1524
|
-
this.applyPanelWidth(this.state.panelWidth - step, true);
|
|
1525
|
-
break;
|
|
1526
|
-
case "ArrowRight":
|
|
1527
|
-
case "ArrowUp":
|
|
1528
|
-
this.applyPanelWidth(this.state.panelWidth + step, true);
|
|
1529
|
-
break;
|
|
1530
|
-
case "Home":
|
|
1531
|
-
this.applyPanelWidth(this.minPanelWidth, true);
|
|
1532
|
-
break;
|
|
1533
|
-
case "End":
|
|
1534
|
-
this.applyPanelWidth(this.maxPanelWidth, true);
|
|
1535
|
-
break;
|
|
1536
|
-
case "PageUp":
|
|
1537
|
-
this.applyPanelWidth(this.state.panelWidth + 50, true);
|
|
1538
|
-
break;
|
|
1539
|
-
case "PageDown":
|
|
1540
|
-
this.applyPanelWidth(this.state.panelWidth - 50, true);
|
|
1541
|
-
break;
|
|
1542
|
-
default:
|
|
1543
|
-
handled = false;
|
|
1544
|
-
}
|
|
1545
|
-
if (handled) {
|
|
1546
|
-
event.preventDefault();
|
|
1547
|
-
this.updateWidthDisplay();
|
|
1548
|
-
}
|
|
1549
|
-
});
|
|
1550
|
-
}
|
|
1551
|
-
/**
|
|
1552
|
-
* Update panel width from pointer event
|
|
1553
|
-
*/
|
|
1554
|
-
updateWidthFromPointer(event, resetBaseline = false) {
|
|
1555
|
-
if (!this.widthSliderEl) return;
|
|
1556
|
-
const sliderWidth = this.widthDragRectWidth || this.widthSliderEl.getBoundingClientRect().width || 1;
|
|
1557
|
-
const widthRange = this.maxPanelWidth - this.minPanelWidth;
|
|
1558
|
-
let width;
|
|
1559
|
-
if (resetBaseline) {
|
|
1560
|
-
const rect = this.widthSliderEl.getBoundingClientRect();
|
|
1561
|
-
const relative = rect.width > 0 ? (event.clientX - rect.left) / rect.width : 0;
|
|
1562
|
-
const clampedRatio = Math.min(1, Math.max(0, relative));
|
|
1563
|
-
width = this.minPanelWidth + clampedRatio * widthRange;
|
|
1564
|
-
this.widthDragStartWidth = width;
|
|
1565
|
-
this.widthDragStartX = event.clientX;
|
|
1566
|
-
} else {
|
|
1567
|
-
const delta = event.clientX - (this.widthDragStartX || event.clientX);
|
|
1568
|
-
width = (this.widthDragStartWidth || this.state.panelWidth) + delta / sliderWidth * widthRange;
|
|
1569
|
-
}
|
|
1570
|
-
this.applyPanelWidth(width, this.isWidthSliderActive);
|
|
1571
|
-
}
|
|
1572
1450
|
/**
|
|
1573
1451
|
* Apply panel width (clamped to min/max)
|
|
1574
1452
|
*/
|
|
@@ -1580,7 +1458,6 @@ class LayerControl {
|
|
|
1580
1458
|
this.state.panelWidth = clamped;
|
|
1581
1459
|
const px = `${clamped}px`;
|
|
1582
1460
|
this.panel.style.width = px;
|
|
1583
|
-
this.updateWidthDisplay();
|
|
1584
1461
|
};
|
|
1585
1462
|
if (immediate) {
|
|
1586
1463
|
applyWidth();
|
|
@@ -1594,34 +1471,6 @@ class LayerControl {
|
|
|
1594
1471
|
this.widthFrame = null;
|
|
1595
1472
|
});
|
|
1596
1473
|
}
|
|
1597
|
-
/**
|
|
1598
|
-
* Update width display (value label and thumb position)
|
|
1599
|
-
*/
|
|
1600
|
-
updateWidthDisplay() {
|
|
1601
|
-
if (this.widthValueEl) {
|
|
1602
|
-
this.widthValueEl.textContent = `${this.state.panelWidth}px`;
|
|
1603
|
-
}
|
|
1604
|
-
if (this.widthSliderEl) {
|
|
1605
|
-
this.widthSliderEl.setAttribute(
|
|
1606
|
-
"aria-valuenow",
|
|
1607
|
-
String(this.state.panelWidth)
|
|
1608
|
-
);
|
|
1609
|
-
const ratio = (this.state.panelWidth - this.minPanelWidth) / (this.maxPanelWidth - this.minPanelWidth || 1);
|
|
1610
|
-
if (this.widthThumbEl) {
|
|
1611
|
-
const sliderWidth = this.widthSliderEl.clientWidth;
|
|
1612
|
-
if (sliderWidth === 0) {
|
|
1613
|
-
requestAnimationFrame(() => this.updateWidthDisplay());
|
|
1614
|
-
return;
|
|
1615
|
-
}
|
|
1616
|
-
const thumbWidth = this.widthThumbEl.offsetWidth || 14;
|
|
1617
|
-
const padding = 16;
|
|
1618
|
-
const available = Math.max(0, sliderWidth - padding - thumbWidth);
|
|
1619
|
-
const clampedRatio = Math.min(1, Math.max(0, ratio));
|
|
1620
|
-
const leftPx = 8 + available * clampedRatio;
|
|
1621
|
-
this.widthThumbEl.style.left = `${leftPx}px`;
|
|
1622
|
-
}
|
|
1623
|
-
}
|
|
1624
|
-
}
|
|
1625
1474
|
/**
|
|
1626
1475
|
* Setup main event listeners
|
|
1627
1476
|
*/
|
|
@@ -1720,7 +1569,21 @@ class LayerControl {
|
|
|
1720
1569
|
const existingItems = this.panel.querySelectorAll(".layer-control-item");
|
|
1721
1570
|
existingItems.forEach((item) => item.remove());
|
|
1722
1571
|
this.styleEditors.clear();
|
|
1723
|
-
|
|
1572
|
+
const orderedLayerIds = this.getUserLayerIdsInMapOrder();
|
|
1573
|
+
const captured = new Set(orderedLayerIds);
|
|
1574
|
+
for (const layerId of Object.keys(this.state.layerStates)) {
|
|
1575
|
+
if (layerId !== "Background" && !captured.has(layerId)) {
|
|
1576
|
+
orderedLayerIds.push(layerId);
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
if (this.state.layerStates["Background"]) {
|
|
1580
|
+
orderedLayerIds.push("Background");
|
|
1581
|
+
}
|
|
1582
|
+
orderedLayerIds.forEach((layerId) => {
|
|
1583
|
+
const state = this.state.layerStates[layerId];
|
|
1584
|
+
if (!state) {
|
|
1585
|
+
return;
|
|
1586
|
+
}
|
|
1724
1587
|
if (this.targetLayers.length === 0 || this.targetLayers.includes(layerId)) {
|
|
1725
1588
|
this.addLayerItem(layerId, state);
|
|
1726
1589
|
}
|
|
@@ -2501,7 +2364,8 @@ class LayerControl {
|
|
|
2501
2364
|
const styleLayers = this.map.getStyle().layers || [];
|
|
2502
2365
|
return styleLayers.filter((layer) => {
|
|
2503
2366
|
if (this.isUserAddedLayer(layer.id)) return false;
|
|
2504
|
-
if (this.excludeDrawnLayers && this.isDrawnLayer(layer.id))
|
|
2367
|
+
if (this.excludeDrawnLayers && this.isDrawnLayer(layer.id))
|
|
2368
|
+
return false;
|
|
2505
2369
|
if (this.isExcludedByPattern(layer.id)) return false;
|
|
2506
2370
|
return true;
|
|
2507
2371
|
}).map((layer) => layer.id);
|
|
@@ -4318,18 +4182,17 @@ class LayerControl {
|
|
|
4318
4182
|
uiLayerIds.push(layerId);
|
|
4319
4183
|
}
|
|
4320
4184
|
});
|
|
4321
|
-
const reversedIds = [...uiLayerIds].reverse();
|
|
4322
4185
|
const style = this.map.getStyle();
|
|
4323
4186
|
const mapLibreLayerIds = new Set(((_a = style == null ? void 0 : style.layers) == null ? void 0 : _a.map((l) => l.id)) || []);
|
|
4324
|
-
for (let i = 0; i <
|
|
4325
|
-
const layerId =
|
|
4187
|
+
for (let i = 0; i < uiLayerIds.length; i++) {
|
|
4188
|
+
const layerId = uiLayerIds[i];
|
|
4326
4189
|
if (!mapLibreLayerIds.has(layerId)) {
|
|
4327
4190
|
continue;
|
|
4328
4191
|
}
|
|
4329
4192
|
let beforeId = void 0;
|
|
4330
4193
|
for (let j = i - 1; j >= 0; j--) {
|
|
4331
|
-
if (mapLibreLayerIds.has(
|
|
4332
|
-
beforeId =
|
|
4194
|
+
if (mapLibreLayerIds.has(uiLayerIds[j])) {
|
|
4195
|
+
beforeId = uiLayerIds[j];
|
|
4333
4196
|
break;
|
|
4334
4197
|
}
|
|
4335
4198
|
}
|