@dxos/react-ui-geo 0.8.4-main.dedc0f3 → 0.8.4-main.dfabb4ec29

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 (68) hide show
  1. package/dist/lib/browser/{countries-110m-ZM3ZIEFS.mjs → countries-110m-RE5RNRQG.mjs} +1 -1
  2. package/dist/lib/browser/data.mjs +4 -3
  3. package/dist/lib/browser/data.mjs.map +4 -4
  4. package/dist/lib/browser/index.mjs +364 -462
  5. package/dist/lib/browser/index.mjs.map +3 -3
  6. package/dist/lib/browser/meta.json +1 -1
  7. package/dist/lib/browser/translations.mjs +19 -0
  8. package/dist/lib/browser/translations.mjs.map +7 -0
  9. package/dist/lib/node-esm/{countries-110m-3SFASWVD.mjs → countries-110m-4EDBXSFJ.mjs} +1 -1
  10. package/dist/lib/node-esm/data.mjs +5 -3
  11. package/dist/lib/node-esm/data.mjs.map +4 -4
  12. package/dist/lib/node-esm/index.mjs +364 -461
  13. package/dist/lib/node-esm/index.mjs.map +3 -3
  14. package/dist/lib/node-esm/meta.json +1 -1
  15. package/dist/lib/node-esm/translations.mjs +21 -0
  16. package/dist/lib/node-esm/translations.mjs.map +7 -0
  17. package/dist/types/data/airports.d.ts +4 -4
  18. package/dist/types/data/airports.d.ts.map +1 -1
  19. package/dist/types/data/cities.d.ts.map +1 -1
  20. package/dist/types/data/countries-110m.d.ts.map +1 -1
  21. package/dist/types/data/countries-dots-3.d.ts.map +1 -1
  22. package/dist/types/data/countries-dots-4.d.ts.map +1 -1
  23. package/dist/types/src/components/Globe/Globe.d.ts +5 -3
  24. package/dist/types/src/components/Globe/Globe.d.ts.map +1 -1
  25. package/dist/types/src/components/Globe/Globe.stories.d.ts +9 -5
  26. package/dist/types/src/components/Globe/Globe.stories.d.ts.map +1 -1
  27. package/dist/types/src/components/Map/Map.d.ts +22 -11
  28. package/dist/types/src/components/Map/Map.d.ts.map +1 -1
  29. package/dist/types/src/components/Map/Map.stories.d.ts +3 -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 +10 -10
  52. package/src/components/Globe/Globe.tsx +55 -28
  53. package/src/components/Map/Map.stories.tsx +12 -10
  54. package/src/components/Map/Map.tsx +82 -71
  55. package/src/components/Toolbar/Controls.tsx +12 -14
  56. package/src/hooks/context.tsx +6 -29
  57. package/src/hooks/useGlobeZoomHandler.ts +8 -2
  58. package/src/hooks/useSpinner.ts +0 -1
  59. package/src/hooks/useTour.ts +1 -0
  60. package/src/index.ts +0 -1
  61. package/src/translations.ts +20 -0
  62. package/src/util/render.ts +0 -1
  63. package/dist/lib/browser/chunk-GMWLKTLN.mjs +0 -9
  64. package/dist/lib/browser/chunk-GMWLKTLN.mjs.map +0 -7
  65. package/dist/lib/node-esm/chunk-JODBF4CC.mjs +0 -11
  66. package/dist/lib/node-esm/chunk-JODBF4CC.mjs.map +0 -7
  67. /package/dist/lib/browser/{countries-110m-ZM3ZIEFS.mjs.map → countries-110m-RE5RNRQG.mjs.map} +0 -0
  68. /package/dist/lib/node-esm/{countries-110m-3SFASWVD.mjs.map → countries-110m-4EDBXSFJ.mjs.map} +0 -0
@@ -1,46 +1,16 @@
1
1
  import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
- import {
3
- loadTopology
4
- } from "./chunk-JODBF4CC.mjs";
5
2
 
6
3
  // src/components/Globe/Globe.tsx
7
- import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
8
4
  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";
