@dxos/react-ui-geo 0.8.2-staging.7ac8446 → 0.8.2

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 (36) hide show
  1. package/dist/lib/browser/index.mjs +457 -380
  2. package/dist/lib/browser/index.mjs.map +3 -3
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +455 -378
  5. package/dist/lib/node/index.cjs.map +3 -3
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/lib/node-esm/index.mjs +457 -380
  8. package/dist/lib/node-esm/index.mjs.map +3 -3
  9. package/dist/lib/node-esm/meta.json +1 -1
  10. package/dist/types/src/components/Globe/Globe.d.ts.map +1 -1
  11. package/dist/types/src/components/Map/Map.stories.d.ts +5 -4
  12. package/dist/types/src/components/Map/Map.stories.d.ts.map +1 -1
  13. package/dist/types/src/components/Toolbar/Controls.d.ts.map +1 -1
  14. package/dist/types/src/hooks/context.d.ts.map +1 -1
  15. package/dist/types/src/hooks/useDrag.d.ts.map +1 -1
  16. package/dist/types/src/hooks/useGlobeZoomHandler.d.ts.map +1 -1
  17. package/dist/types/src/hooks/useMapZoomHandler.d.ts.map +1 -1
  18. package/dist/types/src/hooks/useSpinner.d.ts.map +1 -1
  19. package/dist/types/src/hooks/useTour.d.ts +1 -1
  20. package/dist/types/src/hooks/useTour.d.ts.map +1 -1
  21. package/dist/types/src/util/debug.d.ts.map +1 -1
  22. package/dist/types/src/util/inertia.d.ts +1 -2
  23. package/dist/types/src/util/inertia.d.ts.map +1 -1
  24. package/dist/types/src/util/path.d.ts.map +1 -1
  25. package/dist/types/src/util/render.d.ts.map +1 -1
  26. package/dist/types/tsconfig.tsbuildinfo +1 -1
  27. package/package.json +12 -11
  28. package/src/components/Globe/Globe.stories.tsx +1 -1
  29. package/src/components/Globe/Globe.tsx +20 -11
  30. package/src/components/Map/Map.stories.tsx +5 -5
  31. package/src/hooks/useDrag.ts +3 -3
  32. package/src/hooks/useSpinner.ts +2 -2
  33. package/src/hooks/useTour.ts +9 -13
  34. package/src/util/inertia.ts +4 -5
  35. package/src/util/path.ts +2 -5
  36. package/src/util/render.ts +5 -6
@@ -3,42 +3,49 @@ import {
3
3
  } from "./chunk-ENCWOTYX.mjs";
4
4
 
5
5
  // packages/ui/react-ui-geo/src/components/Globe/Globe.tsx
6
- import * as d37 from "d3";
7
- import React3, { forwardRef, useEffect as useEffect4, useImperativeHandle, useMemo, useRef, useState as useState3 } from "react";
6
+ import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
7
+ import { geoMercator, geoOrthographic, geoPath as geoPath2, geoTransverseMercator, interpolateNumber, transition, easeLinear, easeSinOut } from "d3";
8
+ import React3, { forwardRef, useEffect as useEffect4, useImperativeHandle, useMemo as useMemo2, useRef, useState as useState3 } from "react";
8
9
  import { useResizeDetector } from "react-resize-detector";
9
10
  import { useDynamicRef, useThemeContext } from "@dxos/react-ui";
10
11
  import { mx } from "@dxos/react-ui-theme";
11
12
 
12
13
  // packages/ui/react-ui-geo/src/hooks/context.tsx
14
+ import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
13
15
  import React, { createContext, useContext } from "react";
14
16
  import { raise } from "@dxos/debug";
15
17
  import { useControlledState } from "@dxos/react-ui";
16
18
  var GlobeContext = /* @__PURE__ */ createContext(void 0);
17
19
  var GlobeContextProvider = ({ children, size, center: _center, scale: _scale, translation: _translation, rotation: _rotation }) => {
18
- const [center, setCenter] = useControlledState(_center);
19
- const [scale, setScale] = useControlledState(_scale);
20
- const [translation, setTranslation] = useControlledState(_translation);
21
- const [rotation, setRotation] = useControlledState(_rotation);
22
- return /* @__PURE__ */ React.createElement(GlobeContext.Provider, {
23
- value: {
24
- size,
25
- center,
26
- scale,
27
- translation,
28
- rotation,
29
- setCenter,
30
- setScale,
31
- setTranslation,
32
- setRotation
33
- }
34
- }, children);
20
+ var _effect = _useSignals();
21
+ try {
22
+ const [center, setCenter] = useControlledState(_center);
23
+ const [scale, setScale] = useControlledState(_scale);
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
+ scale,
31
+ translation,
32
+ rotation,
33
+ setCenter,
34
+ setScale,
35
+ setTranslation,
36
+ setRotation
37
+ }
38
+ }, children);
39
+ } finally {
40
+ _effect.f();
41
+ }
35
42
  };
36
43
  var useGlobeContext = () => {
37
44
  return useContext(GlobeContext) ?? raise(new Error("Missing GlobeContext"));
38
45
  };
39
46
 
40
47
  // packages/ui/react-ui-geo/src/hooks/useDrag.ts
41
- import * as d34 from "d3";
48
+ import { select as select2 } from "d3";
42
49
  import { useEffect } from "react";
43
50
 
44
51
  // packages/ui/react-ui-geo/src/util/debug.ts
@@ -57,7 +64,7 @@ var timer = (cb) => {
57
64
  };
