@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.
@@ -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, useCallback, useEffect } from "react";
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 [tileStyle, setTileStyle] = useState("dark");
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 && showTerminator) {
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 (showTerminator) {
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 && showTerminator) {
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 (showGrid) {
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
- showTerminator,
649
+ internalTerminator,
587
650
  terminatorTime,
588
651
  nightTileUrl,
589
652
  lightSources,
590
- showGrid,
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
- (showRecenterButton || showMapStyleToggle && !isExplicitTileUrl) && /* @__PURE__ */ jsxs(
825
+ /* @__PURE__ */ jsxs(
729
826
  "div",
730
827
  {
731
- className: "zendir-map-controls",
732
828
  style: {
733
829
  position: "absolute",
734
- bottom: 28,
735
- left: 10,
830
+ top: 10,
831
+ right: 10,
736
832
  zIndex: 1e3,
737
833
  display: "flex",
738
834
  flexDirection: "row",
739
- gap: 6,
740
- alignItems: "flex-end"
835
+ gap: 4,
836
+ alignItems: "flex-start",
837
+ pointerEvents: "none"
741
838
  },
742
839
  children: [
743
- showRecenterButton && /* @__PURE__ */ jsxs(
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
- background: "rgba(20, 24, 38, 0.92)",
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
- color: "#c8c0d8",
757
- cursor: "pointer",
758
- padding: "6px 10px",
759
- fontSize: 11,
850
+ padding: "6px 8px",
851
+ gap: 4,
852
+ fontSize: 10,
760
853
  fontWeight: 500,
761
- display: "flex",
762
- alignItems: "center",
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
- onMouseLeave: (e) => {
772
- e.currentTarget.style.background = "rgba(20, 24, 38, 0.92)";
773
- e.currentTarget.style.borderColor = "rgba(120, 100, 180, 0.2)";
774
- },
775
- children: [
776
- /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
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
- showMapStyleToggle && !isExplicitTileUrl && /* @__PURE__ */ jsx(
785
- "div",
786
- {
787
- style: {
788
- background: "rgba(20, 24, 38, 0.92)",
789
- backdropFilter: "blur(8px)",
790
- WebkitBackdropFilter: "blur(8px)",
791
- border: "1px solid rgba(120, 100, 180, 0.2)",
792
- borderRadius: 4,
793
- display: "flex",
794
- overflow: "hidden"
795
- },
796
- children: ["dark", "satellite"].map((style) => /* @__PURE__ */ jsxs(
797
- "button",
798
- {
799
- type: "button",
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
- style
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
  )