5
+ import React2, { forwardRef, useEffect as useEffect4, useImperativeHandle, useMemo as useMemo2, useRef, useState as useState3 } from "react";
10
6
  import { useResizeDetector } from "react-resize-detector";
11
- import { useDynamicRef, useThemeContext } from "@dxos/react-ui";
12
- import { mx } from "@dxos/react-ui-theme";
7
+ import { useComposedRefs, useControlledState, useDynamicRef, useThemeContext } from "@dxos/react-ui";
8
+ import { composable, composableProps, mx } from "@dxos/ui-theme";
13
9
 
14
10
  // src/hooks/context.tsx
15
- import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
16
- import React, { createContext, useContext } from "react";
11
+ import { createContext, useContext } from "react";
17
12
  import { raise } from "@dxos/debug";
18
- import { useControlledState } from "@dxos/react-ui";
19
13
  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
14
  var useGlobeContext = () => {
45
15
  return useContext(GlobeContext) ?? raise(new Error("Missing GlobeContext"));
46
16
  };
@@ -377,8 +347,8 @@ var renderLayers = (generator, layers = [], scale, styles) => {
377
347
  generator.pointRadius(value * scale);
378
348
  } else {
379
349
  context[key] = value;
380
- fill || (fill = key === "fillStyle");
381
- stroke || (stroke = key === "strokeStyle");
350
+ fill ||= key === "fillStyle";
351
+ stroke ||= key === "strokeStyle";
382
352
  }
383
353
  });
384
354
  }
@@ -428,6 +398,7 @@ var cancelDrag = (node) => node.on(".drag", null);
428
398
 
429
399
  // src/hooks/useGlobeZoomHandler.ts
430
400
  import { useCallback } from "react";
401
+ var ZOOM_FACTOR = 0.1;
431
402
  var useGlobeZoomHandler = (controller) => {
432
403
  return useCallback((event) => {
433
404
  if (!controller) {
@@ -435,11 +406,15 @@ var useGlobeZoomHandler = (controller) => {
435
406
  }
436
407
  switch (event) {
437
408
  case "zoom-in": {
438
- controller.setZoom((zoom) => zoom * 1.1);
409
+ controller.setZoom((zoom) => {
410
+ return zoom * (1 + ZOOM_FACTOR);
411
+ });
439
412
  break;
440
413
  }
441
414
  case "zoom-out": {
442
- controller.setZoom((zoom) => zoom * 0.9);
415
+ controller.setZoom((zoom) => {
416
+ return zoom * (1 - ZOOM_FACTOR);
417
+ });
443
418
  break;
444
419
  }
445
420
  }
@@ -620,9 +595,9 @@ var useTour = (controller, points, options = {}) => {
620
595
  };
621
596
 
622
597
  // 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";
598
+ import React from "react";
599
+ import { IconButton, Toolbar, useTranslation } from "@dxos/react-ui";
600
+ import { translationKey } from "#translations";
626
601
  var controlPositions = {
627
602
  topleft: "top-2 left-2",
628
603
  topright: "top-2 right-2",
@@ -630,58 +605,42 @@ var controlPositions = {
630
605
  bottomright: "bottom-2 right-2"
631
606
  };
632
607
  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
- }
608
+ const { t } = useTranslation(translationKey);
609
+ return /* @__PURE__ */ React.createElement(Toolbar.Root, {
610
+ classNames: [
611
+ "gap-2",
612
+ classNames
613
+ ]
614
+ }, /* @__PURE__ */ React.createElement(IconButton, {
615
+ icon: "ph--plus--regular",
616
+ iconOnly: true,
617
+ label: t("zoom-in-icon.button"),
618
+ onClick: () => onAction?.("zoom-in")
619
+ }), /* @__PURE__ */ React.createElement(IconButton, {
620
+ icon: "ph--minus--regular",
621
+ iconOnly: true,
622
+ label: t("zoom-out-icon.button"),
623
+ onClick: () => onAction?.("zoom-out")
624
+ }));
658
625
  };
659
626
  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
- }
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--path--regular",
635
+ iconOnly: true,
636
+ label: t("start-icon.button"),
637
+ onClick: () => onAction?.("start")
638
+ }), /* @__PURE__ */ React.createElement(IconButton, {
639
+ icon: "ph--globe-hemisphere-west--regular",
640
+ iconOnly: true,
641
+ label: t("toggle-icon.button"),
642
+ onClick: () => onAction?.("toggle")
643
+ }));
685
644
  };
