@expressivecss/expressive 0.13.1 → 0.14.1

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.
Files changed (158) hide show
  1. package/CHANGELOG.md +109 -1
  2. package/README.md +2 -1
  3. package/dist/css/expressive.css +234 -72
  4. package/dist/css/expressive.css.map +1 -1
  5. package/dist/css/expressive.min.css +1 -1
  6. package/dist/css/expressive.min.css.map +1 -1
  7. package/dist/js/chunks/{chunk-55IA2XUC.mjs → chunk-3GVFZ4XO.mjs} +3 -3
  8. package/dist/js/chunks/{chunk-3CLXLPYS.mjs → chunk-4HZMB7LI.mjs} +22 -8
  9. package/dist/js/chunks/chunk-4HZMB7LI.mjs.map +7 -0
  10. package/dist/js/chunks/{chunk-DTKR54I6.mjs → chunk-4KMNFIFZ.mjs} +2 -2
  11. package/dist/js/chunks/{chunk-K4CJCRGE.mjs → chunk-4TKTLGEM.mjs} +2 -2
  12. package/dist/js/chunks/{chunk-3VOK6J7U.mjs → chunk-5BKHWHYY.mjs} +13 -6
  13. package/dist/js/chunks/chunk-5BKHWHYY.mjs.map +7 -0
  14. package/dist/js/chunks/{chunk-PLYXLSH3.mjs → chunk-5HQSGDZ5.mjs} +18 -9
  15. package/dist/js/chunks/chunk-5HQSGDZ5.mjs.map +7 -0
  16. package/dist/js/chunks/{chunk-LWBQIX5J.mjs → chunk-A7ALMYUR.mjs} +41 -44
  17. package/dist/js/chunks/chunk-A7ALMYUR.mjs.map +7 -0
  18. package/dist/js/chunks/chunk-BG6ZRB5H.mjs +154 -0
  19. package/dist/js/chunks/chunk-BG6ZRB5H.mjs.map +7 -0
  20. package/dist/js/chunks/{chunk-DLWYKFEI.mjs → chunk-CUQPB25U.mjs} +3 -3
  21. package/dist/js/chunks/{chunk-6WLSDZ4O.mjs → chunk-DAIU5SLG.mjs} +2 -2
  22. package/dist/js/chunks/{chunk-VTLBW7QS.mjs → chunk-FS7XY3HT.mjs} +2 -2
  23. package/dist/js/chunks/{chunk-WJXDBPXQ.mjs → chunk-GIW4K4SE.mjs} +8 -12
  24. package/dist/js/chunks/chunk-GIW4K4SE.mjs.map +7 -0
  25. package/dist/js/chunks/{chunk-LNCCYGPC.mjs → chunk-GUB3TNO2.mjs} +6 -5
  26. package/dist/js/chunks/chunk-GUB3TNO2.mjs.map +7 -0
  27. package/dist/js/chunks/{chunk-XH6BEEMY.mjs → chunk-GZKEFWPM.mjs} +39 -31
  28. package/dist/js/chunks/chunk-GZKEFWPM.mjs.map +7 -0
  29. package/dist/js/chunks/{chunk-QKWPQK5N.mjs → chunk-ILP3PDTL.mjs} +11 -3
  30. package/dist/js/chunks/chunk-ILP3PDTL.mjs.map +7 -0
  31. package/dist/js/chunks/{chunk-U2OTHOTI.mjs → chunk-JIDMQGK6.mjs} +3 -2
  32. package/dist/js/chunks/{chunk-U2OTHOTI.mjs.map → chunk-JIDMQGK6.mjs.map} +2 -2
  33. package/dist/js/chunks/chunk-KBNN3QDH.mjs +7 -0
  34. package/dist/js/chunks/{chunk-4PWAPV6F.mjs.map → chunk-KBNN3QDH.mjs.map} +1 -1
  35. package/dist/js/chunks/{chunk-NNYP33NB.mjs → chunk-KHV6DZXX.mjs} +5 -4
  36. package/dist/js/chunks/chunk-KHV6DZXX.mjs.map +7 -0
  37. package/dist/js/chunks/{chunk-XGHORT7J.mjs → chunk-KY6U46SM.mjs} +3 -3
  38. package/dist/js/chunks/{chunk-CKQP6P76.mjs → chunk-LRZMJZ3T.mjs} +4 -3
  39. package/dist/js/chunks/chunk-LRZMJZ3T.mjs.map +7 -0
  40. package/dist/js/chunks/{chunk-6OMRGML6.mjs → chunk-MNPROCZF.mjs} +4 -4
  41. package/dist/js/chunks/{chunk-6OMRGML6.mjs.map → chunk-MNPROCZF.mjs.map} +2 -2
  42. package/dist/js/chunks/{chunk-QV2JAWIZ.mjs → chunk-MZ6Z24BX.mjs} +3 -2
  43. package/dist/js/chunks/{chunk-QV2JAWIZ.mjs.map → chunk-MZ6Z24BX.mjs.map} +2 -2
  44. package/dist/js/chunks/{chunk-CCWDV5CR.mjs → chunk-NS2UMNZV.mjs} +2 -2
  45. package/dist/js/chunks/{chunk-UBLRRJ7N.mjs → chunk-PM655FXL.mjs} +2 -2
  46. package/dist/js/chunks/{chunk-IFXVDDDH.mjs → chunk-QERLECVU.mjs} +3 -3
  47. package/dist/js/chunks/{chunk-GZWPXXY6.mjs → chunk-QJABDLSD.mjs} +5 -2
  48. package/dist/js/chunks/chunk-QJABDLSD.mjs.map +7 -0
  49. package/dist/js/chunks/{chunk-UNEMYWEW.mjs → chunk-S3XDFGSZ.mjs} +2 -2
  50. package/dist/js/chunks/chunk-TBM3FT7G.mjs +398 -0
  51. package/dist/js/chunks/chunk-TBM3FT7G.mjs.map +7 -0
  52. package/dist/js/chunks/chunk-UEXCIMJZ.mjs +214 -0
  53. package/dist/js/chunks/chunk-UEXCIMJZ.mjs.map +7 -0
  54. package/dist/js/chunks/{chunk-P3G3QHII.mjs → chunk-VGZSAFTX.mjs} +11 -4
  55. package/dist/js/chunks/{chunk-P3G3QHII.mjs.map → chunk-VGZSAFTX.mjs.map} +2 -2
  56. package/dist/js/chunks/{chunk-UAEAQBRC.mjs → chunk-X7OCHZVF.mjs} +2 -2
  57. package/dist/js/chunks/{chunk-EC63CHXU.mjs → chunk-YMSXJON6.mjs} +7 -6
  58. package/dist/js/chunks/chunk-YMSXJON6.mjs.map +7 -0
  59. package/dist/js/chunks/{chunk-QVVEWBOF.mjs → chunk-Z2NRKI7R.mjs} +2 -2
  60. package/dist/js/chunks/{chunk-PIJ2TAR3.mjs → chunk-ZAS25YFD.mjs} +2 -2
  61. package/dist/js/chunks/chunk-ZKZKNSLC.mjs +1 -0
  62. package/dist/js/expressive.cjs +905 -117
  63. package/dist/js/expressive.cjs.map +4 -4
  64. package/dist/js/expressive.js +905 -117
  65. package/dist/js/expressive.js.map +4 -4
  66. package/dist/js/expressive.min.js +10 -10
  67. package/dist/js/expressive.min.js.map +4 -4
  68. package/dist/js/expressive.mjs +57 -45
  69. package/dist/js/expressive.mjs.map +1 -1
  70. package/dist/js/internal/behaviors/bottomSheets.mjs +3 -3
  71. package/dist/js/internal/behaviors/dialogs.mjs +2 -2
  72. package/dist/js/internal/behaviors/forms.mjs +2 -2
  73. package/dist/js/internal/behaviors/sheetDrag.mjs +2 -2
  74. package/dist/js/internal/behaviors/sideSheets.mjs +3 -3
  75. package/dist/js/internal/components/autocomplete.mjs +3 -3
  76. package/dist/js/internal/components/buttons.mjs +2 -2
  77. package/dist/js/internal/components/cards.mjs +2 -2
  78. package/dist/js/internal/components/carousel.mjs +2 -2
  79. package/dist/js/internal/components/chips.mjs +4 -4
  80. package/dist/js/internal/components/commandPalette.mjs +2 -2
  81. package/dist/js/internal/components/confetti.mjs +8 -0
  82. package/dist/js/internal/components/confetti.mjs.map +7 -0
  83. package/dist/js/internal/components/datepicker.mjs +5 -5
  84. package/dist/js/internal/components/expandingCard.mjs +2 -2
  85. package/dist/js/internal/components/heatmapChart.mjs +1 -1
  86. package/dist/js/internal/components/index.mjs +50 -38
  87. package/dist/js/internal/components/lightbox.mjs +2 -2
  88. package/dist/js/internal/components/mapView.mjs +9 -0
  89. package/dist/js/internal/components/mapView.mjs.map +7 -0
  90. package/dist/js/internal/components/menu.mjs +2 -2
  91. package/dist/js/internal/components/messageScroller.mjs +2 -2
  92. package/dist/js/internal/components/particles.mjs +8 -0
  93. package/dist/js/internal/components/particles.mjs.map +7 -0
  94. package/dist/js/internal/components/pieChart.mjs +1 -1
  95. package/dist/js/internal/components/questionnaire.mjs +2 -2
  96. package/dist/js/internal/components/registry.mjs +31 -28
  97. package/dist/js/internal/components/richTextEditor.mjs +2 -2
  98. package/dist/js/internal/components/scrollspy.mjs +1 -1
  99. package/dist/js/internal/components/select.mjs +3 -3
  100. package/dist/js/internal/components/slider.mjs +2 -2
  101. package/dist/js/internal/components/snackbar.mjs +2 -2
  102. package/dist/js/internal/components/tabs.mjs +3 -3
  103. package/dist/js/internal/components/timepicker.mjs +3 -3
  104. package/dist/js/internal/components/tooltip.mjs +2 -2
  105. package/dist/js/internal/core/utils.mjs +1 -1
  106. package/dist/js/internal/plugins/dockedDisplayPlugin.mjs +2 -2
  107. package/dist/js/modular.mjs +57 -45
  108. package/dist/types/behaviors/forms.d.ts +5 -0
  109. package/dist/types/components/carousel.d.ts +2 -0
  110. package/dist/types/components/confetti.d.ts +103 -0
  111. package/dist/types/components/datepicker.d.ts +2 -0
  112. package/dist/types/components/index.d.ts +3 -0
  113. package/dist/types/components/mapView.d.ts +151 -0
  114. package/dist/types/components/particles.d.ts +72 -0
  115. package/dist/types/components/pieChart.d.ts +3 -0
  116. package/dist/types/components/registry.d.ts +8 -0
  117. package/dist/types/components/slider.d.ts +1 -1
  118. package/dist/types/components/snackbar.d.ts +2 -0
  119. package/dist/types/components/tabs.d.ts +1 -1
  120. package/dist/types/modular.d.ts +1 -1
  121. package/dist/types/plugins/dockedDisplayPlugin.d.ts +3 -3
  122. package/package.json +2 -1
  123. package/src/sass/components/_buttons.scss +1 -1
  124. package/src/sass/components/_confetti.scss +14 -0
  125. package/src/sass/components/_index.scss +3 -0
  126. package/src/sass/components/_map.scss +188 -0
  127. package/src/sass/components/_particles.scss +14 -0
  128. package/src/sass/components/_table_of_contents.scss +3 -1
  129. package/src/sass/components/forms/_checkboxes.scss +7 -2
  130. package/dist/js/chunks/chunk-3CLXLPYS.mjs.map +0 -7
  131. package/dist/js/chunks/chunk-3VOK6J7U.mjs.map +0 -7
  132. package/dist/js/chunks/chunk-4PWAPV6F.mjs +0 -7
  133. package/dist/js/chunks/chunk-CKQP6P76.mjs.map +0 -7
  134. package/dist/js/chunks/chunk-EC63CHXU.mjs.map +0 -7
  135. package/dist/js/chunks/chunk-GZWPXXY6.mjs.map +0 -7
  136. package/dist/js/chunks/chunk-LNCCYGPC.mjs.map +0 -7
  137. package/dist/js/chunks/chunk-LWBQIX5J.mjs.map +0 -7
  138. package/dist/js/chunks/chunk-NNYP33NB.mjs.map +0 -7
  139. package/dist/js/chunks/chunk-NQLC3YMW.mjs +0 -1
  140. package/dist/js/chunks/chunk-PLYXLSH3.mjs.map +0 -7
  141. package/dist/js/chunks/chunk-QKWPQK5N.mjs.map +0 -7
  142. package/dist/js/chunks/chunk-WJXDBPXQ.mjs.map +0 -7
  143. package/dist/js/chunks/chunk-XH6BEEMY.mjs.map +0 -7
  144. /package/dist/js/chunks/{chunk-55IA2XUC.mjs.map → chunk-3GVFZ4XO.mjs.map} +0 -0
  145. /package/dist/js/chunks/{chunk-DTKR54I6.mjs.map → chunk-4KMNFIFZ.mjs.map} +0 -0
  146. /package/dist/js/chunks/{chunk-K4CJCRGE.mjs.map → chunk-4TKTLGEM.mjs.map} +0 -0
  147. /package/dist/js/chunks/{chunk-DLWYKFEI.mjs.map → chunk-CUQPB25U.mjs.map} +0 -0
  148. /package/dist/js/chunks/{chunk-6WLSDZ4O.mjs.map → chunk-DAIU5SLG.mjs.map} +0 -0
  149. /package/dist/js/chunks/{chunk-VTLBW7QS.mjs.map → chunk-FS7XY3HT.mjs.map} +0 -0
  150. /package/dist/js/chunks/{chunk-XGHORT7J.mjs.map → chunk-KY6U46SM.mjs.map} +0 -0
  151. /package/dist/js/chunks/{chunk-CCWDV5CR.mjs.map → chunk-NS2UMNZV.mjs.map} +0 -0
  152. /package/dist/js/chunks/{chunk-UBLRRJ7N.mjs.map → chunk-PM655FXL.mjs.map} +0 -0
  153. /package/dist/js/chunks/{chunk-IFXVDDDH.mjs.map → chunk-QERLECVU.mjs.map} +0 -0
  154. /package/dist/js/chunks/{chunk-UNEMYWEW.mjs.map → chunk-S3XDFGSZ.mjs.map} +0 -0
  155. /package/dist/js/chunks/{chunk-UAEAQBRC.mjs.map → chunk-X7OCHZVF.mjs.map} +0 -0
  156. /package/dist/js/chunks/{chunk-QVVEWBOF.mjs.map → chunk-Z2NRKI7R.mjs.map} +0 -0
  157. /package/dist/js/chunks/{chunk-PIJ2TAR3.mjs.map → chunk-ZAS25YFD.mjs.map} +0 -0
  158. /package/dist/js/chunks/{chunk-NQLC3YMW.mjs.map → chunk-ZKZKNSLC.mjs.map} +0 -0
