@zendir/ui 0.2.3 → 0.2.4
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/CHANGELOG.md +24 -0
- package/dist/react/charts/GroundTrackMap.d.ts +28 -1
- package/dist/react/charts/GroundTrackMap.js +6 -2
- package/dist/react/charts/GroundTrackMap.js.map +1 -1
- package/dist/react/charts/GroundTrackMapLeaflet.d.ts +6 -2
- package/dist/react/charts/GroundTrackMapLeaflet.js +312 -92
- package/dist/react/charts/GroundTrackMapLeaflet.js.map +1 -1
- package/dist/react/charts/index.d.ts +1 -1
- package/dist/react/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
import { GroundStation } from '../types';
|
|
3
|
-
import { SatelliteTrack, GroundStationEnhanced, SROGroundStation, MapPin, LightSource } from './GroundTrackMap';
|
|
3
|
+
import { SatelliteTrack, GroundStationEnhanced, SROGroundStation, MapPin, LightSource, MapLayerDef } from './GroundTrackMap';
|
|
4
4
|
|
|
5
5
|
export type GroundStationMapItem = GroundStation | GroundStationEnhanced | SROGroundStation;
|
|
6
6
|
export interface GroundTrackMapLeafletProps {
|
|
@@ -43,6 +43,10 @@ export interface GroundTrackMapLeafletProps {
|
|
|
43
43
|
onPinAdd?: (pin: Omit<MapPin, 'id'>) => void;
|
|
44
44
|
onPinUpdate?: (pin: MapPin) => void;
|
|
45
45
|
onPinRemove?: (pinId: string) => void;
|
|
46
|
+
/** Custom overlay layers for the Layers panel */
|
|
47
|
+
customLayers?: MapLayerDef[];
|
|
48
|
+
/** Called when any layer is toggled */
|
|
49
|
+
onLayerChange?: (layerId: string, enabled: boolean) => void;
|
|
46
50
|
}
|
|
47
|
-
export declare function GroundTrackMapLeaflet({ allSatellites, groundStations, showTerminator, terminatorTime, showGrid, showLegend, showEquator, showRecenterButton, showMapStyleToggle, defaultCenter, defaultZoom, height, width, minHeight, emptyMessage, tileUrl, nightTileUrl, lightSources, className, onSatelliteClick, onStationClick, pins, pinsEditable, onPinAdd, onPinUpdate, onPinRemove, }: GroundTrackMapLeafletProps): React.ReactElement;
|
|
51
|
+
export declare function GroundTrackMapLeaflet({ allSatellites, groundStations, showTerminator, terminatorTime, showGrid, showLegend, showEquator, showRecenterButton, showMapStyleToggle, defaultCenter, defaultZoom, height, width, minHeight, emptyMessage, tileUrl, nightTileUrl, lightSources, className, onSatelliteClick, onStationClick, pins, pinsEditable, onPinAdd, onPinUpdate, onPinRemove, customLayers, onLayerChange, }: GroundTrackMapLeafletProps): React.ReactElement;
|
|
48
52
|
export default GroundTrackMapLeaflet;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useRef, useState,
|
|
1
|
+
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useRef, useState, useEffect, useCallback } from "react";
|
|
3
3
|
import L from "leaflet";
|
|
4
4
|
import "leaflet/dist/leaflet.css";
|
|
5
5
|
/* empty css */
|
|
@@ -160,7 +160,9 @@ function GroundTrackMapLeaflet({
|
|
|
160
160
|
pinsEditable = false,
|
|
161
161
|
onPinAdd,
|
|
162
162
|
onPinUpdate,
|
|
163
|
-
onPinRemove
|
|
163
|
+
onPinRemove,
|
|
164
|
+
customLayers,
|
|
165
|
+
onLayerChange
|
|
164
166
|
}) {
|
|
165
167
|
const { tokens } = useTheme();
|
|
166
168
|
const containerRef = useRef(null);
|
|
@@ -170,9 +172,71 @@ function GroundTrackMapLeaflet({
|
|
|
170
172
|
const controlsRef = useRef([]);
|
|
171
173
|
const pinsGroupRef = useRef(null);
|
|
172
174
|
const [ready, setReady] = useState(false);
|
|
173
|
-
const [
|
|
175
|
+
const [layersPanelOpen, setLayersPanelOpen] = useState(false);
|
|
176
|
+
const layersPanelRef = useRef(null);
|
|
177
|
+
useEffect(() => {
|
|
178
|
+
if (!layersPanelOpen) return;
|
|
179
|
+
const handleClickOutside = (e) => {
|
|
180
|
+
if (layersPanelRef.current && !layersPanelRef.current.contains(e.target)) {
|
|
181
|
+
setLayersPanelOpen(false);
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
185
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
186
|
+
}, [layersPanelOpen]);
|
|
187
|
+
const TILE_STORAGE_KEY = "zendir-map-tile-style";
|
|
174
188
|
const isExplicitTileUrl = tileUrl !== void 0;
|
|
189
|
+
const [tileStyle, setTileStyle] = useState(() => {
|
|
190
|
+
if (isExplicitTileUrl) return "dark";
|
|
191
|
+
try {
|
|
192
|
+
const saved = localStorage.getItem(TILE_STORAGE_KEY);
|
|
193
|
+
if (saved === "dark" || saved === "satellite") return saved;
|
|
194
|
+
} catch {
|
|
195
|
+
}
|
|
196
|
+
return "dark";
|
|
197
|
+
});
|
|
198
|
+
const handleTileStyleChange = useCallback((style) => {
|
|
199
|
+
setTileStyle(style);
|
|
200
|
+
try {
|
|
201
|
+
localStorage.setItem(TILE_STORAGE_KEY, style);
|
|
202
|
+
} catch {
|
|
203
|
+
}
|
|
204
|
+
}, []);
|
|
175
205
|
const effectiveTileUrl = isExplicitTileUrl ? tileUrl : TILE_PRESETS[tileStyle];
|
|
206
|
+
const [internalTerminator, setInternalTerminator] = useState(showTerminator);
|
|
207
|
+
const [internalGrid, setInternalGrid] = useState(showGrid);
|
|
208
|
+
useEffect(() => {
|
|
209
|
+
setInternalTerminator(showTerminator);
|
|
210
|
+
}, [showTerminator]);
|
|
211
|
+
useEffect(() => {
|
|
212
|
+
setInternalGrid(showGrid);
|
|
213
|
+
}, [showGrid]);
|
|
214
|
+
const [customLayerState, setCustomLayerState] = useState(() => {
|
|
215
|
+
const state = {};
|
|
216
|
+
for (const l of customLayers ?? []) {
|
|
217
|
+
state[l.id] = l.defaultEnabled ?? true;
|
|
218
|
+
}
|
|
219
|
+
return state;
|
|
220
|
+
});
|
|
221
|
+
useEffect(() => {
|
|
222
|
+
setCustomLayerState((prev) => {
|
|
223
|
+
const next = { ...prev };
|
|
224
|
+
for (const l of customLayers ?? []) {
|
|
225
|
+
if (!(l.id in next)) next[l.id] = l.defaultEnabled ?? true;
|
|
226
|
+
}
|
|
227
|
+
return next;
|
|
228
|
+
});
|
|
229
|
+
}, [customLayers]);
|
|
230
|
+
const handleLayerToggle = useCallback((layerId, enabled) => {
|
|
231
|
+
if (layerId === "terminator") {
|
|
232
|
+
setInternalTerminator(enabled);
|
|
233
|
+
} else if (layerId === "grid") {
|
|
234
|
+
setInternalGrid(enabled);
|
|
235
|
+
} else {
|
|
236
|
+
setCustomLayerState((prev) => ({ ...prev, [layerId]: enabled }));
|
|
237
|
+
}
|
|
238
|
+
onLayerChange == null ? void 0 : onLayerChange(layerId, enabled);
|
|
239
|
+
}, [onLayerChange]);
|
|
176
240
|
const clearLayers = useCallback(() => {
|
|
177
241
|
var _a;
|
|
178
242
|
const map = mapRef.current;
|
|
@@ -204,7 +268,6 @@ function GroundTrackMapLeaflet({
|
|
|
204
268
|
maxBounds: [[-90, -540], [90, 540]],
|
|
205
269
|
maxBoundsViscosity: 1
|
|
206
270
|
});
|
|
207
|
-
L.control.zoom({ position: "topright" }).addTo(map);
|
|
208
271
|
map.attributionControl.setPrefix("");
|
|
209
272
|
const overlayGroup = L.layerGroup();
|
|
210
273
|
overlayGroup.addTo(map);
|
|
@@ -279,7 +342,7 @@ function GroundTrackMapLeaflet({
|
|
|
279
342
|
if (!ready || !mapRef.current) return;
|
|
280
343
|
const map = mapRef.current;
|
|
281
344
|
clearLayers();
|
|
282
|
-
if (nightTileUrl &&
|
|
345
|
+
if (nightTileUrl && internalTerminator) {
|
|
283
346
|
const nightTile = L.tileLayer(nightTileUrl, {
|
|
284
347
|
maxZoom: 19,
|
|
285
348
|
crossOrigin: true,
|
|
@@ -288,7 +351,7 @@ function GroundTrackMapLeaflet({
|
|
|
288
351
|
});
|
|
289
352
|
addLayer(nightTile);
|
|
290
353
|
}
|
|
291
|
-
if (
|
|
354
|
+
if (internalTerminator) {
|
|
292
355
|
const now = terminatorTime ?? /* @__PURE__ */ new Date();
|
|
293
356
|
const BAND_STEP = 2;
|
|
294
357
|
const MAX_DEP = 24;
|
|
@@ -345,7 +408,7 @@ function GroundTrackMapLeaflet({
|
|
|
345
408
|
});
|
|
346
409
|
}
|
|
347
410
|
}
|
|
348
|
-
if (lightSources && lightSources.length > 0 &&
|
|
411
|
+
if (lightSources && lightSources.length > 0 && internalTerminator) {
|
|
349
412
|
const now = terminatorTime ?? /* @__PURE__ */ new Date();
|
|
350
413
|
const dayOfYear = Math.floor((now.getTime() - new Date(now.getFullYear(), 0, 0).getTime()) / 864e5);
|
|
351
414
|
const declination = -23.44 * Math.cos(2 * Math.PI / 365 * (dayOfYear + 10));
|
|
@@ -391,7 +454,7 @@ function GroundTrackMapLeaflet({
|
|
|
391
454
|
}
|
|
392
455
|
}
|
|
393
456
|
}
|
|
394
|
-
if (
|
|
457
|
+
if (internalGrid) {
|
|
395
458
|
const gridStyle = { color: "rgba(157, 112, 255, 0.12)", weight: 0.5, interactive: false };
|
|
396
459
|
[-360, 0, 360].forEach((offset) => {
|
|
397
460
|
for (let lon = -180; lon <= 180; lon += 30) {
|
|
@@ -583,11 +646,11 @@ function GroundTrackMapLeaflet({
|
|
|
583
646
|
ready,
|
|
584
647
|
allSatellites,
|
|
585
648
|
groundStations,
|
|
586
|
-
|
|
649
|
+
internalTerminator,
|
|
587
650
|
terminatorTime,
|
|
588
651
|
nightTileUrl,
|
|
589
652
|
lightSources,
|
|
590
|
-
|
|
653
|
+
internalGrid,
|
|
591
654
|
showEquator,
|
|
592
655
|
showLegend,
|
|
593
656
|
tokens.colors.text.secondary,
|
|
@@ -686,8 +749,42 @@ function GroundTrackMapLeaflet({
|
|
|
686
749
|
map.setView(defaultCenter, defaultZoom);
|
|
687
750
|
}
|
|
688
751
|
}, [allSatellites, groundStations, defaultCenter, defaultZoom]);
|
|
752
|
+
const handleZoomIn = useCallback(() => {
|
|
753
|
+
var _a;
|
|
754
|
+
(_a = mapRef.current) == null ? void 0 : _a.zoomIn();
|
|
755
|
+
}, []);
|
|
756
|
+
const handleZoomOut = useCallback(() => {
|
|
757
|
+
var _a;
|
|
758
|
+
(_a = mapRef.current) == null ? void 0 : _a.zoomOut();
|
|
759
|
+
}, []);
|
|
689
760
|
const resolvedMinHeight = minHeight || (typeof height === "number" ? `${height}px` : "400px");
|
|
690
761
|
const isEmpty = allSatellites.length === 0 && groundStations.length === 0 && (!pins || pins.length === 0);
|
|
762
|
+
const ctrlBtnBase = {
|
|
763
|
+
background: "rgba(20, 24, 38, 0.92)",
|
|
764
|
+
backdropFilter: "blur(8px)",
|
|
765
|
+
WebkitBackdropFilter: "blur(8px)",
|
|
766
|
+
border: "1px solid rgba(120, 100, 180, 0.18)",
|
|
767
|
+
color: "#c8c0d8",
|
|
768
|
+
cursor: "pointer",
|
|
769
|
+
display: "flex",
|
|
770
|
+
alignItems: "center",
|
|
771
|
+
justifyContent: "center",
|
|
772
|
+
transition: "background 0.15s, border-color 0.15s"
|
|
773
|
+
};
|
|
774
|
+
const ctrlHover = (e) => {
|
|
775
|
+
e.currentTarget.style.background = "rgba(30, 34, 52, 0.95)";
|
|
776
|
+
e.currentTarget.style.borderColor = "rgba(157, 112, 255, 0.4)";
|
|
777
|
+
};
|
|
778
|
+
const ctrlLeave = (e) => {
|
|
779
|
+
e.currentTarget.style.background = "rgba(20, 24, 38, 0.92)";
|
|
780
|
+
e.currentTarget.style.borderColor = "rgba(120, 100, 180, 0.18)";
|
|
781
|
+
};
|
|
782
|
+
const overlayItems = [];
|
|
783
|
+
overlayItems.push({ id: "terminator", label: "Day / Night", enabled: internalTerminator });
|
|
784
|
+
overlayItems.push({ id: "grid", label: "Grid Lines", enabled: internalGrid });
|
|
785
|
+
for (const l of customLayers ?? []) {
|
|
786
|
+
overlayItems.push({ id: l.id, label: l.label, enabled: customLayerState[l.id] ?? (l.defaultEnabled ?? true) });
|
|
787
|
+
}
|
|
691
788
|
return /* @__PURE__ */ jsxs(
|
|
692
789
|
"div",
|
|
693
790
|
{
|
|
@@ -725,22 +822,22 @@ function GroundTrackMapLeaflet({
|
|
|
725
822
|
children: emptyMessage
|
|
726
823
|
}
|
|
727
824
|
),
|
|
728
|
-
|
|
825
|
+
/* @__PURE__ */ jsxs(
|
|
729
826
|
"div",
|
|
730
827
|
{
|
|
731
|
-
className: "zendir-map-controls",
|
|
732
828
|
style: {
|
|
733
829
|
position: "absolute",
|
|
734
|
-
|
|
735
|
-
|
|
830
|
+
top: 10,
|
|
831
|
+
right: 10,
|
|
736
832
|
zIndex: 1e3,
|
|
737
833
|
display: "flex",
|
|
738
834
|
flexDirection: "row",
|
|
739
|
-
gap:
|
|
740
|
-
alignItems: "flex-
|
|
835
|
+
gap: 4,
|
|
836
|
+
alignItems: "flex-start",
|
|
837
|
+
pointerEvents: "none"
|
|
741
838
|
},
|
|
742
839
|
children: [
|
|
743
|
-
showRecenterButton && /* @__PURE__ */
|
|
840
|
+
showRecenterButton && /* @__PURE__ */ jsx(
|
|
744
841
|
"button",
|
|
745
842
|
{
|
|
746
843
|
type: "button",
|
|
@@ -748,86 +845,209 @@ function GroundTrackMapLeaflet({
|
|
|
748
845
|
title: "Recenter map to fit all assets and ground stations",
|
|
749
846
|
"aria-label": "Recenter map",
|
|
750
847
|
style: {
|
|
751
|
-
|
|
752
|
-
backdropFilter: "blur(8px)",
|
|
753
|
-
WebkitBackdropFilter: "blur(8px)",
|
|
754
|
-
border: "1px solid rgba(120, 100, 180, 0.2)",
|
|
848
|
+
...ctrlBtnBase,
|
|
755
849
|
borderRadius: 4,
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
fontSize: 11,
|
|
850
|
+
padding: "6px 8px",
|
|
851
|
+
gap: 4,
|
|
852
|
+
fontSize: 10,
|
|
760
853
|
fontWeight: 500,
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
gap: 5,
|
|
764
|
-
transition: "background 0.15s, border-color 0.15s",
|
|
765
|
-
letterSpacing: "0.02em"
|
|
766
|
-
},
|
|
767
|
-
onMouseEnter: (e) => {
|
|
768
|
-
e.currentTarget.style.background = "rgba(30, 34, 52, 0.95)";
|
|
769
|
-
e.currentTarget.style.borderColor = "rgba(157, 112, 255, 0.4)";
|
|
854
|
+
letterSpacing: "0.03em",
|
|
855
|
+
pointerEvents: "auto"
|
|
770
856
|
},
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "3" }),
|
|
778
|
-
/* @__PURE__ */ jsx("path", { d: "M12 2v4M12 18v4M2 12h4M18 12h4" })
|
|
779
|
-
] }),
|
|
780
|
-
"Recenter"
|
|
781
|
-
]
|
|
857
|
+
onMouseEnter: ctrlHover,
|
|
858
|
+
onMouseLeave: ctrlLeave,
|
|
859
|
+
children: /* @__PURE__ */ jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", children: [
|
|
860
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "3" }),
|
|
861
|
+
/* @__PURE__ */ jsx("path", { d: "M12 2v4M12 18v4M2 12h4M18 12h4" })
|
|
862
|
+
] })
|
|
782
863
|
}
|
|
783
864
|
),
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
onClick: () => setTileStyle(style),
|
|
801
|
-
title: style === "dark" ? "Dark ops map" : "Satellite imagery",
|
|
802
|
-
"aria-label": style === "dark" ? "Dark map style" : "Satellite imagery",
|
|
803
|
-
"aria-pressed": tileStyle === style,
|
|
804
|
-
style: {
|
|
805
|
-
background: tileStyle === style ? "rgba(157, 112, 255, 0.22)" : "transparent",
|
|
806
|
-
border: "none",
|
|
807
|
-
borderRight: style === "dark" ? "1px solid rgba(120, 100, 180, 0.15)" : "none",
|
|
808
|
-
color: tileStyle === style ? "#d0c4ee" : "#7a748e",
|
|
809
|
-
cursor: "pointer",
|
|
810
|
-
padding: "5px 8px",
|
|
811
|
-
fontSize: 10,
|
|
812
|
-
fontWeight: tileStyle === style ? 600 : 400,
|
|
813
|
-
display: "flex",
|
|
814
|
-
alignItems: "center",
|
|
815
|
-
gap: 4,
|
|
816
|
-
transition: "all 0.15s ease",
|
|
817
|
-
letterSpacing: "0.02em"
|
|
818
|
-
},
|
|
819
|
-
children: [
|
|
820
|
-
style === "dark" ? /* @__PURE__ */ jsx("svg", { width: "11", height: "11", viewBox: "0 0 24 24", fill: "currentColor", stroke: "none", children: /* @__PURE__ */ jsx("path", { d: "M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z" }) }) : /* @__PURE__ */ jsxs("svg", { width: "11", height: "11", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
821
|
-
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
|
|
822
|
-
/* @__PURE__ */ jsx("path", { d: "M2 12h20M12 2a15.3 15.3 0 014 10 15.3 15.3 0 01-4 10 15.3 15.3 0 01-4-10 15.3 15.3 0 014-10z" })
|
|
823
|
-
] }),
|
|
824
|
-
style === "dark" ? "Dark" : "Satellite"
|
|
825
|
-
]
|
|
865
|
+
/* @__PURE__ */ jsxs("div", { ref: layersPanelRef, style: { position: "relative", pointerEvents: "auto" }, children: [
|
|
866
|
+
/* @__PURE__ */ jsx(
|
|
867
|
+
"button",
|
|
868
|
+
{
|
|
869
|
+
type: "button",
|
|
870
|
+
onClick: () => setLayersPanelOpen((o) => !o),
|
|
871
|
+
title: "Map layers",
|
|
872
|
+
"aria-label": "Toggle map layers panel",
|
|
873
|
+
"aria-expanded": layersPanelOpen,
|
|
874
|
+
style: {
|
|
875
|
+
...ctrlBtnBase,
|
|
876
|
+
borderRadius: 4,
|
|
877
|
+
padding: "6px 8px",
|
|
878
|
+
pointerEvents: "auto",
|
|
879
|
+
borderColor: layersPanelOpen ? "rgba(157, 112, 255, 0.4)" : void 0,
|
|
880
|
+
background: layersPanelOpen ? "rgba(30, 34, 52, 0.95)" : ctrlBtnBase.background
|
|
826
881
|
},
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
882
|
+
onMouseEnter: ctrlHover,
|
|
883
|
+
onMouseLeave: ctrlLeave,
|
|
884
|
+
children: /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinejoin: "round", children: [
|
|
885
|
+
/* @__PURE__ */ jsx("path", { d: "M12 2L2 7l10 5 10-5-10-5z" }),
|
|
886
|
+
/* @__PURE__ */ jsx("path", { d: "M2 17l10 5 10-5" }),
|
|
887
|
+
/* @__PURE__ */ jsx("path", { d: "M2 12l10 5 10-5" })
|
|
888
|
+
] })
|
|
889
|
+
}
|
|
890
|
+
),
|
|
891
|
+
layersPanelOpen && /* @__PURE__ */ jsxs(
|
|
892
|
+
"div",
|
|
893
|
+
{
|
|
894
|
+
style: {
|
|
895
|
+
position: "absolute",
|
|
896
|
+
top: "calc(100% + 6px)",
|
|
897
|
+
right: 0,
|
|
898
|
+
minWidth: 180,
|
|
899
|
+
background: "rgba(16, 18, 30, 0.96)",
|
|
900
|
+
backdropFilter: "blur(16px)",
|
|
901
|
+
WebkitBackdropFilter: "blur(16px)",
|
|
902
|
+
border: "1px solid rgba(120, 100, 180, 0.18)",
|
|
903
|
+
borderRadius: 6,
|
|
904
|
+
padding: "8px 0",
|
|
905
|
+
boxShadow: "0 8px 32px rgba(0,0,0,0.5)"
|
|
906
|
+
},
|
|
907
|
+
children: [
|
|
908
|
+
!isExplicitTileUrl && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
909
|
+
/* @__PURE__ */ jsx("div", { style: {
|
|
910
|
+
padding: "4px 12px 6px",
|
|
911
|
+
fontSize: 9,
|
|
912
|
+
fontWeight: 600,
|
|
913
|
+
letterSpacing: "0.08em",
|
|
914
|
+
textTransform: "uppercase",
|
|
915
|
+
color: "#7a748e"
|
|
916
|
+
}, children: "Base Map" }),
|
|
917
|
+
/* @__PURE__ */ jsx("div", { style: { display: "flex", gap: 2, padding: "0 8px 8px" }, children: ["dark", "satellite"].map((style) => /* @__PURE__ */ jsxs(
|
|
918
|
+
"button",
|
|
919
|
+
{
|
|
920
|
+
type: "button",
|
|
921
|
+
onClick: () => handleTileStyleChange(style),
|
|
922
|
+
"aria-pressed": tileStyle === style,
|
|
923
|
+
style: {
|
|
924
|
+
flex: 1,
|
|
925
|
+
background: tileStyle === style ? "rgba(157, 112, 255, 0.18)" : "rgba(255,255,255,0.03)",
|
|
926
|
+
border: `1px solid ${tileStyle === style ? "rgba(157, 112, 255, 0.35)" : "rgba(120, 100, 180, 0.1)"}`,
|
|
927
|
+
borderRadius: 4,
|
|
928
|
+
color: tileStyle === style ? "#d0c4ee" : "#7a748e",
|
|
929
|
+
cursor: "pointer",
|
|
930
|
+
padding: "5px 6px",
|
|
931
|
+
fontSize: 10,
|
|
932
|
+
fontWeight: tileStyle === style ? 600 : 400,
|
|
933
|
+
display: "flex",
|
|
934
|
+
alignItems: "center",
|
|
935
|
+
justifyContent: "center",
|
|
936
|
+
gap: 4,
|
|
937
|
+
transition: "all 0.15s ease"
|
|
938
|
+
},
|
|
939
|
+
children: [
|
|
940
|
+
style === "dark" ? /* @__PURE__ */ jsx("svg", { width: "10", height: "10", viewBox: "0 0 24 24", fill: "currentColor", stroke: "none", children: /* @__PURE__ */ jsx("path", { d: "M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z" }) }) : /* @__PURE__ */ jsxs("svg", { width: "10", height: "10", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
941
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
|
|
942
|
+
/* @__PURE__ */ jsx("path", { d: "M2 12h20M12 2a15.3 15.3 0 014 10 15.3 15.3 0 01-4 10 15.3 15.3 0 01-4-10 15.3 15.3 0 014-10z" })
|
|
943
|
+
] }),
|
|
944
|
+
style === "dark" ? "Dark" : "Satellite"
|
|
945
|
+
]
|
|
946
|
+
},
|
|
947
|
+
style
|
|
948
|
+
)) }),
|
|
949
|
+
/* @__PURE__ */ jsx("div", { style: { height: 1, background: "rgba(120, 100, 180, 0.1)", margin: "0 8px" } })
|
|
950
|
+
] }),
|
|
951
|
+
/* @__PURE__ */ jsx("div", { style: {
|
|
952
|
+
padding: `${isExplicitTileUrl ? "4px" : "8px"} 12px 4px`,
|
|
953
|
+
fontSize: 9,
|
|
954
|
+
fontWeight: 600,
|
|
955
|
+
letterSpacing: "0.08em",
|
|
956
|
+
textTransform: "uppercase",
|
|
957
|
+
color: "#7a748e"
|
|
958
|
+
}, children: "Overlays" }),
|
|
959
|
+
overlayItems.map((item) => /* @__PURE__ */ jsxs(
|
|
960
|
+
"button",
|
|
961
|
+
{
|
|
962
|
+
type: "button",
|
|
963
|
+
onClick: () => handleLayerToggle(item.id, !item.enabled),
|
|
964
|
+
style: {
|
|
965
|
+
display: "flex",
|
|
966
|
+
alignItems: "center",
|
|
967
|
+
gap: 8,
|
|
968
|
+
width: "100%",
|
|
969
|
+
padding: "5px 12px",
|
|
970
|
+
background: "transparent",
|
|
971
|
+
border: "none",
|
|
972
|
+
color: item.enabled ? "#c8c0d8" : "#5a5470",
|
|
973
|
+
cursor: "pointer",
|
|
974
|
+
fontSize: 11,
|
|
975
|
+
textAlign: "left",
|
|
976
|
+
transition: "background 0.1s"
|
|
977
|
+
},
|
|
978
|
+
onMouseEnter: (e) => {
|
|
979
|
+
e.currentTarget.style.background = "rgba(157, 112, 255, 0.08)";
|
|
980
|
+
},
|
|
981
|
+
onMouseLeave: (e) => {
|
|
982
|
+
e.currentTarget.style.background = "transparent";
|
|
983
|
+
},
|
|
984
|
+
children: [
|
|
985
|
+
/* @__PURE__ */ jsx("span", { style: {
|
|
986
|
+
width: 14,
|
|
987
|
+
height: 14,
|
|
988
|
+
borderRadius: 3,
|
|
989
|
+
border: `1.5px solid ${item.enabled ? "rgba(157, 112, 255, 0.6)" : "rgba(120, 100, 180, 0.25)"}`,
|
|
990
|
+
background: item.enabled ? "rgba(157, 112, 255, 0.22)" : "transparent",
|
|
991
|
+
display: "flex",
|
|
992
|
+
alignItems: "center",
|
|
993
|
+
justifyContent: "center",
|
|
994
|
+
flexShrink: 0,
|
|
995
|
+
transition: "all 0.15s ease"
|
|
996
|
+
}, children: item.enabled && /* @__PURE__ */ jsx("svg", { width: "9", height: "9", viewBox: "0 0 12 12", fill: "none", stroke: "#d0c4ee", strokeWidth: "2", children: /* @__PURE__ */ jsx("path", { d: "M2 6l3 3 5-5" }) }) }),
|
|
997
|
+
item.label
|
|
998
|
+
]
|
|
999
|
+
},
|
|
1000
|
+
item.id
|
|
1001
|
+
))
|
|
1002
|
+
]
|
|
1003
|
+
}
|
|
1004
|
+
)
|
|
1005
|
+
] }),
|
|
1006
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", pointerEvents: "auto" }, children: [
|
|
1007
|
+
/* @__PURE__ */ jsx(
|
|
1008
|
+
"button",
|
|
1009
|
+
{
|
|
1010
|
+
type: "button",
|
|
1011
|
+
onClick: handleZoomIn,
|
|
1012
|
+
title: "Zoom in",
|
|
1013
|
+
"aria-label": "Zoom in",
|
|
1014
|
+
style: {
|
|
1015
|
+
...ctrlBtnBase,
|
|
1016
|
+
borderRadius: "4px 4px 0 0",
|
|
1017
|
+
borderBottom: "none",
|
|
1018
|
+
width: 30,
|
|
1019
|
+
height: 28,
|
|
1020
|
+
fontSize: 16,
|
|
1021
|
+
fontWeight: 300,
|
|
1022
|
+
pointerEvents: "auto"
|
|
1023
|
+
},
|
|
1024
|
+
onMouseEnter: ctrlHover,
|
|
1025
|
+
onMouseLeave: ctrlLeave,
|
|
1026
|
+
children: "+"
|
|
1027
|
+
}
|
|
1028
|
+
),
|
|
1029
|
+
/* @__PURE__ */ jsx(
|
|
1030
|
+
"button",
|
|
1031
|
+
{
|
|
1032
|
+
type: "button",
|
|
1033
|
+
onClick: handleZoomOut,
|
|
1034
|
+
title: "Zoom out",
|
|
1035
|
+
"aria-label": "Zoom out",
|
|
1036
|
+
style: {
|
|
1037
|
+
...ctrlBtnBase,
|
|
1038
|
+
borderRadius: "0 0 4px 4px",
|
|
1039
|
+
width: 30,
|
|
1040
|
+
height: 28,
|
|
1041
|
+
fontSize: 16,
|
|
1042
|
+
fontWeight: 300,
|
|
1043
|
+
pointerEvents: "auto"
|
|
1044
|
+
},
|
|
1045
|
+
onMouseEnter: ctrlHover,
|
|
1046
|
+
onMouseLeave: ctrlLeave,
|
|
1047
|
+
children: "−"
|
|
1048
|
+
}
|
|
1049
|
+
)
|
|
1050
|
+
] })
|
|
831
1051
|
]
|
|
832
1052
|
}
|
|
833
1053
|
)
|