686
645
 
687
646
  // src/components/Globe/Globe.tsx
@@ -739,186 +698,166 @@ var getProjection = (type = "orthographic") => {
739
698
  }
740
699
  return type ?? geoOrthographic();
741
700
  };
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, {
701
+ var GlobeRoot = composable(({ children, center: centerProp, zoom: zoomProp, translation: translationProp, rotation: rotationProp, ...props }, forwardedRef) => {
702
+ const localRef = useRef(null);
703
+ const composedRef = useComposedRefs(localRef, forwardedRef);
704
+ const { width, height } = useResizeDetector({
705
+ targetRef: localRef
706
+ });
707
+ const [center, setCenter] = useControlledState(centerProp);
708
+ const [zoom, setZoom] = useControlledState(zoomProp ?? 4);
709
+ const [translation, setTranslation] = useControlledState(translationProp);
710
+ const [rotation, setRotation] = useControlledState(rotationProp);
711
+ return /* @__PURE__ */ React2.createElement(GlobeContext.Provider, {
712
+ value: {
750
713
  size: {
751
714
  width,
752
715
  height
753
716
  },
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,
717
+ center,
841
718
  zoom,
842
719
  translation,
843
720
  rotation,
844
- layers
845
- ]);
846
- if (!size.width || !size.height) {
847
- return null;
721
+ setCenter,
722
+ setZoom,
723
+ setTranslation,
724
+ setRotation
848
725
  }
849
- return /* @__PURE__ */ React3.createElement("canvas", {
850
- ref: canvasRef,
851
- width: size.width,
852
- height: size.height
853
- });
854
- } finally {
855
- _effect.f();
856
- }
726
+ }, /* @__PURE__ */ React2.createElement("div", {
727
+ ...composableProps(props, {
728
+ classNames: "relative dx-container"
729
+ }),
730
+ ref: composedRef
731
+ }, children));
857
732
  });
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,
733
+ var GlobeCanvas = /* @__PURE__ */ forwardRef(({ projection: projectionProp, topology, features, styles: stylesProp }, forwardRef3) => {
734
+ const { themeMode } = useThemeContext();
735
+ const styles = useMemo2(() => stylesProp ?? defaultStyles[themeMode], [
736
+ stylesProp,
737
+ themeMode
738
+ ]);
739
+ const [canvas, setCanvas] = useState3(null);
740
+ const canvasRef = (canvas2) => setCanvas(canvas2);
741
+ const projection = useMemo2(() => getProjection(projectionProp), [
742
+ projectionProp
743
+ ]);
744
+ const layers = useMemo2(() => {
745
+ return timer(() => createLayers(topology, features, styles));
746
+ }, [
747
+ topology,
748
+ features,
749
+ styles
750
+ ]);
751
+ const { size, center, zoom, translation, rotation, setCenter, setZoom, setTranslation, setRotation } = useGlobeContext();
752
+ const zoomRef = useDynamicRef(zoom);
753
+ useEffect4(() => {
754
+ if (center) {
755
+ setZoom(1);
756
+ setRotation(positionToRotation(geoToPosition(center)));
757
+ }
758
+ }, [
759
+ center
760
+ ]);
761
+ const zooming = useRef(false);
762
+ useImperativeHandle(forwardRef3, () => {
763
+ return {
764
+ canvas,
765
+ projection,
766
+ center,
767
+ get zoom() {
768
+ return zoomRef.current;
769
+ },
869
770
  translation,
870
- rotation
871
- }, null, 2)));
872
- } finally {
873
- _effect.f();
771
+ rotation,
772
+ setCenter,
773
+ setZoom: (state) => {
774
+ if (typeof state === "function") {
775
+ const is = interpolateNumber(zoomRef.current, state(zoomRef.current));
776
+ transition().ease(zooming.current ? easeLinear : easeSinOut).duration(200).tween("scale", () => (t) => setZoom(is(t))).on("end", () => {
777
+ zooming.current = false;
778
+ });
779
+ } else {
780
+ setZoom(state);
781
+ }
782
+ },
783
+ setTranslation,
784
+ setRotation
785
+ };
786
+ }, [
787
+ canvas
788
+ ]);
789
+ const generator = useMemo2(() => canvas && projection && geoPath2(projection, canvas.getContext("2d", {
790
+ alpha: false
791
+ })), [
792
+ canvas,
793
+ projection
794
+ ]);
795
+ useEffect4(() => {
796
+ if (canvas && projection) {
797
+ timer(() => {
798
+ projection.scale(Math.min(size.width, size.height) / 2 * zoom).translate([
799
+ size.width / 2 + (translation?.x ?? 0),
800
+ size.height / 2 + (translation?.y ?? 0)
801
+ ]).rotate(rotation ?? [
802
+ 0,
803
+ 0,
804
+ 0
805
+ ]);
806
+ renderLayers(generator, layers, zoom, styles);
807
+ });
808
+ }
809
+ }, [
810
+ generator,
811
+ size,
812
+ zoom,
813
+ translation,
814
+ rotation,
815
+ layers
816
+ ]);
817
+ if (!size.width || !size.height) {
818
+ return null;
874
819
  }