@@ -0,0 +1,398 @@
1
+ import {
2
+ Utils
3
+ } from "./chunk-MNPROCZF.mjs";
4
+ import {
5
+ Component
6
+ } from "./chunk-LTWPGFBR.mjs";
7
+
8
+ // src/ts/components/mapView.ts
9
+ var OPENFREEMAP = "https://tiles.openfreemap.org/styles/";
10
+ var _defaults = {
11
+ maplibregl: null,
12
+ style: { light: `${OPENFREEMAP}positron`, dark: `${OPENFREEMAP}dark` },
13
+ center: [0, 20],
14
+ zoom: 1,
15
+ mapOptions: {}
16
+ };
17
+ var lngLat = (el) => el.dataset.lngLat.split(",").map(Number);
18
+ function arc([x0, y0], [x2, y2], steps = 32) {
19
+ const bow = x2 >= x0 ? 0.25 : -0.25;
20
+ const x1 = (x0 + x2) / 2 - (y2 - y0) * bow;
21
+ const y1 = (y0 + y2) / 2 + (x2 - x0) * bow;
22
+ return Array.from({ length: steps + 1 }, (_, i) => {
23
+ const t = i / steps, u = 1 - t;
24
+ return [u * u * x0 + 2 * u * t * x1 + t * t * x2, u * u * y0 + 2 * u * t * y1 + t * t * y2];
25
+ });
26
+ }
27
+ var MapView = class _MapView extends Component {
28
+ constructor(el, options) {
29
+ super(el, options, _MapView);
30
+ /** The MapLibre map. */
31
+ this.map = null;
32
+ /** The MapLibre markers made from `.map-marker` children, in order. */
33
+ this.markers = [];
34
+ this._children = [];
35
+ this._popups = [];
36
+ this._markerPopups = /* @__PURE__ */ new Map();
37
+ this._overlays = /* @__PURE__ */ new Map();
38
+ this._styleReady = false;
39
+ this._dark = false;
40
+ this._location = null;
41
+ this._media = null;
42
+ this._observer = null;
43
+ // Looked up once: `move` fires every frame of a pan or zoom.
44
+ this._zoomIn = [];
45
+ this._zoomOut = [];
46
+ this._handleStyleLoad = () => {
47
+ this._styleReady = true;
48
+ for (const overlay of this._overlays.values()) overlay.draw();
49
+ };
50
+ this._handleScheme = () => {
51
+ const dark = this._isDark();
52
+ if (dark === this._dark) return;
53
+ this._dark = dark;
54
+ this._styleReady = false;
55
+ this.map.setStyle(this._style(), { diff: false });
56
+ };
57
+ this._sync = () => {
58
+ const zoom = this.map.getZoom();
59
+ for (const button of this._zoomIn) button.disabled = zoom >= this.map.getMaxZoom();
60
+ for (const button of this._zoomOut) button.disabled = zoom <= this.map.getMinZoom();
61
+ this.el.style.setProperty("--md-comp-map-bearing", `${-this.map.getBearing()}deg`);
62
+ };
63
+ this._handleFullscreen = () => {
64
+ for (const button of this._buttons("fullscreen")) {
65
+ button.setAttribute("aria-pressed", String(document.fullscreenElement === this.el));
66
+ }
67
+ };
68
+ this._handleClick = (e) => {
69
+ const target = e.target;
70
+ const button = target.closest(".map-controls [data-action]");
71
+ const action = button?.dataset.action;
72
+ if (action === "zoom-in") this.map.zoomIn();
73
+ else if (action === "zoom-out") this.map.zoomOut();
74
+ else if (action === "compass") this.map.resetNorthPitch();
75
+ else if (action === "locate") this._locate(button);
76
+ else if (action === "fullscreen") {
77
+ if (document.fullscreenElement === this.el) document.exitFullscreen();
78
+ else this.el.requestFullscreen();
79
+ } else {
80
+ const marker = target.closest(".map-marker");
81
+ if (this._markerPopups.has(marker)) this._toggle(marker);
82
+ }
83
+ };
84
+ // A click on the map closes marker popups, but not the one being toggled.
85
+ this._handleMapClick = (e) => {
86
+ const target = e.originalEvent.target;
87
+ for (const [marker, popup] of this._markerPopups) {
88
+ if (!marker.contains(target) && !popup.getElement()?.contains(target)) popup.remove();
89
+ }
90
+ };
91
+ this._handleKeydown = (e) => {
92
+ if (e.key !== "Escape") return;
93
+ for (const popup of this._popups) {
94
+ if (popup.getElement()?.contains(e.target)) {
95
+ e.preventDefault();
96
+ popup.remove();
97
+ }
98
+ }
99
+ };
100
+ this.el["Expressive_MapView"] = this;
101
+ this.options = {
102
+ ..._MapView.defaults,
103
+ ...options
104
+ };
105
+ const lib = this.options.maplibregl;
106
+ if (!lib) {
107
+ console.error("MapView needs the maplibre-gl module in options.maplibregl.");
108
+ return;
109
+ }
110
+ this._children = [...el.children];
111
+ this._zoomIn = [...this._buttons("zoom-in")];
112
+ this._zoomOut = [...this._buttons("zoom-out")];
113
+ this._dark = this._isDark();
114
+ this.map = new lib.Map({
115
+ ...this.options.mapOptions,
116
+ container: el,
117
+ style: this._style(),
118
+ center: this.options.center,
119
+ zoom: this.options.zoom
120
+ });
121
+ this.map.on("style.load", this._handleStyleLoad);
122
+ this.map.on("move", this._sync);
123
+ this.map.on("click", this._handleMapClick);
124
+ const children = this._children.filter((child) => child instanceof HTMLElement);
125
+ const claimed = /* @__PURE__ */ new Set();
126
+ for (const marker of children.filter((child) => child.matches(".map-marker[data-lng-lat]"))) {
127
+ const target = marker.hasAttribute("aria-controls") ? Utils.getElementById(marker, marker.getAttribute("aria-controls")) : null;
128
+ const popup = target?.parentElement === el && target.matches(".map-popup") ? target : null;
129
+ if (popup) claimed.add(popup);
130
+ this._addMarker(marker, popup);
131
+ }
132
+ for (const popup of children.filter((child) => child.matches(".map-popup[data-lng-lat]") && !claimed.has(child))) {
133
+ this._popup(popup, 0).setLngLat(lngLat(popup)).addTo(this.map);
134
+ }
135
+ if (this._themed()) {
136
+ this._media = matchMedia("(prefers-color-scheme: dark)");
137
+ this._media.addEventListener("change", this._handleScheme);
138
+ this._observer = new MutationObserver(this._handleScheme);
139
+ this._observer.observe(document.documentElement, { attributes: true, attributeFilter: ["theme"], subtree: true });
140
+ }
141
+ for (const button of this._buttons("fullscreen")) button.hidden = !document.fullscreenEnabled;
142
+ document.addEventListener("fullscreenchange", this._handleFullscreen);
143
+ el.addEventListener("click", this._handleClick);
144
+ el.addEventListener("keydown", this._handleKeydown);
145
+ this._sync();
146
+ }
147
+ static get defaults() {
148
+ return _defaults;
149
+ }
150
+ /**
151
+ * Initializes instances of MapView.
152
+ * @param els HTML elements.
153
+ * @param options Component options.
154
+ */
155
+ static init(els, options = {}) {
156
+ return super.init(els, options, _MapView);
157
+ }
158
+ static getInstance(el) {
159
+ return el["Expressive_MapView"];
160
+ }
161
+ destroy() {
162
+ this.el["Expressive_MapView"] = void 0;
163
+ if (!this.map) return;
164
+ this.el.removeEventListener("click", this._handleClick);
165
+ this.el.removeEventListener("keydown", this._handleKeydown);
166
+ document.removeEventListener("fullscreenchange", this._handleFullscreen);
167
+ this._media?.removeEventListener("change", this._handleScheme);
168
+ this._observer?.disconnect();
169
+ for (const overlay of this._overlays.values()) overlay.off?.();
170
+ for (const popup of this._popups) popup.remove();
171
+ for (const marker of this.markers) {
172
+ marker.remove();
173
+ const element = marker.getElement();
174
+ element.classList.remove(...[...element.classList].filter((name) => name.startsWith("maplibregl-")));
175
+ element.style.removeProperty("transform");
176
+ element.style.removeProperty("opacity");
177
+ if (element.hasAttribute("aria-controls")) element.removeAttribute("aria-expanded");
178
+ }
179
+ this._location?.remove();
180
+ this._location = null;
181
+ this.map.remove();
182
+ this.map = null;
183
+ this.markers = [];
184
+ this._popups = [];
185
+ this._markerPopups.clear();
186
+ this._overlays.clear();
187
+ this.el.style.removeProperty("--md-comp-map-bearing");
188
+ for (const button of this.el.querySelectorAll(".map-controls [data-action]")) {
189
+ button.disabled = false;
190
+ button.hidden = false;
191
+ button.removeAttribute("aria-pressed");
192
+ }
193
+ this.el.append(...this._children);
194
+ }
195
+ /** Draws a line through `[longitude, latitude]` points. Replaces an overlay with the same id. */
196
+ addRoute(id, coordinates, options = {}) {
197
+ this._line(id, { type: "LineString", coordinates }, "route", { width: 4, ...options });
198
+ }
199
+ /** Draws a curved line for each `{ from, to }`. Replaces an overlay with the same id. */
200
+ addArcs(id, arcs, options = {}) {
201
+ this._line(id, { type: "MultiLineString", coordinates: arcs.map(({ from, to }) => arc(from, to)) }, "arc", { width: 2, ...options });
202
+ }
203
+ /**
204
+ * Draws GeoJSON points, or the URL of a GeoJSON file, as clusters that
205
+ * show their count and zoom in when clicked. The layers are
206
+ * `${id}-clusters`, `${id}-count` and `${id}-points`.
207
+ */
208
+ addClusters(id, data, options = {}) {
209
+ const clusters = `${id}-clusters`, points = `${id}-points`;
210
+ const zoomIn = async (e) => {
211
+ const [feature] = e.features;
212
+ const zoom = await this.map.getSource(id).getClusterExpansionZoom(feature.properties.cluster_id);
213
+ this.map.easeTo({ center: feature.geometry.coordinates, zoom });
214
+ };
215
+ const pointer = () => {
216
+ this.map.getCanvas().style.cursor = "pointer";
217
+ };
218
+ const reset = () => {
219
+ this.map.getCanvas().style.cursor = "";
220
+ };
221
+ this._draw(id, {
222
+ draw: () => {
223
+ const color = options.color ?? this._color("var(--md-comp-map-cluster-color)");
224
+ const surface = this._color("var(--md-comp-map-marker-ring-color)");
225
+ this.map.addSource(id, {
226
+ type: "geojson",
227
+ data,
228
+ cluster: true,
229
+ clusterRadius: options.radius ?? 50,
230
+ clusterMaxZoom: options.maxZoom ?? 14
231
+ });
232
+ this.map.addLayer({
233
+ id: clusters,
234
+ type: "circle",
235
+ source: id,
236
+ filter: ["has", "point_count"],
237
+ paint: {
238
+ "circle-color": color,
239
+ "circle-radius": ["step", ["get", "point_count"], 16, 10, 20, 100, 26],
240
+ "circle-stroke-width": 6,
241
+ "circle-stroke-color": color,
242
+ "circle-stroke-opacity": 0.3
243
+ }
244
+ });
245
+ const style = this.map.getStyle();
246
+ const font = style.glyphs && style.layers.find((layer) => layer.layout?.["text-font"])?.layout["text-font"];
247
+ if (font) {
248
+ this.map.addLayer({
249
+ id: `${id}-count`,
250
+ type: "symbol",
251
+ source: id,
252
+ filter: ["has", "point_count"],
253
+ layout: { "text-field": ["get", "point_count_abbreviated"], "text-font": font, "text-size": 12 },
254
+ paint: { "text-color": this._color("var(--md-comp-map-cluster-label-color)") }
255
+ });
256
+ }
257
+ this.map.addLayer({
258
+ id: points,
259
+ type: "circle",
260
+ source: id,
261
+ filter: ["!", ["has", "point_count"]],
262
+ paint: { "circle-color": color, "circle-radius": 6, "circle-stroke-width": 2, "circle-stroke-color": surface }
263
+ });
264
+ },
265
+ off: () => {
266
+ this.map.off("click", clusters, zoomIn);
267
+ for (const layer of [clusters, points]) {
268
+ this.map.off("mouseenter", layer, pointer);
269
+ this.map.off("mouseleave", layer, reset);
270
+ }
271
+ }
272
+ });
273
+ this.map.on("click", clusters, zoomIn);
274
+ for (const layer of [clusters, points]) {
275
+ this.map.on("mouseenter", layer, pointer);
276
+ this.map.on("mouseleave", layer, reset);
277
+ }
278
+ }
279
+ /** Removes a route, arcs or clusters added with this id. */
280
+ removeOverlay(id) {
281
+ const overlay = this._overlays.get(id);
282
+ if (!overlay) return;
283
+ this._overlays.delete(id);
284
+ overlay.off?.();
285
+ if (!this._styleReady || !this.map.getSource(id)) return;
286
+ for (const layer of this.map.getStyle().layers) if (layer.source === id) this.map.removeLayer(layer.id);
287
+ this.map.removeSource(id);
288
+ }
289
+ _line(id, geometry, token, options) {
290
+ this._draw(id, {
291
+ draw: () => {
292
+ this.map.addSource(id, { type: "geojson", data: { type: "Feature", properties: {}, geometry } });
293
+ this.map.addLayer({
294
+ id,
295
+ type: "line",
296
+ source: id,
297
+ layout: { "line-cap": "round", "line-join": "round" },
298
+ paint: {
299
+ "line-color": options.color ?? this._color(`var(--md-comp-map-${token}-color)`),
300
+ "line-width": options.width,
301
+ "line-opacity": options.opacity ?? 1,
302
+ ...options.dashArray && { "line-dasharray": options.dashArray }
303
+ }
304
+ });
305
+ }
306
+ });
307
+ }
308
+ // Sources and layers go with the style, so every overlay is drawn again
309
+ // when a theme change swaps it.
310
+ _draw(id, overlay) {
311
+ this.removeOverlay(id);
312
+ this._overlays.set(id, overlay);
313
+ if (this._styleReady) overlay.draw();
314
+ }
315
+ _addMarker(element, content) {
316
+ const marker = new this.options.maplibregl.Marker({
317
+ element,
318
+ draggable: element.hasAttribute("data-draggable")
319
+ }).setLngLat(lngLat(element)).addTo(this.map);
320
+ marker.on("dragend", () => {
321
+ const { lng, lat } = marker.getLngLat();
322
+ element.dataset.lngLat = `${lng},${lat}`;
323
+ element.dispatchEvent(new Event("change", { bubbles: true }));
324
+ });
325
+ this.markers.push(marker);
326
+ if (!content) return;
327
+ element.setAttribute("aria-expanded", "false");
328
+ const popup = this._popup(content, 16);
329
+ popup.on("open", () => element.setAttribute("aria-expanded", "true"));
330
+ popup.on("close", () => {
331
+ element.setAttribute("aria-expanded", "false");
332
+ if (!document.activeElement || document.activeElement === document.body) element.focus();
333
+ });
334
+ this._markerPopups.set(element, popup);
335
+ }
336
+ _popup(content, offset) {
337
+ const popup = new this.options.maplibregl.Popup({ closeOnClick: false, maxWidth: "none", offset }).setDOMContent(content);
338
+ this._popups.push(popup);
339
+ return popup;
340
+ }
341
+ _toggle(marker) {
342
+ const popup = this._markerPopups.get(marker);
343
+ if (popup.isOpen()) popup.remove();
344
+ else popup.setLngLat(this.markers.find((m) => m.getElement() === marker).getLngLat()).addTo(this.map);
345
+ }
346
+ _buttons(action) {
347
+ return this.el.querySelectorAll(`.map-controls [data-action="${action}"]`);
348
+ }
349
+ _locate(button) {
350
+ navigator.geolocation?.getCurrentPosition(
351
+ ({ coords }) => {
352
+ if (!this.map) return;
353
+ const center = [coords.longitude, coords.latitude];
354
+ if (!this._location) {
355
+ const dot = document.createElement("span");
356
+ dot.className = "map-marker location";
357
+ dot.setAttribute("aria-hidden", "true");
358
+ this._location = new this.options.maplibregl.Marker({ element: dot });
359
+ }
360
+ this._location.setLngLat(center).addTo(this.map);
361
+ this.map.flyTo({ center, zoom: Math.max(this.map.getZoom(), 14) });
362
+ },
363
+ (error) => {
364
+ if (this.map && error.code === error.PERMISSION_DENIED) button.disabled = true;
365
+ }
366
+ );
367
+ }
368
+ // Resolves a CSS color where the map is, so light-dark() and scoped
369
+ // themes apply, then paints it on a canvas to read back the sRGB value.
370
+ // MapLibre does not parse the oklch() the theme tokens compute to.
371
+ _color(value) {
372
+ const probe = document.createElement("span");
373
+ probe.hidden = true;
374
+ probe.style.color = value;
375
+ this.el.append(probe);
376
+ const context = document.createElement("canvas").getContext("2d", { willReadFrequently: true });
377
+ context.fillStyle = getComputedStyle(probe).color;
378
+ probe.remove();
379
+ context.fillRect(0, 0, 1, 1);
380
+ const [r, g, b, a] = context.getImageData(0, 0, 1, 1).data;
381
+ return `rgba(${r}, ${g}, ${b}, ${Math.round(a / 255 * 100) / 100})`;
382
+ }
383
+ _isDark() {
384
+ return this._color("light-dark(black, white)") === "rgba(255, 255, 255, 1)";
385
+ }
386
+ _themed() {
387
+ const style = this.options.style;
388
+ return typeof style === "object" && "light" in style && "dark" in style;
389
+ }
390
+ _style() {
391
+ return this._themed() ? this.options.style[this._dark ? "dark" : "light"] : this.options.style;
392
+ }
393
+ };
394
+
395
+ export {
396
+ MapView
397
+ };
398
+ //# sourceMappingURL=chunk-TBM3FT7G.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/ts/components/mapView.ts"],
4
+ "sourcesContent": ["import { Utils } from '../core/utils';\nimport { Component, BaseOptions, InitElements, InitElement } from '../core/component';\n\n/** `[longitude, latitude]`, MapLibre's order. */\nexport type LngLat = [number, number];\n\n/**\n * The parts of the `maplibre-gl` module this component uses. Declared here so\n * the published types do not depend on MapLibre.\n */\nexport interface MapLibre {\n Map: new (options: object) => any;\n Marker: new (options: object) => any;\n Popup: new (options: object) => any;\n}\n\n/** A style for each color scheme. The map follows the page's theme. */\nexport interface MapThemedStyle {\n light: string | object;\n dark: string | object;\n}\n\nexport interface MapViewOptions extends BaseOptions {\n /**\n * The `maplibre-gl` module. ExpressiveCSS does not bundle MapLibre, so the\n * page imports it and passes it in.\n * @default null\n */\n maplibregl: MapLibre | null;\n /**\n * A MapLibre style URL or object, or `{ light, dark }` to follow the theme.\n * @default OpenFreeMap Positron and Dark\n */\n style: string | object | MapThemedStyle;\n /**\n * Starting `[longitude, latitude]`.\n * @default [0, 20]\n */\n center: LngLat;\n /**\n * Starting zoom level.\n * @default 1\n */\n zoom: number;\n /**\n * More MapLibre `Map` options, such as `maxZoom` or `bearing`.\n * @default {}\n */\n mapOptions: object;\n}\n\nexport interface MapLineOptions {\n /** CSS color. Defaults to the route or arc color token. */\n color?: string;\n /** Width in pixels. Routes default to 4, arcs to 2. */\n width?: number;\n /** 0 to 1. */\n opacity?: number;\n /** Dash and gap lengths in line widths, such as `[2, 2]`. */\n dashArray?: number[];\n}\n\nexport interface MapArc {\n from: LngLat;\n to: LngLat;\n}\n\nexport interface MapClusterOptions {\n /** CSS color. Defaults to the cluster color token. */\n color?: string;\n /**\n * Pixels within which points join a cluster.\n * @default 50\n */\n radius?: number;\n /**\n * Last zoom level that clusters points.\n * @default 14\n */\n maxZoom?: number;\n}\n\nconst OPENFREEMAP = 'https://tiles.openfreemap.org/styles/';\n\nconst _defaults: MapViewOptions = {\n maplibregl: null,\n style: { light: `${OPENFREEMAP}positron`, dark: `${OPENFREEMAP}dark` },\n center: [0, 20],\n zoom: 1,\n mapOptions: {}\n};\n\ntype Overlay = { draw: () => void; off?: () => void };\n\nconst lngLat = (el: HTMLElement) => el.dataset.lngLat.split(',').map(Number) as LngLat;\n\n// A quadratic B\u00E9zier from `from` to `to`, bowed north of an eastward line.\n// ponytail: drawn in degrees, so an arc across the antimeridian goes the long\n// way round; split it at \u00B1180 if that matters.\nfunction arc([x0, y0]: LngLat, [x2, y2]: LngLat, steps = 32): LngLat[] {\n const bow = x2 >= x0 ? 0.25 : -0.25;\n const x1 = (x0 + x2) / 2 - (y2 - y0) * bow;\n const y1 = (y0 + y2) / 2 + (x2 - x0) * bow;\n return Array.from({ length: steps + 1 }, (_, i) => {\n const t = i / steps, u = 1 - t;\n return [u * u * x0 + 2 * u * t * x1 + t * t * x2, u * u * y0 + 2 * u * t * y1 + t * t * y2];\n });\n}\n\n/**\n * An interactive map built on MapLibre: a `.map` holding `.map-marker`,\n * `.map-popup` and `.map-controls` children.\n *\n * Each marker sits at its `data-lng-lat`. A marker button with\n * `aria-controls` opens the `.map-popup` it names; a popup with its own\n * `data-lng-lat` and no marker opens at init. Buttons in `.map-controls`\n * run their `data-action`: `zoom-in`, `zoom-out`, `compass`, `locate` or\n * `fullscreen`. Routes, arcs and clusters are data, so they are added from\n * script. The default style follows the page's light or dark theme, and\n * line and cluster colors come from the theme.\n *\n * The class is `MapView` rather than `Map` so importing it does not shadow\n * JavaScript's `Map`.\n */\nexport class MapView extends Component<MapViewOptions> {\n /** The MapLibre map. */\n map: any = null;\n /** The MapLibre markers made from `.map-marker` children, in order. */\n markers: any[] = [];\n private _children: Element[] = [];\n private _popups: any[] = [];\n private _markerPopups = new Map<HTMLElement, any>();\n private _overlays = new Map<string, Overlay>();\n private _styleReady = false;\n private _dark = false;\n private _location: any = null;\n private _media: MediaQueryList | null = null;\n private _observer: MutationObserver | null = null;\n // Looked up once: `move` fires every frame of a pan or zoom.\n private _zoomIn: HTMLButtonElement[] = [];\n private _zoomOut: HTMLButtonElement[] = [];\n\n constructor(el: HTMLElement, options: Partial<MapViewOptions>) {\n super(el, options, MapView);\n this.el['Expressive_MapView'] = this;\n this.options = {\n ...MapView.defaults,\n ...options\n };\n const lib = this.options.maplibregl;\n if (!lib) {\n console.error('MapView needs the maplibre-gl module in options.maplibregl.');\n return;\n }\n\n this._children = [...el.children];\n this._zoomIn = [...this._buttons('zoom-in')];\n this._zoomOut = [...this._buttons('zoom-out')];\n this._dark = this._isDark();\n this.map = new lib.Map({\n ...this.options.mapOptions,\n container: el,\n style: this._style(),\n center: this.options.center,\n zoom: this.options.zoom\n });\n this.map.on('style.load', this._handleStyleLoad);\n this.map.on('move', this._sync);\n this.map.on('click', this._handleMapClick);\n\n const children = this._children.filter((child): child is HTMLElement => child instanceof HTMLElement);\n const claimed = new Set<Element>();\n for (const marker of children.filter((child) => child.matches('.map-marker[data-lng-lat]'))) {\n const target = marker.hasAttribute('aria-controls') ? Utils.getElementById(marker, marker.getAttribute('aria-controls')) : null;\n const popup = target?.parentElement === el && target.matches('.map-popup') ? target : null;\n if (popup) claimed.add(popup);\n this._addMarker(marker, popup);\n }\n for (const popup of children.filter((child) => child.matches('.map-popup[data-lng-lat]') && !claimed.has(child))) {\n this._popup(popup, 0).setLngLat(lngLat(popup)).addTo(this.map);\n }\n\n if (this._themed()) {\n this._media = matchMedia('(prefers-color-scheme: dark)');\n this._media.addEventListener('change', this._handleScheme);\n this._observer = new MutationObserver(this._handleScheme);\n this._observer.observe(document.documentElement, { attributes: true, attributeFilter: ['theme'], subtree: true });\n }\n for (const button of this._buttons('fullscreen')) button.hidden = !document.fullscreenEnabled;\n document.addEventListener('fullscreenchange', this._handleFullscreen);\n el.addEventListener('click', this._handleClick);\n el.addEventListener('keydown', this._handleKeydown);\n this._sync();\n }\n\n static get defaults(): MapViewOptions {\n return _defaults;\n }\n\n /**\n * Initializes instance of MapView.\n * @param el HTML element.\n * @param options Component options.\n */\n static init(el: HTMLElement, options?: Partial<MapViewOptions>): MapView;\n /**\n * Initializes instances of MapView.\n * @param els HTML elements.\n * @param options Component options.\n */\n static init(els: InitElements<InitElement>, options?: Partial<MapViewOptions>): MapView[];\n /**\n * Initializes instances of MapView.\n * @param els HTML elements.\n * @param options Component options.\n */\n static init(\n els: HTMLElement | InitElements<InitElement>,\n options: Partial<MapViewOptions> = {}\n ): MapView | MapView[] {\n return super.init(els, options, MapView);\n }\n\n static getInstance(el: HTMLElement): MapView {\n return el['Expressive_MapView'];\n }\n\n destroy() {\n this.el['Expressive_MapView'] = undefined;\n if (!this.map) return;\n this.el.removeEventListener('click', this._handleClick);\n this.el.removeEventListener('keydown', this._handleKeydown);\n document.removeEventListener('fullscreenchange', this._handleFullscreen);\n this._media?.removeEventListener('change', this._handleScheme);\n this._observer?.disconnect();\n for (const overlay of this._overlays.values()) overlay.off?.();\n for (const popup of this._popups) popup.remove();\n for (const marker of this.markers) {\n marker.remove();\n const element: HTMLElement = marker.getElement();\n element.classList.remove(...[...element.classList].filter((name) => name.startsWith('maplibregl-')));\n element.style.removeProperty('transform');\n element.style.removeProperty('opacity');\n if (element.hasAttribute('aria-controls')) element.removeAttribute('aria-expanded');\n }\n this._location?.remove();\n this._location = null;\n this.map.remove();\n this.map = null;\n this.markers = [];\n this._popups = [];\n this._markerPopups.clear();\n this._overlays.clear();\n this.el.style.removeProperty('--md-comp-map-bearing');\n for (const button of this.el.querySelectorAll<HTMLButtonElement>('.map-controls [data-action]')) {\n button.disabled = false;\n button.hidden = false;\n button.removeAttribute('aria-pressed');\n }\n this.el.append(...this._children);\n }\n\n /** Draws a line through `[longitude, latitude]` points. Replaces an overlay with the same id. */\n addRoute(id: string, coordinates: LngLat[], options: MapLineOptions = {}) {\n this._line(id, { type: 'LineString', coordinates }, 'route', { width: 4, ...options });\n }\n\n /** Draws a curved line for each `{ from, to }`. Replaces an overlay with the same id. */\n addArcs(id: string, arcs: MapArc[], options: MapLineOptions = {}) {\n this._line(id, { type: 'MultiLineString', coordinates: arcs.map(({ from, to }) => arc(from, to)) }, 'arc', { width: 2, ...options });\n }\n\n /**\n * Draws GeoJSON points, or the URL of a GeoJSON file, as clusters that\n * show their count and zoom in when clicked. The layers are\n * `${id}-clusters`, `${id}-count` and `${id}-points`.\n */\n addClusters(id: string, data: object | string, options: MapClusterOptions = {}) {\n const clusters = `${id}-clusters`, points = `${id}-points`;\n const zoomIn = async (e: any) => {\n const [feature] = e.features;\n const zoom = await this.map.getSource(id).getClusterExpansionZoom(feature.properties.cluster_id);\n this.map.easeTo({ center: feature.geometry.coordinates, zoom });\n };\n const pointer = () => { this.map.getCanvas().style.cursor = 'pointer'; };\n const reset = () => { this.map.getCanvas().style.cursor = ''; };\n this._draw(id, {\n draw: () => {\n const color = options.color ?? this._color('var(--md-comp-map-cluster-color)');\n const surface = this._color('var(--md-comp-map-marker-ring-color)');\n this.map.addSource(id, {\n type: 'geojson',\n data,\n cluster: true,\n clusterRadius: options.radius ?? 50,\n clusterMaxZoom: options.maxZoom ?? 14\n });\n this.map.addLayer({\n id: clusters,\n type: 'circle',\n source: id,\n filter: ['has', 'point_count'],\n paint: {\n 'circle-color': color,\n 'circle-radius': ['step', ['get', 'point_count'], 16, 10, 20, 100, 26],\n 'circle-stroke-width': 6,\n 'circle-stroke-color': color,\n 'circle-stroke-opacity': 0.3\n }\n });\n // A symbol layer needs the style's glyphs and one of its fonts.\n const style = this.map.getStyle();\n const font = style.glyphs && style.layers.find((layer: any) => layer.layout?.['text-font'])?.layout['text-font'];\n if (font) {\n this.map.addLayer({\n id: `${id}-count`,\n type: 'symbol',\n source: id,\n filter: ['has', 'point_count'],\n layout: { 'text-field': ['get', 'point_count_abbreviated'], 'text-font': font, 'text-size': 12 },\n paint: { 'text-color': this._color('var(--md-comp-map-cluster-label-color)') }\n });\n }\n this.map.addLayer({\n id: points,\n type: 'circle',\n source: id,\n filter: ['!', ['has', 'point_count']],\n paint: { 'circle-color': color, 'circle-radius': 6, 'circle-stroke-width': 2, 'circle-stroke-color': surface }\n });\n },\n off: () => {\n this.map.off('click', clusters, zoomIn);\n for (const layer of [clusters, points]) {\n this.map.off('mouseenter', layer, pointer);\n this.map.off('mouseleave', layer, reset);\n }\n }\n });\n this.map.on('click', clusters, zoomIn);\n for (const layer of [clusters, points]) {\n this.map.on('mouseenter', layer, pointer);\n this.map.on('mouseleave', layer, reset);\n }\n }\n\n /** Removes a route, arcs or clusters added with this id. */\n removeOverlay(id: string) {\n const overlay = this._overlays.get(id);\n if (!overlay) return;\n this._overlays.delete(id);\n overlay.off?.();\n if (!this._styleReady || !this.map.getSource(id)) return;\n for (const layer of this.map.getStyle().layers) if (layer.source === id) this.map.removeLayer(layer.id);\n this.map.removeSource(id);\n }\n\n private _line(id: string, geometry: object, token: string, options: MapLineOptions) {\n this._draw(id, {\n draw: () => {\n this.map.addSource(id, { type: 'geojson', data: { type: 'Feature', properties: {}, geometry } });\n this.map.addLayer({\n id,\n type: 'line',\n source: id,\n layout: { 'line-cap': 'round', 'line-join': 'round' },\n paint: {\n 'line-color': options.color ?? this._color(`var(--md-comp-map-${token}-color)`),\n 'line-width': options.width,\n 'line-opacity': options.opacity ?? 1,\n ...(options.dashArray && { 'line-dasharray': options.dashArray })\n }\n });\n }\n });\n }\n\n // Sources and layers go with the style, so every overlay is drawn again\n // when a theme change swaps it.\n private _draw(id: string, overlay: Overlay) {\n this.removeOverlay(id);\n this._overlays.set(id, overlay);\n if (this._styleReady) overlay.draw();\n }\n\n private _addMarker(element: HTMLElement, content: HTMLElement | null) {\n const marker = new this.options.maplibregl.Marker({\n element,\n draggable: element.hasAttribute('data-draggable')\n }).setLngLat(lngLat(element)).addTo(this.map);\n marker.on('dragend', () => {\n const { lng, lat } = marker.getLngLat();\n element.dataset.lngLat = `${lng},${lat}`;\n element.dispatchEvent(new Event('change', { bubbles: true }));\n });\n this.markers.push(marker);\n if (!content) return;\n element.setAttribute('aria-expanded', 'false');\n const popup = this._popup(content, 16);\n popup.on('open', () => element.setAttribute('aria-expanded', 'true'));\n popup.on('close', () => {\n element.setAttribute('aria-expanded', 'false');\n if (!document.activeElement || document.activeElement === document.body) element.focus();\n });\n this._markerPopups.set(element, popup);\n }\n\n private _popup(content: HTMLElement, offset: number) {\n const popup = new this.options.maplibregl.Popup({ closeOnClick: false, maxWidth: 'none', offset }).setDOMContent(content);\n this._popups.push(popup);\n return popup;\n }\n\n private _toggle(marker: HTMLElement) {\n const popup = this._markerPopups.get(marker);\n if (popup.isOpen()) popup.remove();\n else popup.setLngLat(this.markers.find((m) => m.getElement() === marker).getLngLat()).addTo(this.map);\n }\n\n private _buttons(action: string) {\n return this.el.querySelectorAll<HTMLButtonElement>(`.map-controls [data-action=\"${action}\"]`);\n }\n\n private _locate(button: HTMLButtonElement) {\n navigator.geolocation?.getCurrentPosition(\n ({ coords }) => {\n if (!this.map) return;\n const center = [coords.longitude, coords.latitude];\n if (!this._location) {\n const dot = document.createElement('span');\n dot.className = 'map-marker location';\n dot.setAttribute('aria-hidden', 'true');\n this._location = new this.options.maplibregl.Marker({ element: dot });\n }\n this._location.setLngLat(center).addTo(this.map);\n this.map.flyTo({ center, zoom: Math.max(this.map.getZoom(), 14) });\n },\n (error) => { if (this.map && error.code === error.PERMISSION_DENIED) button.disabled = true; }\n );\n }\n\n // Resolves a CSS color where the map is, so light-dark() and scoped\n // themes apply, then paints it on a canvas to read back the sRGB value.\n // MapLibre does not parse the oklch() the theme tokens compute to.\n private _color(value: string) {\n const probe = document.createElement('span');\n probe.hidden = true;\n probe.style.color = value;\n this.el.append(probe);\n const context = document.createElement('canvas').getContext('2d', { willReadFrequently: true });\n context.fillStyle = getComputedStyle(probe).color;\n probe.remove();\n context.fillRect(0, 0, 1, 1);\n const [r, g, b, a] = context.getImageData(0, 0, 1, 1).data;\n return `rgba(${r}, ${g}, ${b}, ${Math.round((a / 255) * 100) / 100})`;\n }\n\n private _isDark() {\n return this._color('light-dark(black, white)') === 'rgba(255, 255, 255, 1)';\n }\n\n private _themed() {\n const style = this.options.style;\n return typeof style === 'object' && 'light' in style && 'dark' in style;\n }\n\n private _style() {\n return this._themed() ? this.options.style[this._dark ? 'dark' : 'light'] : this.options.style;\n }\n\n private _handleStyleLoad = () => {\n this._styleReady = true;\n for (const overlay of this._overlays.values()) overlay.draw();\n };\n\n private _handleScheme = () => {\n const dark = this._isDark();\n if (dark === this._dark) return;\n this._dark = dark;\n this._styleReady = false;\n this.map.setStyle(this._style(), { diff: false });\n };\n\n private _sync = () => {\n const zoom = this.map.getZoom();\n for (const button of this._zoomIn) button.disabled = zoom >= this.map.getMaxZoom();\n for (const button of this._zoomOut) button.disabled = zoom <= this.map.getMinZoom();\n this.el.style.setProperty('--md-comp-map-bearing', `${-this.map.getBearing()}deg`);\n };\n\n private _handleFullscreen = () => {\n for (const button of this._buttons('fullscreen')) {\n button.setAttribute('aria-pressed', String(document.fullscreenElement === this.el));\n }\n };\n\n private _handleClick = (e: MouseEvent) => {\n const target = e.target as Element;\n const button = target.closest<HTMLButtonElement>('.map-controls [data-action]');\n const action = button?.dataset.action;\n if (action === 'zoom-in') this.map.zoomIn();\n else if (action === 'zoom-out') this.map.zoomOut();\n else if (action === 'compass') this.map.resetNorthPitch();\n else if (action === 'locate') this._locate(button);\n else if (action === 'fullscreen') {\n if (document.fullscreenElement === this.el) document.exitFullscreen();\n else this.el.requestFullscreen();\n } else {\n const marker = target.closest<HTMLElement>('.map-marker');\n if (this._markerPopups.has(marker)) this._toggle(marker);\n }\n };\n\n // A click on the map closes marker popups, but not the one being toggled.\n private _handleMapClick = (e: any) => {\n const target = e.originalEvent.target as Node;\n for (const [marker, popup] of this._markerPopups) {\n if (!marker.contains(target) && !popup.getElement()?.contains(target)) popup.remove();\n }\n };\n\n private _handleKeydown = (e: KeyboardEvent) => {\n if (e.key !== 'Escape') return;\n for (const popup of this._popups) {\n if (popup.getElement()?.contains(e.target as Node)) {\n e.preventDefault();\n popup.remove();\n }\n }\n };\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }