@dxos/react-ui-geo 0.8.4-main.ae835ea → 0.8.4-main.bc2380dfbc

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 (67) hide show
  1. package/LICENSE +102 -5
  2. package/dist/lib/browser/{countries-110m-ZM3ZIEFS.mjs → countries-110m-RE5RNRQG.mjs} +1 -1
  3. package/dist/lib/browser/data.mjs +4 -3
  4. package/dist/lib/browser/data.mjs.map +4 -4
  5. package/dist/lib/browser/index.mjs +355 -449
  6. package/dist/lib/browser/index.mjs.map +3 -3
  7. package/dist/lib/browser/meta.json +1 -1
  8. package/dist/lib/browser/translations.mjs +19 -0
  9. package/dist/lib/browser/translations.mjs.map +7 -0
  10. package/dist/lib/node-esm/{countries-110m-3SFASWVD.mjs → countries-110m-4EDBXSFJ.mjs} +1 -1
  11. package/dist/lib/node-esm/data.mjs +5 -3
  12. package/dist/lib/node-esm/data.mjs.map +4 -4
  13. package/dist/lib/node-esm/index.mjs +355 -448
  14. package/dist/lib/node-esm/index.mjs.map +3 -3
  15. package/dist/lib/node-esm/meta.json +1 -1
  16. package/dist/lib/node-esm/translations.mjs +21 -0
  17. package/dist/lib/node-esm/translations.mjs.map +7 -0
  18. package/dist/types/data/airports.d.ts +4 -4
  19. package/dist/types/data/airports.d.ts.map +1 -1
  20. package/dist/types/data/cities.d.ts.map +1 -1
  21. package/dist/types/data/countries-110m.d.ts.map +1 -1
  22. package/dist/types/data/countries-dots-3.d.ts.map +1 -1
  23. package/dist/types/data/countries-dots-4.d.ts.map +1 -1
  24. package/dist/types/src/components/Globe/Globe.d.ts +5 -3
  25. package/dist/types/src/components/Globe/Globe.d.ts.map +1 -1
  26. package/dist/types/src/components/Globe/Globe.stories.d.ts +6 -4
  27. package/dist/types/src/components/Globe/Globe.stories.d.ts.map +1 -1
  28. package/dist/types/src/components/Map/Map.d.ts +19 -5
  29. package/dist/types/src/components/Map/Map.d.ts.map +1 -1
  30. package/dist/types/src/components/Map/Map.stories.d.ts.map +1 -1
  31. package/dist/types/src/components/Toolbar/Controls.d.ts.map +1 -1
  32. package/dist/types/src/hooks/context.d.ts +1 -3
  33. package/dist/types/src/hooks/context.d.ts.map +1 -1
  34. package/dist/types/src/hooks/useDrag.d.ts.map +1 -1
  35. package/dist/types/src/hooks/useGlobeZoomHandler.d.ts +1 -1
  36. package/dist/types/src/hooks/useGlobeZoomHandler.d.ts.map +1 -1
  37. package/dist/types/src/hooks/useMapZoomHandler.d.ts +1 -1
  38. package/dist/types/src/hooks/useMapZoomHandler.d.ts.map +1 -1
  39. package/dist/types/src/hooks/useSpinner.d.ts.map +1 -1
  40. package/dist/types/src/hooks/useTour.d.ts.map +1 -1
  41. package/dist/types/src/index.d.ts +0 -1
  42. package/dist/types/src/index.d.ts.map +1 -1
  43. package/dist/types/src/translations.d.ts +12 -0
  44. package/dist/types/src/translations.d.ts.map +1 -0
  45. package/dist/types/src/util/debug.d.ts.map +1 -1
  46. package/dist/types/src/util/inertia.d.ts.map +1 -1
  47. package/dist/types/src/util/path.d.ts.map +1 -1
  48. package/dist/types/src/util/render.d.ts.map +1 -1
  49. package/dist/types/tsconfig.tsbuildinfo +1 -1
  50. package/package.json +42 -36
  51. package/src/components/Globe/Globe.stories.tsx +7 -8
  52. package/src/components/Globe/Globe.tsx +55 -29
  53. package/src/components/Map/Map.stories.tsx +9 -8
  54. package/src/components/Map/Map.tsx +70 -29
  55. package/src/components/Toolbar/Controls.tsx +12 -14
  56. package/src/hooks/context.tsx +5 -34
  57. package/src/hooks/useSpinner.ts +0 -1
  58. package/src/hooks/useTour.ts +1 -0
  59. package/src/index.ts +0 -1
  60. package/src/translations.ts +20 -0
  61. package/src/util/render.ts +0 -1
  62. package/dist/lib/browser/chunk-GMWLKTLN.mjs +0 -9
  63. package/dist/lib/browser/chunk-GMWLKTLN.mjs.map +0 -7
  64. package/dist/lib/node-esm/chunk-JODBF4CC.mjs +0 -11
  65. package/dist/lib/node-esm/chunk-JODBF4CC.mjs.map +0 -7
  66. /package/dist/lib/browser/{countries-110m-ZM3ZIEFS.mjs.map → countries-110m-RE5RNRQG.mjs.map} +0 -0
  67. /package/dist/lib/node-esm/{countries-110m-3SFASWVD.mjs.map → countries-110m-4EDBXSFJ.mjs.map} +0 -0
