@dxos/react-ui-geo 0.8.4-main.fd6878d → 0.8.4-staging.ac66bdf99f

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