@dxos/react-ui-geo 0.8.4-main.84f28bd → 0.8.4-main.a4bbb77

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 (74) hide show
  1. package/data/airports.ts +1 -1
  2. package/data/cities.ts +1 -1
  3. package/data/countries-110m.ts +1 -1
  4. package/data/countries-dots-3.ts +1 -1
  5. package/data/countries-dots-4.ts +1 -1
  6. package/dist/lib/browser/chunk-GMWLKTLN.mjs +9 -0
  7. package/dist/lib/browser/{countries-110m-37VAAFCK.mjs → countries-110m-ZM3ZIEFS.mjs} +1 -1
  8. package/dist/lib/browser/countries-110m-ZM3ZIEFS.mjs.map +7 -0
  9. package/dist/lib/browser/data.mjs +1 -1
  10. package/dist/lib/browser/index.mjs +174 -146
  11. package/dist/lib/browser/index.mjs.map +3 -3
  12. package/dist/lib/browser/meta.json +1 -1
  13. package/dist/lib/node-esm/{chunk-OPJPAAEK.mjs → chunk-JODBF4CC.mjs} +2 -2
  14. package/dist/lib/node-esm/{countries-110m-36TTKK5B.mjs → countries-110m-3SFASWVD.mjs} +1 -1
  15. package/dist/lib/node-esm/countries-110m-3SFASWVD.mjs.map +7 -0
  16. package/dist/lib/node-esm/data.mjs +1 -1
  17. package/dist/lib/node-esm/index.mjs +174 -146
  18. package/dist/lib/node-esm/index.mjs.map +3 -3
  19. package/dist/lib/node-esm/meta.json +1 -1
  20. package/dist/types/src/components/Globe/Globe.d.ts +1 -1
  21. package/dist/types/src/components/Globe/Globe.d.ts.map +1 -1
  22. package/dist/types/src/components/Globe/Globe.stories.d.ts +25 -9
  23. package/dist/types/src/components/Globe/Globe.stories.d.ts.map +1 -1
  24. package/dist/types/src/components/Map/Map.d.ts +25 -12
  25. package/dist/types/src/components/Map/Map.d.ts.map +1 -1
  26. package/dist/types/src/components/Map/Map.stories.d.ts +14 -8
  27. package/dist/types/src/components/Map/Map.stories.d.ts.map +1 -1
  28. package/dist/types/src/components/Toolbar/Controls.d.ts.map +1 -1
  29. package/dist/types/src/components/index.d.ts +0 -1
  30. package/dist/types/src/components/index.d.ts.map +1 -1
  31. package/dist/types/src/hooks/context.d.ts +7 -7
  32. package/dist/types/src/hooks/context.d.ts.map +1 -1
  33. package/dist/types/src/hooks/useGlobeZoomHandler.d.ts +1 -1
  34. package/dist/types/src/hooks/useGlobeZoomHandler.d.ts.map +1 -1
  35. package/dist/types/src/hooks/useMapZoomHandler.d.ts +1 -1
  36. package/dist/types/src/hooks/useMapZoomHandler.d.ts.map +1 -1
  37. package/dist/types/src/hooks/useSpinner.d.ts +1 -1
  38. package/dist/types/src/hooks/useSpinner.d.ts.map +1 -1
  39. package/dist/types/src/hooks/useTour.d.ts +4 -3
  40. package/dist/types/src/hooks/useTour.d.ts.map +1 -1
  41. package/dist/types/src/index.d.ts +1 -1
  42. package/dist/types/src/index.d.ts.map +1 -1
  43. package/dist/types/src/types.d.ts +2 -1
  44. package/dist/types/src/types.d.ts.map +1 -1
  45. package/dist/types/src/util/path.d.ts +5 -8
  46. package/dist/types/src/util/path.d.ts.map +1 -1
  47. package/dist/types/src/util/render.d.ts +4 -4
  48. package/dist/types/src/util/render.d.ts.map +1 -1
  49. package/dist/types/tsconfig.tsbuildinfo +1 -1
  50. package/package.json +22 -19
  51. package/src/components/Globe/Globe.stories.tsx +81 -33
  52. package/src/components/Globe/Globe.tsx +74 -58
  53. package/src/components/Map/Map.stories.tsx +25 -14
  54. package/src/components/Map/Map.tsx +206 -91
  55. package/src/components/Toolbar/Controls.tsx +2 -6
  56. package/src/components/index.ts +0 -2
  57. package/src/hooks/context.tsx +10 -10
  58. package/src/hooks/useGlobeZoomHandler.ts +3 -3
  59. package/src/hooks/useMapZoomHandler.ts +1 -1
  60. package/src/hooks/useSpinner.ts +2 -1
  61. package/src/hooks/useTour.ts +9 -8
  62. package/src/index.ts +1 -1
  63. package/src/types.ts +3 -1
  64. package/src/util/inertia.ts +1 -1
  65. package/src/util/path.ts +5 -6
  66. package/src/util/render.ts +5 -3
  67. package/dist/lib/browser/chunk-CYCBMCOP.mjs +0 -9
  68. package/dist/lib/browser/countries-110m-37VAAFCK.mjs.map +0 -7
  69. package/dist/lib/node-esm/countries-110m-36TTKK5B.mjs.map +0 -7
  70. package/dist/types/src/components/types.d.ts +0 -15
  71. package/dist/types/src/components/types.d.ts.map +0 -1
  72. package/src/components/types.ts +0 -19
  73. /package/dist/lib/browser/{chunk-CYCBMCOP.mjs.map → chunk-GMWLKTLN.mjs.map} +0 -0
  74. /package/dist/lib/node-esm/{chunk-OPJPAAEK.mjs.map → chunk-JODBF4CC.mjs.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
2
  import {
3
3
  loadTopology
4
- } from "./chunk-OPJPAAEK.mjs";
4
+ } from "./chunk-JODBF4CC.mjs";
5
5
  export {
6
6
  loadTopology
7
7
  };