@@ -1,52 +1,14 @@
1
- import {
2
- loadTopology
3
- } from "./chunk-GMWLKTLN.mjs";
4
-
5
1
  // src/components/Globe/Globe.tsx
6
- import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
7
2
  import { easeLinear, easeSinOut, geoMercator, geoOrthographic, geoPath as geoPath2, geoTransverseMercator, interpolateNumber, transition } from "d3";
8
- import React3, { forwardRef, useEffect as useEffect4, useImperativeHandle, useMemo as useMemo2, useRef, useState as useState3 } from "react";
3
+ import React2, { forwardRef, useEffect as useEffect4, useImperativeHandle, useMemo as useMemo2, useRef, useState as useState3 } from "react";
9
4
  import { useResizeDetector } from "react-resize-detector";
10
- import { useDynamicRef, useThemeContext } from "@dxos/react-ui";
11
- import { mx } from "@dxos/react-ui-theme";
5
+ import { useComposedRefs, useControlledState, useDynamicRef, useThemeContext } from "@dxos/react-ui";
6
+ import { composable, composableProps, mx } from "@dxos/ui-theme";
12
7
 
13
8
  // src/hooks/context.tsx
14
- import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
15
- import React, { createContext, useContext } from "react";
9
+ import { createContext, useContext } from "react";
16
10
  import { raise } from "@dxos/debug";
17
- import { useControlledState } from "@dxos/react-ui";
18
- var defaults = {
19
- center: {
20
- lat: 51,
21
- lng: 0
22
- },
23
- zoom: 4
24
- };
25
11
  var GlobeContext = /* @__PURE__ */ createContext(void 0);
26
- var GlobeContextProvider = ({ children, size, center: centerParam = defaults.center, zoom: zoomParam = defaults.zoom, translation: translationParam, rotation: rotationParam }) => {
27
- var _effect = _useSignals();
28
- try {
29
- const [center, setCenter] = useControlledState(centerParam);
30
- const [zoom, setZoom] = useControlledState(zoomParam);
31
- const [translation, setTranslation] = useControlledState(translationParam);
32
- const [rotation, setRotation] = useControlledState(rotationParam);
33
- return /* @__PURE__ */ React.createElement(GlobeContext.Provider, {
34
- value: {
35
- size,
36
- center,
37
- zoom,
38
- translation,
39
- rotation,
40
- setCenter,
41
- setZoom,
42
- setTranslation,
43
- setRotation
44
- }
45
- }, children);
46
- } finally {
47
- _effect.f();
48
- }
49
- };
50
12
  var useGlobeContext = () => {
51
13
  return useContext(GlobeContext) ?? raise(new Error("Missing GlobeContext"));
52
14
  };
@@ -631,9 +593,9 @@ var useTour = (controller, points, options = {}) => {
631
593
  };
632
594
 
633
595
  // src/components/Toolbar/Controls.tsx