820
+ return /* @__PURE__ */ React2.createElement("canvas", {
821
+ ref: canvasRef,
822
+ width: size.width,
823
+ height: size.height
824
+ });
825
+ });
826
+ var GlobeDebug = ({ position = "topleft" }) => {
827
+ const { size, zoom, translation, rotation } = useGlobeContext();
828
+ return /* @__PURE__ */ React2.createElement("div", {
829
+ className: mx("z-10 absolute w-96 p-2 overflow-hidden border border-green-700 rounded-sm", controlPositions[position])
830
+ }, /* @__PURE__ */ React2.createElement("pre", {
831
+ className: "font-mono text-xs text-green-700"
832
+ }, JSON.stringify({
833
+ size,
834
+ zoom,
835
+ translation,
836
+ rotation
837
+ }, null, 2)));
875
838
  };
876
839
  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
- }
840
+ return /* @__PURE__ */ React2.createElement("div", {
841
+ className: mx("z-10 absolute overflow-hidden", controlPositions[position], classNames)
842
+ }, children);
885
843
  };
886
844
  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
- }
845
+ return /* @__PURE__ */ React2.createElement("div", {
846
+ className: mx("z-10 absolute overflow-hidden", controlPositions[position])
847
+ }, children);
921
848
  };
849
+ var GlobeZoom = ({ onAction, position = "bottomleft", ...props }) => /* @__PURE__ */ React2.createElement(CustomControl, {
850
+ position,
851
+ ...props
852
+ }, /* @__PURE__ */ React2.createElement(ZoomControls, {
853
+ onAction
854
+ }));
855
+ var GlobeAction = ({ onAction, position = "bottomright", ...props }) => /* @__PURE__ */ React2.createElement(CustomControl, {
856
+ position,
857
+ ...props
858
+ }, /* @__PURE__ */ React2.createElement(ActionControls, {
859
+ onAction
860
+ }));
922
861
  var Globe = {
923
862
  Root: GlobeRoot,
924
863
  Canvas: GlobeCanvas,
@@ -929,16 +868,14 @@ var Globe = {
929
868
  };
930
869
 
931
870
  // src/components/Map/Map.tsx
932
- import { useSignals as _useSignals4 } from "@preact-signals/safe-react/tracking";
933
871
  import "leaflet/dist/leaflet.css";
934
872
  import { createContext as createContext2 } from "@radix-ui/react-context";
935
873
  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";
874
+ import React3, { forwardRef as forwardRef2, useEffect as useEffect5, useImperativeHandle as useImperativeHandle2, useRef as useRef2 } from "react";
937
875
  import { createRoot } from "react-dom/client";
938
- import { MapContainer, Marker, Popup, TileLayer, useMap } from "react-leaflet";
939
- import { debounce } from "@dxos/async";
876
+ import { MapContainer, Marker, Popup, TileLayer, useMap, useMapEvents } from "react-leaflet";
940
877
  import { ThemeProvider, Tooltip } from "@dxos/react-ui";
941
- import { defaultTx, mx as mx2 } from "@dxos/react-ui-theme";
878
+ import { composable as composable2, composableProps as composableProps2, defaultTx, mx as mx2 } from "@dxos/ui-theme";
942
879
  var defaults = {
943
880
  center: {
944
881
  lat: 51,
@@ -946,216 +883,183 @@ var defaults = {
946
883
  },
947
884
  zoom: 4
948
885
  };
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
- }
886
+ var [MapContextProvider, useMapContext] = createContext2("Map");
887
+ var MapRoot = composable2(({ children, onChange, ...props }, forwardedRef) => {
888
+ const attention = false;
889
+ return /* @__PURE__ */ React3.createElement(MapContextProvider, {
890
+ attention,
891
+ onChange
892
+ }, /* @__PURE__ */ React3.createElement("div", {
893
+ ...composableProps2(props, {
894
+ role: "none",
895
+ classNames: "dx-container grid dx-focus-ring-inset"
896
+ }),
897
+ ref: forwardedRef
898
+ }, children));
1019
899
  });
1020
900
  MapRoot.displayName = "Map.Root";
901
+ var MAP_CONTENT_NAME = "Map.Content";
902
+ var MapContent = /* @__PURE__ */ forwardRef2(({ classNames, scrollWheelZoom = true, doubleClickZoom = true, touchZoom = true, center, zoom, children, ...props }, forwardedRef) => {
903
+ const { attention } = useMapContext(MAP_CONTENT_NAME);
904
+ const mapRef = useRef2(null);
905
+ const map = mapRef.current;
906
+ useImperativeHandle2(forwardedRef, () => ({
907
+ setCenter: (center2, zoom2) => {
908
+ mapRef.current?.setView(center2, zoom2);
909
+ },
910
+ setZoom: (cb) => {
911
+ mapRef.current?.setZoom(cb(mapRef.current?.getZoom() ?? 0));
912
+ }
913
+ }), []);
914
+ useEffect5(() => {
915
+ if (!map) {
916
+ return;
917
+ }
918
+ if (attention) {
919
+ map.scrollWheelZoom.enable();
920
+ } else {
921
+ map.scrollWheelZoom.disable();
922
+ }
923
+ }, [
924
+ map,
925
+ attention
926
+ ]);
927
+ return /* @__PURE__ */ React3.createElement(MapContainer, {
928
+ ...props,
929
+ className: mx2("group relative grid bg-base-surface!", classNames),
930
+ attributionControl: false,
931
+ zoomControl: false,
932
+ scrollWheelZoom,
933
+ doubleClickZoom,
934
+ touchZoom,
935
+ center: center ?? defaults.center,
936
+ zoom: zoom ?? defaults.zoom,
937
+ whenReady: () => {
938
+ },
939
+ ref: mapRef
940
+ }, children);
941
+ });
942
+ MapContent.displayName = "Map.Content";
943
+ var MAP_TILES_NAME = "Map.Tiles";
1021
944
  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
- }
945
+ const ref = useRef2(null);
946
+ const { onChange } = useMapContext(MAP_TILES_NAME);
947
+ useMapEvents({
948
+ zoomstart: (ev) => {
949
+ onChange?.({
950
+ center: ev.target.getCenter(),
951
+ zoom: ev.target.getZoom()
952
+ });
953
+ }
954
+ });
955
+ const { attention } = useMapContext(MAP_TILES_NAME);
956
+ useEffect5(() => {
957
+ if (ref.current) {
958
+ ref.current.getContainer().dataset.attention = attention ? "1" : "0";
959
+ }
960
+ }, [
961
+ attention
962
+ ]);
963
+ return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(TileLayer, {
964
+ ref,
965
+ "data-attention": attention,
966
+ detectRetina: true,
967
+ className: 'dark:grayscale dark:invert data-[attention="0"]:!opacity-80',
968
+ url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
969
+ keepBuffer: 4
970
+ }));
1044
971
  };
