maplibre-gl-components 0.10.0 → 0.11.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.
@@ -7663,6 +7663,88 @@ const DEFAULT_OPTIONS = {
7663
7663
  maxzoom: 24
7664
7664
  };
7665
7665
  const WRENCH_ICON = `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/></svg>`;
7666
+ const COMPASS_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="29" height="29" viewBox="0 0 29 29"><path d="m10.5 14 4-8 4 8z" fill="#333"/><path d="m10.5 16 4 8 4-8z" fill="#ccc"/></svg>`;
7667
+ class NorthControl {
7668
+ constructor() {
7669
+ __publicField(this, "_map");
7670
+ __publicField(this, "_container");
7671
+ __publicField(this, "_icon");
7672
+ __publicField(this, "_rotateHandler");
7673
+ }
7674
+ onAdd(map) {
7675
+ this._map = map;
7676
+ this._container = document.createElement("div");
7677
+ this._container.className = "maplibregl-ctrl maplibregl-ctrl-group";
7678
+ const btn = document.createElement("button");
7679
+ btn.className = "maplibregl-ctrl-compass";
7680
+ btn.type = "button";
7681
+ btn.title = "Reset bearing to north";
7682
+ btn.setAttribute("aria-label", "Reset bearing to north");
7683
+ this._icon = document.createElement("span");
7684
+ this._icon.className = "maplibregl-ctrl-icon";
7685
+ this._icon.setAttribute("aria-hidden", "true");
7686
+ this._icon.style.backgroundImage = `url("data:image/svg+xml,${encodeURIComponent(COMPASS_SVG)}")`;
7687
+ this._icon.style.backgroundSize = "contain";
7688
+ this._icon.style.width = "29px";
7689
+ this._icon.style.height = "29px";
7690
+ this._icon.style.display = "block";
7691
+ btn.appendChild(this._icon);
7692
+ btn.addEventListener("click", () => {
7693
+ var _a;
7694
+ return (_a = this._map) == null ? void 0 : _a.resetNorth();
7695
+ });
7696
+ this._container.appendChild(btn);
7697
+ this._rotateHandler = () => {
7698
+ if (this._icon && this._map) {
7699
+ this._icon.style.transform = `rotate(${-this._map.getBearing()}deg)`;
7700
+ }
7701
+ };
7702
+ this._map.on("rotate", this._rotateHandler);
7703
+ this._rotateHandler();
7704
+ return this._container;
7705
+ }
7706
+ onRemove() {
7707
+ var _a, _b;
7708
+ if (this._map && this._rotateHandler) {
7709
+ this._map.off("rotate", this._rotateHandler);
7710
+ }
7711
+ (_b = (_a = this._container) == null ? void 0 : _a.parentNode) == null ? void 0 : _b.removeChild(this._container);
7712
+ this._map = void 0;
7713
+ this._container = void 0;
7714
+ this._icon = void 0;
7715
+ }
7716
+ }
7717
+ const DEM_SOURCE_ID = "maplibre-gl-components-terrain-dem";
7718
+ const DEM_TILE_URL = "https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png";
7719
+ class DemTerrainControl {
7720
+ constructor() {
7721
+ __publicField(this, "_inner");
7722
+ }
7723
+ _addSource(map) {
7724
+ if (!map.getSource(DEM_SOURCE_ID)) {
7725
+ map.addSource(DEM_SOURCE_ID, {
7726
+ type: "raster-dem",
7727
+ tiles: [DEM_TILE_URL],
7728
+ tileSize: 256,
7729
+ encoding: "terrarium"
7730
+ });
7731
+ }
7732
+ }
7733
+ onAdd(map) {
7734
+ if (map.isStyleLoaded()) {
7735
+ this._addSource(map);
7736
+ } else {
7737
+ map.once("styledata", () => this._addSource(map));
7738
+ }
7739
+ this._inner = new maplibregl.TerrainControl({ source: DEM_SOURCE_ID });
7740
+ return this._inner.onAdd(map);
7741
+ }
7742
+ onRemove() {
7743
+ var _a;
7744
+ (_a = this._inner) == null ? void 0 : _a.onRemove();
7745
+ this._inner = void 0;
7746
+ }
7747
+ }
7666
7748
  class ControlGrid {
7667
7749
  constructor(options) {
7668
7750
  __publicField(this, "_container");
@@ -7674,6 +7756,8 @@ class ControlGrid {
7674
7756
  __publicField(this, "_map");
7675
7757
  __publicField(this, "_handleZoom");
7676
7758
  __publicField(this, "_zoomVisible", true);
7759
+ __publicField(this, "_floatingEntry", null);
7760
+ __publicField(this, "_floatingPanel", null);
7677
7761
  this._options = { ...DEFAULT_OPTIONS, ...options };
7678
7762
  this._state = {
7679
7763
  visible: this._options.visible,
@@ -7682,20 +7766,43 @@ class ControlGrid {
7682
7766
  columns: this._options.columns
7683
7767
  };
7684
7768
  const initial = (options == null ? void 0 : options.controls) ?? this._options.controls ?? [];
7685
- initial.forEach((c) => this._children.push({ control: c, element: null }));
7769
+ initial.forEach(
7770
+ (c) => this._children.push({
7771
+ control: c,
7772
+ element: null,
7773
+ expandable: this._isExpandable(c),
7774
+ collapsedSnapshot: null,
7775
+ expandHandler: null,
7776
+ collapseHandler: null,
7777
+ _placeholder: null
7778
+ })
7779
+ );
7686
7780
  const defaults = (options == null ? void 0 : options.defaultControls) ?? [];
7687
7781
  for (const name of defaults) {
7688
7782
  const ctrl = ControlGrid._createDefaultControl(name);
7689
- if (ctrl) this._children.push({ control: ctrl, element: null });
7783
+ if (ctrl)
7784
+ this._children.push({
7785
+ control: ctrl,
7786
+ element: null,
7787
+ expandable: this._isExpandable(ctrl),
7788
+ collapsedSnapshot: null,
7789
+ expandHandler: null,
7790
+ collapseHandler: null,
7791
+ _placeholder: null
7792
+ });
7690
7793
  }
7691
7794
  this._autoGrowRows();
7692
7795
  }
7693
7796
  static _createDefaultControl(name) {
7694
7797
  switch (name) {
7798
+ case "fullscreen":
7799
+ return new maplibregl.FullscreenControl();
7695
7800
  case "globe":
7696
7801
  return new maplibregl.GlobeControl();
7802
+ case "north":
7803
+ return new NorthControl();
7697
7804
  case "terrain":
7698
- return new TerrainControl({ hillshade: true });
7805
+ return new DemTerrainControl();
7699
7806
  case "search":
7700
7807
  return new SearchControl({ collapsed: true });
7701
7808
  case "viewState":
@@ -7743,11 +7850,25 @@ class ControlGrid {
7743
7850
  */
7744
7851
  addControl(control) {
7745
7852
  if (this._children.some((e) => e.control === control)) return;
7746
- const entry = { control, element: null };
7853
+ const entry = {
7854
+ control,
7855
+ element: null,
7856
+ expandable: this._isExpandable(control),
7857
+ collapsedSnapshot: null,
7858
+ expandHandler: null,
7859
+ collapseHandler: null,
7860
+ _placeholder: null
7861
+ };
7747
7862
  this._children.push(entry);
7748
7863
  this._autoGrowRows();
7749
7864
  if (this._map && this._gridEl) {
7750
7865
  entry.element = control.onAdd(this._map);
7866
+ if (entry.expandable) {
7867
+ entry.collapsedSnapshot = entry.element.cloneNode(
7868
+ true
7869
+ );
7870
+ this._attachExpandListeners(entry);
7871
+ }
7751
7872
  this._gridEl.appendChild(entry.element);
7752
7873
  }
7753
7874
  this._emit("controladd", control);
@@ -7756,11 +7877,18 @@ class ControlGrid {
7756
7877
  * Remove a control from the grid. The control's onRemove is called.
7757
7878
  */
7758
7879
  removeControl(control) {
7759
- var _a;
7880
+ var _a, _b;
7760
7881
  const index = this._children.findIndex((e) => e.control === control);
7761
7882
  if (index === -1) return;
7762
7883
  const entry = this._children[index];
7763
- if ((_a = entry.element) == null ? void 0 : _a.parentNode) {
7884
+ if (this._floatingEntry === entry) {
7885
+ this._clearFloating();
7886
+ }
7887
+ this._detachExpandListeners(entry);
7888
+ if ((_a = entry._placeholder) == null ? void 0 : _a.parentNode) {
7889
+ entry._placeholder.parentNode.removeChild(entry._placeholder);
7890
+ }
7891
+ if ((_b = entry.element) == null ? void 0 : _b.parentNode) {
7764
7892
  entry.element.parentNode.removeChild(entry.element);
7765
7893
  }
7766
7894
  if (this._map) control.onRemove(this._map);
@@ -7906,30 +8034,153 @@ class ControlGrid {
7906
8034
  _mountChildren() {
7907
8035
  if (!this._map || !this._gridEl) return;
7908
8036
  this._children.forEach((entry) => {
7909
- if (entry.element) {
8037
+ if (!entry.element) {
8038
+ entry.element = entry.control.onAdd(this._map);
8039
+ if (entry.expandable && !entry.collapsedSnapshot) {
8040
+ entry.collapsedSnapshot = entry.element.cloneNode(
8041
+ true
8042
+ );
8043
+ }
8044
+ this._attachExpandListeners(entry);
8045
+ }
8046
+ if (this._floatingEntry === entry) {
8047
+ this._mountAsFloating(entry);
8048
+ } else {
7910
8049
  if (entry.element.parentNode !== this._gridEl) {
7911
8050
  this._gridEl.appendChild(entry.element);
7912
8051
  }
7913
- } else {
7914
- entry.element = entry.control.onAdd(this._map);
7915
- this._gridEl.appendChild(entry.element);
7916
8052
  }
7917
8053
  });
7918
8054
  }
7919
8055
  _unmountChildren() {
8056
+ this._clearFloating();
7920
8057
  const map = this._map;
7921
8058
  this._children.forEach((entry) => {
7922
- var _a;
7923
- if ((_a = entry.element) == null ? void 0 : _a.parentNode) {
8059
+ var _a, _b;
8060
+ this._detachExpandListeners(entry);
8061
+ if ((_a = entry._placeholder) == null ? void 0 : _a.parentNode) {
8062
+ entry._placeholder.parentNode.removeChild(entry._placeholder);
8063
+ }
8064
+ entry._placeholder = null;
8065
+ if ((_b = entry.element) == null ? void 0 : _b.parentNode) {
7924
8066
  entry.element.parentNode.removeChild(entry.element);
7925
8067
  }
7926
8068
  if (map) entry.control.onRemove(map);
7927
8069
  });
7928
8070
  this._children = this._children.map((e) => ({
7929
8071
  control: e.control,
7930
- element: null
8072
+ element: null,
8073
+ expandable: e.expandable,
8074
+ collapsedSnapshot: null,
8075
+ expandHandler: null,
8076
+ collapseHandler: null,
8077
+ _placeholder: null
7931
8078
  }));
7932
8079
  }
8080
+ _isExpandable(control) {
8081
+ return typeof control.on === "function";
8082
+ }
8083
+ _attachExpandListeners(entry) {
8084
+ if (!entry.expandable) return;
8085
+ const ctrl = entry.control;
8086
+ entry.expandHandler = () => this._onChildExpand(entry);
8087
+ entry.collapseHandler = () => this._onChildCollapse(entry);
8088
+ ctrl.on("expand", entry.expandHandler);
8089
+ ctrl.on("collapse", entry.collapseHandler);
8090
+ }
8091
+ _detachExpandListeners(entry) {
8092
+ if (!entry.expandable) return;
8093
+ const ctrl = entry.control;
8094
+ if (entry.expandHandler) ctrl.off("expand", entry.expandHandler);
8095
+ if (entry.collapseHandler) ctrl.off("collapse", entry.collapseHandler);
8096
+ entry.expandHandler = null;
8097
+ entry.collapseHandler = null;
8098
+ }
8099
+ _onChildExpand(entry) {
8100
+ if (this._floatingEntry && this._floatingEntry !== entry) {
8101
+ this._collapseFloatingChild();
8102
+ }
8103
+ if (!entry.element || !this._gridEl) return;
8104
+ const placeholder = entry.collapsedSnapshot ? entry.collapsedSnapshot.cloneNode(true) : document.createElement("div");
8105
+ placeholder.classList.add("maplibre-gl-control-grid-placeholder--active");
8106
+ placeholder.addEventListener("click", () => {
8107
+ entry.control.collapse();
8108
+ if (this._floatingEntry === entry) {
8109
+ this._onChildCollapse(entry);
8110
+ }
8111
+ });
8112
+ entry._placeholder = placeholder;
8113
+ this._gridEl.replaceChild(placeholder, entry.element);
8114
+ const panel = this._ensureFloatingPanel();
8115
+ panel.appendChild(entry.element);
8116
+ this._floatingEntry = entry;
8117
+ }
8118
+ _onChildCollapse(entry) {
8119
+ if (this._floatingEntry !== entry) return;
8120
+ if (entry._placeholder && entry.element && this._gridEl) {
8121
+ if (entry._placeholder.parentNode === this._gridEl) {
8122
+ this._gridEl.replaceChild(entry.element, entry._placeholder);
8123
+ } else {
8124
+ this._gridEl.appendChild(entry.element);
8125
+ }
8126
+ }
8127
+ entry._placeholder = null;
8128
+ if (entry.element) {
8129
+ entry.collapsedSnapshot = entry.element.cloneNode(true);
8130
+ }
8131
+ if (this._floatingPanel) {
8132
+ this._floatingPanel.style.display = "none";
8133
+ }
8134
+ this._floatingEntry = null;
8135
+ }
8136
+ _mountAsFloating(entry) {
8137
+ if (!this._gridEl || !entry.element) return;
8138
+ const placeholder = entry.collapsedSnapshot ? entry.collapsedSnapshot.cloneNode(true) : document.createElement("div");
8139
+ placeholder.classList.add("maplibre-gl-control-grid-placeholder--active");
8140
+ placeholder.addEventListener("click", () => {
8141
+ entry.control.collapse();
8142
+ if (this._floatingEntry === entry) {
8143
+ this._onChildCollapse(entry);
8144
+ }
8145
+ });
8146
+ entry._placeholder = placeholder;
8147
+ this._gridEl.appendChild(placeholder);
8148
+ const panel = this._ensureFloatingPanel();
8149
+ panel.appendChild(entry.element);
8150
+ }
8151
+ _ensureFloatingPanel() {
8152
+ if (!this._floatingPanel) {
8153
+ this._floatingPanel = document.createElement("div");
8154
+ this._floatingPanel.className = "maplibre-gl-control-grid-floating-panel";
8155
+ }
8156
+ if (this._container && this._floatingPanel.parentNode !== this._container) {
8157
+ this._container.appendChild(this._floatingPanel);
8158
+ }
8159
+ const isCollapsedWithHeader = this._state.collapsed && (this._options.title || this._options.collapsible);
8160
+ const expandedOffset = Math.max(0, this._options.padding - 1);
8161
+ const expandedContainerPad = Math.max(0, this._options.padding - 10);
8162
+ const rightPad = isCollapsedWithHeader ? expandedOffset - expandedContainerPad : expandedOffset;
8163
+ this._floatingPanel.style.right = `-${rightPad}px`;
8164
+ this._floatingPanel.style.display = "block";
8165
+ return this._floatingPanel;
8166
+ }
8167
+ _clearFloating() {
8168
+ if (this._floatingEntry) {
8169
+ this._floatingEntry._placeholder = null;
8170
+ }
8171
+ this._floatingEntry = null;
8172
+ if (this._floatingPanel) {
8173
+ this._floatingPanel.remove();
8174
+ this._floatingPanel = null;
8175
+ }
8176
+ }
8177
+ _collapseFloatingChild() {
8178
+ if (!this._floatingEntry) return;
8179
+ const ctrl = this._floatingEntry.control;
8180
+ if (typeof ctrl.collapse === "function") {
8181
+ ctrl.collapse();
8182
+ }
8183
+ }
7933
8184
  _render() {
7934
8185
  if (!this._container) return;
7935
8186
  const {
@@ -8158,4 +8409,4 @@ exports.terrain = terrain;
8158
8409
  exports.throttle = throttle;
8159
8410
  exports.turbo = turbo;
8160
8411
  exports.viridis = viridis;
8161
- //# sourceMappingURL=ControlGrid-EJTb0ceR.cjs.map
8412
+ //# sourceMappingURL=ControlGrid-CT_rvuo_.cjs.map