@dxos/react-ui-geo 0.8.4-main.84f28bd → 0.8.4-main.ae835ea
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/data/airports.ts +1 -1
- package/data/cities.ts +1 -1
- package/data/countries-110m.ts +1 -1
- package/data/countries-dots-3.ts +1 -1
- package/data/countries-dots-4.ts +1 -1
- package/dist/lib/browser/chunk-GMWLKTLN.mjs +9 -0
- package/dist/lib/browser/{countries-110m-37VAAFCK.mjs → countries-110m-ZM3ZIEFS.mjs} +1 -1
- package/dist/lib/browser/countries-110m-ZM3ZIEFS.mjs.map +7 -0
- package/dist/lib/browser/data.mjs +1 -1
- package/dist/lib/browser/index.mjs +187 -163
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/{chunk-OPJPAAEK.mjs → chunk-JODBF4CC.mjs} +2 -2
- package/dist/lib/node-esm/{countries-110m-36TTKK5B.mjs → countries-110m-3SFASWVD.mjs} +1 -1
- package/dist/lib/node-esm/countries-110m-3SFASWVD.mjs.map +7 -0
- package/dist/lib/node-esm/data.mjs +1 -1
- package/dist/lib/node-esm/index.mjs +187 -163
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/Globe/Globe.d.ts +1 -1
- package/dist/types/src/components/Globe/Globe.d.ts.map +1 -1
- package/dist/types/src/components/Globe/Globe.stories.d.ts +25 -9
- package/dist/types/src/components/Globe/Globe.stories.d.ts.map +1 -1
- package/dist/types/src/components/Map/Map.d.ts +27 -17
- package/dist/types/src/components/Map/Map.d.ts.map +1 -1
- package/dist/types/src/components/Map/Map.stories.d.ts +14 -8
- package/dist/types/src/components/Map/Map.stories.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Controls.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +0 -1
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/hooks/context.d.ts +7 -7
- package/dist/types/src/hooks/context.d.ts.map +1 -1
- package/dist/types/src/hooks/useGlobeZoomHandler.d.ts +1 -1
- package/dist/types/src/hooks/useGlobeZoomHandler.d.ts.map +1 -1
- package/dist/types/src/hooks/useMapZoomHandler.d.ts +1 -1
- package/dist/types/src/hooks/useMapZoomHandler.d.ts.map +1 -1
- package/dist/types/src/hooks/useSpinner.d.ts +1 -1
- package/dist/types/src/hooks/useSpinner.d.ts.map +1 -1
- package/dist/types/src/hooks/useTour.d.ts +4 -3
- package/dist/types/src/hooks/useTour.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +2 -1
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/src/util/path.d.ts +5 -8
- package/dist/types/src/util/path.d.ts.map +1 -1
- package/dist/types/src/util/render.d.ts +4 -4
- package/dist/types/src/util/render.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +22 -19
- package/src/components/Globe/Globe.stories.tsx +81 -33
- package/src/components/Globe/Globe.tsx +78 -61
- package/src/components/Map/Map.stories.tsx +25 -14
- package/src/components/Map/Map.tsx +180 -95
- package/src/components/Toolbar/Controls.tsx +2 -6
- package/src/components/index.ts +0 -2
- package/src/hooks/context.tsx +22 -16
- package/src/hooks/useGlobeZoomHandler.ts +9 -3
- package/src/hooks/useMapZoomHandler.ts +1 -1
- package/src/hooks/useSpinner.ts +2 -1
- package/src/hooks/useTour.ts +9 -8
- package/src/index.ts +1 -1
- package/src/types.ts +3 -1
- package/src/util/inertia.ts +1 -1
- package/src/util/path.ts +5 -6
- package/src/util/render.ts +5 -3
- package/dist/lib/browser/chunk-CYCBMCOP.mjs +0 -9
- package/dist/lib/browser/countries-110m-37VAAFCK.mjs.map +0 -7
- package/dist/lib/node-esm/countries-110m-36TTKK5B.mjs.map +0 -7
- package/dist/types/src/components/types.d.ts +0 -15
- package/dist/types/src/components/types.d.ts.map +0 -1
- package/src/components/types.ts +0 -19
- /package/dist/lib/browser/{chunk-CYCBMCOP.mjs.map → chunk-GMWLKTLN.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-OPJPAAEK.mjs.map → chunk-JODBF4CC.mjs.map} +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
loadTopology
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-GMWLKTLN.mjs";
|
|
4
4
|
|
|
5
5
|
// src/components/Globe/Globe.tsx
|
|
6
6
|
import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
|
|
7
|
-
import { geoMercator, geoOrthographic, geoPath as geoPath2, geoTransverseMercator, interpolateNumber, transition
|
|
7
|
+
import { easeLinear, easeSinOut, geoMercator, geoOrthographic, geoPath as geoPath2, geoTransverseMercator, interpolateNumber, transition } from "d3";
|
|
8
8
|
import React3, { forwardRef, useEffect as useEffect4, useImperativeHandle, useMemo as useMemo2, useRef, useState as useState3 } from "react";
|
|
9
9
|
import { useResizeDetector } from "react-resize-detector";
|
|
10
10
|
import { useDynamicRef, useThemeContext } from "@dxos/react-ui";
|
|
@@ -15,23 +15,30 @@ import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
|
|
|
15
15
|
import React, { createContext, useContext } from "react";
|
|
16
16
|
import { raise } from "@dxos/debug";
|
|
17
17
|
import { useControlledState } from "@dxos/react-ui";
|
|
18
|
+
var defaults = {
|
|
19
|
+
center: {
|
|
20
|
+
lat: 51,
|
|
21
|
+
lng: 0
|
|
22
|
+
},
|
|
23
|
+
zoom: 4
|
|
24
|
+
};
|
|
18
25
|
var GlobeContext = /* @__PURE__ */ createContext(void 0);
|
|
19
|
-
var GlobeContextProvider = ({ children, size, center:
|
|
26
|
+
var GlobeContextProvider = ({ children, size, center: centerParam = defaults.center, zoom: zoomParam = defaults.zoom, translation: translationParam, rotation: rotationParam }) => {
|
|
20
27
|
var _effect = _useSignals();
|
|
21
28
|
try {
|
|
22
|
-
const [center, setCenter] = useControlledState(
|
|
23
|
-
const [
|
|
24
|
-
const [translation, setTranslation] = useControlledState(
|
|
25
|
-
const [rotation, setRotation] = useControlledState(
|
|
29
|
+
const [center, setCenter] = useControlledState(centerParam);
|
|
30
|
+
const [zoom, setZoom] = useControlledState(zoomParam);
|
|
31
|
+
const [translation, setTranslation] = useControlledState(translationParam);
|
|
32
|
+
const [rotation, setRotation] = useControlledState(rotationParam);
|
|
26
33
|
return /* @__PURE__ */ React.createElement(GlobeContext.Provider, {
|
|
27
34
|
value: {
|
|
28
35
|
size,
|
|
29
36
|
center,
|
|
30
|
-
|
|
37
|
+
zoom,
|
|
31
38
|
translation,
|
|
32
39
|
rotation,
|
|
33
40
|
setCenter,
|
|
34
|
-
|
|
41
|
+
setZoom,
|
|
35
42
|
setTranslation,
|
|
36
43
|
setRotation
|
|
37
44
|
}
|
|
@@ -64,7 +71,7 @@ var timer = (cb) => {
|
|
|
64
71
|
};
|
|
65
72
|
|
|
66
73
|
// src/util/inertia.ts
|
|
67
|
-
import {
|
|
74
|
+
import { drag, select, timer as timer2 } from "d3";
|
|
68
75
|
import versor from "versor";
|
|
69
76
|
var restrictAxis = (axis) => (original, current) => current.map((d, i) => axis[i] ? d : original[i]);
|
|
70
77
|
var geoInertiaDrag = (target, render, projection, options) => {
|
|
@@ -427,6 +434,7 @@ var cancelDrag = (node) => node.on(".drag", null);
|
|
|
427
434
|
|
|
428
435
|
// src/hooks/useGlobeZoomHandler.ts
|
|
429
436
|
import { useCallback } from "react";
|
|
437
|
+
var ZOOM_FACTOR = 0.1;
|
|
430
438
|
var useGlobeZoomHandler = (controller) => {
|
|
431
439
|
return useCallback((event) => {
|
|
432
440
|
if (!controller) {
|
|
@@ -434,11 +442,15 @@ var useGlobeZoomHandler = (controller) => {
|
|
|
434
442
|
}
|
|
435
443
|
switch (event) {
|
|
436
444
|
case "zoom-in": {
|
|
437
|
-
controller.
|
|
445
|
+
controller.setZoom((zoom) => {
|
|
446
|
+
return zoom * (1 + ZOOM_FACTOR);
|
|
447
|
+
});
|
|
438
448
|
break;
|
|
439
449
|
}
|
|
440
450
|
case "zoom-out": {
|
|
441
|
-
controller.
|
|
451
|
+
controller.setZoom((zoom) => {
|
|
452
|
+
return zoom * (1 - ZOOM_FACTOR);
|
|
453
|
+
});
|
|
442
454
|
break;
|
|
443
455
|
}
|
|
444
456
|
}
|
|
@@ -523,8 +535,8 @@ var useSpinner = (controller, options = {}) => {
|
|
|
523
535
|
};
|
|
524
536
|
|
|
525
537
|
// src/hooks/useTour.ts
|
|
526
|
-
import {
|
|
527
|
-
import { useEffect as useEffect3, useState as useState2
|
|
538
|
+
import { selection as d3Selection, geoDistance, geoInterpolate, geoPath } from "d3";
|
|
539
|
+
import { useEffect as useEffect3, useMemo, useState as useState2 } from "react";
|
|
528
540
|
import versor2 from "versor";
|
|
529
541
|
var TRANSITION_NAME = "globe-tour";
|
|
530
542
|
var defaultDuration = 1500;
|
|
@@ -571,7 +583,7 @@ var useTour = (controller, points, options = {}) => {
|
|
|
571
583
|
{
|
|
572
584
|
context.beginPath();
|
|
573
585
|
context.strokeStyle = options?.styles?.arc?.strokeStyle ?? "yellow";
|
|
574
|
-
context.lineWidth = (options?.styles?.arc?.lineWidth ?? 1.5) * (controller?.
|
|
586
|
+
context.lineWidth = (options?.styles?.arc?.lineWidth ?? 1.5) * (controller?.zoom ?? 1);
|
|
575
587
|
context.setLineDash(options?.styles?.arc?.lineDash ?? []);
|
|
576
588
|
path({
|
|
577
589
|
type: "LineString",
|
|
@@ -583,7 +595,7 @@ var useTour = (controller, points, options = {}) => {
|
|
|
583
595
|
context.stroke();
|
|
584
596
|
context.beginPath();
|
|
585
597
|
context.fillStyle = options?.styles?.cursor?.fillStyle ?? "orange";
|
|
586
|
-
path.pointRadius((options?.styles?.cursor?.pointRadius ?? 2) * (controller?.
|
|
598
|
+
path.pointRadius((options?.styles?.cursor?.pointRadius ?? 2) * (controller?.zoom ?? 1));
|
|
587
599
|
path({
|
|
588
600
|
type: "Point",
|
|
589
601
|
coordinates: ip(t22)
|
|
@@ -597,7 +609,7 @@ var useTour = (controller, points, options = {}) => {
|
|
|
597
609
|
await transition2.end();
|
|
598
610
|
last = next;
|
|
599
611
|
}
|
|
600
|
-
} catch
|
|
612
|
+
} catch {
|
|
601
613
|
} finally {
|
|
602
614
|
setRunning(false);
|
|
603
615
|
}
|
|
@@ -633,11 +645,10 @@ var ZoomControls = ({ classNames, onAction }) => {
|
|
|
633
645
|
try {
|
|
634
646
|
return /* @__PURE__ */ React2.createElement(Toolbar.Root, {
|
|
635
647
|
classNames: [
|
|
636
|
-
"gap-
|
|
648
|
+
"gap-2",
|
|
637
649
|
classNames
|
|
638
650
|
]
|
|
639
651
|
}, /* @__PURE__ */ React2.createElement(IconButton, {
|
|
640
|
-
//
|
|
641
652
|
icon: "ph--plus--regular",
|
|
642
653
|
label: "zoom in",
|
|
643
654
|
iconOnly: true,
|
|
@@ -645,7 +656,6 @@ var ZoomControls = ({ classNames, onAction }) => {
|
|
|
645
656
|
classNames: "px-0 aspect-square",
|
|
646
657
|
onClick: () => onAction?.("zoom-in")
|
|
647
658
|
}), /* @__PURE__ */ React2.createElement(IconButton, {
|
|
648
|
-
//
|
|
649
659
|
icon: "ph--minus--regular",
|
|
650
660
|
label: "zoom out",
|
|
651
661
|
iconOnly: true,
|
|
@@ -662,11 +672,10 @@ var ActionControls = ({ classNames, onAction }) => {
|
|
|
662
672
|
try {
|
|
663
673
|
return /* @__PURE__ */ React2.createElement(Toolbar.Root, {
|
|
664
674
|
classNames: [
|
|
665
|
-
"gap-
|
|
675
|
+
"gap-2",
|
|
666
676
|
classNames
|
|
667
677
|
]
|
|
668
678
|
}, /* @__PURE__ */ React2.createElement(IconButton, {
|
|
669
|
-
//
|
|
670
679
|
icon: "ph--play--regular",
|
|
671
680
|
label: "start",
|
|
672
681
|
iconOnly: true,
|
|
@@ -674,7 +683,6 @@ var ActionControls = ({ classNames, onAction }) => {
|
|
|
674
683
|
classNames: "px-0 aspect-square",
|
|
675
684
|
onClick: () => onAction?.("start")
|
|
676
685
|
}), /* @__PURE__ */ React2.createElement(IconButton, {
|
|
677
|
-
//
|
|
678
686
|
icon: "ph--globe-hemisphere-west--regular",
|
|
679
687
|
label: "toggle",
|
|
680
688
|
iconOnly: true,
|
|
@@ -760,18 +768,18 @@ var GlobeRoot = ({ classNames, children, ...props }) => {
|
|
|
760
768
|
_effect.f();
|
|
761
769
|
}
|
|
762
770
|
};
|
|
763
|
-
var GlobeCanvas = /* @__PURE__ */ forwardRef(({ projection:
|
|
771
|
+
var GlobeCanvas = /* @__PURE__ */ forwardRef(({ projection: projectionParam, topology, features, styles: stylesParam }, forwardRef3) => {
|
|
764
772
|
var _effect = _useSignals3();
|
|
765
773
|
try {
|
|
766
774
|
const { themeMode } = useThemeContext();
|
|
767
|
-
const styles = useMemo2(() =>
|
|
768
|
-
|
|
775
|
+
const styles = useMemo2(() => stylesParam ?? defaultStyles[themeMode], [
|
|
776
|
+
stylesParam,
|
|
769
777
|
themeMode
|
|
770
778
|
]);
|
|
771
779
|
const [canvas, setCanvas] = useState3(null);
|
|
772
780
|
const canvasRef = (canvas2) => setCanvas(canvas2);
|
|
773
|
-
const projection = useMemo2(() => getProjection(
|
|
774
|
-
|
|
781
|
+
const projection = useMemo2(() => getProjection(projectionParam), [
|
|
782
|
+
projectionParam
|
|
775
783
|
]);
|
|
776
784
|
const layers = useMemo2(() => {
|
|
777
785
|
return timer(() => createLayers(topology, features, styles));
|
|
@@ -780,11 +788,11 @@ var GlobeCanvas = /* @__PURE__ */ forwardRef(({ projection: _projection, topolog
|
|
|
780
788
|
features,
|
|
781
789
|
styles
|
|
782
790
|
]);
|
|
783
|
-
const { size, center,
|
|
784
|
-
const
|
|
791
|
+
const { size, center, zoom, translation, rotation, setCenter, setZoom, setTranslation, setRotation } = useGlobeContext();
|
|
792
|
+
const zoomRef = useDynamicRef(zoom);
|
|
785
793
|
useEffect4(() => {
|
|
786
794
|
if (center) {
|
|
787
|
-
|
|
795
|
+
setZoom(1);
|
|
788
796
|
setRotation(positionToRotation(geoToPosition(center)));
|
|
789
797
|
}
|
|
790
798
|
}, [
|
|
@@ -796,20 +804,20 @@ var GlobeCanvas = /* @__PURE__ */ forwardRef(({ projection: _projection, topolog
|
|
|
796
804
|
canvas,
|
|
797
805
|
projection,
|
|
798
806
|
center,
|
|
799
|
-
get
|
|
800
|
-
return
|
|
807
|
+
get zoom() {
|
|
808
|
+
return zoomRef.current;
|
|
801
809
|
},
|
|
802
810
|
translation,
|
|
803
811
|
rotation,
|
|
804
812
|
setCenter,
|
|
805
|
-
|
|
813
|
+
setZoom: (s) => {
|
|
806
814
|
if (typeof s === "function") {
|
|
807
|
-
const is = interpolateNumber(
|
|
808
|
-
transition().ease(zooming.current ? easeLinear : easeSinOut).duration(200).tween("scale", () => (t) =>
|
|
815
|
+
const is = interpolateNumber(zoomRef.current, s(zoomRef.current));
|
|
816
|
+
transition().ease(zooming.current ? easeLinear : easeSinOut).duration(200).tween("scale", () => (t) => setZoom(is(t))).on("end", () => {
|
|
809
817
|
zooming.current = false;
|
|
810
818
|
});
|
|
811
819
|
} else {
|
|
812
|
-
|
|
820
|
+
setZoom(s);
|
|
813
821
|
}
|
|
814
822
|
},
|
|
815
823
|
setTranslation,
|
|
@@ -827,7 +835,7 @@ var GlobeCanvas = /* @__PURE__ */ forwardRef(({ projection: _projection, topolog
|
|
|
827
835
|
useEffect4(() => {
|
|
828
836
|
if (canvas && projection) {
|
|
829
837
|
timer(() => {
|
|
830
|
-
projection.scale(Math.min(size.width, size.height) / 2 *
|
|
838
|
+
projection.scale(Math.min(size.width, size.height) / 2 * zoom).translate([
|
|
831
839
|
size.width / 2 + (translation?.x ?? 0),
|
|
832
840
|
size.height / 2 + (translation?.y ?? 0)
|
|
833
841
|
]).rotate(rotation ?? [
|
|
@@ -835,13 +843,13 @@ var GlobeCanvas = /* @__PURE__ */ forwardRef(({ projection: _projection, topolog
|
|
|
835
843
|
0,
|
|
836
844
|
0
|
|
837
845
|
]);
|
|
838
|
-
renderLayers(generator, layers,
|
|
846
|
+
renderLayers(generator, layers, zoom, styles);
|
|
839
847
|
});
|
|
840
848
|
}
|
|
841
849
|
}, [
|
|
842
850
|
generator,
|
|
843
851
|
size,
|
|
844
|
-
|
|
852
|
+
zoom,
|
|
845
853
|
translation,
|
|
846
854
|
rotation,
|
|
847
855
|
layers
|
|
@@ -861,14 +869,14 @@ var GlobeCanvas = /* @__PURE__ */ forwardRef(({ projection: _projection, topolog
|
|
|
861
869
|
var GlobeDebug = ({ position = "topleft" }) => {
|
|
862
870
|
var _effect = _useSignals3();
|
|
863
871
|
try {
|
|
864
|
-
const { size,
|
|
872
|
+
const { size, zoom, translation, rotation } = useGlobeContext();
|
|
865
873
|
return /* @__PURE__ */ React3.createElement("div", {
|
|
866
874
|
className: mx("z-10 absolute w-96 p-2 overflow-hidden border border-green-700 rounded", controlPositions[position])
|
|
867
875
|
}, /* @__PURE__ */ React3.createElement("pre", {
|
|
868
876
|
className: "font-mono text-xs text-green-700"
|
|
869
877
|
}, JSON.stringify({
|
|
870
878
|
size,
|
|
871
|
-
|
|
879
|
+
zoom,
|
|
872
880
|
translation,
|
|
873
881
|
rotation
|
|
874
882
|
}, null, 2)));
|
|
@@ -896,35 +904,37 @@ var CustomControl = ({ position, children }) => {
|
|
|
896
904
|
_effect.f();
|
|
897
905
|
}
|
|
898
906
|
};
|
|
907
|
+
var GlobeZoom = ({ onAction, position = "bottomleft", ...props }) => {
|
|
908
|
+
var _effect = _useSignals3();
|
|
909
|
+
try {
|
|
910
|
+
return /* @__PURE__ */ React3.createElement(CustomControl, {
|
|
911
|
+
position,
|
|
912
|
+
...props
|
|
913
|
+
}, /* @__PURE__ */ React3.createElement(ZoomControls, {
|
|
914
|
+
onAction
|
|
915
|
+
}));
|
|
916
|
+
} finally {
|
|
917
|
+
_effect.f();
|
|
918
|
+
}
|
|
919
|
+
};
|
|
920
|
+
var GlobeAction = ({ onAction, position = "bottomright", ...props }) => {
|
|
921
|
+
var _effect = _useSignals3();
|
|
922
|
+
try {
|
|
923
|
+
return /* @__PURE__ */ React3.createElement(CustomControl, {
|
|
924
|
+
position,
|
|
925
|
+
...props
|
|
926
|
+
}, /* @__PURE__ */ React3.createElement(ActionControls, {
|
|
927
|
+
onAction
|
|
928
|
+
}));
|
|
929
|
+
} finally {
|
|
930
|
+
_effect.f();
|
|
931
|
+
}
|
|
932
|
+
};
|
|
899
933
|
var Globe = {
|
|
900
934
|
Root: GlobeRoot,
|
|
901
935
|
Canvas: GlobeCanvas,
|
|
902
|
-
Zoom:
|
|
903
|
-
|
|
904
|
-
try {
|
|
905
|
-
return /* @__PURE__ */ React3.createElement(CustomControl, {
|
|
906
|
-
position,
|
|
907
|
-
...props
|
|
908
|
-
}, /* @__PURE__ */ React3.createElement(ZoomControls, {
|
|
909
|
-
onAction
|
|
910
|
-
}));
|
|
911
|
-
} finally {
|
|
912
|
-
_effect.f();
|
|
913
|
-
}
|
|
914
|
-
},
|
|
915
|
-
Action: ({ onAction, position = "bottomright", ...props }) => {
|
|
916
|
-
var _effect = _useSignals3();
|
|
917
|
-
try {
|
|
918
|
-
return /* @__PURE__ */ React3.createElement(CustomControl, {
|
|
919
|
-
position,
|
|
920
|
-
...props
|
|
921
|
-
}, /* @__PURE__ */ React3.createElement(ActionControls, {
|
|
922
|
-
onAction
|
|
923
|
-
}));
|
|
924
|
-
} finally {
|
|
925
|
-
_effect.f();
|
|
926
|
-
}
|
|
927
|
-
},
|
|
936
|
+
Zoom: GlobeZoom,
|
|
937
|
+
Action: GlobeAction,
|
|
928
938
|
Debug: GlobeDebug,
|
|
929
939
|
Panel: GlobePanel
|
|
930
940
|
};
|
|
@@ -932,108 +942,117 @@ var Globe = {
|
|
|
932
942
|
// src/components/Map/Map.tsx
|
|
933
943
|
import { useSignals as _useSignals4 } from "@preact-signals/safe-react/tracking";
|
|
934
944
|
import "leaflet/dist/leaflet.css";
|
|
945
|
+
import { createContext as createContext2 } from "@radix-ui/react-context";
|
|
935
946
|
import L, { Control, DomEvent, DomUtil, latLngBounds } from "leaflet";
|
|
936
|
-
import React4, { forwardRef as forwardRef2, useEffect as useEffect5, useImperativeHandle as useImperativeHandle2 } from "react";
|
|
947
|
+
import React4, { forwardRef as forwardRef2, useEffect as useEffect5, useImperativeHandle as useImperativeHandle2, useRef as useRef2, useState as useState4 } from "react";
|
|
937
948
|
import { createRoot } from "react-dom/client";
|
|
938
|
-
import { MapContainer, Marker, Popup, TileLayer, useMap } from "react-leaflet";
|
|
939
|
-
import { useResizeDetector as useResizeDetector2 } from "react-resize-detector";
|
|
940
|
-
import { debounce } from "@dxos/async";
|
|
949
|
+
import { MapContainer, Marker, Popup, TileLayer, useMap, useMapEvents } from "react-leaflet";
|
|
941
950
|
import { ThemeProvider, Tooltip } from "@dxos/react-ui";
|
|
942
951
|
import { defaultTx, mx as mx2 } from "@dxos/react-ui-theme";
|
|
943
|
-
var
|
|
944
|
-
// TODO(burdon): Guess location.
|
|
952
|
+
var defaults2 = {
|
|
945
953
|
center: {
|
|
946
954
|
lat: 51,
|
|
947
955
|
lng: 0
|
|
948
956
|
},
|
|
949
957
|
zoom: 4
|
|
950
958
|
};
|
|
951
|
-
var
|
|
959
|
+
var [MapContextProvier, useMapContext] = createContext2("Map");
|
|
960
|
+
var MapRoot = /* @__PURE__ */ forwardRef2(({ classNames, scrollWheelZoom = true, doubleClickZoom = true, touchZoom = true, center, zoom, onChange, ...props }, forwardedRef) => {
|
|
952
961
|
var _effect = _useSignals4();
|
|
953
962
|
try {
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
// TODO(burdon): Only if attention.
|
|
958
|
-
scrollWheelZoom: true,
|
|
959
|
-
zoomControl: false,
|
|
960
|
-
center,
|
|
961
|
-
zoom,
|
|
962
|
-
...props
|
|
963
|
-
});
|
|
964
|
-
} finally {
|
|
965
|
-
_effect.f();
|
|
966
|
-
}
|
|
967
|
-
};
|
|
968
|
-
var MapCanvas = /* @__PURE__ */ forwardRef2(({ markers, center, zoom, onChange }, forwardedRef) => {
|
|
969
|
-
var _effect = _useSignals4();
|
|
970
|
-
try {
|
|
971
|
-
const { ref, width, height } = useResizeDetector2({
|
|
972
|
-
refreshRate: 200
|
|
973
|
-
});
|
|
974
|
-
const map = useMap();
|
|
963
|
+
const [attention, setAttention] = useState4(false);
|
|
964
|
+
const mapRef = useRef2(null);
|
|
965
|
+
const map = mapRef.current;
|
|
975
966
|
useImperativeHandle2(forwardedRef, () => ({
|
|
976
967
|
setCenter: (center2, zoom2) => {
|
|
977
|
-
|
|
968
|
+
mapRef.current?.setView(center2, zoom2);
|
|
978
969
|
},
|
|
979
970
|
setZoom: (cb) => {
|
|
980
|
-
|
|
971
|
+
mapRef.current?.setZoom(cb(mapRef.current?.getZoom() ?? 0));
|
|
981
972
|
}
|
|
982
|
-
}), [
|
|
983
|
-
map
|
|
984
|
-
]);
|
|
973
|
+
}), []);
|
|
985
974
|
useEffect5(() => {
|
|
986
|
-
if (
|
|
987
|
-
|
|
975
|
+
if (!map) {
|
|
976
|
+
return;
|
|
988
977
|
}
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
useEffect5(() => {
|
|
994
|
-
if (center) {
|
|
995
|
-
map.setView(center, zoom);
|
|
996
|
-
} else if (zoom !== void 0) {
|
|
997
|
-
map.setZoom(zoom);
|
|
978
|
+
if (attention) {
|
|
979
|
+
map.scrollWheelZoom.enable();
|
|
980
|
+
} else {
|
|
981
|
+
map.scrollWheelZoom.disable();
|
|
998
982
|
}
|
|
999
983
|
}, [
|
|
1000
|
-
|
|
1001
|
-
|
|
984
|
+
map,
|
|
985
|
+
attention
|
|
1002
986
|
]);
|
|
1003
|
-
|
|
1004
|
-
|
|
987
|
+
return /* @__PURE__ */ React4.createElement(MapContextProvier, {
|
|
988
|
+
attention,
|
|
989
|
+
onChange
|
|
990
|
+
}, /* @__PURE__ */ React4.createElement(MapContainer, {
|
|
991
|
+
...props,
|
|
992
|
+
ref: mapRef,
|
|
993
|
+
className: mx2("group relative grid bs-full is-full !bg-baseSurface dx-focus-ring-inset", classNames),
|
|
994
|
+
attributionControl: false,
|
|
995
|
+
zoomControl: false,
|
|
996
|
+
scrollWheelZoom,
|
|
997
|
+
doubleClickZoom,
|
|
998
|
+
touchZoom,
|
|
999
|
+
center: center ?? defaults2.center,
|
|
1000
|
+
zoom: zoom ?? defaults2.zoom
|
|
1001
|
+
}));
|
|
1002
|
+
} finally {
|
|
1003
|
+
_effect.f();
|
|
1004
|
+
}
|
|
1005
|
+
});
|
|
1006
|
+
MapRoot.displayName = "Map.Root";
|
|
1007
|
+
var MapTiles = (_props) => {
|
|
1008
|
+
var _effect = _useSignals4();
|
|
1009
|
+
try {
|
|
1010
|
+
const ref = useRef2(null);
|
|
1011
|
+
const { onChange } = useMapContext(MapTiles.displayName);
|
|
1012
|
+
useMapEvents({
|
|
1013
|
+
zoomstart: (ev) => {
|
|
1005
1014
|
onChange?.({
|
|
1006
|
-
center:
|
|
1007
|
-
zoom:
|
|
1015
|
+
center: ev.target.getCenter(),
|
|
1016
|
+
zoom: ev.target.getZoom()
|
|
1008
1017
|
});
|
|
1009
|
-
}
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
}
|
|
1018
|
+
}
|
|
1019
|
+
});
|
|
1020
|
+
const { attention } = useMapContext(MapTiles.displayName);
|
|
1021
|
+
useEffect5(() => {
|
|
1022
|
+
if (ref.current) {
|
|
1023
|
+
ref.current.getContainer().dataset.attention = attention ? "1" : "0";
|
|
1024
|
+
}
|
|
1016
1025
|
}, [
|
|
1017
|
-
|
|
1018
|
-
onChange
|
|
1026
|
+
attention
|
|
1019
1027
|
]);
|
|
1028
|
+
return /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(TileLayer, {
|
|
1029
|
+
ref,
|
|
1030
|
+
"data-attention": attention,
|
|
1031
|
+
detectRetina: true,
|
|
1032
|
+
className: 'dark:grayscale dark:invert data-[attention="0"]:!opacity-80',
|
|
1033
|
+
url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
|
|
1034
|
+
keepBuffer: 4
|
|
1035
|
+
}));
|
|
1036
|
+
} finally {
|
|
1037
|
+
_effect.f();
|
|
1038
|
+
}
|
|
1039
|
+
};
|
|
1040
|
+
MapTiles.displayName = "Map.Tiles";
|
|
1041
|
+
var MapMarkers = ({ selected, markers }) => {
|
|
1042
|
+
var _effect = _useSignals4();
|
|
1043
|
+
try {
|
|
1044
|
+
const map = useMap();
|
|
1020
1045
|
useEffect5(() => {
|
|
1021
1046
|
if (markers.length > 0) {
|
|
1022
1047
|
const bounds = latLngBounds(markers.map((marker) => marker.location));
|
|
1023
1048
|
map.fitBounds(bounds);
|
|
1024
1049
|
} else {
|
|
1025
|
-
map.setView(
|
|
1050
|
+
map.setView(defaults2.center, defaults2.zoom);
|
|
1026
1051
|
}
|
|
1027
1052
|
}, [
|
|
1028
1053
|
markers
|
|
1029
1054
|
]);
|
|
1030
|
-
return /* @__PURE__ */ React4.createElement(
|
|
1031
|
-
ref,
|
|
1032
|
-
className: "flex w-full h-full overflow-hidden bg-baseSurface"
|
|
1033
|
-
}, /* @__PURE__ */ React4.createElement(TileLayer, {
|
|
1034
|
-
className: "dark:filter dark:grayscale dark:invert",
|
|
1035
|
-
url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
|
1036
|
-
}), markers?.map(({ id, title, location: { lat, lng } }) => {
|
|
1055
|
+
return /* @__PURE__ */ React4.createElement(React4.Fragment, null, markers?.map(({ id, title, location: { lat, lng } }) => {
|
|
1037
1056
|
return /* @__PURE__ */ React4.createElement(Marker, {
|
|
1038
1057
|
key: id,
|
|
1039
1058
|
position: {
|
|
@@ -1042,6 +1061,7 @@ var MapCanvas = /* @__PURE__ */ forwardRef2(({ markers, center, zoom, onChange }
|
|
|
1042
1061
|
},
|
|
1043
1062
|
icon: (
|
|
1044
1063
|
// TODO(burdon): Create custom icon from bundled assets.
|
|
1064
|
+
// TODO(burdon): Selection state.
|
|
1045
1065
|
new L.Icon({
|
|
1046
1066
|
iconUrl: "https://dxos.network/marker-icon.png",
|
|
1047
1067
|
iconRetinaUrl: "https://dxos.network/marker-icon-2x.png",
|
|
@@ -1069,7 +1089,8 @@ var MapCanvas = /* @__PURE__ */ forwardRef2(({ markers, center, zoom, onChange }
|
|
|
1069
1089
|
} finally {
|
|
1070
1090
|
_effect.f();
|
|
1071
1091
|
}
|
|
1072
|
-
}
|
|
1092
|
+
};
|
|
1093
|
+
MapMarkers.displayName = "Map.Markers";
|
|
1073
1094
|
var CustomControl2 = ({ position, children }) => {
|
|
1074
1095
|
var _effect = _useSignals4();
|
|
1075
1096
|
try {
|
|
@@ -1102,35 +1123,38 @@ var CustomControl2 = ({ position, children }) => {
|
|
|
1102
1123
|
_effect.f();
|
|
1103
1124
|
}
|
|
1104
1125
|
};
|
|
1126
|
+
var MapZoom = ({ onAction, position = "bottomleft", ...props }) => {
|
|
1127
|
+
var _effect = _useSignals4();
|
|
1128
|
+
try {
|
|
1129
|
+
return /* @__PURE__ */ React4.createElement(CustomControl2, {
|
|
1130
|
+
position,
|
|
1131
|
+
...props
|
|
1132
|
+
}, /* @__PURE__ */ React4.createElement(ZoomControls, {
|
|
1133
|
+
onAction
|
|
1134
|
+
}));
|
|
1135
|
+
} finally {
|
|
1136
|
+
_effect.f();
|
|
1137
|
+
}
|
|
1138
|
+
};
|
|
1139
|
+
var MapAction = ({ onAction, position = "bottomright", ...props }) => {
|
|
1140
|
+
var _effect = _useSignals4();
|
|
1141
|
+
try {
|
|
1142
|
+
return /* @__PURE__ */ React4.createElement(CustomControl2, {
|
|
1143
|
+
position,
|
|
1144
|
+
...props
|
|
1145
|
+
}, /* @__PURE__ */ React4.createElement(ActionControls, {
|
|
1146
|
+
onAction
|
|
1147
|
+
}));
|
|
1148
|
+
} finally {
|
|
1149
|
+
_effect.f();
|
|
1150
|
+
}
|
|
1151
|
+
};
|
|
1105
1152
|
var Map = {
|
|
1106
1153
|
Root: MapRoot,
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
return /* @__PURE__ */ React4.createElement(CustomControl2, {
|
|
1112
|
-
position,
|
|
1113
|
-
...props
|
|
1114
|
-
}, /* @__PURE__ */ React4.createElement(ZoomControls, {
|
|
1115
|
-
onAction
|
|
1116
|
-
}));
|
|
1117
|
-
} finally {
|
|
1118
|
-
_effect.f();
|
|
1119
|
-
}
|
|
1120
|
-
},
|
|
1121
|
-
Action: ({ onAction, position = "bottomright", ...props }) => {
|
|
1122
|
-
var _effect = _useSignals4();
|
|
1123
|
-
try {
|
|
1124
|
-
return /* @__PURE__ */ React4.createElement(CustomControl2, {
|
|
1125
|
-
position,
|
|
1126
|
-
...props
|
|
1127
|
-
}, /* @__PURE__ */ React4.createElement(ActionControls, {
|
|
1128
|
-
onAction
|
|
1129
|
-
}));
|
|
1130
|
-
} finally {
|
|
1131
|
-
_effect.f();
|
|
1132
|
-
}
|
|
1133
|
-
}
|
|
1154
|
+
Tiles: MapTiles,
|
|
1155
|
+
Markers: MapMarkers,
|
|
1156
|
+
Zoom: MapZoom,
|
|
1157
|
+
Action: MapAction
|
|
1134
1158
|
};
|
|
1135
1159
|
export {
|
|
1136
1160
|
ActionControls,
|