634
- import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
635
- import React2 from "react";
636
- import { IconButton, Toolbar } from "@dxos/react-ui";
596
+ import React from "react";
597
+ import { IconButton, Toolbar, useTranslation } from "@dxos/react-ui";
598
+ import { translationKey } from "#translations";
637
599
  var controlPositions = {
638
600
  topleft: "top-2 left-2",
639
601
  topright: "top-2 right-2",
@@ -641,58 +603,42 @@ var controlPositions = {
641
603
  bottomright: "bottom-2 right-2"
642
604
  };
643
605
  var ZoomControls = ({ classNames, onAction }) => {
644
- var _effect = _useSignals2();
645
- try {
646
- return /* @__PURE__ */ React2.createElement(Toolbar.Root, {
647
- classNames: [
648
- "gap-2",
649
- classNames
650
- ]
651
- }, /* @__PURE__ */ React2.createElement(IconButton, {
652
- icon: "ph--plus--regular",
653
- label: "zoom in",
654
- iconOnly: true,
655
- size: 5,
656
- classNames: "px-0 aspect-square",
657
- onClick: () => onAction?.("zoom-in")
658
- }), /* @__PURE__ */ React2.createElement(IconButton, {
659
- icon: "ph--minus--regular",
660
- label: "zoom out",
661
- iconOnly: true,
662
- size: 5,
663
- classNames: "px-0 aspect-square",
664
- onClick: () => onAction?.("zoom-out")
665
- }));
666
- } finally {
667
- _effect.f();
668
- }
606
+ const { t } = useTranslation(translationKey);
607
+ return /* @__PURE__ */ React.createElement(Toolbar.Root, {
608
+ classNames: [
609
+ "gap-2",
610
+ classNames
611
+ ]
612
+ }, /* @__PURE__ */ React.createElement(IconButton, {
613
+ icon: "ph--plus--regular",
614
+ iconOnly: true,
615
+ label: t("zoom-in-icon.button"),
616
+ onClick: () => onAction?.("zoom-in")
617
+ }), /* @__PURE__ */ React.createElement(IconButton, {
618
+ icon: "ph--minus--regular",
619
+ iconOnly: true,
620
+ label: t("zoom-out-icon.button"),
621
+ onClick: () => onAction?.("zoom-out")
622
+ }));
669
623
  };
670
624
  var ActionControls = ({ classNames, onAction }) => {
671
- var _effect = _useSignals2();
672
- try {
673
- return /* @__PURE__ */ React2.createElement(Toolbar.Root, {
674
- classNames: [
675
- "gap-2",
676
- classNames
677
- ]
678
- }, /* @__PURE__ */ React2.createElement(IconButton, {
679
- icon: "ph--play--regular",
680
- label: "start",
681
- iconOnly: true,
682
- size: 5,
683
- classNames: "px-0 aspect-square",
684
- onClick: () => onAction?.("start")
685
- }), /* @__PURE__ */ React2.createElement(IconButton, {
686
- icon: "ph--globe-hemisphere-west--regular",
687
- label: "toggle",
688
- iconOnly: true,
689
- size: 5,
690
- classNames: "px-0 aspect-square",
691
- onClick: () => onAction?.("toggle")
692
- }));
693
- } finally {
694
- _effect.f();
695
- }
625
+ const { t } = useTranslation(translationKey);
626
+ return /* @__PURE__ */ React.createElement(Toolbar.Root, {
627
+ classNames: [
628
+ "gap-2",
629
+ classNames
630
+ ]
631
+ }, /* @__PURE__ */ React.createElement(IconButton, {
632
+ icon: "ph--path--regular",
633
+ iconOnly: true,
634
+ label: t("start-icon.button"),
635
+ onClick: () => onAction?.("start")
636
+ }), /* @__PURE__ */ React.createElement(IconButton, {
637
+ icon: "ph--globe-hemisphere-west--regular",
638
+ iconOnly: true,
639
+ label: t("toggle-icon.button"),
640
+ onClick: () => onAction?.("toggle")
641
+ }));
696
642
  };
697
643
 
698
644
  // src/components/Globe/Globe.tsx
@@ -750,186 +696,166 @@ var getProjection = (type = "orthographic") => {
750
696
  }
751
697
  return type ?? geoOrthographic();
752
698
  };
