maplibre-gl-components 0.2.1 → 0.3.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 +57 -0
- package/dist/{HtmlControl-mwWlMV6V.js → HtmlControl-CxD6T9bG.js} +130 -31
- package/dist/HtmlControl-CxD6T9bG.js.map +1 -0
- package/dist/{HtmlControl-te5F3x7c.cjs → HtmlControl-CzXIBk1H.cjs} +130 -31
- package/dist/HtmlControl-CzXIBk1H.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/react.cjs +12 -4
- package/dist/react.cjs.map +1 -1
- package/dist/react.mjs +12 -4
- package/dist/react.mjs.map +1 -1
- package/dist/types/lib/core/Colorbar.d.ts +12 -1
- package/dist/types/lib/core/Colorbar.d.ts.map +1 -1
- package/dist/types/lib/core/ColorbarReact.d.ts.map +1 -1
- package/dist/types/lib/core/HtmlControl.d.ts +12 -1
- package/dist/types/lib/core/HtmlControl.d.ts.map +1 -1
- package/dist/types/lib/core/HtmlControlReact.d.ts.map +1 -1
- package/dist/types/lib/core/Legend.d.ts +12 -1
- package/dist/types/lib/core/Legend.d.ts.map +1 -1
- package/dist/types/lib/core/LegendReact.d.ts.map +1 -1
- package/dist/types/lib/core/types.d.ts +12 -0
- package/dist/types/lib/core/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/HtmlControl-mwWlMV6V.js.map +0 -1
- package/dist/HtmlControl-te5F3x7c.cjs.map +0 -1
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@ Legend, colorbar, and HTML control components for MapLibre GL JS maps.
|
|
|
10
10
|
- **Colorbar** - Continuous gradient legends with built-in matplotlib colormaps
|
|
11
11
|
- **Legend** - Categorical legends with color swatches and labels
|
|
12
12
|
- **HtmlControl** - Flexible HTML content control for custom info panels
|
|
13
|
+
- **Zoom-based Visibility** - Show/hide components at specific zoom levels with `minzoom`/`maxzoom`
|
|
13
14
|
- **React Support** - First-class React components and hooks
|
|
14
15
|
- **TypeScript** - Full type definitions included
|
|
15
16
|
- **20+ Built-in Colormaps** - viridis, plasma, terrain, jet, and more
|
|
@@ -160,6 +161,8 @@ interface ColorbarOptions {
|
|
|
160
161
|
opacity?: number;
|
|
161
162
|
fontSize?: number;
|
|
162
163
|
fontColor?: string;
|
|
164
|
+
minzoom?: number; // Min zoom level to show (default: 0)
|
|
165
|
+
maxzoom?: number; // Max zoom level to show (default: 24)
|
|
163
166
|
}
|
|
164
167
|
|
|
165
168
|
// Methods
|
|
@@ -190,6 +193,8 @@ interface LegendOptions {
|
|
|
190
193
|
opacity?: number;
|
|
191
194
|
fontSize?: number;
|
|
192
195
|
fontColor?: string;
|
|
196
|
+
minzoom?: number; // Min zoom level to show (default: 0)
|
|
197
|
+
maxzoom?: number; // Max zoom level to show (default: 24)
|
|
193
198
|
}
|
|
194
199
|
|
|
195
200
|
interface LegendItem {
|
|
@@ -229,6 +234,8 @@ interface HtmlControlOptions {
|
|
|
229
234
|
opacity?: number;
|
|
230
235
|
maxWidth?: number;
|
|
231
236
|
maxHeight?: number;
|
|
237
|
+
minzoom?: number; // Min zoom level to show (default: 0)
|
|
238
|
+
maxzoom?: number; // Max zoom level to show (default: 24)
|
|
232
239
|
}
|
|
233
240
|
|
|
234
241
|
// Methods
|
|
@@ -293,6 +300,56 @@ const colorbar = new Colorbar({
|
|
|
293
300
|
});
|
|
294
301
|
```
|
|
295
302
|
|
|
303
|
+
## Zoom-based Visibility
|
|
304
|
+
|
|
305
|
+
All components support `minzoom` and `maxzoom` options to control visibility based on the map's zoom level. This is useful for showing different legends at different zoom levels, similar to how map layers work.
|
|
306
|
+
|
|
307
|
+
```typescript
|
|
308
|
+
// Show legend only when zoomed in (zoom >= 10)
|
|
309
|
+
const detailLegend = new Legend({
|
|
310
|
+
title: 'Detailed Features',
|
|
311
|
+
items: [...],
|
|
312
|
+
minzoom: 10, // Only visible at zoom 10 and above
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
// Show legend only when zoomed out (zoom <= 8)
|
|
316
|
+
const overviewLegend = new Legend({
|
|
317
|
+
title: 'Overview',
|
|
318
|
+
items: [...],
|
|
319
|
+
maxzoom: 8, // Only visible at zoom 8 and below
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
// Show colorbar only within a specific zoom range
|
|
323
|
+
const colorbar = new Colorbar({
|
|
324
|
+
colormap: 'viridis',
|
|
325
|
+
vmin: 0,
|
|
326
|
+
vmax: 100,
|
|
327
|
+
minzoom: 5, // Visible from zoom 5...
|
|
328
|
+
maxzoom: 15, // ...up to zoom 15
|
|
329
|
+
});
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### React Example
|
|
333
|
+
|
|
334
|
+
```tsx
|
|
335
|
+
<LegendReact
|
|
336
|
+
map={map}
|
|
337
|
+
title="Lidar Point Cloud"
|
|
338
|
+
items={[
|
|
339
|
+
{ label: 'QL0 (Approx. <= 0.35m NPS)', color: '#003300' },
|
|
340
|
+
{ label: 'QL1 (Approx. 0.35m NPS)', color: '#006600' },
|
|
341
|
+
{ label: 'QL2 (Approx. 0.7m NPS)', color: '#00cc00' },
|
|
342
|
+
{ label: 'QL3 (Approx. 1.4m NPS)', color: '#ccff00' },
|
|
343
|
+
{ label: 'Other', color: '#99ccff' },
|
|
344
|
+
]}
|
|
345
|
+
minzoom={8}
|
|
346
|
+
maxzoom={18}
|
|
347
|
+
position="top-left"
|
|
348
|
+
/>
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
**Note:** The `visible` option takes precedence - if `visible` is `false`, the component will be hidden regardless of zoom level.
|
|
352
|
+
|
|
296
353
|
## React Hooks
|
|
297
354
|
|
|
298
355
|
```typescript
|
|
@@ -305,7 +305,9 @@ const DEFAULT_OPTIONS$2 = {
|
|
|
305
305
|
fontSize: 11,
|
|
306
306
|
fontColor: "#333",
|
|
307
307
|
borderRadius: 4,
|
|
308
|
-
padding: 8
|
|
308
|
+
padding: 8,
|
|
309
|
+
minzoom: 0,
|
|
310
|
+
maxzoom: 24
|
|
309
311
|
};
|
|
310
312
|
class Colorbar {
|
|
311
313
|
/**
|
|
@@ -318,6 +320,9 @@ class Colorbar {
|
|
|
318
320
|
__publicField(this, "_options");
|
|
319
321
|
__publicField(this, "_state");
|
|
320
322
|
__publicField(this, "_eventHandlers", /* @__PURE__ */ new Map());
|
|
323
|
+
__publicField(this, "_map");
|
|
324
|
+
__publicField(this, "_handleZoom");
|
|
325
|
+
__publicField(this, "_zoomVisible", true);
|
|
321
326
|
this._options = { ...DEFAULT_OPTIONS$2, ...options };
|
|
322
327
|
this._state = {
|
|
323
328
|
visible: this._options.visible,
|
|
@@ -333,9 +338,13 @@ class Colorbar {
|
|
|
333
338
|
* @param map - The MapLibre GL map instance.
|
|
334
339
|
* @returns The control's container element.
|
|
335
340
|
*/
|
|
336
|
-
onAdd(
|
|
341
|
+
onAdd(map) {
|
|
342
|
+
this._map = map;
|
|
337
343
|
this._container = this._createContainer();
|
|
338
344
|
this._render();
|
|
345
|
+
this._handleZoom = () => this._checkZoomVisibility();
|
|
346
|
+
this._map.on("zoom", this._handleZoom);
|
|
347
|
+
this._checkZoomVisibility();
|
|
339
348
|
return this._container;
|
|
340
349
|
}
|
|
341
350
|
/**
|
|
@@ -344,6 +353,11 @@ class Colorbar {
|
|
|
344
353
|
*/
|
|
345
354
|
onRemove() {
|
|
346
355
|
var _a, _b;
|
|
356
|
+
if (this._map && this._handleZoom) {
|
|
357
|
+
this._map.off("zoom", this._handleZoom);
|
|
358
|
+
this._handleZoom = void 0;
|
|
359
|
+
}
|
|
360
|
+
this._map = void 0;
|
|
347
361
|
(_b = (_a = this._container) == null ? void 0 : _a.parentNode) == null ? void 0 : _b.removeChild(this._container);
|
|
348
362
|
this._container = void 0;
|
|
349
363
|
this._eventHandlers.clear();
|
|
@@ -354,9 +368,7 @@ class Colorbar {
|
|
|
354
368
|
show() {
|
|
355
369
|
if (!this._state.visible) {
|
|
356
370
|
this._state.visible = true;
|
|
357
|
-
|
|
358
|
-
this._container.style.display = "flex";
|
|
359
|
-
}
|
|
371
|
+
this._updateDisplayState();
|
|
360
372
|
this._emit("show");
|
|
361
373
|
}
|
|
362
374
|
}
|
|
@@ -366,9 +378,7 @@ class Colorbar {
|
|
|
366
378
|
hide() {
|
|
367
379
|
if (this._state.visible) {
|
|
368
380
|
this._state.visible = false;
|
|
369
|
-
|
|
370
|
-
this._container.style.display = "none";
|
|
371
|
-
}
|
|
381
|
+
this._updateDisplayState();
|
|
372
382
|
this._emit("hide");
|
|
373
383
|
}
|
|
374
384
|
}
|
|
@@ -489,6 +499,27 @@ class Colorbar {
|
|
|
489
499
|
handlers.forEach((handler) => handler(eventData));
|
|
490
500
|
}
|
|
491
501
|
}
|
|
502
|
+
/**
|
|
503
|
+
* Checks if the current zoom level is within the visibility range.
|
|
504
|
+
*/
|
|
505
|
+
_checkZoomVisibility() {
|
|
506
|
+
if (!this._map) return;
|
|
507
|
+
const zoom = this._map.getZoom();
|
|
508
|
+
const { minzoom, maxzoom } = this._options;
|
|
509
|
+
const inRange = zoom >= minzoom && zoom <= maxzoom;
|
|
510
|
+
if (inRange !== this._zoomVisible) {
|
|
511
|
+
this._zoomVisible = inRange;
|
|
512
|
+
this._updateDisplayState();
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Updates the display state based on visibility and zoom level.
|
|
517
|
+
*/
|
|
518
|
+
_updateDisplayState() {
|
|
519
|
+
if (!this._container) return;
|
|
520
|
+
const shouldShow = this._state.visible && this._zoomVisible;
|
|
521
|
+
this._container.style.display = shouldShow ? "flex" : "none";
|
|
522
|
+
}
|
|
492
523
|
/**
|
|
493
524
|
* Creates the main container element.
|
|
494
525
|
*
|
|
@@ -497,7 +528,8 @@ class Colorbar {
|
|
|
497
528
|
_createContainer() {
|
|
498
529
|
const container = document.createElement("div");
|
|
499
530
|
container.className = `maplibregl-ctrl maplibre-gl-colorbar${this._options.className ? ` ${this._options.className}` : ""}`;
|
|
500
|
-
|
|
531
|
+
const shouldShow = this._state.visible && this._zoomVisible;
|
|
532
|
+
if (!shouldShow) {
|
|
501
533
|
container.style.display = "none";
|
|
502
534
|
}
|
|
503
535
|
return container;
|
|
@@ -522,6 +554,7 @@ class Colorbar {
|
|
|
522
554
|
const isVertical = orientation === "vertical";
|
|
523
555
|
const ticks = this._generateTicks();
|
|
524
556
|
this._container.innerHTML = "";
|
|
557
|
+
const shouldShow = this._state.visible && this._zoomVisible;
|
|
525
558
|
Object.assign(this._container.style, {
|
|
526
559
|
backgroundColor,
|
|
527
560
|
opacity: opacity.toString(),
|
|
@@ -529,7 +562,7 @@ class Colorbar {
|
|
|
529
562
|
padding: `${padding}px`,
|
|
530
563
|
fontSize: `${fontSize}px`,
|
|
531
564
|
color: fontColor,
|
|
532
|
-
display:
|
|
565
|
+
display: shouldShow ? "flex" : "none",
|
|
533
566
|
flexDirection: isVertical ? "row" : "column",
|
|
534
567
|
alignItems: "stretch",
|
|
535
568
|
gap: "6px",
|
|
@@ -604,7 +637,9 @@ const DEFAULT_OPTIONS$1 = {
|
|
|
604
637
|
fontColor: "#333",
|
|
605
638
|
swatchSize: 16,
|
|
606
639
|
borderRadius: 4,
|
|
607
|
-
padding: 10
|
|
640
|
+
padding: 10,
|
|
641
|
+
minzoom: 0,
|
|
642
|
+
maxzoom: 24
|
|
608
643
|
};
|
|
609
644
|
class Legend {
|
|
610
645
|
/**
|
|
@@ -617,6 +652,9 @@ class Legend {
|
|
|
617
652
|
__publicField(this, "_options");
|
|
618
653
|
__publicField(this, "_state");
|
|
619
654
|
__publicField(this, "_eventHandlers", /* @__PURE__ */ new Map());
|
|
655
|
+
__publicField(this, "_map");
|
|
656
|
+
__publicField(this, "_handleZoom");
|
|
657
|
+
__publicField(this, "_zoomVisible", true);
|
|
620
658
|
this._options = { ...DEFAULT_OPTIONS$1, ...options };
|
|
621
659
|
this._state = {
|
|
622
660
|
visible: this._options.visible,
|
|
@@ -630,9 +668,13 @@ class Legend {
|
|
|
630
668
|
* @param map - The MapLibre GL map instance.
|
|
631
669
|
* @returns The control's container element.
|
|
632
670
|
*/
|
|
633
|
-
onAdd(
|
|
671
|
+
onAdd(map) {
|
|
672
|
+
this._map = map;
|
|
634
673
|
this._container = this._createContainer();
|
|
635
674
|
this._render();
|
|
675
|
+
this._handleZoom = () => this._checkZoomVisibility();
|
|
676
|
+
this._map.on("zoom", this._handleZoom);
|
|
677
|
+
this._checkZoomVisibility();
|
|
636
678
|
return this._container;
|
|
637
679
|
}
|
|
638
680
|
/**
|
|
@@ -640,6 +682,11 @@ class Legend {
|
|
|
640
682
|
*/
|
|
641
683
|
onRemove() {
|
|
642
684
|
var _a, _b;
|
|
685
|
+
if (this._map && this._handleZoom) {
|
|
686
|
+
this._map.off("zoom", this._handleZoom);
|
|
687
|
+
this._handleZoom = void 0;
|
|
688
|
+
}
|
|
689
|
+
this._map = void 0;
|
|
643
690
|
(_b = (_a = this._container) == null ? void 0 : _a.parentNode) == null ? void 0 : _b.removeChild(this._container);
|
|
644
691
|
this._container = void 0;
|
|
645
692
|
this._eventHandlers.clear();
|
|
@@ -650,9 +697,7 @@ class Legend {
|
|
|
650
697
|
show() {
|
|
651
698
|
if (!this._state.visible) {
|
|
652
699
|
this._state.visible = true;
|
|
653
|
-
|
|
654
|
-
this._container.style.display = "block";
|
|
655
|
-
}
|
|
700
|
+
this._updateDisplayState();
|
|
656
701
|
this._emit("show");
|
|
657
702
|
}
|
|
658
703
|
}
|
|
@@ -662,9 +707,7 @@ class Legend {
|
|
|
662
707
|
hide() {
|
|
663
708
|
if (this._state.visible) {
|
|
664
709
|
this._state.visible = false;
|
|
665
|
-
|
|
666
|
-
this._container.style.display = "none";
|
|
667
|
-
}
|
|
710
|
+
this._updateDisplayState();
|
|
668
711
|
this._emit("hide");
|
|
669
712
|
}
|
|
670
713
|
}
|
|
@@ -786,6 +829,27 @@ class Legend {
|
|
|
786
829
|
handlers.forEach((handler) => handler(eventData));
|
|
787
830
|
}
|
|
788
831
|
}
|
|
832
|
+
/**
|
|
833
|
+
* Checks if the current zoom level is within the visibility range.
|
|
834
|
+
*/
|
|
835
|
+
_checkZoomVisibility() {
|
|
836
|
+
if (!this._map) return;
|
|
837
|
+
const zoom = this._map.getZoom();
|
|
838
|
+
const { minzoom, maxzoom } = this._options;
|
|
839
|
+
const inRange = zoom >= minzoom && zoom <= maxzoom;
|
|
840
|
+
if (inRange !== this._zoomVisible) {
|
|
841
|
+
this._zoomVisible = inRange;
|
|
842
|
+
this._updateDisplayState();
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
/**
|
|
846
|
+
* Updates the display state based on visibility and zoom level.
|
|
847
|
+
*/
|
|
848
|
+
_updateDisplayState() {
|
|
849
|
+
if (!this._container) return;
|
|
850
|
+
const shouldShow = this._state.visible && this._zoomVisible;
|
|
851
|
+
this._container.style.display = shouldShow ? "block" : "none";
|
|
852
|
+
}
|
|
789
853
|
/**
|
|
790
854
|
* Creates the main container element.
|
|
791
855
|
*
|
|
@@ -794,7 +858,8 @@ class Legend {
|
|
|
794
858
|
_createContainer() {
|
|
795
859
|
const container = document.createElement("div");
|
|
796
860
|
container.className = `maplibregl-ctrl maplibre-gl-legend${this._options.className ? ` ${this._options.className}` : ""}`;
|
|
797
|
-
|
|
861
|
+
const shouldShow = this._state.visible && this._zoomVisible;
|
|
862
|
+
if (!shouldShow) {
|
|
798
863
|
container.style.display = "none";
|
|
799
864
|
}
|
|
800
865
|
return container;
|
|
@@ -877,6 +942,7 @@ class Legend {
|
|
|
877
942
|
this._container.innerHTML = "";
|
|
878
943
|
const isCollapsedWithHeader = this._state.collapsed && (title || collapsible);
|
|
879
944
|
const vertPadding = isCollapsedWithHeader ? 4 : padding;
|
|
945
|
+
const shouldShow = this._state.visible && this._zoomVisible;
|
|
880
946
|
Object.assign(this._container.style, {
|
|
881
947
|
backgroundColor,
|
|
882
948
|
opacity: opacity.toString(),
|
|
@@ -887,7 +953,7 @@ class Legend {
|
|
|
887
953
|
width: isCollapsedWithHeader ? "auto" : `${width}px`,
|
|
888
954
|
maxWidth: `${width}px`,
|
|
889
955
|
boxShadow: "0 0 0 2px rgba(0, 0, 0, 0.1)",
|
|
890
|
-
display:
|
|
956
|
+
display: shouldShow ? "block" : "none",
|
|
891
957
|
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
|
|
892
958
|
});
|
|
893
959
|
if (title || collapsible) {
|
|
@@ -960,7 +1026,9 @@ const DEFAULT_OPTIONS = {
|
|
|
960
1026
|
maxWidth: 300,
|
|
961
1027
|
maxHeight: 400,
|
|
962
1028
|
fontSize: 12,
|
|
963
|
-
fontColor: "#333"
|
|
1029
|
+
fontColor: "#333",
|
|
1030
|
+
minzoom: 0,
|
|
1031
|
+
maxzoom: 24
|
|
964
1032
|
};
|
|
965
1033
|
class HtmlControl {
|
|
966
1034
|
/**
|
|
@@ -974,6 +1042,9 @@ class HtmlControl {
|
|
|
974
1042
|
__publicField(this, "_options");
|
|
975
1043
|
__publicField(this, "_state");
|
|
976
1044
|
__publicField(this, "_eventHandlers", /* @__PURE__ */ new Map());
|
|
1045
|
+
__publicField(this, "_map");
|
|
1046
|
+
__publicField(this, "_handleZoom");
|
|
1047
|
+
__publicField(this, "_zoomVisible", true);
|
|
977
1048
|
this._options = { ...DEFAULT_OPTIONS, ...options };
|
|
978
1049
|
this._state = {
|
|
979
1050
|
visible: this._options.visible,
|
|
@@ -988,9 +1059,13 @@ class HtmlControl {
|
|
|
988
1059
|
* @param map - The MapLibre GL map instance.
|
|
989
1060
|
* @returns The control's container element.
|
|
990
1061
|
*/
|
|
991
|
-
onAdd(
|
|
1062
|
+
onAdd(map) {
|
|
1063
|
+
this._map = map;
|
|
992
1064
|
this._container = this._createContainer();
|
|
993
1065
|
this._render();
|
|
1066
|
+
this._handleZoom = () => this._checkZoomVisibility();
|
|
1067
|
+
this._map.on("zoom", this._handleZoom);
|
|
1068
|
+
this._checkZoomVisibility();
|
|
994
1069
|
return this._container;
|
|
995
1070
|
}
|
|
996
1071
|
/**
|
|
@@ -999,6 +1074,11 @@ class HtmlControl {
|
|
|
999
1074
|
*/
|
|
1000
1075
|
onRemove() {
|
|
1001
1076
|
var _a, _b;
|
|
1077
|
+
if (this._map && this._handleZoom) {
|
|
1078
|
+
this._map.off("zoom", this._handleZoom);
|
|
1079
|
+
this._handleZoom = void 0;
|
|
1080
|
+
}
|
|
1081
|
+
this._map = void 0;
|
|
1002
1082
|
(_b = (_a = this._container) == null ? void 0 : _a.parentNode) == null ? void 0 : _b.removeChild(this._container);
|
|
1003
1083
|
this._container = void 0;
|
|
1004
1084
|
this._contentEl = void 0;
|
|
@@ -1010,9 +1090,7 @@ class HtmlControl {
|
|
|
1010
1090
|
show() {
|
|
1011
1091
|
if (!this._state.visible) {
|
|
1012
1092
|
this._state.visible = true;
|
|
1013
|
-
|
|
1014
|
-
this._container.style.display = "block";
|
|
1015
|
-
}
|
|
1093
|
+
this._updateDisplayState();
|
|
1016
1094
|
this._emit("show");
|
|
1017
1095
|
}
|
|
1018
1096
|
}
|
|
@@ -1022,9 +1100,7 @@ class HtmlControl {
|
|
|
1022
1100
|
hide() {
|
|
1023
1101
|
if (this._state.visible) {
|
|
1024
1102
|
this._state.visible = false;
|
|
1025
|
-
|
|
1026
|
-
this._container.style.display = "none";
|
|
1027
|
-
}
|
|
1103
|
+
this._updateDisplayState();
|
|
1028
1104
|
this._emit("hide");
|
|
1029
1105
|
}
|
|
1030
1106
|
}
|
|
@@ -1150,6 +1226,27 @@ class HtmlControl {
|
|
|
1150
1226
|
handlers.forEach((handler) => handler(eventData));
|
|
1151
1227
|
}
|
|
1152
1228
|
}
|
|
1229
|
+
/**
|
|
1230
|
+
* Checks if the current zoom level is within the visibility range.
|
|
1231
|
+
*/
|
|
1232
|
+
_checkZoomVisibility() {
|
|
1233
|
+
if (!this._map) return;
|
|
1234
|
+
const zoom = this._map.getZoom();
|
|
1235
|
+
const { minzoom, maxzoom } = this._options;
|
|
1236
|
+
const inRange = zoom >= minzoom && zoom <= maxzoom;
|
|
1237
|
+
if (inRange !== this._zoomVisible) {
|
|
1238
|
+
this._zoomVisible = inRange;
|
|
1239
|
+
this._updateDisplayState();
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
/**
|
|
1243
|
+
* Updates the display state based on visibility and zoom level.
|
|
1244
|
+
*/
|
|
1245
|
+
_updateDisplayState() {
|
|
1246
|
+
if (!this._container) return;
|
|
1247
|
+
const shouldShow = this._state.visible && this._zoomVisible;
|
|
1248
|
+
this._container.style.display = shouldShow ? "block" : "none";
|
|
1249
|
+
}
|
|
1153
1250
|
/**
|
|
1154
1251
|
* Creates the main container element.
|
|
1155
1252
|
*
|
|
@@ -1158,7 +1255,8 @@ class HtmlControl {
|
|
|
1158
1255
|
_createContainer() {
|
|
1159
1256
|
const container = document.createElement("div");
|
|
1160
1257
|
container.className = `maplibregl-ctrl maplibre-gl-html-control${this._options.className ? ` ${this._options.className}` : ""}`;
|
|
1161
|
-
|
|
1258
|
+
const shouldShow = this._state.visible && this._zoomVisible;
|
|
1259
|
+
if (!shouldShow) {
|
|
1162
1260
|
container.style.display = "none";
|
|
1163
1261
|
}
|
|
1164
1262
|
return container;
|
|
@@ -1183,6 +1281,7 @@ class HtmlControl {
|
|
|
1183
1281
|
this._container.innerHTML = "";
|
|
1184
1282
|
const isCollapsedWithHeader = this._state.collapsed && (title || collapsible);
|
|
1185
1283
|
const vertPadding = isCollapsedWithHeader ? 4 : padding;
|
|
1284
|
+
const shouldShow = this._state.visible && this._zoomVisible;
|
|
1186
1285
|
Object.assign(this._container.style, {
|
|
1187
1286
|
backgroundColor,
|
|
1188
1287
|
opacity: String(opacity),
|
|
@@ -1192,7 +1291,7 @@ class HtmlControl {
|
|
|
1192
1291
|
fontSize: `${fontSize}px`,
|
|
1193
1292
|
color: fontColor,
|
|
1194
1293
|
boxShadow: "0 0 0 2px rgba(0, 0, 0, 0.1)",
|
|
1195
|
-
display:
|
|
1294
|
+
display: shouldShow ? "block" : "none",
|
|
1196
1295
|
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
|
|
1197
1296
|
});
|
|
1198
1297
|
if (collapsible || title) {
|
|
@@ -1278,4 +1377,4 @@ export {
|
|
|
1278
1377
|
clamp as y,
|
|
1279
1378
|
formatNumericValue as z
|
|
1280
1379
|
};
|
|
1281
|
-
//# sourceMappingURL=HtmlControl-
|
|
1380
|
+
//# sourceMappingURL=HtmlControl-CxD6T9bG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HtmlControl-CxD6T9bG.js","sources":["../src/lib/colormaps/sequential.ts","../src/lib/colormaps/diverging.ts","../src/lib/colormaps/misc.ts","../src/lib/colormaps/index.ts","../src/lib/utils/helpers.ts","../src/lib/core/Colorbar.ts","../src/lib/core/Legend.ts","../src/lib/core/HtmlControl.ts"],"sourcesContent":["import type { ColorStop } from '../core/types';\n\n/**\n * Viridis colormap - perceptually uniform, colorblind-friendly.\n */\nexport const viridis: ColorStop[] = [\n { position: 0.0, color: '#440154' },\n { position: 0.1, color: '#482878' },\n { position: 0.2, color: '#3e4a89' },\n { position: 0.3, color: '#31688e' },\n { position: 0.4, color: '#26838f' },\n { position: 0.5, color: '#1f9e89' },\n { position: 0.6, color: '#35b779' },\n { position: 0.7, color: '#6ece58' },\n { position: 0.8, color: '#b5de2b' },\n { position: 0.9, color: '#fde725' },\n { position: 1.0, color: '#fde725' },\n];\n\n/**\n * Plasma colormap - perceptually uniform.\n */\nexport const plasma: ColorStop[] = [\n { position: 0.0, color: '#0d0887' },\n { position: 0.1, color: '#41049d' },\n { position: 0.2, color: '#6a00a8' },\n { position: 0.3, color: '#8f0da4' },\n { position: 0.4, color: '#b12a90' },\n { position: 0.5, color: '#cc4778' },\n { position: 0.6, color: '#e16462' },\n { position: 0.7, color: '#f2844b' },\n { position: 0.8, color: '#fca636' },\n { position: 0.9, color: '#fcce25' },\n { position: 1.0, color: '#f0f921' },\n];\n\n/**\n * Inferno colormap - perceptually uniform.\n */\nexport const inferno: ColorStop[] = [\n { position: 0.0, color: '#000004' },\n { position: 0.1, color: '#1b0c41' },\n { position: 0.2, color: '#4a0c6b' },\n { position: 0.3, color: '#781c6d' },\n { position: 0.4, color: '#a52c60' },\n { position: 0.5, color: '#cf4446' },\n { position: 0.6, color: '#ed6925' },\n { position: 0.7, color: '#fb9b06' },\n { position: 0.8, color: '#f7d13d' },\n { position: 0.9, color: '#fcffa4' },\n { position: 1.0, color: '#fcffa4' },\n];\n\n/**\n * Magma colormap - perceptually uniform.\n */\nexport const magma: ColorStop[] = [\n { position: 0.0, color: '#000004' },\n { position: 0.1, color: '#180f3d' },\n { position: 0.2, color: '#440f76' },\n { position: 0.3, color: '#721f81' },\n { position: 0.4, color: '#9e2f7f' },\n { position: 0.5, color: '#cd4071' },\n { position: 0.6, color: '#f1605d' },\n { position: 0.7, color: '#fd9668' },\n { position: 0.8, color: '#fec98d' },\n { position: 0.9, color: '#fcfdbf' },\n { position: 1.0, color: '#fcfdbf' },\n];\n\n/**\n * Cividis colormap - colorblind-friendly.\n */\nexport const cividis: ColorStop[] = [\n { position: 0.0, color: '#00204d' },\n { position: 0.1, color: '#00306f' },\n { position: 0.2, color: '#2a406c' },\n { position: 0.3, color: '#4a5068' },\n { position: 0.4, color: '#636166' },\n { position: 0.5, color: '#7b7362' },\n { position: 0.6, color: '#94865c' },\n { position: 0.7, color: '#af9b51' },\n { position: 0.8, color: '#cab040' },\n { position: 0.9, color: '#e6c628' },\n { position: 1.0, color: '#ffdd00' },\n];\n","import type { ColorStop } from '../core/types';\n\n/**\n * Coolwarm diverging colormap.\n */\nexport const coolwarm: ColorStop[] = [\n { position: 0.0, color: '#3b4cc0' },\n { position: 0.1, color: '#5977e3' },\n { position: 0.2, color: '#7b9ff9' },\n { position: 0.3, color: '#9ebeff' },\n { position: 0.4, color: '#c0d4f5' },\n { position: 0.5, color: '#dddcdc' },\n { position: 0.6, color: '#f2cbb7' },\n { position: 0.7, color: '#f7ac8e' },\n { position: 0.8, color: '#ee8468' },\n { position: 0.9, color: '#d65244' },\n { position: 1.0, color: '#b40426' },\n];\n\n/**\n * Blue-White-Red diverging colormap.\n */\nexport const bwr: ColorStop[] = [\n { position: 0.0, color: '#0000ff' },\n { position: 0.5, color: '#ffffff' },\n { position: 1.0, color: '#ff0000' },\n];\n\n/**\n * Seismic diverging colormap.\n */\nexport const seismic: ColorStop[] = [\n { position: 0.0, color: '#00004d' },\n { position: 0.25, color: '#0000ff' },\n { position: 0.5, color: '#ffffff' },\n { position: 0.75, color: '#ff0000' },\n { position: 1.0, color: '#4d0000' },\n];\n\n/**\n * Red-Blue diverging colormap.\n */\nexport const RdBu: ColorStop[] = [\n { position: 0.0, color: '#67001f' },\n { position: 0.1, color: '#b2182b' },\n { position: 0.2, color: '#d6604d' },\n { position: 0.3, color: '#f4a582' },\n { position: 0.4, color: '#fddbc7' },\n { position: 0.5, color: '#f7f7f7' },\n { position: 0.6, color: '#d1e5f0' },\n { position: 0.7, color: '#92c5de' },\n { position: 0.8, color: '#4393c3' },\n { position: 0.9, color: '#2166ac' },\n { position: 1.0, color: '#053061' },\n];\n\n/**\n * Red-Yellow-Blue diverging colormap.\n */\nexport const RdYlBu: ColorStop[] = [\n { position: 0.0, color: '#a50026' },\n { position: 0.1, color: '#d73027' },\n { position: 0.2, color: '#f46d43' },\n { position: 0.3, color: '#fdae61' },\n { position: 0.4, color: '#fee090' },\n { position: 0.5, color: '#ffffbf' },\n { position: 0.6, color: '#e0f3f8' },\n { position: 0.7, color: '#abd9e9' },\n { position: 0.8, color: '#74add1' },\n { position: 0.9, color: '#4575b4' },\n { position: 1.0, color: '#313695' },\n];\n\n/**\n * Red-Yellow-Green diverging colormap.\n */\nexport const RdYlGn: ColorStop[] = [\n { position: 0.0, color: '#a50026' },\n { position: 0.1, color: '#d73027' },\n { position: 0.2, color: '#f46d43' },\n { position: 0.3, color: '#fdae61' },\n { position: 0.4, color: '#fee08b' },\n { position: 0.5, color: '#ffffbf' },\n { position: 0.6, color: '#d9ef8b' },\n { position: 0.7, color: '#a6d96a' },\n { position: 0.8, color: '#66bd63' },\n { position: 0.9, color: '#1a9850' },\n { position: 1.0, color: '#006837' },\n];\n\n/**\n * Spectral diverging colormap.\n */\nexport const spectral: ColorStop[] = [\n { position: 0.0, color: '#9e0142' },\n { position: 0.1, color: '#d53e4f' },\n { position: 0.2, color: '#f46d43' },\n { position: 0.3, color: '#fdae61' },\n { position: 0.4, color: '#fee08b' },\n { position: 0.5, color: '#ffffbf' },\n { position: 0.6, color: '#e6f598' },\n { position: 0.7, color: '#abdda4' },\n { position: 0.8, color: '#66c2a5' },\n { position: 0.9, color: '#3288bd' },\n { position: 1.0, color: '#5e4fa2' },\n];\n","import type { ColorStop } from '../core/types';\n\n/**\n * Jet colormap (classic rainbow-like).\n */\nexport const jet: ColorStop[] = [\n { position: 0.0, color: '#00007f' },\n { position: 0.125, color: '#0000ff' },\n { position: 0.25, color: '#007fff' },\n { position: 0.375, color: '#00ffff' },\n { position: 0.5, color: '#7fff7f' },\n { position: 0.625, color: '#ffff00' },\n { position: 0.75, color: '#ff7f00' },\n { position: 0.875, color: '#ff0000' },\n { position: 1.0, color: '#7f0000' },\n];\n\n/**\n * Rainbow colormap.\n */\nexport const rainbow: ColorStop[] = [\n { position: 0.0, color: '#ff0000' },\n { position: 0.17, color: '#ff8000' },\n { position: 0.33, color: '#ffff00' },\n { position: 0.5, color: '#00ff00' },\n { position: 0.67, color: '#00ffff' },\n { position: 0.83, color: '#0000ff' },\n { position: 1.0, color: '#8000ff' },\n];\n\n/**\n * Turbo colormap (improved rainbow).\n */\nexport const turbo: ColorStop[] = [\n { position: 0.0, color: '#30123b' },\n { position: 0.1, color: '#4662d7' },\n { position: 0.2, color: '#36aaf9' },\n { position: 0.3, color: '#1ae4b6' },\n { position: 0.4, color: '#72fe5e' },\n { position: 0.5, color: '#c8ef34' },\n { position: 0.6, color: '#faba39' },\n { position: 0.7, color: '#f66b19' },\n { position: 0.8, color: '#ca2a04' },\n { position: 0.9, color: '#7a0403' },\n { position: 1.0, color: '#7a0403' },\n];\n\n/**\n * Terrain colormap.\n */\nexport const terrain: ColorStop[] = [\n { position: 0.0, color: '#333399' },\n { position: 0.15, color: '#0099cc' },\n { position: 0.25, color: '#00cc99' },\n { position: 0.35, color: '#99cc00' },\n { position: 0.5, color: '#ffcc00' },\n { position: 0.65, color: '#cc6600' },\n { position: 0.75, color: '#993300' },\n { position: 0.85, color: '#996633' },\n { position: 1.0, color: '#ffffff' },\n];\n\n/**\n * Ocean colormap.\n */\nexport const ocean: ColorStop[] = [\n { position: 0.0, color: '#007f00' },\n { position: 0.25, color: '#00007f' },\n { position: 0.5, color: '#0000ff' },\n { position: 0.75, color: '#7fffff' },\n { position: 1.0, color: '#ffffff' },\n];\n\n/**\n * Hot colormap (black-red-yellow-white).\n */\nexport const hot: ColorStop[] = [\n { position: 0.0, color: '#000000' },\n { position: 0.33, color: '#ff0000' },\n { position: 0.67, color: '#ffff00' },\n { position: 1.0, color: '#ffffff' },\n];\n\n/**\n * Cool colormap (cyan-magenta).\n */\nexport const cool: ColorStop[] = [\n { position: 0.0, color: '#00ffff' },\n { position: 1.0, color: '#ff00ff' },\n];\n\n/**\n * Gray/Grayscale colormap.\n */\nexport const gray: ColorStop[] = [\n { position: 0.0, color: '#000000' },\n { position: 1.0, color: '#ffffff' },\n];\n\n/**\n * Bone colormap.\n */\nexport const bone: ColorStop[] = [\n { position: 0.0, color: '#000000' },\n { position: 0.375, color: '#545474' },\n { position: 0.75, color: '#a9c8c8' },\n { position: 1.0, color: '#ffffff' },\n];\n","import type { ColorStop, ColormapName } from '../core/types';\nimport { viridis, plasma, inferno, magma, cividis } from './sequential';\nimport { coolwarm, bwr, seismic, RdBu, RdYlBu, RdYlGn, spectral } from './diverging';\nimport { jet, rainbow, turbo, terrain, ocean, hot, cool, gray, bone } from './misc';\n\n/**\n * Map of all built-in colormaps.\n */\nexport const COLORMAPS: Record<ColormapName, ColorStop[]> = {\n // Sequential\n viridis,\n plasma,\n inferno,\n magma,\n cividis,\n // Diverging\n coolwarm,\n bwr,\n seismic,\n RdBu,\n RdYlBu,\n RdYlGn,\n spectral,\n // Miscellaneous\n jet,\n rainbow,\n turbo,\n terrain,\n ocean,\n hot,\n cool,\n gray,\n bone,\n};\n\n/**\n * Gets a colormap by name.\n *\n * @param name - The colormap name.\n * @returns Array of color stops.\n */\nexport function getColormap(name: ColormapName): ColorStop[] {\n return COLORMAPS[name] || COLORMAPS.viridis;\n}\n\n/**\n * Checks if a colormap name is valid.\n *\n * @param name - The name to check.\n * @returns True if the name is a valid colormap.\n */\nexport function isValidColormap(name: string): name is ColormapName {\n return name in COLORMAPS;\n}\n\n/**\n * Gets all available colormap names.\n *\n * @returns Array of colormap names.\n */\nexport function getColormapNames(): ColormapName[] {\n return Object.keys(COLORMAPS) as ColormapName[];\n}\n\n// Re-export individual colormaps\nexport { viridis, plasma, inferno, magma, cividis };\nexport { coolwarm, bwr, seismic, RdBu, RdYlBu, RdYlGn, spectral };\nexport { jet, rainbow, turbo, terrain, ocean, hot, cool, gray, bone };\n","/**\n * Clamps a value between min and max.\n *\n * @param value - The value to clamp.\n * @param min - The minimum value.\n * @param max - The maximum value.\n * @returns The clamped value.\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\n/**\n * Formats a numeric value based on the range.\n *\n * @param value - The value to format.\n * @param range - The total range (max - min).\n * @returns Formatted string.\n */\nexport function formatNumericValue(value: number, range: number): string {\n if (range >= 100) {\n return Math.round(value).toString();\n } else if (range >= 1) {\n return value.toFixed(1);\n } else if (range >= 0.1) {\n return value.toFixed(2);\n } else {\n return value.toFixed(3);\n }\n}\n\n/**\n * Generates a unique ID with optional prefix.\n *\n * @param prefix - Optional prefix for the ID.\n * @returns A unique ID string.\n */\nexport function generateId(prefix = 'mlgl'): string {\n return `${prefix}-${Math.random().toString(36).substring(2, 9)}`;\n}\n\n/**\n * Debounces a function call.\n *\n * @param fn - The function to debounce.\n * @param delay - The delay in milliseconds.\n * @returns A debounced function.\n */\nexport function debounce<T extends (...args: unknown[]) => void>(\n fn: T,\n delay: number\n): (...args: Parameters<T>) => void {\n let timeoutId: ReturnType<typeof setTimeout>;\n return (...args: Parameters<T>) => {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => fn(...args), delay);\n };\n}\n\n/**\n * Throttles a function call.\n *\n * @param fn - The function to throttle.\n * @param limit - The minimum time between calls in milliseconds.\n * @returns A throttled function.\n */\nexport function throttle<T extends (...args: unknown[]) => void>(\n fn: T,\n limit: number\n): (...args: Parameters<T>) => void {\n let inThrottle = false;\n return (...args: Parameters<T>) => {\n if (!inThrottle) {\n fn(...args);\n inThrottle = true;\n setTimeout(() => (inThrottle = false), limit);\n }\n };\n}\n\n/**\n * Joins class names, filtering out falsy values.\n *\n * @param classes - Class names to join.\n * @returns Joined class string.\n */\nexport function classNames(...classes: (string | undefined | null | false)[]): string {\n return classes.filter(Boolean).join(' ');\n}\n","import type { IControl, Map as MapLibreMap } from 'maplibre-gl';\nimport type {\n ColorbarOptions,\n ColorbarState,\n ComponentEvent,\n ComponentEventHandler,\n ColorStop,\n} from './types';\nimport { getColormap, isValidColormap } from '../colormaps';\nimport { formatNumericValue } from '../utils';\n\n/**\n * Default options for the Colorbar control.\n */\nconst DEFAULT_OPTIONS: Required<Omit<ColorbarOptions, 'colorStops'>> & { colorStops: ColorStop[] } = {\n colormap: 'viridis',\n colorStops: [],\n vmin: 0,\n vmax: 1,\n label: '',\n units: '',\n orientation: 'vertical',\n position: 'bottom-right',\n barThickness: 20,\n barLength: 200,\n ticks: { count: 5 },\n className: '',\n visible: true,\n opacity: 1,\n backgroundColor: 'rgba(255, 255, 255, 0.9)',\n fontSize: 11,\n fontColor: '#333',\n borderRadius: 4,\n padding: 8,\n minzoom: 0,\n maxzoom: 24,\n};\n\n/**\n * A continuous gradient colorbar control for MapLibre GL maps.\n *\n * Displays a color gradient legend with customizable colormaps,\n * tick marks, labels, and positioning.\n *\n * @example\n * ```typescript\n * const colorbar = new Colorbar({\n * colormap: 'viridis',\n * vmin: 0,\n * vmax: 100,\n * label: 'Temperature',\n * units: '°C',\n * orientation: 'vertical',\n * });\n * map.addControl(colorbar, 'bottom-right');\n * ```\n */\nexport class Colorbar implements IControl {\n private _container?: HTMLElement;\n private _options: Required<Omit<ColorbarOptions, 'colorStops'>> & { colorStops: ColorStop[] };\n private _state: ColorbarState;\n private _eventHandlers: Map<ComponentEvent, Set<ComponentEventHandler<ColorbarState>>> =\n new Map();\n private _map?: MapLibreMap;\n private _handleZoom?: () => void;\n private _zoomVisible: boolean = true;\n\n /**\n * Creates a new Colorbar instance.\n *\n * @param options - Configuration options for the colorbar.\n */\n constructor(options?: ColorbarOptions) {\n this._options = { ...DEFAULT_OPTIONS, ...options };\n this._state = {\n visible: this._options.visible,\n vmin: this._options.vmin,\n vmax: this._options.vmax,\n colormap: this._options.colormap,\n };\n }\n\n /**\n * Called when the control is added to the map.\n * Implements the IControl interface.\n *\n * @param map - The MapLibre GL map instance.\n * @returns The control's container element.\n */\n onAdd(map: MapLibreMap): HTMLElement {\n this._map = map;\n this._container = this._createContainer();\n this._render();\n\n // Set up zoom listener\n this._handleZoom = () => this._checkZoomVisibility();\n this._map.on('zoom', this._handleZoom);\n\n // Check initial zoom\n this._checkZoomVisibility();\n\n return this._container;\n }\n\n /**\n * Called when the control is removed from the map.\n * Implements the IControl interface.\n */\n onRemove(): void {\n if (this._map && this._handleZoom) {\n this._map.off('zoom', this._handleZoom);\n this._handleZoom = undefined;\n }\n this._map = undefined;\n this._container?.parentNode?.removeChild(this._container);\n this._container = undefined;\n this._eventHandlers.clear();\n }\n\n /**\n * Shows the colorbar.\n */\n show(): void {\n if (!this._state.visible) {\n this._state.visible = true;\n this._updateDisplayState();\n this._emit('show');\n }\n }\n\n /**\n * Hides the colorbar.\n */\n hide(): void {\n if (this._state.visible) {\n this._state.visible = false;\n this._updateDisplayState();\n this._emit('hide');\n }\n }\n\n /**\n * Updates the colorbar options and re-renders.\n *\n * @param options - Partial options to update.\n */\n update(options: Partial<ColorbarOptions>): void {\n this._options = { ...this._options, ...options };\n if (options.vmin !== undefined) this._state.vmin = options.vmin;\n if (options.vmax !== undefined) this._state.vmax = options.vmax;\n if (options.colormap !== undefined) this._state.colormap = options.colormap;\n if (options.visible !== undefined) this._state.visible = options.visible;\n this._render();\n this._emit('update');\n }\n\n /**\n * Gets the current state.\n *\n * @returns The current colorbar state.\n */\n getState(): ColorbarState {\n return { ...this._state };\n }\n\n /**\n * Registers an event handler.\n *\n * @param event - The event type to listen for.\n * @param handler - The callback function.\n */\n on(event: ComponentEvent, handler: ComponentEventHandler<ColorbarState>): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n }\n\n /**\n * Removes an event handler.\n *\n * @param event - The event type.\n * @param handler - The callback function to remove.\n */\n off(event: ComponentEvent, handler: ComponentEventHandler<ColorbarState>): void {\n this._eventHandlers.get(event)?.delete(handler);\n }\n\n /**\n * Gets the resolved color stops for the current colormap.\n *\n * @returns Array of color stops.\n */\n private _getColorStops(): ColorStop[] {\n // Custom color stops take priority\n if (this._options.colorStops && this._options.colorStops.length > 0) {\n return this._options.colorStops;\n }\n\n const colormap = this._options.colormap;\n\n // If colormap is a string array, convert to color stops\n if (Array.isArray(colormap)) {\n return colormap.map((color, i) => ({\n position: i / (colormap.length - 1),\n color,\n }));\n }\n\n // If colormap is a name, get the built-in colormap\n if (typeof colormap === 'string' && isValidColormap(colormap)) {\n return getColormap(colormap);\n }\n\n // Default to viridis\n return getColormap('viridis');\n }\n\n /**\n * Generates the CSS gradient string.\n *\n * @returns CSS linear-gradient string.\n */\n private _generateGradient(): string {\n const stops = this._getColorStops();\n const direction = this._options.orientation === 'horizontal' ? 'to right' : 'to top';\n const colorStops = stops.map((stop) => `${stop.color} ${stop.position * 100}%`).join(', ');\n return `linear-gradient(${direction}, ${colorStops})`;\n }\n\n /**\n * Generates tick values.\n *\n * @returns Array of tick values.\n */\n private _generateTicks(): number[] {\n const { ticks, vmin, vmax } = this._options;\n\n if (ticks.values && ticks.values.length > 0) {\n return ticks.values;\n }\n\n const count = ticks.count || 5;\n const step = (vmax - vmin) / (count - 1);\n return Array.from({ length: count }, (_, i) => vmin + i * step);\n }\n\n /**\n * Formats a tick value for display.\n *\n * @param value - The tick value.\n * @returns Formatted string.\n */\n private _formatTick(value: number): string {\n const { ticks, units } = this._options;\n\n if (ticks.format) {\n return ticks.format(value);\n }\n\n // Auto-format based on range\n const range = this._options.vmax - this._options.vmin;\n const formatted = formatNumericValue(value, range);\n\n return units ? `${formatted}${units}` : formatted;\n }\n\n /**\n * Emits an event to all registered handlers.\n *\n * @param event - The event type to emit.\n */\n private _emit(event: ComponentEvent): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n const eventData = { type: event, state: this.getState() };\n handlers.forEach((handler) => handler(eventData));\n }\n }\n\n /**\n * Checks if the current zoom level is within the visibility range.\n */\n private _checkZoomVisibility(): void {\n if (!this._map) return;\n\n const zoom = this._map.getZoom();\n const { minzoom, maxzoom } = this._options;\n const inRange = zoom >= minzoom && zoom <= maxzoom;\n\n if (inRange !== this._zoomVisible) {\n this._zoomVisible = inRange;\n this._updateDisplayState();\n }\n }\n\n /**\n * Updates the display state based on visibility and zoom level.\n */\n private _updateDisplayState(): void {\n if (!this._container) return;\n const shouldShow = this._state.visible && this._zoomVisible;\n this._container.style.display = shouldShow ? 'flex' : 'none';\n }\n\n /**\n * Creates the main container element.\n *\n * @returns The container element.\n */\n private _createContainer(): HTMLElement {\n const container = document.createElement('div');\n container.className = `maplibregl-ctrl maplibre-gl-colorbar${\n this._options.className ? ` ${this._options.className}` : ''\n }`;\n\n const shouldShow = this._state.visible && this._zoomVisible;\n if (!shouldShow) {\n container.style.display = 'none';\n }\n\n return container;\n }\n\n /**\n * Renders the colorbar content.\n */\n private _render(): void {\n if (!this._container) return;\n\n const {\n orientation,\n barThickness,\n barLength,\n label,\n backgroundColor,\n opacity,\n fontSize,\n fontColor,\n borderRadius,\n padding,\n } = this._options;\n const isVertical = orientation === 'vertical';\n const ticks = this._generateTicks();\n\n // Clear existing content\n this._container.innerHTML = '';\n\n // Apply container styles\n const shouldShow = this._state.visible && this._zoomVisible;\n Object.assign(this._container.style, {\n backgroundColor,\n opacity: opacity.toString(),\n borderRadius: `${borderRadius}px`,\n padding: `${padding}px`,\n fontSize: `${fontSize}px`,\n color: fontColor,\n display: shouldShow ? 'flex' : 'none',\n flexDirection: isVertical ? 'row' : 'column',\n alignItems: 'stretch',\n gap: '6px',\n boxShadow: '0 0 0 2px rgba(0, 0, 0, 0.1)',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n });\n\n // Add label if provided\n if (label) {\n const labelEl = document.createElement('div');\n labelEl.className = 'maplibre-gl-colorbar-label';\n labelEl.textContent = label;\n Object.assign(labelEl.style, {\n fontWeight: '600',\n textAlign: 'center',\n marginBottom: isVertical ? '0' : '4px',\n writingMode: isVertical ? 'vertical-rl' : 'horizontal-tb',\n transform: isVertical ? 'rotate(180deg)' : 'none',\n });\n this._container.appendChild(labelEl);\n }\n\n // Create gradient bar with ticks\n const barWrapper = document.createElement('div');\n barWrapper.className = 'maplibre-gl-colorbar-bar-wrapper';\n Object.assign(barWrapper.style, {\n display: 'flex',\n flexDirection: isVertical ? 'row' : 'column',\n alignItems: 'stretch',\n });\n\n // Gradient bar\n const bar = document.createElement('div');\n bar.className = 'maplibre-gl-colorbar-bar';\n Object.assign(bar.style, {\n background: this._generateGradient(),\n width: isVertical ? `${barThickness}px` : `${barLength}px`,\n height: isVertical ? `${barLength}px` : `${barThickness}px`,\n borderRadius: '2px',\n border: '1px solid rgba(0, 0, 0, 0.2)',\n });\n\n // Ticks container\n const ticksContainer = document.createElement('div');\n ticksContainer.className = 'maplibre-gl-colorbar-ticks';\n Object.assign(ticksContainer.style, {\n display: 'flex',\n flexDirection: isVertical ? 'column-reverse' : 'row',\n justifyContent: 'space-between',\n width: isVertical ? 'auto' : `${barLength}px`,\n height: isVertical ? `${barLength}px` : 'auto',\n marginLeft: isVertical ? '4px' : '0',\n marginTop: isVertical ? '0' : '4px',\n });\n\n ticks.forEach((value) => {\n const tick = document.createElement('span');\n tick.className = 'maplibre-gl-colorbar-tick';\n tick.textContent = this._formatTick(value);\n tick.style.fontSize = `${fontSize - 1}px`;\n ticksContainer.appendChild(tick);\n });\n\n barWrapper.appendChild(bar);\n barWrapper.appendChild(ticksContainer);\n this._container.appendChild(barWrapper);\n }\n}\n","import type { IControl, Map as MapLibreMap } from 'maplibre-gl';\nimport type {\n LegendOptions,\n LegendState,\n LegendItem,\n ComponentEvent,\n ComponentEventHandler,\n} from './types';\n\n/**\n * Default options for the Legend control.\n */\nconst DEFAULT_OPTIONS: Required<LegendOptions> = {\n title: '',\n items: [],\n position: 'bottom-left',\n className: '',\n visible: true,\n collapsible: false,\n collapsed: false,\n width: 200,\n maxHeight: 300,\n opacity: 1,\n backgroundColor: 'rgba(255, 255, 255, 0.9)',\n fontSize: 12,\n fontColor: '#333',\n swatchSize: 16,\n borderRadius: 4,\n padding: 10,\n minzoom: 0,\n maxzoom: 24,\n};\n\n/**\n * A categorical legend control for MapLibre GL maps.\n *\n * Displays discrete legend items with color swatches and labels.\n *\n * @example\n * ```typescript\n * const legend = new Legend({\n * title: 'Land Use',\n * items: [\n * { label: 'Residential', color: '#ff6b6b' },\n * { label: 'Commercial', color: '#4ecdc4' },\n * { label: 'Industrial', color: '#95a5a6' },\n * ],\n * });\n * map.addControl(legend, 'bottom-left');\n * ```\n */\nexport class Legend implements IControl {\n private _container?: HTMLElement;\n private _options: Required<LegendOptions>;\n private _state: LegendState;\n private _eventHandlers: Map<ComponentEvent, Set<ComponentEventHandler<LegendState>>> = new Map();\n private _map?: MapLibreMap;\n private _handleZoom?: () => void;\n private _zoomVisible: boolean = true;\n\n /**\n * Creates a new Legend instance.\n *\n * @param options - Configuration options for the legend.\n */\n constructor(options?: LegendOptions) {\n this._options = { ...DEFAULT_OPTIONS, ...options };\n this._state = {\n visible: this._options.visible,\n collapsed: this._options.collapsed,\n items: [...this._options.items],\n };\n }\n\n /**\n * Called when the control is added to the map.\n *\n * @param map - The MapLibre GL map instance.\n * @returns The control's container element.\n */\n onAdd(map: MapLibreMap): HTMLElement {\n this._map = map;\n this._container = this._createContainer();\n this._render();\n\n // Set up zoom listener\n this._handleZoom = () => this._checkZoomVisibility();\n this._map.on('zoom', this._handleZoom);\n\n // Check initial zoom\n this._checkZoomVisibility();\n\n return this._container;\n }\n\n /**\n * Called when the control is removed from the map.\n */\n onRemove(): void {\n if (this._map && this._handleZoom) {\n this._map.off('zoom', this._handleZoom);\n this._handleZoom = undefined;\n }\n this._map = undefined;\n this._container?.parentNode?.removeChild(this._container);\n this._container = undefined;\n this._eventHandlers.clear();\n }\n\n /**\n * Shows the legend.\n */\n show(): void {\n if (!this._state.visible) {\n this._state.visible = true;\n this._updateDisplayState();\n this._emit('show');\n }\n }\n\n /**\n * Hides the legend.\n */\n hide(): void {\n if (this._state.visible) {\n this._state.visible = false;\n this._updateDisplayState();\n this._emit('hide');\n }\n }\n\n /**\n * Expands the legend (if collapsible).\n */\n expand(): void {\n if (this._state.collapsed) {\n this._state.collapsed = false;\n this._render();\n this._emit('expand');\n }\n }\n\n /**\n * Collapses the legend (if collapsible).\n */\n collapse(): void {\n if (!this._state.collapsed) {\n this._state.collapsed = true;\n this._render();\n this._emit('collapse');\n }\n }\n\n /**\n * Toggles the collapsed state.\n */\n toggle(): void {\n if (this._state.collapsed) {\n this.expand();\n } else {\n this.collapse();\n }\n }\n\n /**\n * Updates the legend items.\n *\n * @param items - New legend items.\n */\n setItems(items: LegendItem[]): void {\n this._state.items = [...items];\n this._options.items = [...items];\n this._render();\n this._emit('update');\n }\n\n /**\n * Adds a legend item.\n *\n * @param item - Legend item to add.\n */\n addItem(item: LegendItem): void {\n this._state.items.push(item);\n this._options.items.push(item);\n this._render();\n this._emit('update');\n }\n\n /**\n * Removes a legend item by label.\n *\n * @param label - Label of the item to remove.\n */\n removeItem(label: string): void {\n this._state.items = this._state.items.filter((item) => item.label !== label);\n this._options.items = [...this._state.items];\n this._render();\n this._emit('update');\n }\n\n /**\n * Updates legend options and re-renders.\n *\n * @param options - Partial options to update.\n */\n update(options: Partial<LegendOptions>): void {\n this._options = { ...this._options, ...options };\n if (options.items) this._state.items = [...options.items];\n if (options.visible !== undefined) this._state.visible = options.visible;\n if (options.collapsed !== undefined) this._state.collapsed = options.collapsed;\n this._render();\n this._emit('update');\n }\n\n /**\n * Gets the current state.\n *\n * @returns The current legend state.\n */\n getState(): LegendState {\n return { ...this._state, items: [...this._state.items] };\n }\n\n /**\n * Registers an event handler.\n *\n * @param event - The event type to listen for.\n * @param handler - The callback function.\n */\n on(event: ComponentEvent, handler: ComponentEventHandler<LegendState>): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n }\n\n /**\n * Removes an event handler.\n *\n * @param event - The event type.\n * @param handler - The callback function to remove.\n */\n off(event: ComponentEvent, handler: ComponentEventHandler<LegendState>): void {\n this._eventHandlers.get(event)?.delete(handler);\n }\n\n /**\n * Emits an event to all registered handlers.\n *\n * @param event - The event type to emit.\n */\n private _emit(event: ComponentEvent): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n const eventData = { type: event, state: this.getState() };\n handlers.forEach((handler) => handler(eventData));\n }\n }\n\n /**\n * Checks if the current zoom level is within the visibility range.\n */\n private _checkZoomVisibility(): void {\n if (!this._map) return;\n\n const zoom = this._map.getZoom();\n const { minzoom, maxzoom } = this._options;\n const inRange = zoom >= minzoom && zoom <= maxzoom;\n\n if (inRange !== this._zoomVisible) {\n this._zoomVisible = inRange;\n this._updateDisplayState();\n }\n }\n\n /**\n * Updates the display state based on visibility and zoom level.\n */\n private _updateDisplayState(): void {\n if (!this._container) return;\n const shouldShow = this._state.visible && this._zoomVisible;\n this._container.style.display = shouldShow ? 'block' : 'none';\n }\n\n /**\n * Creates the main container element.\n *\n * @returns The container element.\n */\n private _createContainer(): HTMLElement {\n const container = document.createElement('div');\n container.className = `maplibregl-ctrl maplibre-gl-legend${\n this._options.className ? ` ${this._options.className}` : ''\n }`;\n\n const shouldShow = this._state.visible && this._zoomVisible;\n if (!shouldShow) {\n container.style.display = 'none';\n }\n\n return container;\n }\n\n /**\n * Creates a color swatch element.\n *\n * @param item - Legend item configuration.\n * @returns The swatch element.\n */\n private _createSwatch(item: LegendItem): HTMLElement {\n const { swatchSize = 16 } = this._options;\n const shape = item.shape || 'square';\n const swatch = document.createElement('span');\n swatch.className = `maplibre-gl-legend-swatch maplibre-gl-legend-swatch-${shape}`;\n\n // Base styles\n const baseStyles: Record<string, string> = {\n flexShrink: '0',\n display: 'inline-block',\n };\n\n if (shape === 'line') {\n // Line shape: horizontal line with rounded ends\n Object.assign(swatch.style, {\n ...baseStyles,\n width: `${swatchSize}px`,\n height: '4px',\n backgroundColor: item.color,\n borderRadius: '2px',\n border: 'none',\n alignSelf: 'center',\n });\n } else if (shape === 'circle') {\n // Circle shape\n Object.assign(swatch.style, {\n ...baseStyles,\n width: `${swatchSize}px`,\n height: `${swatchSize}px`,\n backgroundColor: item.color,\n borderRadius: '50%',\n border: item.strokeColor ? `2px solid ${item.strokeColor}` : '1px solid rgba(0,0,0,0.1)',\n });\n } else {\n // Square shape (default)\n Object.assign(swatch.style, {\n ...baseStyles,\n width: `${swatchSize}px`,\n height: `${swatchSize}px`,\n backgroundColor: item.color,\n borderRadius: '2px',\n border: item.strokeColor ? `2px solid ${item.strokeColor}` : '1px solid rgba(0,0,0,0.1)',\n });\n }\n\n // If icon is provided, use background image\n if (item.icon) {\n Object.assign(swatch.style, {\n backgroundImage: `url(${item.icon})`,\n backgroundSize: 'contain',\n backgroundRepeat: 'no-repeat',\n backgroundPosition: 'center',\n backgroundColor: 'transparent',\n border: 'none',\n width: `${swatchSize}px`,\n height: `${swatchSize}px`,\n });\n }\n\n return swatch;\n }\n\n /**\n * Renders the legend content.\n */\n private _render(): void {\n if (!this._container) return;\n\n const {\n title,\n backgroundColor,\n opacity,\n fontSize,\n fontColor,\n borderRadius,\n padding,\n width,\n maxHeight,\n collapsible,\n } = this._options;\n\n // Clear existing content\n this._container.innerHTML = '';\n\n // Apply container styles\n // When collapsed with header, use minimal vertical padding to match HtmlControl\n const isCollapsedWithHeader = this._state.collapsed && (title || collapsible);\n const vertPadding = isCollapsedWithHeader ? 4 : padding;\n const shouldShow = this._state.visible && this._zoomVisible;\n Object.assign(this._container.style, {\n backgroundColor,\n opacity: opacity.toString(),\n borderRadius: `${borderRadius}px`,\n padding: `${vertPadding}px ${padding}px`,\n fontSize: `${fontSize}px`,\n color: fontColor,\n width: isCollapsedWithHeader ? 'auto' : `${width}px`,\n maxWidth: `${width}px`,\n boxShadow: '0 0 0 2px rgba(0, 0, 0, 0.1)',\n display: shouldShow ? 'block' : 'none',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n });\n\n // Add title/header\n if (title || collapsible) {\n const header = document.createElement('div');\n header.className = 'maplibre-gl-legend-header';\n Object.assign(header.style, {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingBottom: this._state.collapsed ? '0' : '4px',\n cursor: collapsible ? 'pointer' : 'default',\n });\n\n if (title) {\n const titleEl = document.createElement('span');\n titleEl.className = 'maplibre-gl-legend-title';\n titleEl.textContent = title;\n titleEl.style.fontWeight = '600';\n header.appendChild(titleEl);\n }\n\n if (collapsible) {\n const toggleBtn = document.createElement('span');\n toggleBtn.className = 'maplibre-gl-legend-toggle';\n toggleBtn.innerHTML = this._state.collapsed ? '▶' : '▼';\n toggleBtn.style.marginLeft = '8px';\n header.appendChild(toggleBtn);\n header.addEventListener('click', () => this.toggle());\n }\n\n this._container.appendChild(header);\n }\n\n // Content area\n const content = document.createElement('div');\n content.className = 'maplibre-gl-legend-content';\n Object.assign(content.style, {\n maxHeight: `${maxHeight}px`,\n overflowY: 'auto',\n display: this._state.collapsed ? 'none' : 'block',\n });\n\n // Render legend items\n this._state.items.forEach((item) => {\n const row = document.createElement('div');\n row.className = 'maplibre-gl-legend-item';\n Object.assign(row.style, {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n padding: '4px 0',\n });\n\n const swatch = this._createSwatch(item);\n const label = document.createElement('span');\n label.className = 'maplibre-gl-legend-label';\n label.textContent = item.label;\n\n row.appendChild(swatch);\n row.appendChild(label);\n content.appendChild(row);\n });\n\n this._container.appendChild(content);\n }\n}\n","import type { IControl, Map as MapLibreMap } from 'maplibre-gl';\nimport type {\n HtmlControlOptions,\n HtmlControlState,\n ComponentEvent,\n ComponentEventHandler,\n} from './types';\n\n/**\n * Default options for the HtmlControl.\n */\nconst DEFAULT_OPTIONS: Required<Omit<HtmlControlOptions, 'element'>> & { element?: HTMLElement } = {\n html: '',\n element: undefined,\n title: '',\n position: 'top-left',\n className: '',\n visible: true,\n collapsible: false,\n collapsed: false,\n backgroundColor: 'rgba(255, 255, 255, 0.9)',\n padding: 10,\n borderRadius: 4,\n opacity: 1,\n maxWidth: 300,\n maxHeight: 400,\n fontSize: 12,\n fontColor: '#333',\n minzoom: 0,\n maxzoom: 24,\n};\n\n/**\n * A flexible HTML content control for MapLibre GL maps.\n *\n * Allows displaying arbitrary HTML content that can be dynamically updated.\n * Supports collapsible mode with a toggle button.\n *\n * @example\n * ```typescript\n * const htmlControl = new HtmlControl({\n * html: '<div><strong>Stats:</strong> 1,234 features</div>',\n * position: 'top-left',\n * collapsible: true,\n * title: 'Statistics',\n * });\n * map.addControl(htmlControl, 'top-left');\n *\n * // Update content dynamically\n * htmlControl.setHtml('<div><strong>Stats:</strong> 5,678 features</div>');\n * ```\n */\nexport class HtmlControl implements IControl {\n private _container?: HTMLElement;\n private _contentEl?: HTMLElement;\n private _options: Required<Omit<HtmlControlOptions, 'element'>> & { element?: HTMLElement };\n private _state: HtmlControlState;\n private _eventHandlers: Map<ComponentEvent, Set<ComponentEventHandler<HtmlControlState>>> =\n new Map();\n private _map?: MapLibreMap;\n private _handleZoom?: () => void;\n private _zoomVisible: boolean = true;\n\n /**\n * Creates a new HtmlControl instance.\n *\n * @param options - Configuration options for the control.\n */\n constructor(options?: HtmlControlOptions) {\n this._options = { ...DEFAULT_OPTIONS, ...options };\n this._state = {\n visible: this._options.visible,\n collapsed: this._options.collapsed,\n html: this._options.html,\n };\n }\n\n /**\n * Called when the control is added to the map.\n * Implements the IControl interface.\n *\n * @param map - The MapLibre GL map instance.\n * @returns The control's container element.\n */\n onAdd(map: MapLibreMap): HTMLElement {\n this._map = map;\n this._container = this._createContainer();\n this._render();\n\n // Set up zoom listener\n this._handleZoom = () => this._checkZoomVisibility();\n this._map.on('zoom', this._handleZoom);\n\n // Check initial zoom\n this._checkZoomVisibility();\n\n return this._container;\n }\n\n /**\n * Called when the control is removed from the map.\n * Implements the IControl interface.\n */\n onRemove(): void {\n if (this._map && this._handleZoom) {\n this._map.off('zoom', this._handleZoom);\n this._handleZoom = undefined;\n }\n this._map = undefined;\n this._container?.parentNode?.removeChild(this._container);\n this._container = undefined;\n this._contentEl = undefined;\n this._eventHandlers.clear();\n }\n\n /**\n * Shows the control.\n */\n show(): void {\n if (!this._state.visible) {\n this._state.visible = true;\n this._updateDisplayState();\n this._emit('show');\n }\n }\n\n /**\n * Hides the control.\n */\n hide(): void {\n if (this._state.visible) {\n this._state.visible = false;\n this._updateDisplayState();\n this._emit('hide');\n }\n }\n\n /**\n * Expands the control (if collapsible).\n */\n expand(): void {\n if (this._state.collapsed) {\n this._state.collapsed = false;\n this._render();\n this._emit('expand');\n }\n }\n\n /**\n * Collapses the control (if collapsible).\n */\n collapse(): void {\n if (!this._state.collapsed) {\n this._state.collapsed = true;\n this._render();\n this._emit('collapse');\n }\n }\n\n /**\n * Toggles the collapsed state.\n */\n toggle(): void {\n if (this._state.collapsed) {\n this.expand();\n } else {\n this.collapse();\n }\n }\n\n /**\n * Sets the HTML content.\n *\n * @param html - The HTML string to display.\n */\n setHtml(html: string): void {\n this._state.html = html;\n this._options.html = html;\n this._options.element = undefined; // Clear element when setting HTML\n if (this._contentEl) {\n this._contentEl.innerHTML = html;\n }\n this._emit('update');\n }\n\n /**\n * Sets a DOM element as content.\n *\n * @param element - The DOM element to display.\n */\n setElement(element: HTMLElement): void {\n this._options.element = element;\n this._options.html = '';\n this._state.html = '';\n if (this._contentEl) {\n this._contentEl.innerHTML = '';\n this._contentEl.appendChild(element);\n }\n this._emit('update');\n }\n\n /**\n * Gets the content container element.\n *\n * @returns The content container element, or undefined if not yet added to map.\n */\n getElement(): HTMLElement | undefined {\n return this._contentEl;\n }\n\n /**\n * Updates control options and re-renders.\n *\n * @param options - Partial options to update.\n */\n update(options: Partial<HtmlControlOptions>): void {\n this._options = { ...this._options, ...options };\n if (options.html !== undefined) this._state.html = options.html;\n if (options.visible !== undefined) this._state.visible = options.visible;\n if (options.collapsed !== undefined) this._state.collapsed = options.collapsed;\n this._render();\n this._emit('update');\n }\n\n /**\n * Gets the current state.\n *\n * @returns The current control state.\n */\n getState(): HtmlControlState {\n return { ...this._state };\n }\n\n /**\n * Registers an event handler.\n *\n * @param event - The event type to listen for.\n * @param handler - The callback function.\n */\n on(event: ComponentEvent, handler: ComponentEventHandler<HtmlControlState>): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n }\n\n /**\n * Removes an event handler.\n *\n * @param event - The event type.\n * @param handler - The callback function to remove.\n */\n off(event: ComponentEvent, handler: ComponentEventHandler<HtmlControlState>): void {\n this._eventHandlers.get(event)?.delete(handler);\n }\n\n /**\n * Emits an event to all registered handlers.\n *\n * @param event - The event type to emit.\n */\n private _emit(event: ComponentEvent): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n const eventData = { type: event, state: this.getState() };\n handlers.forEach((handler) => handler(eventData));\n }\n }\n\n /**\n * Checks if the current zoom level is within the visibility range.\n */\n private _checkZoomVisibility(): void {\n if (!this._map) return;\n\n const zoom = this._map.getZoom();\n const { minzoom, maxzoom } = this._options;\n const inRange = zoom >= minzoom && zoom <= maxzoom;\n\n if (inRange !== this._zoomVisible) {\n this._zoomVisible = inRange;\n this._updateDisplayState();\n }\n }\n\n /**\n * Updates the display state based on visibility and zoom level.\n */\n private _updateDisplayState(): void {\n if (!this._container) return;\n const shouldShow = this._state.visible && this._zoomVisible;\n this._container.style.display = shouldShow ? 'block' : 'none';\n }\n\n /**\n * Creates the main container element.\n *\n * @returns The container element.\n */\n private _createContainer(): HTMLElement {\n const container = document.createElement('div');\n container.className = `maplibregl-ctrl maplibre-gl-html-control${\n this._options.className ? ` ${this._options.className}` : ''\n }`;\n\n const shouldShow = this._state.visible && this._zoomVisible;\n if (!shouldShow) {\n container.style.display = 'none';\n }\n\n return container;\n }\n\n /**\n * Renders the control content.\n */\n private _render(): void {\n if (!this._container) return;\n\n const {\n title = '',\n collapsible = false,\n backgroundColor = 'rgba(255, 255, 255, 0.9)',\n opacity = 1,\n borderRadius = 4,\n padding = 10,\n maxWidth = 300,\n maxHeight = 400,\n fontSize = 12,\n fontColor = '#333',\n } = this._options;\n\n // Clear existing content\n this._container.innerHTML = '';\n\n // Apply container styles\n // When collapsed with header, use minimal vertical padding\n const isCollapsedWithHeader = this._state.collapsed && (title || collapsible);\n const vertPadding = isCollapsedWithHeader ? 4 : padding;\n const shouldShow = this._state.visible && this._zoomVisible;\n Object.assign(this._container.style, {\n backgroundColor,\n opacity: String(opacity),\n borderRadius: `${borderRadius}px`,\n padding: `${vertPadding}px ${padding}px`,\n maxWidth: `${maxWidth}px`,\n fontSize: `${fontSize}px`,\n color: fontColor,\n boxShadow: '0 0 0 2px rgba(0, 0, 0, 0.1)',\n display: shouldShow ? 'block' : 'none',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n });\n\n // Add header with toggle if collapsible\n if (collapsible || title) {\n const header = document.createElement('div');\n header.className = 'maplibre-gl-html-control-header';\n Object.assign(header.style, {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingBottom: this._state.collapsed ? '0' : '8px',\n cursor: collapsible ? 'pointer' : 'default',\n });\n\n if (title) {\n const titleEl = document.createElement('span');\n titleEl.className = 'maplibre-gl-html-control-title';\n titleEl.textContent = title;\n titleEl.style.fontWeight = '600';\n header.appendChild(titleEl);\n }\n\n if (collapsible) {\n const toggleBtn = document.createElement('span');\n toggleBtn.className = 'maplibre-gl-html-control-toggle';\n toggleBtn.innerHTML = this._state.collapsed ? '▶' : '▼';\n Object.assign(toggleBtn.style, {\n marginLeft: '8px',\n fontSize: '10px',\n userSelect: 'none',\n });\n header.appendChild(toggleBtn);\n header.addEventListener('click', () => this.toggle());\n }\n\n this._container.appendChild(header);\n }\n\n // Create content element\n const content = document.createElement('div');\n content.className = 'maplibre-gl-html-control-content';\n Object.assign(content.style, {\n maxHeight: `${maxHeight}px`,\n overflowY: 'auto',\n display: this._state.collapsed ? 'none' : 'block',\n });\n this._contentEl = content;\n\n // Set content\n if (this._options.element) {\n content.appendChild(this._options.element);\n } else if (this._options.html) {\n content.innerHTML = this._options.html;\n }\n\n this._container.appendChild(content);\n }\n}\n"],"names":["DEFAULT_OPTIONS"],"mappings":"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"}
|