@dxos/react-ui-geo 0.8.4-main.f5c0578 → 0.8.4-main.fcfe5033a5

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