753
- var GlobeRoot = ({ classNames, children, ...props }) => {
754
- var _effect = _useSignals3();
755
- try {
756
- const { ref, width, height } = useResizeDetector();
757
- return /* @__PURE__ */ React3.createElement("div", {
758
- ref,
759
- className: mx("relative flex grow overflow-hidden", classNames)
760
- }, /* @__PURE__ */ React3.createElement(GlobeContextProvider, {
699
+ var GlobeRoot = composable(({ children, center: centerProp, zoom: zoomProp, translation: translationProp, rotation: rotationProp, ...props }, forwardedRef) => {
700
+ const localRef = useRef(null);
701
+ const composedRef = useComposedRefs(localRef, forwardedRef);
702
+ const { width, height } = useResizeDetector({
703
+ targetRef: localRef
704
+ });
705
+ const [center, setCenter] = useControlledState(centerProp);
706
+ const [zoom, setZoom] = useControlledState(zoomProp ?? 4);
707
+ const [translation, setTranslation] = useControlledState(translationProp);
708
+ const [rotation, setRotation] = useControlledState(rotationProp);
709
+ return /* @__PURE__ */ React2.createElement(GlobeContext.Provider, {
710
+ value: {
761
711
  size: {
762
712
  width,
763
713
  height
764
714
  },
765
- ...props
766
- }, children));
767
- } finally {
768
- _effect.f();
769
- }
770
- };
771
- var GlobeCanvas = /* @__PURE__ */ forwardRef(({ projection: projectionParam, topology, features, styles: stylesParam }, forwardRef3) => {
772
- var _effect = _useSignals3();
773
- try {
774
- const { themeMode } = useThemeContext();
775
- const styles = useMemo2(() => stylesParam ?? defaultStyles[themeMode], [
776
- stylesParam,
777
- themeMode
778
- ]);
779
- const [canvas, setCanvas] = useState3(null);
780
- const canvasRef = (canvas2) => setCanvas(canvas2);
781
- const projection = useMemo2(() => getProjection(projectionParam), [
782
- projectionParam
783
- ]);
784
- const layers = useMemo2(() => {
785
- return timer(() => createLayers(topology, features, styles));
786
- }, [
787
- topology,
788
- features,
789
- styles
790
- ]);
791
- const { size, center, zoom, translation, rotation, setCenter, setZoom, setTranslation, setRotation } = useGlobeContext();
792
- const zoomRef = useDynamicRef(zoom);
793
- useEffect4(() => {
794
- if (center) {
795
- setZoom(1);
796
- setRotation(positionToRotation(geoToPosition(center)));
797
- }
798
- }, [
799
- center
800
- ]);
801
- const zooming = useRef(false);
802
- useImperativeHandle(forwardRef3, () => {
803
- return {
804
- canvas,
805
- projection,
806
- center,
807
- get zoom() {
808
- return zoomRef.current;
809
- },
810
- translation,
811
- rotation,
812
- setCenter,
813
- setZoom: (s) => {
814
- if (typeof s === "function") {
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", () => {
817
- zooming.current = false;
818
- });
819
- } else {
820
- setZoom(s);
821
- }
822
- },
823
- setTranslation,
824
- setRotation
825
- };
826
- }, [
827
- canvas
828
- ]);
829
- const generator = useMemo2(() => canvas && projection && geoPath2(projection, canvas.getContext("2d", {
830
- alpha: false
831
- })), [
832
- canvas,
833
- projection
834
- ]);
835
- useEffect4(() => {
836
- if (canvas && projection) {
837
- timer(() => {
838
- projection.scale(Math.min(size.width, size.height) / 2 * zoom).translate([
839
- size.width / 2 + (translation?.x ?? 0),
840
- size.height / 2 + (translation?.y ?? 0)
841
- ]).rotate(rotation ?? [
842
- 0,
843
- 0,
844
- 0
845
- ]);
846
- renderLayers(generator, layers, zoom, styles);
847
- });
848
- }
849
- }, [
850
- generator,
851
- size,
715
+ center,
852
716
  zoom,
853
717
  translation,
854
718
  rotation,
855
- layers
856
- ]);
857
- if (!size.width || !size.height) {
858
- return null;
719
+ setCenter,
720
+ setZoom,
721
+ setTranslation,
722
+ setRotation
859
723
  }
860
- return /* @__PURE__ */ React3.createElement("canvas", {
861
- ref: canvasRef,
862
- width: size.width,
863
- height: size.height
864
- });
865
- } finally {
866
- _effect.f();
867
- }
724
+ }, /* @__PURE__ */ React2.createElement("div", {
725
+ ...composableProps(props, {
726
+ classNames: "relative dx-container"
727
+ }),
728
+ ref: composedRef
729
+ }, children));
868
730
  });
869
- var GlobeDebug = ({ position = "topleft" }) => {
870
- var _effect = _useSignals3();
871
- try {
872
- const { size, zoom, translation, rotation } = useGlobeContext();
873
- return /* @__PURE__ */ React3.createElement("div", {
874
- className: mx("z-10 absolute w-96 p-2 overflow-hidden border border-green-700 rounded", controlPositions[position])
875
- }, /* @__PURE__ */ React3.createElement("pre", {
876
- className: "font-mono text-xs text-green-700"
877
- }, JSON.stringify({
878
- size,
879
- zoom,
731
+ var GlobeCanvas = /* @__PURE__ */ forwardRef(({ projection: projectionProp, topology, features, styles: stylesProp }, forwardRef3) => {
732
+ const { themeMode } = useThemeContext();
733
+ const styles = useMemo2(() => stylesProp ?? defaultStyles[themeMode], [
734
+ stylesProp,
735
+ themeMode
736
+ ]);
737
+ const [canvas, setCanvas] = useState3(null);
738
+ const canvasRef = (canvas2) => setCanvas(canvas2);
739
+ const projection = useMemo2(() => getProjection(projectionProp), [
740
+ projectionProp
741
+ ]);
742
+ const layers = useMemo2(() => {
743
+ return timer(() => createLayers(topology, features, styles));
744
+ }, [
745
+ topology,
746
+ features,
747
+ styles
748
+ ]);
749
+ const { size, center, zoom, translation, rotation, setCenter, setZoom, setTranslation, setRotation } = useGlobeContext();
750
+ const zoomRef = useDynamicRef(zoom);
751
+ useEffect4(() => {
752
+ if (center) {
753
+ setZoom(1);
754
+ setRotation(positionToRotation(geoToPosition(center)));
755
+ }
756
+ }, [
757
+ center
758
+ ]);
759
+ const zooming = useRef(false);
760
+ useImperativeHandle(forwardRef3, () => {
761
+ return {
762
+ canvas,
763
+ projection,
764
+ center,
765
+ get zoom() {
766
+ return zoomRef.current;
767
+ },
880
768
  translation,
881
- rotation
882
- }, null, 2)));
883
- } finally {
884
- _effect.f();
769
+ rotation,
770
+ setCenter,
771
+ setZoom: (state) => {
772
+ if (typeof state === "function") {
773
+ const is = interpolateNumber(zoomRef.current, state(zoomRef.current));
774
+ transition().ease(zooming.current ? easeLinear : easeSinOut).duration(200).tween("scale", () => (t) => setZoom(is(t))).on("end", () => {
775
+ zooming.current = false;
776
+ });
777
+ } else {
778
+ setZoom(state);
779
+ }
780
+ },
781
+ setTranslation,
782
+ setRotation
783
+ };
784
+ }, [
785
+ canvas
786
+ ]);
787
+ const generator = useMemo2(() => canvas && projection && geoPath2(projection, canvas.getContext("2d", {
788
+ alpha: false
789
+ })), [
790
+ canvas,
791
+ projection
792
+ ]);
793
+ useEffect4(() => {
794
+ if (canvas && projection) {
795
+ timer(() => {
796
+ projection.scale(Math.min(size.width, size.height) / 2 * zoom).translate([
797
+ size.width / 2 + (translation?.x ?? 0),
798
+ size.height / 2 + (translation?.y ?? 0)
799
+ ]).rotate(rotation ?? [
800
+ 0,
801
+ 0,
802
+ 0
803
+ ]);
804
+ renderLayers(generator, layers, zoom, styles);
805
+ });
806
+ }
807
+ }, [
808
+ generator,
809
+ size,
810
+ zoom,
811
+ translation,
812
+ rotation,
813
+ layers
814
+ ]);
815
+ if (!size.width || !size.height) {
816
+ return null;
885
817
  }
818
+ return /* @__PURE__ */ React2.createElement("canvas", {
819
+ ref: canvasRef,
820
+ width: size.width,
821
+ height: size.height
822
+ });
823
+ });
824
+ var GlobeDebug = ({ position = "topleft" }) => {
825
+ const { size, zoom, translation, rotation } = useGlobeContext();
826
+ return /* @__PURE__ */ React2.createElement("div", {
827
+ className: mx("z-10 absolute w-96 p-2 overflow-hidden border border-green-700 rounded-sm", controlPositions[position])
828
+ }, /* @__PURE__ */ React2.createElement("pre", {
829
+ className: "font-mono text-xs text-green-700"
830
+ }, JSON.stringify({
831
+ size,
832
+ zoom,
833
+ translation,
834
+ rotation
835
+ }, null, 2)));
886
836
  };
887
837
  var GlobePanel = ({ position, classNames, children }) => {
888
- var _effect = _useSignals3();
889
- try {
890
- return /* @__PURE__ */ React3.createElement("div", {
891
- className: mx("z-10 absolute overflow-hidden", controlPositions[position], classNames)
892
- }, children);
893
- } finally {
894
- _effect.f();
895
- }
838
+ return /* @__PURE__ */ React2.createElement("div", {
839
+ className: mx("z-10 absolute overflow-hidden", controlPositions[position], classNames)
840
+ }, children);
896
841
  };
897
842
  var CustomControl = ({ position, children }) => {
898
- var _effect = _useSignals3();
899
- try {
900
- return /* @__PURE__ */ React3.createElement("div", {
901
- className: mx("z-10 absolute overflow-hidden", controlPositions[position])
902
- }, children);
903
- } finally {
904
- _effect.f();
905
- }
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
- }
843
+ return /* @__PURE__ */ React2.createElement("div", {
844
+ className: mx("z-10 absolute overflow-hidden", controlPositions[position])
845
+ }, children);
932
846
  };
847
+ var GlobeZoom = ({ onAction, position = "bottomleft", ...props }) => /* @__PURE__ */ React2.createElement(CustomControl, {
848
+ position,
849
+ ...props
850
+ }, /* @__PURE__ */ React2.createElement(ZoomControls, {
851
+ onAction
852
+ }));
853
+ var GlobeAction = ({ onAction, position = "bottomright", ...props }) => /* @__PURE__ */ React2.createElement(CustomControl, {
854
+ position,
855
+ ...props
856
+ }, /* @__PURE__ */ React2.createElement(ActionControls, {
857
+ onAction
858
+ }));
933
859
  var Globe = {
934
860
  Root: GlobeRoot,
935
861
  Canvas: GlobeCanvas,
@@ -940,217 +866,198 @@ var Globe = {
940
866
  };
941
867
 
942
868
  // src/components/Map/Map.tsx
943
- import { useSignals as _useSignals4 } from "@preact-signals/safe-react/tracking";
944
869
  import "leaflet/dist/leaflet.css";
945
870
  import { createContext as createContext2 } from "@radix-ui/react-context";
946
871
  import L, { Control, DomEvent, DomUtil, latLngBounds } from "leaflet";
947
- import React4, { forwardRef as forwardRef2, useEffect as useEffect5, useImperativeHandle as useImperativeHandle2, useRef as useRef2, useState as useState4 } from "react";
872
+ import React3, { forwardRef as forwardRef2, useEffect as useEffect5, useImperativeHandle as useImperativeHandle2, useRef as useRef2 } from "react";
948
873
  import { createRoot } from "react-dom/client";
949
874
  import { MapContainer, Marker, Popup, TileLayer, useMap, useMapEvents } from "react-leaflet";
950
875
  import { ThemeProvider, Tooltip } from "@dxos/react-ui";
951
- import { defaultTx, mx as mx2 } from "@dxos/react-ui-theme";
952
- var defaults2 = {
876
+ import { composable as composable2, composableProps as composableProps2, defaultTx, mx as mx2 } from "@dxos/ui-theme";
877
+ var defaults = {
953
878
  center: {
954
879
  lat: 51,
955
880
  lng: 0
956
881
  },
957
882
  zoom: 4
958
883
  };
959
- var [MapContextProvier, useMapContext] = createContext2("Map");
960
- var MapRoot = /* @__PURE__ */ forwardRef2(({ classNames, scrollWheelZoom = true, doubleClickZoom = true, touchZoom = true, center, zoom, onChange, ...props }, forwardedRef) => {
961
- var _effect = _useSignals4();
962
- try {
963
- const [attention, setAttention] = useState4(false);
964
- const mapRef = useRef2(null);
965
- const map = mapRef.current;
966
- useImperativeHandle2(forwardedRef, () => ({
967
- setCenter: (center2, zoom2) => {
968
- mapRef.current?.setView(center2, zoom2);
969
- },
970
- setZoom: (cb) => {
971
- mapRef.current?.setZoom(cb(mapRef.current?.getZoom() ?? 0));
972
- }
973
- }), []);
974
- useEffect5(() => {
975
- if (!map) {
976
- return;
977
- }
978
- if (attention) {
979
- map.scrollWheelZoom.enable();
980
- } else {
981
- map.scrollWheelZoom.disable();
982
- }
983
- }, [
984
- map,
985
- attention
986
- ]);
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
- }
884
+ var [MapContextProvider, useMapContext] = createContext2("Map");
885
+ var MapRoot = composable2(({ children, onChange, ...props }, forwardedRef) => {
886
+ const attention = false;
887
+ return /* @__PURE__ */ React3.createElement(MapContextProvider, {
888
+ attention,
889
+ onChange
890
+ }, /* @__PURE__ */ React3.createElement("div", {
891
+ ...composableProps2(props, {
892
+ role: "none",
893
+ classNames: "dx-container grid dx-focus-ring-inset"
894
+ }),
895
+ ref: forwardedRef
896
+ }, children));
1005
897
  });
1006
898
  MapRoot.displayName = "Map.Root";
899
+ var MAP_CONTENT_NAME = "Map.Content";
900
+ var MapContent = /* @__PURE__ */ forwardRef2(({ classNames, scrollWheelZoom = true, doubleClickZoom = true, touchZoom = true, center, zoom, children, ...props }, forwardedRef) => {
901
+ const { attention } = useMapContext(MAP_CONTENT_NAME);
902
+ const mapRef = useRef2(null);
903
+ const map = mapRef.current;
904
+ useImperativeHandle2(forwardedRef, () => ({
905
+ setCenter: (center2, zoom2) => {
906
+ mapRef.current?.setView(center2, zoom2);
907
+ },
908
+ setZoom: (cb) => {
909
+ mapRef.current?.setZoom(cb(mapRef.current?.getZoom() ?? 0));
910
+ }
911
+ }), []);
912
+ useEffect5(() => {
913
+ if (!map) {
914
+ return;
915
+ }
916
+ if (attention) {
917
+ map.scrollWheelZoom.enable();
918
+ } else {
919
+ map.scrollWheelZoom.disable();
920
+ }
921
+ }, [
922
+ map,
923
+ attention
924
+ ]);
925
+ return /* @__PURE__ */ React3.createElement(MapContainer, {
926
+ ...props,
927
+ className: mx2("group relative grid bg-base-surface!", classNames),
928
+ attributionControl: false,
929
+ zoomControl: false,
930
+ scrollWheelZoom,
931
+ doubleClickZoom,
932
+ touchZoom,
933
+ center: center ?? defaults.center,
934
+ zoom: zoom ?? defaults.zoom,
935
+ whenReady: () => {
936
+ },
937
+ ref: mapRef
938
+ }, children);
939
+ });
940
+ MapContent.displayName = "Map.Content";
941
+ var MAP_TILES_NAME = "Map.Tiles";
1007
942
  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) => {
1014
- onChange?.({
1015
- center: ev.target.getCenter(),
1016
- zoom: ev.target.getZoom()
1017
- });
1018
- }
1019
- });
1020
- const { attention } = useMapContext(MapTiles.displayName);
1021
- useEffect5(() => {
1022
- if (ref.current) {
1023
- ref.current.getContainer().dataset.attention = attention ? "1" : "0";
1024
- }
1025
- }, [
1026
- attention
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
- }
943
+ const ref = useRef2(null);
944
+ const { onChange } = useMapContext(MAP_TILES_NAME);
945
+ useMapEvents({
946
+ zoomstart: (ev) => {
947
+ onChange?.({
948
+ center: ev.target.getCenter(),
949
+ zoom: ev.target.getZoom()
950
+ });
951
+ }
952
+ });
953
+ const { attention } = useMapContext(MAP_TILES_NAME);
954
+ useEffect5(() => {
955
+ if (ref.current) {
956
+ ref.current.getContainer().dataset.attention = attention ? "1" : "0";
957
+ }
958
+ }, [
959
+ attention
960
+ ]);
961
+ return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(TileLayer, {
962
+ ref,
963
+ "data-attention": attention,
964
+ detectRetina: true,
965
+ className: 'dark:grayscale dark:invert data-[attention="0"]:!opacity-80',
966
+ url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
967
+ keepBuffer: 4
968
+ }));
1039
969
  };
1040
- MapTiles.displayName = "Map.Tiles";
970
+ MapTiles.displayName = MAP_TILES_NAME;
1041
971
  var MapMarkers = ({ selected, markers }) => {
1042
- var _effect = _useSignals4();
1043
- try {
1044
- const map = useMap();
1045
- useEffect5(() => {
1046
- if (markers.length > 0) {
1047
- const bounds = latLngBounds(markers.map((marker) => marker.location));
1048
- map.fitBounds(bounds);
1049
- } else {
1050
- map.setView(defaults2.center, defaults2.zoom);
1051
- }
1052
- }, [
1053
- markers
1054
- ]);
1055
- return /* @__PURE__ */ React4.createElement(React4.Fragment, null, markers?.map(({ id, title, location: { lat, lng } }) => {
1056
- return /* @__PURE__ */ React4.createElement(Marker, {
1057
- key: id,
1058
- position: {
1059
- lat,
1060
- lng
1061
- },
1062
- icon: (
1063
- // TODO(burdon): Create custom icon from bundled assets.
1064
- // TODO(burdon): Selection state.
1065
- new L.Icon({
1066
- iconUrl: "https://dxos.network/marker-icon.png",
1067
- iconRetinaUrl: "https://dxos.network/marker-icon-2x.png",
1068
- shadowUrl: "https://dxos.network/marker-shadow.png",
1069
- iconSize: [
1070
- 25,
1071
- 41
1072
- ],
1073
- iconAnchor: [
1074
- 12,
1075
- 41
1076
- ],
1077
- popupAnchor: [
1078
- 1,
1079
- -34
1080
- ],
1081
- shadowSize: [
1082
- 41,
1083
- 41
1084
- ]
1085
- })
1086
- )
1087
- }, title && /* @__PURE__ */ React4.createElement(Popup, null, title));
1088
- }));
1089
- } finally {
1090
- _effect.f();
1091
- }
972
+ const map = useMap();
973
+ useEffect5(() => {
974
+ if (markers.length > 0) {
975
+ const bounds = latLngBounds(markers.map((marker) => marker.location));
976
+ map.fitBounds(bounds);
977
+ } else {
978
+ map.setView(defaults.center, defaults.zoom);
979
+ }
980
+ }, [
981
+ markers
982
+ ]);
983
+ return /* @__PURE__ */ React3.createElement(React3.Fragment, null, markers?.map(({ id, title, location: { lat, lng } }) => {
984
+ return /* @__PURE__ */ React3.createElement(Marker, {
985
+ key: id,
986
+ position: {
987
+ lat,
988
+ lng
989
+ },
990
+ icon: (
991
+ // TODO(burdon): Create custom icon from bundled assets.
992
+ // TODO(burdon): Selection state.
993
+ new L.Icon({
994
+ iconUrl: "https://dxos.network/marker-icon.png",
995
+ iconRetinaUrl: "https://dxos.network/marker-icon-2x.png",
996
+ shadowUrl: "https://dxos.network/marker-shadow.png",
997
+ iconSize: [
998
+ 25,
999
+ 41
1000
+ ],
1001
+ iconAnchor: [
1002
+ 12,
1003
+ 41
1004
+ ],
1005
+ popupAnchor: [
1006
+ 1,
1007
+ -34
1008
+ ],
1009
+ shadowSize: [
1010
+ 41,
1011
+ 41
1012
+ ]
1013
+ })
1014
+ )
1015
+ }, title && /* @__PURE__ */ React3.createElement(Popup, null, title));
1016
+ }));
1092
1017
  };
1093
1018
  MapMarkers.displayName = "Map.Markers";
1094
1019
  var CustomControl2 = ({ position, children }) => {
1095
- var _effect = _useSignals4();
1096
- try {
1097
- const map = useMap();
1098
- useEffect5(() => {
1099
- const control = new Control({
1100
- position
1101
- });
1102
- control.onAdd = () => {
1103
- const container = DomUtil.create("div", mx2("!m-0", controlPositions[position]));
1104
- DomEvent.disableClickPropagation(container);
1105
- DomEvent.disableScrollPropagation(container);
1106
- const root = createRoot(container);
1107
- root.render(/* @__PURE__ */ React4.createElement(ThemeProvider, {
1108
- tx: defaultTx
1109
- }, /* @__PURE__ */ React4.createElement(Tooltip.Provider, null, children)));
1110
- return container;
1111
- };
1112
- control.addTo(map);
1113
- return () => {
1114
- control.remove();
1115
- };
1116
- }, [
1117
- map,
1118
- position,
1119
- children
1120
- ]);
1121
- return null;
1122
- } finally {
1123
- _effect.f();
1124
- }
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
- }
1020
+ const map = useMap();
1021
+ useEffect5(() => {
1022
+ const control = new Control({
1023
+ position
1024
+ });
1025
+ control.onAdd = () => {
1026
+ const container = DomUtil.create("div", mx2("m-0!", controlPositions[position]));
1027
+ DomEvent.disableClickPropagation(container);
1028
+ DomEvent.disableScrollPropagation(container);
1029
+ const root = createRoot(container);
1030
+ root.render(/* @__PURE__ */ React3.createElement(ThemeProvider, {
1031
+ tx: defaultTx
1032
+ }, /* @__PURE__ */ React3.createElement(Tooltip.Provider, null, children)));
1033
+ return container;
1034
+ };
1035
+ control.addTo(map);
1036
+ return () => {
1037
+ control.remove();
1038
+ };
1039
+ }, [
1040
+ map,
1041
+ position,
1042
+ children
1043
+ ]);
1044
+ return null;
1151
1045
  };
1046
+ var MapZoom = ({ onAction, position = "bottomleft", ...props }) => /* @__PURE__ */ React3.createElement(CustomControl2, {
1047
+ position,
1048
+ ...props
1049
+ }, /* @__PURE__ */ React3.createElement(ZoomControls, {
1050
+ onAction
1051
+ }));
1052
+ var MapAction = ({ onAction, position = "bottomright", ...props }) => /* @__PURE__ */ React3.createElement(CustomControl2, {
1053
+ position,
1054
+ ...props
1055
+ }, /* @__PURE__ */ React3.createElement(ActionControls, {
1056
+ onAction
1057
+ }));
1152
1058
  var Map = {
1153
1059
  Root: MapRoot,
1060
+ Content: MapContent,
1154
1061
  Tiles: MapTiles,
1155
1062
  Markers: MapMarkers,
1156
1063
  Zoom: MapZoom,
@@ -1159,7 +1066,7 @@ var Map = {
1159
1066
  export {
1160
1067
  ActionControls,
1161
1068
  Globe,
1162
- GlobeContextProvider,
1069
+ GlobeContext,
1163
1070
  Map,
1164
1071
  ZoomControls,
1165
1072
  closestPoint,
@@ -1171,7 +1078,6 @@ export {
1171
1078
  geoPoint,
1172
1079
  geoToPosition,
1173
1080
  getDistance,
1174
- loadTopology,
1175
1081
  positionToRotation,
1176
1082
  renderLayers,
1177
1083
  restrictAxis,