@dxos/react-ui-geo 0.8.1 → 0.8.2-main.10c050d

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