1045
- MapTiles.displayName = "Map.Tiles";
972
+ MapTiles.displayName = MAP_TILES_NAME;
1046
973
  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
- }
974
+ const map = useMap();
975
+ useEffect5(() => {
976
+ if (markers.length > 0) {
977
+ const bounds = latLngBounds(markers.map((marker) => marker.location));
978
+ map.fitBounds(bounds);
979
+ } else {
980
+ map.setView(defaults.center, defaults.zoom);
981
+ }
982
+ }, [
983
+ markers
984
+ ]);
985
+ return /* @__PURE__ */ React3.createElement(React3.Fragment, null, markers?.map(({ id, title, location: { lat, lng } }) => {
986
+ return /* @__PURE__ */ React3.createElement(Marker, {
987
+ key: id,
988
+ position: {
989
+ lat,
990
+ lng
991
+ },
992
+ icon: (
993
+ // TODO(burdon): Create custom icon from bundled assets.
994
+ // TODO(burdon): Selection state.
995
+ new L.Icon({
996
+ iconUrl: "https://dxos.network/marker-icon.png",
997
+ iconRetinaUrl: "https://dxos.network/marker-icon-2x.png",
998
+ shadowUrl: "https://dxos.network/marker-shadow.png",
999
+ iconSize: [
1000
+ 25,
1001
+ 41
1002
+ ],
1003
+ iconAnchor: [
1004
+ 12,
1005
+ 41
1006
+ ],
1007
+ popupAnchor: [
1008
+ 1,
1009
+ -34
1010
+ ],
1011
+ shadowSize: [
1012
+ 41,
1013
+ 41
1014
+ ]
1015
+ })
1016
+ )
1017
+ }, title && /* @__PURE__ */ React3.createElement(Popup, null, title));
1018
+ }));
1097
1019
  };