58
65
 
59
66
  // packages/ui/react-ui-geo/src/util/inertia.ts
60
- import * as d3 from "d3";
67
+ import { select, drag, timer as timer2 } from "d3";
61
68
  import versor from "versor";
62
69
  var restrictAxis = (axis) => (original, current) => current.map((d, i) => axis[i] ? d : original[i]);
63
70
  var geoInertiaDrag = (target, render, projection, options) => {
@@ -67,7 +74,7 @@ var geoInertiaDrag = (target, render, projection, options) => {
67
74
  if (target.node) {
68
75
  target = target.node();
69
76
  }
70
- target = d3.select(target);
77
+ target = select(target);
71
78
  const inertia = geoInertiaDragHelper({
72
79
  projection,
73
80
  render: (rotation) => {
@@ -91,7 +98,7 @@ var geoInertiaDrag = (target, render, projection, options) => {
91
98
  time: options.time,
92
99
  hold: options.hold
93
100
  });
94
- target.call(d3.drag().on("start", inertia.start).on("drag", inertia.move).on("end", inertia.end));
101
+ target.call(drag().on("start", inertia.start).on("drag", inertia.move).on("end", inertia.end));
95
102
  return inertia;
96
103
  };
97
104
  var geoInertiaDragHelper = (opt) => {
@@ -152,7 +159,7 @@ function inertiaHelper(opt) {
152
159
  0,
153
160
  0
154
161
  ],
155
- timer: d3.timer(() => {
162
+ timer: timer2(() => {
156
163
  }),
157
164
  time: 0,
158
165
  t: 0,
@@ -232,7 +239,7 @@ function inertiaHelper(opt) {
232
239
  }
233
240
 
234
241
  // packages/ui/react-ui-geo/src/util/path.ts
235
- import * as d32 from "d3";
242
+ import { geoCircle as d3GeoCircle } from "d3";
236
243
  var positionToRotation = ([lng, lat], tilt = 0) => [
237
244
  -lng,
238
245
  tilt - lat,
@@ -246,7 +253,7 @@ var geoPoint = (point) => ({
246
253
  type: "Point",
247
254
  coordinates: geoToPosition(point)
248
255
  });
249
- var geoCircle2 = ({ lat, lng }, radius) => d32.geoCircle().radius(radius).center([
256
+ var geoCircle = ({ lat, lng }, radius) => d3GeoCircle().radius(radius).center([
250
257
  lng,
251
258
  lat
252
259
  ])();
@@ -285,8 +292,8 @@ var getDistance = (point1, point2) => {
285
292
  };
286
293
 
287
294
  // packages/ui/react-ui-geo/src/util/render.ts
288
- import * as d33 from "d3";
289
- import * as topojson from "topojson-client";
295
+ import { geoGraticule } from "d3";
296
+ import { feature, mesh } from "topojson-client";
290
297
  var createLayers = (topology, features, styles) => {
291
298
  const layers = [];
292
299
  if (styles.water) {
@@ -300,7 +307,7 @@ var createLayers = (topology, features, styles) => {
300
307
  if (styles.graticule) {
301
308
  layers.push({
302
309
  styles: styles.graticule,
303
- path: d33.geoGraticule().step([
310
+ path: geoGraticule().step([
304
311
  6,
305
312
  6
306
313
  ])()
@@ -310,13 +317,13 @@ var createLayers = (topology, features, styles) => {
310
317
  if (topology.objects.land && styles.land) {
311
318
  layers.push({
312
319
  styles: styles.land,
313
- path: topojson.feature(topology, topology.objects.land)
320
+ path: feature(topology, topology.objects.land)
314
321
  });
315
322
  }
316
323
  if (topology.objects.countries && styles.border) {
317
324
  layers.push({
318
325
  styles: styles.border,
319
- path: topojson.mesh(topology, topology.objects.countries, (a, b) => a !== b)
326
+ path: mesh(topology, topology.objects.countries, (a, b) => a !== b)
320
327
  });
321
328
  }
322
329
  if (topology.objects.dots && styles.dots) {
@@ -390,7 +397,7 @@ var useDrag = (controller, options = {}) => {
390
397
  if (!canvas || options.disabled) {
391
398
  return;
392
399
  }
393
- geoInertiaDrag(d34.select(canvas), () => {
400
+ geoInertiaDrag(select2(canvas), () => {
394
401
  controller.setRotation(controller.projection.rotate());
395
402
  options.onUpdate?.({
396
403
  type: "move",
@@ -409,7 +416,7 @@ var useDrag = (controller, options = {}) => {
409
416
  })
410
417
  });
411
418
  return () => {
412
- cancelDrag(d34.select(canvas));
419
+ cancelDrag(select2(canvas));
413
420
  };
414
421
  }, [
415
422
  controller,
@@ -463,12 +470,12 @@ var useMapZoomHandler = (controller) => {
463
470
  };
464
471
 
465
472
  // packages/ui/react-ui-geo/src/hooks/useSpinner.ts
466
- import * as d35 from "d3";
473
+ import { timer as d3Timer } from "d3";
467
474
  import { useEffect as useEffect2, useState } from "react";
468
475
  var useSpinner = (controller, options = {}) => {
469
476
  const [running, setRunning] = useState(false);
470
477
  useEffect2(() => {
471
- let timer4;
478
+ let timer3;
472
479
  const start = () => {
473
480
  const delta = options.delta ?? [
474
481
  1e-3,
@@ -477,7 +484,7 @@ var useSpinner = (controller, options = {}) => {
477
484
  ];
478
485
  let t = 0;
479
486
  let lastRotation = controller.projection.rotate();
480
- timer4 = d35.timer((elapsed) => {
487
+ timer3 = d3Timer((elapsed) => {
481
488
  const dt = elapsed - t;
482
489
  t = elapsed;
483
490
  const rotation = [
@@ -490,9 +497,9 @@ var useSpinner = (controller, options = {}) => {
490
497
  });
491
498
  };
492
499
  const stop = () => {
493
- if (timer4) {
494
- timer4.stop();
495
- timer4 = void 0;
500
+ if (timer3) {
501
+ timer3.stop();
502
+ timer3 = void 0;
496
503
  }
497
504
  };
498
505
  if (controller && running) {
@@ -516,19 +523,17 @@ var useSpinner = (controller, options = {}) => {
516
523
  };
517
524
 
518
525
  // packages/ui/react-ui-geo/src/hooks/useTour.ts
519
- import * as d36 from "d3";
520
- import { useEffect as useEffect3, useState as useState2 } from "react";
526
+ import { geoPath, geoInterpolate, geoDistance, selection as d3Selection } from "d3";
527
+ import { useEffect as useEffect3, useState as useState2, useMemo } from "react";
521
528
  import versor2 from "versor";
522
- import { log } from "@dxos/log";
523
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-geo/src/hooks/useTour.ts";
524
529
  var TRANSITION_NAME = "globe-tour";
525
530
  var defaultDuration = 1500;
526
531
  var useTour = (controller, points, options = {}) => {
527
- const selection2 = d36.selection();
532
+ const selection = useMemo(() => d3Selection(), []);
528
533
  const [running, setRunning] = useState2(options.running ?? false);
529
534
  useEffect3(() => {
530
535
  if (!running) {
531
- selection2.interrupt(TRANSITION_NAME);
536
+ selection.interrupt(TRANSITION_NAME);
532
537
  return;
533
538
  }
534
539
  let t;
@@ -538,7 +543,7 @@ var useTour = (controller, points, options = {}) => {
538
543
  const context = canvas.getContext("2d", {
539
544
  alpha: false
540
545
  });
541
- const path = d36.geoPath(projection, context).pointRadius(2);
546
+ const path = geoPath(projection, context).pointRadius(2);
542
547
  const tilt = options.tilt ?? 0;
543
548
  let last;
544
549
  try {
@@ -554,12 +559,12 @@ var useTour = (controller, points, options = {}) => {
554
559
  }
555
560
  const p1 = last ? geoToPosition(last) : void 0;
556
561
  const p2 = geoToPosition(next);
557
- const ip = d36.geoInterpolate(p1 || p2, p2);
558
- const distance = d36.geoDistance(p1 || p2, p2);
562
+ const ip = geoInterpolate(p1 || p2, p2);
563
+ const distance = geoDistance(p1 || p2, p2);
559
564
  const r1 = p1 ? positionToRotation(p1, tilt) : controller.projection.rotate();
560
565
  const r2 = positionToRotation(p2, tilt);
561
566
  const iv = versor2.interpolate(r1, r2);
562
- const transition2 = selection2.transition(TRANSITION_NAME).duration(Math.max(options.duration ?? defaultDuration, distance * 2e3)).tween("render", () => (t2) => {
567
+ const transition2 = selection.transition(TRANSITION_NAME).duration(Math.max(options.duration ?? defaultDuration, distance * 2e3)).tween("render", () => (t2) => {
563
568
  const t1 = Math.max(0, Math.min(1, t2 * 2 - 1));
564
569
  const t22 = Math.min(1, t2 * 2);
565
570
  context.save();
@@ -586,28 +591,20 @@ var useTour = (controller, points, options = {}) => {
586
591
  context.fill();
587
592
  }
588
593
  context.restore();
589
- if (options.autoRotate) {
590
- projection.rotate(iv(t2));
591
- setRotation(projection.rotate());
592
- }
594
+ projection.rotate(iv(t2));
595
+ setRotation(projection.rotate());
593
596
  });
594
597
  await transition2.end();
595
598
  last = next;
596
599
  }
597
600
  } catch (err) {
598
- log.catch(err, void 0, {
599
- F: __dxlog_file,
600
- L: 112,
601
- S: void 0,
602
- C: (f, a) => f(...a)
603
- });
604
601
  } finally {
605
602
  setRunning(false);
606
603
  }
607
604
  });
608
605
  return () => {
609
606
  clearTimeout(t);
610
- selection2.interrupt(TRANSITION_NAME);
607
+ selection.interrupt(TRANSITION_NAME);
611
608
  };
612
609
  }
613
610
  }, [
@@ -622,6 +619,7 @@ var useTour = (controller, points, options = {}) => {
622
619
  };
623
620
 
624
621
  // packages/ui/react-ui-geo/src/components/Toolbar/Controls.tsx
622
+ import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
625
623
  import React2 from "react";
626
624
  import { IconButton, Toolbar } from "@dxos/react-ui";
627
625
  var controlPositions = {
@@ -631,52 +629,62 @@ var controlPositions = {
631
629
  bottomright: "bottom-2 right-2"
632
630
  };
633
631
  var ZoomControls = ({ classNames, onAction }) => {
634
- return /* @__PURE__ */ React2.createElement(Toolbar.Root, {
635
- classNames: [
636
- "gap-1",
637
- classNames
638
- ]
639
- }, /* @__PURE__ */ React2.createElement(IconButton, {
640
- //
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
- //
649
- icon: "ph--minus--regular",
650
- label: "zoom out",
651
- iconOnly: true,
652
- size: 5,
653
- classNames: "px-0 aspect-square",
654
- onClick: () => onAction?.("zoom-out")
655
- }));
632
+ var _effect = _useSignals2();
633
+ try {
634
+ return /* @__PURE__ */ React2.createElement(Toolbar.Root, {
635
+ classNames: [
636
+ "gap-1",
637
+ classNames
638
+ ]
639
+ }, /* @__PURE__ */ React2.createElement(IconButton, {
640
+ //
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
+ //
649
+ icon: "ph--minus--regular",
650
+ label: "zoom out",
651
+ iconOnly: true,
652
+ size: 5,
653
+ classNames: "px-0 aspect-square",
654
+ onClick: () => onAction?.("zoom-out")
655
+ }));
656
+ } finally {
657
+ _effect.f();
658
+ }
656
659
  };
657
660
  var ActionControls = ({ classNames, onAction }) => {
658
- return /* @__PURE__ */ React2.createElement(Toolbar.Root, {
659
- classNames: [
660
- "gap-1",
661
- classNames
662
- ]
663
- }, /* @__PURE__ */ React2.createElement(IconButton, {
664
- //
665
- icon: "ph--play--regular",
666
- label: "start",
667
- iconOnly: true,
668
- size: 5,
669
- classNames: "px-0 aspect-square",
670
- onClick: () => onAction?.("start")
671
- }), /* @__PURE__ */ React2.createElement(IconButton, {
672
- //
673
- icon: "ph--globe-hemisphere-west--regular",
674
- label: "toggle",
675
- iconOnly: true,
676
- size: 5,
677
- classNames: "px-0 aspect-square",
678
- onClick: () => onAction?.("toggle")
679
- }));
661
+ var _effect = _useSignals2();
662
+ try {
663
+ return /* @__PURE__ */ React2.createElement(Toolbar.Root, {
664
+ classNames: [
665
+ "gap-1",
666
+ classNames
667
+ ]
668
+ }, /* @__PURE__ */ React2.createElement(IconButton, {
669
+ //
670
+ icon: "ph--play--regular",
671
+ label: "start",
672
+ iconOnly: true,
673
+ size: 5,
674
+ classNames: "px-0 aspect-square",
675
+ onClick: () => onAction?.("start")
676
+ }), /* @__PURE__ */ React2.createElement(IconButton, {
677
+ //
678
+ icon: "ph--globe-hemisphere-west--regular",
679
+ label: "toggle",
680
+ iconOnly: true,
681
+ size: 5,
682
+ classNames: "px-0 aspect-square",
683
+ onClick: () => onAction?.("toggle")
684
+ }));
685
+ } finally {
686
+ _effect.f();
687
+ }
680
688
  };
681
689
 
682
690
  // packages/ui/react-ui-geo/src/components/Globe/Globe.tsx
@@ -723,166 +731,206 @@ var defaultStyles = {
723
731
  }
724
732
  };
725
733
  var projectionMap = {
726
- orthographic: d37.geoOrthographic,
727
- mercator: d37.geoMercator,
728
- "transverse-mercator": d37.geoTransverseMercator
734
+ orthographic: geoOrthographic,
735
+ mercator: geoMercator,
736
+ "transverse-mercator": geoTransverseMercator
729
737
  };
730
738
  var getProjection = (type = "orthographic") => {
731
739
  if (typeof type === "string") {
732
- const constructor = projectionMap[type] ?? d37.geoOrthographic;
740
+ const constructor = projectionMap[type] ?? geoOrthographic;
733
741
  return constructor();
734
742
  }
735
- return type ?? d37.geoOrthographic();
743
+ return type ?? geoOrthographic();
736
744
  };
737
745
  var GlobeRoot = ({ classNames, children, ...props }) => {
738
- const { ref, width, height } = useResizeDetector();
739
- return /* @__PURE__ */ React3.createElement("div", {
740
- ref,
741
- className: mx("relative flex grow overflow-hidden", classNames)
742
- }, /* @__PURE__ */ React3.createElement(GlobeContextProvider, {
743
- size: {
744
- width,
745
- height
746
- },
747
- ...props
748
- }, children));
746
+ var _effect = _useSignals3();
747
+ try {
748
+ const { ref, width, height } = useResizeDetector();
749
+ return /* @__PURE__ */ React3.createElement("div", {
750
+ ref,
751
+ className: mx("relative flex grow overflow-hidden", classNames)
752
+ }, /* @__PURE__ */ React3.createElement(GlobeContextProvider, {
753
+ size: {
754
+ width,
755
+ height
756
+ },
757
+ ...props
758
+ }, children));
759
+ } finally {
760
+ _effect.f();
761
+ }
749
762
  };
750
763
  var GlobeCanvas = /* @__PURE__ */ forwardRef(({ projection: _projection, topology, features, styles: _styles }, forwardRef3) => {
751
- const { themeMode } = useThemeContext();
752
- const styles = useMemo(() => _styles ?? defaultStyles[themeMode], [
753
- _styles,
754
- themeMode
755
- ]);
756
- const [canvas, setCanvas] = useState3(null);
757
- const canvasRef = (canvas2) => setCanvas(canvas2);
758
- const projection = useMemo(() => getProjection(_projection), [
759
- _projection
760
- ]);
761
- const layers = useMemo(() => {
762
- return timer(() => createLayers(topology, features, styles));
763
- }, [
764
- topology,
765
- features,
766
- styles
767
- ]);
768
- const { size, center, scale, translation, rotation, setCenter, setScale, setTranslation, setRotation } = useGlobeContext();
769
- const scaleRef = useDynamicRef(scale);
770
- useEffect4(() => {
771
- if (center) {
772
- setScale(1);
773
- setRotation(positionToRotation(geoToPosition(center)));
774
- }
775
- }, [
776
- center
777
- ]);
778
- const zooming = useRef(false);
779
- useImperativeHandle(forwardRef3, () => {
780
- return {
764
+ var _effect = _useSignals3();
765
+ try {
766
+ const { themeMode } = useThemeContext();
767
+ const styles = useMemo2(() => _styles ?? defaultStyles[themeMode], [
768
+ _styles,
769
+ themeMode
770
+ ]);
771
+ const [canvas, setCanvas] = useState3(null);
772
+ const canvasRef = (canvas2) => setCanvas(canvas2);
773
+ const projection = useMemo2(() => getProjection(_projection), [
774
+ _projection
775
+ ]);
776
+ const layers = useMemo2(() => {
777
+ return timer(() => createLayers(topology, features, styles));
778
+ }, [
779
+ topology,
780
+ features,
781
+ styles
782
+ ]);
783
+ const { size, center, scale, translation, rotation, setCenter, setScale, setTranslation, setRotation } = useGlobeContext();
784
+ const scaleRef = useDynamicRef(scale);
785
+ useEffect4(() => {
786
+ if (center) {
787
+ setScale(1);
788
+ setRotation(positionToRotation(geoToPosition(center)));
789
+ }
790
+ }, [
791
+ center
792
+ ]);
793
+ const zooming = useRef(false);
794
+ useImperativeHandle(forwardRef3, () => {
795
+ return {
796
+ canvas,
797
+ projection,
798
+ center,
799
+ get scale() {
800
+ return scaleRef.current;
801
+ },
802
+ translation,
803
+ rotation,
804
+ setCenter,
805
+ setScale: (s) => {
806
+ if (typeof s === "function") {
807
+ const is = interpolateNumber(scaleRef.current, s(scaleRef.current));
808
+ transition().ease(zooming.current ? easeLinear : easeSinOut).duration(200).tween("scale", () => (t) => setScale(is(t))).on("end", () => {
809
+ zooming.current = false;
810
+ });
811
+ } else {
812
+ setScale(s);
813
+ }
814
+ },
815
+ setTranslation,
816
+ setRotation
817
+ };
818
+ }, [
819
+ canvas
820
+ ]);
821
+ const generator = useMemo2(() => canvas && projection && geoPath2(projection, canvas.getContext("2d", {
822
+ alpha: false
823
+ })), [
781
824
  canvas,
782
- projection,
783
- center,
784
- get scale() {
785
- return scaleRef.current;
786
- },
825
+ projection
826
+ ]);
827
+ useEffect4(() => {
828
+ if (canvas && projection) {
829
+ timer(() => {
830
+ projection.scale(Math.min(size.width, size.height) / 2 * scale).translate([
831
+ size.width / 2 + (translation?.x ?? 0),
832
+ size.height / 2 + (translation?.y ?? 0)
833
+ ]).rotate(rotation ?? [
834
+ 0,
835
+ 0,
836
+ 0
837
+ ]);
838
+ renderLayers(generator, layers, scale, styles);
839
+ });
840
+ }
841
+ }, [
842
+ generator,
843
+ size,
844
+ scale,
787
845
  translation,
788
846
  rotation,
789
- setCenter,
790
- setScale: (s) => {
791
- if (typeof s === "function") {
792
- const is = d37.interpolateNumber(scaleRef.current, s(scaleRef.current));
793
- d37.transition().ease(zooming.current ? d37.easeLinear : d37.easeSinOut).duration(200).tween("scale", () => (t) => setScale(is(t))).on("end", () => {
794
- zooming.current = false;
795
- });
796
- } else {
797
- setScale(s);
798
- }
799
- },
800
- setTranslation,
801
- setRotation
802
- };
803
- }, [
804
- canvas
805
- ]);
806
- const generator = useMemo(() => canvas && projection && d37.geoPath(projection, canvas.getContext("2d", {
807
- alpha: false
808
- })), [
809
- canvas,
810
- projection
811
- ]);
812
- useEffect4(() => {
813
- if (canvas && projection) {
814
- timer(() => {
815
- projection.scale(Math.min(size.width, size.height) / 2 * scale).translate([
816
- size.width / 2 + (translation?.x ?? 0),
817
- size.height / 2 + (translation?.y ?? 0)
818
- ]).rotate(rotation ?? [
819
- 0,
820
- 0,
821
- 0
822
- ]);
823
- renderLayers(generator, layers, scale, styles);
824
- });
847
+ layers
848
+ ]);
849
+ if (!size.width || !size.height) {
850
+ return null;
825
851
  }
826
- }, [
827
- generator,
828
- size,
829
- scale,
830
- translation,
831
- rotation,
832
- layers
833
- ]);
834
- if (!size.width || !size.height) {
835
- return null;
852
+ return /* @__PURE__ */ React3.createElement("canvas", {
853
+ ref: canvasRef,
854
+ width: size.width,
855
+ height: size.height
856
+ });
857
+ } finally {
858
+ _effect.f();
836
859
  }
837
- return /* @__PURE__ */ React3.createElement("canvas", {
838
- ref: canvasRef,
839
- width: size.width,
840
- height: size.height
841
- });
842
860
  });
843
861
  var GlobeDebug = ({ position = "topleft" }) => {
844
- const { size, scale, translation, rotation } = useGlobeContext();
845
- return /* @__PURE__ */ React3.createElement("div", {
846
- className: mx("z-10 absolute w-96 p-2 overflow-hidden border border-green-700 rounded", controlPositions[position])
847
- }, /* @__PURE__ */ React3.createElement("pre", {
848
- className: "font-mono text-xs text-green-700"
849
- }, JSON.stringify({
850
- size,
851
- scale,
852
- translation,
853
- rotation
854
- }, null, 2)));
862
+ var _effect = _useSignals3();
863
+ try {
864
+ const { size, scale, translation, rotation } = useGlobeContext();
865
+ return /* @__PURE__ */ React3.createElement("div", {
866
+ className: mx("z-10 absolute w-96 p-2 overflow-hidden border border-green-700 rounded", controlPositions[position])
867
+ }, /* @__PURE__ */ React3.createElement("pre", {
868
+ className: "font-mono text-xs text-green-700"
869
+ }, JSON.stringify({
870
+ size,
871
+ scale,
872
+ translation,
873
+ rotation
874
+ }, null, 2)));
875
+ } finally {
876
+ _effect.f();
877
+ }
855
878
  };
856
879
  var GlobePanel = ({ position, classNames, children }) => {
857
- return /* @__PURE__ */ React3.createElement("div", {
858
- className: mx("z-10 absolute overflow-hidden", controlPositions[position], classNames)
859
- }, children);
880
+ var _effect = _useSignals3();
881
+ try {
882
+ return /* @__PURE__ */ React3.createElement("div", {
883
+ className: mx("z-10 absolute overflow-hidden", controlPositions[position], classNames)
884
+ }, children);
885
+ } finally {
886
+ _effect.f();
887
+ }
860
888
  };
861
889
  var CustomControl = ({ position, children }) => {
862
- return /* @__PURE__ */ React3.createElement("div", {
863
- className: mx("z-10 absolute overflow-hidden", controlPositions[position])
864
- }, children);
890
+ var _effect = _useSignals3();
891
+ try {
892
+ return /* @__PURE__ */ React3.createElement("div", {
893
+ className: mx("z-10 absolute overflow-hidden", controlPositions[position])
894
+ }, children);
895
+ } finally {
896
+ _effect.f();
897
+ }
865
898
  };
866
899
  var Globe = {
867
900
  Root: GlobeRoot,
868
901
  Canvas: GlobeCanvas,
869
- Zoom: ({ onAction, position = "bottomleft", ...props }) => /* @__PURE__ */ React3.createElement(CustomControl, {
870
- position,
871
- ...props
872
- }, /* @__PURE__ */ React3.createElement(ZoomControls, {
873
- onAction
874
- })),
875
- Action: ({ onAction, position = "bottomright", ...props }) => /* @__PURE__ */ React3.createElement(CustomControl, {
876
- position,
877
- ...props
878
- }, /* @__PURE__ */ React3.createElement(ActionControls, {
879
- onAction
880
- })),
902
+ Zoom: ({ onAction, position = "bottomleft", ...props }) => {
903
+ var _effect = _useSignals3();
904
+ try {
905
+ return /* @__PURE__ */ React3.createElement(CustomControl, {
906
+ position,
907
+ ...props
908
+ }, /* @__PURE__ */ React3.createElement(ZoomControls, {
909
+ onAction
910
+ }));
911
+ } finally {
912
+ _effect.f();
913
+ }
914
+ },
915
+ Action: ({ onAction, position = "bottomright", ...props }) => {
916
+ var _effect = _useSignals3();
917
+ try {
918
+ return /* @__PURE__ */ React3.createElement(CustomControl, {
919
+ position,
920
+ ...props
921
+ }, /* @__PURE__ */ React3.createElement(ActionControls, {
922
+ onAction
923
+ }));
924
+ } finally {
925
+ _effect.f();
926
+ }
927
+ },
881
928
  Debug: GlobeDebug,
882
929
  Panel: GlobePanel
883
930
  };
884
931
 
885
932
  // packages/ui/react-ui-geo/src/components/Map/Map.tsx
933
+ import { useSignals as _useSignals4 } from "@preact-signals/safe-react/tracking";
886
934
  import "leaflet/dist/leaflet.css";
887
935
  import L, { Control, DomEvent, DomUtil, latLngBounds } from "leaflet";
888
936
  import React4, { forwardRef as forwardRef2, useEffect as useEffect5, useImperativeHandle as useImperativeHandle2 } from "react";
@@ -901,159 +949,188 @@ var defaults = {
901
949
  zoom: 4
902
950
  };
903
951
  var MapRoot = ({ classNames, center = defaults.center, zoom = defaults.zoom, ...props }) => {
904
- return /* @__PURE__ */ React4.createElement(MapContainer, {
905
- className: mx2("relative flex w-full h-full grow bg-baseSurface", classNames),
906
- attributionControl: false,
907
- // TODO(burdon): Only if attention.
908
- scrollWheelZoom: true,
909
- zoomControl: false,
910
- center,
911
- zoom,
912
- ...props
913
- });
952
+ var _effect = _useSignals4();
953
+ try {
954
+ return /* @__PURE__ */ React4.createElement(MapContainer, {
955
+ className: mx2("relative flex w-full h-full grow bg-baseSurface", classNames),
956
+ attributionControl: false,
957
+ // TODO(burdon): Only if attention.
958
+ scrollWheelZoom: true,
959
+ zoomControl: false,
960
+ center,
961
+ zoom,
962
+ ...props
963
+ });
964
+ } finally {
965
+ _effect.f();
966
+ }
914
967
  };
915
968
  var MapCanvas = /* @__PURE__ */ forwardRef2(({ markers, center, zoom, onChange }, forwardedRef) => {
916
- const { ref, width, height } = useResizeDetector2({
917
- refreshRate: 200
918
- });
919
- const map = useMap();
920
- useImperativeHandle2(forwardedRef, () => ({
921
- setCenter: (center2, zoom2) => {
922
- map.setView(center2, zoom2);
923
- },
924
- setZoom: (cb) => {
925
- map.setZoom(cb(map.getZoom()));
926
- }
927
- }), [
928
- map
929
- ]);
930
- useEffect5(() => {
931
- if (width && height) {
932
- map.invalidateSize();
933
- }
934
- }, [
935
- width,
936
- height
937
- ]);
938
- useEffect5(() => {
939
- if (center) {
940
- map.setView(center, zoom);
941
- } else if (zoom !== void 0) {
942
- map.setZoom(zoom);
943
- }
944
- }, [
945
- center,
946
- zoom
947
- ]);
948
- useEffect5(() => {
949
- const handler = debounce(() => {
950
- onChange?.({
951
- center: map.getCenter(),
952
- zoom: map.getZoom()
953
- });
954
- }, 100);
955
- map.on("move", handler);
956
- map.on("zoom", handler);
957
- return () => {
958
- map.off("move", handler);
959
- map.off("zoom", handler);
960
- };
961
- }, [
962
- map,
963
- onChange
964
- ]);
965
- useEffect5(() => {
966
- if (markers.length > 0) {
967
- const bounds = latLngBounds(markers.map((marker) => marker.location));
968
- map.fitBounds(bounds);
969
- } else {
970
- map.setView(defaults.center, defaults.zoom);
971
- }
972
- }, [
973
- markers
974
- ]);
975
- return /* @__PURE__ */ React4.createElement("div", {
976
- ref,
977
- className: "flex w-full h-full overflow-hidden bg-baseSurface"
978
- }, /* @__PURE__ */ React4.createElement(TileLayer, {
979
- className: "dark:filter dark:grayscale dark:invert",
980
- url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
981
- }), markers?.map(({ id, title, location: { lat, lng } }) => {
982
- return /* @__PURE__ */ React4.createElement(Marker, {
983
- key: id,
984
- position: {
985
- lat,
986
- lng
969
+ var _effect = _useSignals4();
970
+ try {
971
+ const { ref, width, height } = useResizeDetector2({
972
+ refreshRate: 200
973
+ });
974
+ const map = useMap();
975
+ useImperativeHandle2(forwardedRef, () => ({
976
+ setCenter: (center2, zoom2) => {
977
+ map.setView(center2, zoom2);
987
978
  },
988
- icon: (
989
- // TODO(burdon): Create custom icon from bundled assets.
990
- new L.Icon({
991
- iconUrl: "https://dxos.network/marker-icon.png",
992
- iconRetinaUrl: "https://dxos.network/marker-icon-2x.png",
993
- shadowUrl: "https://dxos.network/marker-shadow.png",
994
- iconSize: [
995
- 25,
996
- 41
997
- ],
998
- iconAnchor: [
999
- 12,
1000
- 41
1001
- ],
1002
- popupAnchor: [
1003
- 1,
1004
- -34
1005
- ],
1006
- shadowSize: [
1007
- 41,
1008
- 41
1009
- ]
1010
- })
1011
- )
1012
- }, title && /* @__PURE__ */ React4.createElement(Popup, null, title));
1013
- }));
979
+ setZoom: (cb) => {
980
+ map.setZoom(cb(map.getZoom()));
981
+ }
982
+ }), [
983
+ map
984
+ ]);
985
+ useEffect5(() => {
986
+ if (width && height) {
987
+ map.invalidateSize();
988
+ }
989
+ }, [
990
+ width,
991
+ height
992
+ ]);
993
+ useEffect5(() => {
994
+ if (center) {
995
+ map.setView(center, zoom);
996
+ } else if (zoom !== void 0) {
997
+ map.setZoom(zoom);
998
+ }
999
+ }, [
1000
+ center,
1001
+ zoom
1002
+ ]);
1003
+ useEffect5(() => {
1004
+ const handler = debounce(() => {
1005
+ onChange?.({
1006
+ center: map.getCenter(),
1007
+ zoom: map.getZoom()
1008
+ });
1009
+ }, 100);
1010
+ map.on("move", handler);
1011
+ map.on("zoom", handler);
1012
+ return () => {
1013
+ map.off("move", handler);
1014
+ map.off("zoom", handler);
1015
+ };
1016
+ }, [
1017
+ map,
1018
+ onChange
1019
+ ]);
1020
+ useEffect5(() => {
1021
+ if (markers.length > 0) {
1022
+ const bounds = latLngBounds(markers.map((marker) => marker.location));
1023
+ map.fitBounds(bounds);
1024
+ } else {
1025
+ map.setView(defaults.center, defaults.zoom);
1026
+ }
1027
+ }, [
1028
+ markers
1029
+ ]);
1030
+ return /* @__PURE__ */ React4.createElement("div", {
1031
+ ref,
1032
+ className: "flex w-full h-full overflow-hidden bg-baseSurface"
1033
+ }, /* @__PURE__ */ React4.createElement(TileLayer, {
1034
+ className: "dark:filter dark:grayscale dark:invert",
1035
+ url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
1036
+ }), markers?.map(({ id, title, location: { lat, lng } }) => {
1037
+ return /* @__PURE__ */ React4.createElement(Marker, {
1038
+ key: id,
1039
+ position: {
1040
+ lat,
1041
+ lng
1042
+ },
1043
+ icon: (
1044
+ // TODO(burdon): Create custom icon from bundled assets.
1045
+ new L.Icon({
1046
+ iconUrl: "https://dxos.network/marker-icon.png",
1047
+ iconRetinaUrl: "https://dxos.network/marker-icon-2x.png",
1048
+ shadowUrl: "https://dxos.network/marker-shadow.png",
1049
+ iconSize: [
1050
+ 25,
1051
+ 41
1052
+ ],
1053
+ iconAnchor: [
1054
+ 12,
1055
+ 41
1056
+ ],
1057
+ popupAnchor: [
1058
+ 1,
1059
+ -34
1060
+ ],
1061
+ shadowSize: [
1062
+ 41,
1063
+ 41
1064
+ ]
1065
+ })
1066
+ )
1067
+ }, title && /* @__PURE__ */ React4.createElement(Popup, null, title));
1068
+ }));
1069
+ } finally {
1070
+ _effect.f();
1071
+ }
1014
1072
  });
1015
1073
  var CustomControl2 = ({ position, children }) => {
1016
- const map = useMap();
1017
- useEffect5(() => {
1018
- const control = new Control({
1019
- position
1020
- });
1021
- control.onAdd = () => {
1022
- const container = DomUtil.create("div", mx2("!m-0", controlPositions[position]));
1023
- DomEvent.disableClickPropagation(container);
1024
- DomEvent.disableScrollPropagation(container);
1025
- const root = createRoot(container);
1026
- root.render(/* @__PURE__ */ React4.createElement(ThemeProvider, {
1027
- tx: defaultTx
1028
- }, /* @__PURE__ */ React4.createElement(Tooltip.Provider, null, children)));
1029
- return container;
1030
- };
1031
- control.addTo(map);
1032
- return () => {
1033
- control.remove();
1034
- };
1035
- }, [
1036
- map,
1037
- position,
1038
- children
1039
- ]);
1040
- return null;
1074
+ var _effect = _useSignals4();
1075
+ try {
1076
+ const map = useMap();
1077
+ useEffect5(() => {
1078
+ const control = new Control({
1079
+ position
1080
+ });
1081
+ control.onAdd = () => {
1082
+ const container = DomUtil.create("div", mx2("!m-0", controlPositions[position]));
1083
+ DomEvent.disableClickPropagation(container);
1084
+ DomEvent.disableScrollPropagation(container);
1085
+ const root = createRoot(container);
1086
+ root.render(/* @__PURE__ */ React4.createElement(ThemeProvider, {
1087
+ tx: defaultTx
1088
+ }, /* @__PURE__ */ React4.createElement(Tooltip.Provider, null, children)));
1089
+ return container;
1090
+ };
1091
+ control.addTo(map);
1092
+ return () => {
1093
+ control.remove();
1094
+ };
1095
+ }, [
1096
+ map,
1097
+ position,
1098
+ children
1099
+ ]);
1100
+ return null;
1101
+ } finally {
1102
+ _effect.f();
1103
+ }
1041
1104
  };
1042
1105
  var Map = {
1043
1106
  Root: MapRoot,
1044
1107
  Canvas: MapCanvas,
1045
- Zoom: ({ onAction, position = "bottomleft", ...props }) => /* @__PURE__ */ React4.createElement(CustomControl2, {
1046
- position,
1047
- ...props
1048
- }, /* @__PURE__ */ React4.createElement(ZoomControls, {
1049
- onAction
1050
- })),
1051
- Action: ({ onAction, position = "bottomright", ...props }) => /* @__PURE__ */ React4.createElement(CustomControl2, {
1052
- position,
1053
- ...props
1054
- }, /* @__PURE__ */ React4.createElement(ActionControls, {
1055
- onAction
1056
- }))
1108
+ Zoom: ({ onAction, position = "bottomleft", ...props }) => {
1109
+ var _effect = _useSignals4();
1110
+ try {
1111
+ return /* @__PURE__ */ React4.createElement(CustomControl2, {
1112
+ position,
1113
+ ...props
1114
+ }, /* @__PURE__ */ React4.createElement(ZoomControls, {
1115
+ onAction
1116
+ }));
1117
+ } finally {
1118
+ _effect.f();
1119
+ }
1120
+ },
1121
+ Action: ({ onAction, position = "bottomright", ...props }) => {
1122
+ var _effect = _useSignals4();
1123
+ try {
1124
+ return /* @__PURE__ */ React4.createElement(CustomControl2, {
1125
+ position,
1126
+ ...props
1127
+ }, /* @__PURE__ */ React4.createElement(ActionControls, {
1128
+ onAction
1129
+ }));
1130
+ } finally {
1131
+ _effect.f();
1132
+ }
1133
+ }
1057
1134
  };
1058
1135
  export {
1059
1136
  ActionControls,
@@ -1064,7 +1141,7 @@ export {
1064
1141
  closestPoint,
1065
1142
  controlPositions,
1066
1143
  createLayers,
1067
- geoCircle2 as geoCircle,
1144
+ geoCircle,
1068
1145
  geoInertiaDrag,
1069
1146
  geoLine,
1070
1147
  geoPoint,