@@ -1,11 +1,11 @@
1
1
  import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
2
  import {
3
3
  loadTopology
4
- } from "./chunk-OPJPAAEK.mjs";
4
+ } from "./chunk-JODBF4CC.mjs";
5
5
 
6
6
  // src/components/Globe/Globe.tsx
7
7
  import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
8
- import { geoMercator, geoOrthographic, geoPath as geoPath2, geoTransverseMercator, interpolateNumber, transition, easeLinear, easeSinOut } from "d3";
8
+ import { easeLinear, easeSinOut, geoMercator, geoOrthographic, geoPath as geoPath2, geoTransverseMercator, interpolateNumber, transition } from "d3";
9
9
  import React3, { forwardRef, useEffect as useEffect4, useImperativeHandle, useMemo as useMemo2, useRef, useState as useState3 } from "react";
10
10
  import { useResizeDetector } from "react-resize-detector";
11
11
  import { useDynamicRef, useThemeContext } from "@dxos/react-ui";
@@ -17,22 +17,22 @@ import React, { createContext, useContext } from "react";
17
17
  import { raise } from "@dxos/debug";
18
18
  import { useControlledState } from "@dxos/react-ui";
19
19
  var GlobeContext = /* @__PURE__ */ createContext(void 0);
20
- var GlobeContextProvider = ({ children, size, center: _center, scale: _scale, translation: _translation, rotation: _rotation }) => {
20
+ var GlobeContextProvider = ({ children, size, center: _center, zoom: _zoom, translation: _translation, rotation: _rotation }) => {
21
21
  var _effect = _useSignals();
22
22
  try {
23
23
  const [center, setCenter] = useControlledState(_center);
24
- const [scale, setScale] = useControlledState(_scale);
24
+ const [zoom, setZoom] = useControlledState(_zoom);
25
25
  const [translation, setTranslation] = useControlledState(_translation);
26
26
  const [rotation, setRotation] = useControlledState(_rotation);
27
27
  return /* @__PURE__ */ React.createElement(GlobeContext.Provider, {
28
28
  value: {
29
29
  size,
30
30
  center,
31
- scale,
31
+ zoom,
32
32
  translation,
33
33
  rotation,
34
34
  setCenter,
35
- setScale,
35
+ setZoom,
36
36
  setTranslation,
37
37
  setRotation
38
38
  }
@@ -65,7 +65,7 @@ var timer = (cb) => {
65
65
  };
66
66
 
67
67
  // src/util/inertia.ts
68
- import { select, drag, timer as timer2 } from "d3";
68
+ import { drag, select, timer as timer2 } from "d3";
69
69
  import versor from "versor";
70
70
  var restrictAxis = (axis) => (original, current) => current.map((d, i) => axis[i] ? d : original[i]);
71
71
  var geoInertiaDrag = (target, render, projection, options) => {
@@ -377,8 +377,8 @@ var renderLayers = (generator, layers = [], scale, styles) => {
377
377
  generator.pointRadius(value * scale);
378
378
  } else {
379
379
  context[key] = value;
380
- fill ||= key === "fillStyle";
381
- stroke ||= key === "strokeStyle";
380
+ fill || (fill = key === "fillStyle");
381
+ stroke || (stroke = key === "strokeStyle");
382
382
  }
383
383
  });
384
384
  }
@@ -435,11 +435,11 @@ var useGlobeZoomHandler = (controller) => {
435
435
  }
436
436
  switch (event) {
437
437
  case "zoom-in": {
438
- controller.setScale((scale) => scale * 1.1);
438
+ controller.setZoom((zoom) => zoom * 1.1);
439
439
  break;
440
440
  }
441
441
  case "zoom-out": {
442
- controller.setScale((scale) => scale * 0.9);
442
+ controller.setZoom((zoom) => zoom * 0.9);
443
443
  break;
444
444
  }
445
445
  }
@@ -524,8 +524,8 @@ var useSpinner = (controller, options = {}) => {
524
524
  };
525
525
 
526
526
  // src/hooks/useTour.ts
527
- import { geoPath, geoInterpolate, geoDistance, selection as d3Selection } from "d3";
528
- import { useEffect as useEffect3, useState as useState2, useMemo } from "react";
527
+ import { selection as d3Selection, geoDistance, geoInterpolate, geoPath } from "d3";
528
+ import { useEffect as useEffect3, useMemo, useState as useState2 } from "react";
529
529
  import versor2 from "versor";
530
530
  var TRANSITION_NAME = "globe-tour";
531
531
  var defaultDuration = 1500;
@@ -572,7 +572,7 @@ var useTour = (controller, points, options = {}) => {
572
572
  {
573
573
  context.beginPath();
574
574
  context.strokeStyle = options?.styles?.arc?.strokeStyle ?? "yellow";
575
- context.lineWidth = (options?.styles?.arc?.lineWidth ?? 1.5) * (controller?.scale ?? 1);
575
+ context.lineWidth = (options?.styles?.arc?.lineWidth ?? 1.5) * (controller?.zoom ?? 1);
576
576
  context.setLineDash(options?.styles?.arc?.lineDash ?? []);
577
577
  path({
578
578
  type: "LineString",
@@ -584,7 +584,7 @@ var useTour = (controller, points, options = {}) => {
584
584
  context.stroke();
585
585
  context.beginPath();
586
586
  context.fillStyle = options?.styles?.cursor?.fillStyle ?? "orange";
587
- path.pointRadius((options?.styles?.cursor?.pointRadius ?? 2) * (controller?.scale ?? 1));
587
+ path.pointRadius((options?.styles?.cursor?.pointRadius ?? 2) * (controller?.zoom ?? 1));
588
588
  path({
589
589
  type: "Point",
590
590
  coordinates: ip(t22)
@@ -598,7 +598,7 @@ var useTour = (controller, points, options = {}) => {
598
598
  await transition2.end();
599
599
  last = next;
600
600
  }
601
- } catch (err) {
601
+ } catch {
602
602
  } finally {
603
603
  setRunning(false);
604
604
  }
@@ -634,11 +634,10 @@ var ZoomControls = ({ classNames, onAction }) => {
634
634
  try {
635
635
  return /* @__PURE__ */ React2.createElement(Toolbar.Root, {
636
636
  classNames: [
637
- "gap-1",
637
+ "gap-2",
638
638
  classNames
639
639
  ]
640
640
  }, /* @__PURE__ */ React2.createElement(IconButton, {
641
- //
642
641
  icon: "ph--plus--regular",
643
642
  label: "zoom in",
644
643
  iconOnly: true,
@@ -646,7 +645,6 @@ var ZoomControls = ({ classNames, onAction }) => {
646
645
  classNames: "px-0 aspect-square",
647
646
  onClick: () => onAction?.("zoom-in")
648
647
  }), /* @__PURE__ */ React2.createElement(IconButton, {
649
- //
650
648
  icon: "ph--minus--regular",
651
649
  label: "zoom out",
652
650
  iconOnly: true,
@@ -663,11 +661,10 @@ var ActionControls = ({ classNames, onAction }) => {
663
661
  try {
664
662
  return /* @__PURE__ */ React2.createElement(Toolbar.Root, {
665
663
  classNames: [
666
- "gap-1",
664
+ "gap-2",
667
665
  classNames
668
666
  ]
669
667
  }, /* @__PURE__ */ React2.createElement(IconButton, {
670
- //
671
668
  icon: "ph--play--regular",
672
669
  label: "start",
673
670
  iconOnly: true,
@@ -675,7 +672,6 @@ var ActionControls = ({ classNames, onAction }) => {
675
672
  classNames: "px-0 aspect-square",
676
673
  onClick: () => onAction?.("start")
677
674
  }), /* @__PURE__ */ React2.createElement(IconButton, {
678
- //
679
675
  icon: "ph--globe-hemisphere-west--regular",
680
676
  label: "toggle",
681
677
  iconOnly: true,
@@ -781,11 +777,11 @@ var GlobeCanvas = /* @__PURE__ */ forwardRef(({ projection: _projection, topolog
781
777
  features,
782
778
  styles
783
779
  ]);
784
- const { size, center, scale, translation, rotation, setCenter, setScale, setTranslation, setRotation } = useGlobeContext();
785
- const scaleRef = useDynamicRef(scale);
780
+ const { size, center, zoom, translation, rotation, setCenter, setZoom, setTranslation, setRotation } = useGlobeContext();
781
+ const zoomRef = useDynamicRef(zoom);
786
782
  useEffect4(() => {
787
783
  if (center) {
788
- setScale(1);
784
+ setZoom(1);
789
785
  setRotation(positionToRotation(geoToPosition(center)));
790
786
  }
791
787
  }, [
@@ -797,20 +793,20 @@ var GlobeCanvas = /* @__PURE__ */ forwardRef(({ projection: _projection, topolog
797
793
  canvas,
798
794
  projection,
799
795
  center,
800
- get scale() {
801
- return scaleRef.current;
796
+ get zoom() {
797
+ return zoomRef.current;
802
798
  },
803
799
  translation,
804
800
  rotation,
805
801
  setCenter,
806
- setScale: (s) => {
802
+ setZoom: (s) => {
807
803
  if (typeof s === "function") {
808
- const is = interpolateNumber(scaleRef.current, s(scaleRef.current));
809
- transition().ease(zooming.current ? easeLinear : easeSinOut).duration(200).tween("scale", () => (t) => setScale(is(t))).on("end", () => {
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", () => {
810
806
  zooming.current = false;
811
807
  });
812
808
  } else {
813
- setScale(s);
809
+ setZoom(s);
814
810
  }
815
811
  },
816
812
  setTranslation,
@@ -828,7 +824,7 @@ var GlobeCanvas = /* @__PURE__ */ forwardRef(({ projection: _projection, topolog
828
824
  useEffect4(() => {
829
825
  if (canvas && projection) {
830
826
  timer(() => {
831
- projection.scale(Math.min(size.width, size.height) / 2 * scale).translate([
827
+ projection.scale(Math.min(size.width, size.height) / 2 * zoom).translate([
832
828
  size.width / 2 + (translation?.x ?? 0),
833
829
  size.height / 2 + (translation?.y ?? 0)
834
830
  ]).rotate(rotation ?? [
@@ -836,13 +832,13 @@ var GlobeCanvas = /* @__PURE__ */ forwardRef(({ projection: _projection, topolog
836
832
  0,
837
833
  0
838
834
  ]);
839
- renderLayers(generator, layers, scale, styles);
835
+ renderLayers(generator, layers, zoom, styles);
840
836
  });
841
837
  }
842
838
  }, [
843
839
  generator,
844
840
  size,
845
- scale,
841
+ zoom,
846
842
  translation,
847
843
  rotation,
848
844
  layers
@@ -862,14 +858,14 @@ var GlobeCanvas = /* @__PURE__ */ forwardRef(({ projection: _projection, topolog
862
858
  var GlobeDebug = ({ position = "topleft" }) => {
863
859
  var _effect = _useSignals3();
864
860
  try {
865
- const { size, scale, translation, rotation } = useGlobeContext();
861
+ const { size, zoom, translation, rotation } = useGlobeContext();
866
862
  return /* @__PURE__ */ React3.createElement("div", {
867
863
  className: mx("z-10 absolute w-96 p-2 overflow-hidden border border-green-700 rounded", controlPositions[position])
868
864
  }, /* @__PURE__ */ React3.createElement("pre", {
869
865
  className: "font-mono text-xs text-green-700"
870
866
  }, JSON.stringify({
871
867
  size,
872
- scale,
868
+ zoom,
873
869
  translation,
874
870
  rotation
875
871
  }, null, 2)));
@@ -897,35 +893,37 @@ var CustomControl = ({ position, children }) => {
897
893
  _effect.f();
898
894
  }
899
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
+ }
921
+ };
900
922
  var Globe = {
901
923
  Root: GlobeRoot,
902
924
  Canvas: GlobeCanvas,
903
- Zoom: ({ onAction, position = "bottomleft", ...props }) => {
904
- var _effect = _useSignals3();
905
- try {
906
- return /* @__PURE__ */ React3.createElement(CustomControl, {
907
- position,
908
- ...props
909
- }, /* @__PURE__ */ React3.createElement(ZoomControls, {
910
- onAction
911
- }));
912
- } finally {
913
- _effect.f();
914
- }
915
- },
916
- Action: ({ onAction, position = "bottomright", ...props }) => {
917
- var _effect = _useSignals3();
918
- try {
919
- return /* @__PURE__ */ React3.createElement(CustomControl, {
920
- position,
921
- ...props
922
- }, /* @__PURE__ */ React3.createElement(ActionControls, {
923
- onAction
924
- }));
925
- } finally {
926
- _effect.f();
927
- }
928
- },
925
+ Zoom: GlobeZoom,
926
+ Action: GlobeAction,
929
927
  Debug: GlobeDebug,
930
928
  Panel: GlobePanel
931
929
  };
@@ -933,76 +931,42 @@ var Globe = {
933
931
  // src/components/Map/Map.tsx
934
932
  import { useSignals as _useSignals4 } from "@preact-signals/safe-react/tracking";
935
933
  import "leaflet/dist/leaflet.css";
934
+ import { createContext as createContext2 } from "@radix-ui/react-context";
936
935
  import L, { Control, DomEvent, DomUtil, latLngBounds } from "leaflet";
937
- import React4, { forwardRef as forwardRef2, useEffect as useEffect5, useImperativeHandle as useImperativeHandle2 } from "react";
936
+ import React4, { forwardRef as forwardRef2, useEffect as useEffect5, useImperativeHandle as useImperativeHandle2, useRef as useRef2, useState as useState4 } from "react";
938
937
  import { createRoot } from "react-dom/client";
939
938
  import { MapContainer, Marker, Popup, TileLayer, useMap } from "react-leaflet";
940
- import { useResizeDetector as useResizeDetector2 } from "react-resize-detector";
941
939
  import { debounce } from "@dxos/async";
942
940
  import { ThemeProvider, Tooltip } from "@dxos/react-ui";
943
941
  import { defaultTx, mx as mx2 } from "@dxos/react-ui-theme";
944
942
  var defaults = {
945
- // TODO(burdon): Guess location.
946
943
  center: {
947
944
  lat: 51,
948
945
  lng: 0
949
946
  },
950
947
  zoom: 4
951
948
  };
952
- var MapRoot = ({ classNames, center = defaults.center, zoom = defaults.zoom, ...props }) => {
953
- var _effect = _useSignals4();
954
- try {
955
- return /* @__PURE__ */ React4.createElement(MapContainer, {
956
- className: mx2("relative grid grow bg-baseSurface", classNames),
957
- attributionControl: false,
958
- // TODO(burdon): Only if attention.
959
- scrollWheelZoom: true,
960
- zoomControl: false,
961
- center,
962
- zoom,
963
- ...props
964
- });
965
- } finally {
966
- _effect.f();
967
- }
968
- };
969
- var MapCanvas = /* @__PURE__ */ forwardRef2(({ markers, center, zoom, onChange }, forwardedRef) => {
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) => {
970
951
  var _effect = _useSignals4();
971
952
  try {
972
- const { ref, width, height } = useResizeDetector2({
973
- refreshRate: 200
974
- });
975
- const map = useMap();
953
+ const [attention, setAttention] = useState4(false);
954
+ const mapRef = useRef2(null);
955
+ const map = mapRef.current;
976
956
  useImperativeHandle2(forwardedRef, () => ({
977
957
  setCenter: (center2, zoom2) => {
978
- map.setView(center2, zoom2);
958
+ mapRef.current?.setView(center2, zoom2);
979
959
  },
980
960
  setZoom: (cb) => {
981
- map.setZoom(cb(map.getZoom()));
961
+ mapRef.current?.setZoom(cb(mapRef.current?.getZoom() ?? 0));
982
962
  }
983
- }), [
984
- map
985
- ]);
963
+ }), []);
986
964
  useEffect5(() => {
987
- if (width && height) {
988
- map.invalidateSize();
989
- }
990
- }, [
991
- width,
992
- height
993
- ]);
994
- useEffect5(() => {
995
- if (center) {
996
- map.setView(center, zoom);
997
- } else if (zoom !== void 0) {
998
- map.setZoom(zoom);
965
+ if (!map) {
966
+ return;
999
967
  }
1000
- }, [
1001
- center,
1002
- zoom
1003
- ]);
1004
- useEffect5(() => {
1005
968
  const handler = debounce(() => {
969
+ setAttention(true);
1006
970
  onChange?.({
1007
971
  center: map.getCenter(),
1008
972
  zoom: map.getZoom()
@@ -1010,14 +974,79 @@ var MapCanvas = /* @__PURE__ */ forwardRef2(({ markers, center, zoom, onChange }
1010
974
  }, 100);
1011
975
  map.on("move", handler);
1012
976
  map.on("zoom", handler);
977
+ map.on("focus", () => setAttention(true));
978
+ map.on("blur", () => setAttention(false));
1013
979
  return () => {
1014
- map.off("move", handler);
1015
- map.off("zoom", handler);
980
+ map.off("move");
981
+ map.off("zoom");
982
+ map.off("focus");
983
+ map.off("blur");
1016
984
  };
1017
985
  }, [
1018
986
  map,
1019
987
  onChange
1020
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
+ }
1019
+ });
1020
+ MapRoot.displayName = "Map.Root";
1021
+ 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
+ }
1044
+ };
1045
+ MapTiles.displayName = "Map.Tiles";
1046
+ var MapMarkers = ({ selected, markers }) => {
1047
+ var _effect = _useSignals4();
1048
+ try {
1049
+ const map = useMap();
1021
1050
  useEffect5(() => {
1022
1051
  if (markers.length > 0) {
1023
1052
  const bounds = latLngBounds(markers.map((marker) => marker.location));
@@ -1028,13 +1057,7 @@ var MapCanvas = /* @__PURE__ */ forwardRef2(({ markers, center, zoom, onChange }
1028
1057
  }, [
1029
1058
  markers
1030
1059
  ]);
1031
- return /* @__PURE__ */ React4.createElement("div", {
1032
- ref,
1033
- className: "flex w-full h-full overflow-hidden bg-baseSurface"
1034
- }, /* @__PURE__ */ React4.createElement(TileLayer, {
1035
- className: "dark:filter dark:grayscale dark:invert",
1036
- url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
1037
- }), markers?.map(({ id, title, location: { lat, lng } }) => {
1060
+ return /* @__PURE__ */ React4.createElement(React4.Fragment, null, markers?.map(({ id, title, location: { lat, lng } }) => {
1038
1061
  return /* @__PURE__ */ React4.createElement(Marker, {
1039
1062
  key: id,
1040
1063
  position: {
@@ -1043,6 +1066,7 @@ var MapCanvas = /* @__PURE__ */ forwardRef2(({ markers, center, zoom, onChange }
1043
1066
  },
1044
1067
  icon: (
1045
1068
  // TODO(burdon): Create custom icon from bundled assets.
1069
+ // TODO(burdon): Selection state.
1046
1070
  new L.Icon({
1047
1071
  iconUrl: "https://dxos.network/marker-icon.png",
1048
1072
  iconRetinaUrl: "https://dxos.network/marker-icon-2x.png",
@@ -1070,7 +1094,8 @@ var MapCanvas = /* @__PURE__ */ forwardRef2(({ markers, center, zoom, onChange }
1070
1094
  } finally {
1071
1095
  _effect.f();
1072
1096
  }
1073
- });
1097
+ };
1098
+ MapMarkers.displayName = "Map.Markers";
1074
1099
  var CustomControl2 = ({ position, children }) => {
1075
1100
  var _effect = _useSignals4();
1076
1101
  try {
@@ -1103,35 +1128,38 @@ var CustomControl2 = ({ position, children }) => {
1103
1128
  _effect.f();
1104
1129
  }
1105
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
+ }
1156
+ };
1106
1157
  var Map = {
1107
1158
  Root: MapRoot,
1108
- Canvas: MapCanvas,
1109
- Zoom: ({ onAction, position = "bottomleft", ...props }) => {
1110
- var _effect = _useSignals4();
1111
- try {
1112
- return /* @__PURE__ */ React4.createElement(CustomControl2, {
1113
- position,
1114
- ...props
1115
- }, /* @__PURE__ */ React4.createElement(ZoomControls, {
1116
- onAction
1117
- }));
1118
- } finally {
1119
- _effect.f();
1120
- }
1121
- },
1122
- Action: ({ onAction, position = "bottomright", ...props }) => {
1123
- var _effect = _useSignals4();
1124
- try {
1125
- return /* @__PURE__ */ React4.createElement(CustomControl2, {
1126
- position,
1127
- ...props
1128
- }, /* @__PURE__ */ React4.createElement(ActionControls, {
1129
- onAction
1130
- }));
1131
- } finally {
1132
- _effect.f();
1133
- }
1134
- }
1159
+ Tiles: MapTiles,
1160
+ Markers: MapMarkers,
1161
+ Zoom: MapZoom,
1162
+ Action: MapAction
1135
1163
  };
1136
1164
  export {
1137
1165
  ActionControls,