1098
1020
  MapMarkers.displayName = "Map.Markers";
1099
1021
  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
- }
1022
+ const map = useMap();
1023
+ useEffect5(() => {
1024
+ const control = new Control({
1025
+ position
1026
+ });
1027
+ control.onAdd = () => {
1028
+ const container = DomUtil.create("div", mx2("m-0!", controlPositions[position]));
1029
+ DomEvent.disableClickPropagation(container);
1030
+ DomEvent.disableScrollPropagation(container);
1031
+ const root = createRoot(container);
1032
+ root.render(/* @__PURE__ */ React3.createElement(ThemeProvider, {
1033
+ tx: defaultTx
1034
+ }, /* @__PURE__ */ React3.createElement(Tooltip.Provider, null, children)));
1035
+ return container;
1036
+ };
1037
+ control.addTo(map);
1038
+ return () => {
1039
+ control.remove();
1040
+ };
1041
+ }, [
1042
+ map,
1043
+ position,
1044
+ children
1045
+ ]);
1046
+ return null;
1156
1047
  };
1048
+ var MapZoom = ({ onAction, position = "bottomleft", ...props }) => /* @__PURE__ */ React3.createElement(CustomControl2, {
1049
+ position,
1050
+ ...props
1051
+ }, /* @__PURE__ */ React3.createElement(ZoomControls, {
1052
+ onAction
1053
+ }));
1054
+ var MapAction = ({ onAction, position = "bottomright", ...props }) => /* @__PURE__ */ React3.createElement(CustomControl2, {
1055
+ position,
1056
+ ...props
1057
+ }, /* @__PURE__ */ React3.createElement(ActionControls, {
1058
+ onAction
1059
+ }));
1157
1060
  var Map = {
1158
1061
  Root: MapRoot,
1062
+ Content: MapContent,
1159
1063
  Tiles: MapTiles,
1160
1064
  Markers: MapMarkers,
1161
1065
  Zoom: MapZoom,
@@ -1164,7 +1068,7 @@ var Map = {
1164
1068
  export {
1165
1069
  ActionControls,
1166
1070
  Globe,
1167
- GlobeContextProvider,
1071
+ GlobeContext,
1168
1072
  Map,
1169
1073
  ZoomControls,
1170
1074
  closestPoint,
@@ -1176,7 +1080,6 @@ export {
1176
1080
  geoPoint,
1177
1081
  geoToPosition,
1178
1082
  getDistance,
1179
- loadTopology,
1180
1083
  positionToRotation,
1181
1084
  renderLayers,
1182
1085
  restrictAxis,