@dxos/react-ui-geo 0.8.4-main.fffef41 → 0.8.4-staging.60fe92afc8

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 (121) hide show
  1. package/LICENSE +102 -5
  2. package/data/countries-10m.ts +12 -0
  3. package/data/countries-110m.ts +4 -10579
  4. package/data/countries-50m.ts +12 -0
  5. package/dist/lib/browser/chunk-SC2FBYFU.mjs +17 -0
  6. package/dist/lib/browser/chunk-SC2FBYFU.mjs.map +7 -0
  7. package/dist/lib/browser/countries-10m-CWWDOKH7.mjs +6 -0
  8. package/dist/lib/browser/countries-10m-CWWDOKH7.mjs.map +7 -0
  9. package/dist/lib/browser/countries-110m-72QBAA5E.mjs +6 -0
  10. package/dist/lib/browser/countries-110m-72QBAA5E.mjs.map +7 -0
  11. package/dist/lib/browser/countries-50m-H7SL7KVF.mjs +6 -0
  12. package/dist/lib/browser/countries-50m-H7SL7KVF.mjs.map +7 -0
  13. package/dist/lib/browser/data.mjs +1 -1
  14. package/dist/lib/browser/index.mjs +1046 -579
  15. package/dist/lib/browser/index.mjs.map +4 -4
  16. package/dist/lib/browser/meta.json +1 -1
  17. package/dist/lib/browser/translations.mjs +19 -0
  18. package/dist/lib/browser/translations.mjs.map +7 -0
  19. package/dist/lib/node-esm/chunk-VZENBYLJ.mjs +19 -0
  20. package/dist/lib/node-esm/chunk-VZENBYLJ.mjs.map +7 -0
  21. package/dist/lib/node-esm/countries-10m-DJZV66KG.mjs +8 -0
  22. package/dist/lib/node-esm/countries-10m-DJZV66KG.mjs.map +7 -0
  23. package/dist/lib/node-esm/countries-110m-H3WY6K4Q.mjs +8 -0
  24. package/dist/lib/node-esm/countries-110m-H3WY6K4Q.mjs.map +7 -0
  25. package/dist/lib/node-esm/countries-50m-ZY7Z3IWD.mjs +8 -0
  26. package/dist/lib/node-esm/countries-50m-ZY7Z3IWD.mjs.map +7 -0
  27. package/dist/lib/node-esm/data.mjs +1 -1
  28. package/dist/lib/node-esm/index.mjs +1046 -579
  29. package/dist/lib/node-esm/index.mjs.map +4 -4
  30. package/dist/lib/node-esm/meta.json +1 -1
  31. package/dist/lib/node-esm/translations.mjs +21 -0
  32. package/dist/lib/node-esm/translations.mjs.map +7 -0
  33. package/dist/types/data/airports.d.ts +4 -4
  34. package/dist/types/data/airports.d.ts.map +1 -1
  35. package/dist/types/data/cities.d.ts.map +1 -1
  36. package/dist/types/data/countries-10m.d.ts +8 -0
  37. package/dist/types/data/countries-10m.d.ts.map +1 -0
  38. package/dist/types/data/countries-110m.d.ts +2 -30
  39. package/dist/types/data/countries-110m.d.ts.map +1 -1
  40. package/dist/types/data/countries-50m.d.ts +8 -0
  41. package/dist/types/data/countries-50m.d.ts.map +1 -0
  42. package/dist/types/data/countries-dots-3.d.ts.map +1 -1
  43. package/dist/types/data/countries-dots-4.d.ts.map +1 -1
  44. package/dist/types/src/components/Globe/Globe.d.ts +19 -9
  45. package/dist/types/src/components/Globe/Globe.d.ts.map +1 -1
  46. package/dist/types/src/components/Globe/Globe.stories.d.ts +17 -7
  47. package/dist/types/src/components/Globe/Globe.stories.d.ts.map +1 -1
  48. package/dist/types/src/components/Map/Map.d.ts +51 -9
  49. package/dist/types/src/components/Map/Map.d.ts.map +1 -1
  50. package/dist/types/src/components/Map/Map.stories.d.ts +9 -5
  51. package/dist/types/src/components/Map/Map.stories.d.ts.map +1 -1
  52. package/dist/types/src/components/Toolbar/Controls.d.ts.map +1 -1
  53. package/dist/types/src/data.d.ts +9 -1
  54. package/dist/types/src/data.d.ts.map +1 -1
  55. package/dist/types/src/hooks/context.d.ts +38 -3
  56. package/dist/types/src/hooks/context.d.ts.map +1 -1
  57. package/dist/types/src/hooks/index.d.ts +3 -0
  58. package/dist/types/src/hooks/index.d.ts.map +1 -1
  59. package/dist/types/src/hooks/useDrag.d.ts +22 -2
  60. package/dist/types/src/hooks/useDrag.d.ts.map +1 -1
  61. package/dist/types/src/hooks/useGlobeZoomHandler.d.ts +3 -2
  62. package/dist/types/src/hooks/useGlobeZoomHandler.d.ts.map +1 -1
  63. package/dist/types/src/hooks/useMapZoomHandler.d.ts +1 -1
  64. package/dist/types/src/hooks/useMapZoomHandler.d.ts.map +1 -1
  65. package/dist/types/src/hooks/useSimplifiedTopology.d.ts +32 -0
  66. package/dist/types/src/hooks/useSimplifiedTopology.d.ts.map +1 -0
  67. package/dist/types/src/hooks/useSpinner.d.ts +1 -1
  68. package/dist/types/src/hooks/useSpinner.d.ts.map +1 -1
  69. package/dist/types/src/hooks/useTopology.d.ts +26 -0
  70. package/dist/types/src/hooks/useTopology.d.ts.map +1 -0
  71. package/dist/types/src/hooks/useTour.d.ts +3 -2
  72. package/dist/types/src/hooks/useTour.d.ts.map +1 -1
  73. package/dist/types/src/hooks/useWheel.d.ts +24 -0
  74. package/dist/types/src/hooks/useWheel.d.ts.map +1 -0
  75. package/dist/types/src/index.d.ts +0 -2
  76. package/dist/types/src/index.d.ts.map +1 -1
  77. package/dist/types/src/translations.d.ts +6 -6
  78. package/dist/types/src/translations.d.ts.map +1 -1
  79. package/dist/types/src/util/animation.d.ts +16 -0
  80. package/dist/types/src/util/animation.d.ts.map +1 -0
  81. package/dist/types/src/util/debug.d.ts.map +1 -1
  82. package/dist/types/src/util/index.d.ts +2 -0
  83. package/dist/types/src/util/index.d.ts.map +1 -1
  84. package/dist/types/src/util/inertia.d.ts.map +1 -1
  85. package/dist/types/src/util/path.d.ts.map +1 -1
  86. package/dist/types/src/util/render.d.ts +25 -1
  87. package/dist/types/src/util/render.d.ts.map +1 -1
  88. package/dist/types/src/util/styles.d.ts +4 -0
  89. package/dist/types/src/util/styles.d.ts.map +1 -0
  90. package/dist/types/tsconfig.tsbuildinfo +1 -1
  91. package/package.json +41 -35
  92. package/src/components/Globe/Globe.stories.tsx +141 -65
  93. package/src/components/Globe/Globe.tsx +262 -119
  94. package/src/components/Map/Map.stories.tsx +59 -12
  95. package/src/components/Map/Map.tsx +325 -82
  96. package/src/components/Toolbar/Controls.tsx +5 -5
  97. package/src/data.ts +19 -2
  98. package/src/hooks/context.tsx +46 -31
  99. package/src/hooks/index.ts +3 -0
  100. package/src/hooks/useDrag.ts +33 -5
  101. package/src/hooks/useGlobeZoomHandler.ts +2 -1
  102. package/src/hooks/useSimplifiedTopology.ts +81 -0
  103. package/src/hooks/useSpinner.ts +1 -2
  104. package/src/hooks/useTopology.ts +95 -0
  105. package/src/hooks/useTour.ts +70 -81
  106. package/src/hooks/useWheel.ts +83 -0
  107. package/src/index.ts +0 -2
  108. package/src/translations.ts +5 -5
  109. package/src/util/animation.ts +35 -0
  110. package/src/util/index.ts +2 -0
  111. package/src/util/inertia.ts +87 -4
  112. package/src/util/render.ts +105 -17
  113. package/src/util/styles.ts +62 -0
  114. package/dist/lib/browser/chunk-GMWLKTLN.mjs +0 -9
  115. package/dist/lib/browser/chunk-GMWLKTLN.mjs.map +0 -7
  116. package/dist/lib/browser/countries-110m-ZM3ZIEFS.mjs +0 -37859
  117. package/dist/lib/browser/countries-110m-ZM3ZIEFS.mjs.map +0 -7
  118. package/dist/lib/node-esm/chunk-JODBF4CC.mjs +0 -11
  119. package/dist/lib/node-esm/chunk-JODBF4CC.mjs.map +0 -7
  120. package/dist/lib/node-esm/countries-110m-3SFASWVD.mjs +0 -37861
  121. package/dist/lib/node-esm/countries-110m-3SFASWVD.mjs.map +0 -7
package/package.json CHANGED
@@ -1,42 +1,48 @@
1
1
  {
2
2
  "name": "@dxos/react-ui-geo",
3
- "version": "0.8.4-main.fffef41",
3
+ "version": "0.8.4-staging.60fe92afc8",
4
4
  "description": "Geo components.",
5
5
  "homepage": "https://github.com/dxos",
6
6
  "bugs": "https://github.com/dxos/issues",
7
- "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/dxos/dxos"
10
+ },
11
+ "license": "FSL-1.1-Apache-2.0",
8
12
  "author": "DXOS.org",
9
13
  "sideEffects": true,
10
14
  "type": "module",
15
+ "imports": {
16
+ "#translations": "./src/translations.ts"
17
+ },
11
18
  "exports": {
19
+ ".": {
20
+ "source": "./src/index.ts",
21
+ "types": "./dist/types/src/index.d.ts",
22
+ "browser": "./dist/lib/browser/index.mjs",
23
+ "node": "./dist/lib/node-esm/index.mjs"
24
+ },
12
25
  "./data": {
13
26
  "source": "./src/data.ts",
14
27
  "types": "./dist/types/src/data.d.ts",
15
28
  "browser": "./dist/lib/browser/data.mjs",
16
29
  "node": "./dist/lib/node-esm/data.mjs"
17
30
  },
18
- ".": {
19
- "source": "./src/index.ts",
20
- "types": "./dist/types/src/index.d.ts",
21
- "browser": "./dist/lib/browser/index.mjs",
22
- "node": "./dist/lib/node-esm/index.mjs"
31
+ "./translations": {
32
+ "source": "./src/translations.ts",
33
+ "types": "./dist/types/src/translations.d.ts",
34
+ "browser": "./dist/lib/browser/translations.mjs",
35
+ "node": "./dist/lib/node-esm/translations.mjs"
23
36
  }
24
37
  },
25
38
  "types": "dist/types/src/index.d.ts",
26
- "typesVersions": {
27
- "*": {
28
- "data": [
29
- "dist/types/src/data.d.ts"
30
- ]
31
- }
32
- },
33
39
  "files": [
34
40
  "data",
35
41
  "dist",
36
42
  "src"
37
43
  ],
38
44
  "dependencies": {
39
- "@preact-signals/safe-react": "^0.9.0",
45
+ "@radix-ui/react-compose-refs": "1.1.1",
40
46
  "@radix-ui/react-context": "1.1.1",
41
47
  "d3": "^7.9.0",
42
48
  "d3-geo-projection": "^4.0.0",
@@ -49,39 +55,39 @@
49
55
  "topojson-client": "^3.1.0",
50
56
  "topojson-simplify": "^3.0.3",
51
57
  "versor": "^0.2.0",
52
- "@dxos/async": "0.8.4-main.fffef41",
53
- "@dxos/log": "0.8.4-main.fffef41",
54
- "@dxos/node-std": "0.8.4-main.fffef41",
55
- "@dxos/debug": "0.8.4-main.fffef41",
56
- "@dxos/util": "0.8.4-main.fffef41"
58
+ "@dxos/debug": "0.8.4-staging.60fe92afc8",
59
+ "@dxos/util": "0.8.4-staging.60fe92afc8",
60
+ "@dxos/node-std": "0.8.4-staging.60fe92afc8",
61
+ "@dxos/log": "0.8.4-staging.60fe92afc8",
62
+ "@dxos/async": "0.8.4-staging.60fe92afc8"
57
63
  },
58
64
  "devDependencies": {
59
- "@react-three/drei": "^9.99.0",
60
- "@react-three/fiber": "^9.3.0",
65
+ "@react-three/drei": "^10.7.7",
66
+ "@react-three/fiber": "^9.5.0",
61
67
  "@types/d3": "^7.4.3",
62
68
  "@types/geojson": "^7946.0.14",
63
69
  "@types/leaflet": "^1.9.16",
64
- "@types/react": "~19.2.2",
65
- "@types/react-dom": "~19.2.2",
70
+ "@types/react": "~19.2.7",
71
+ "@types/react-dom": "~19.2.3",
66
72
  "@types/three": "0.165.0",
67
73
  "@types/topojson-client": "^3.1.4",
68
74
  "@types/topojson-simplify": "^3.0.3",
69
75
  "@types/topojson-specification": "^1.0.5",
70
76
  "JSONStream": "^1.3.5",
71
77
  "geojson2h3": "^1.2.0",
72
- "leva": "^0.9.35",
73
- "react": "~19.2.0",
74
- "react-dom": "~19.2.0",
75
- "three": "0.165.0",
76
- "@dxos/react-ui": "0.8.4-main.fffef41",
77
- "@dxos/storybook-utils": "0.8.4-main.fffef41",
78
- "@dxos/react-ui-theme": "0.8.4-main.fffef41"
78
+ "leva": "^0.10.1",
79
+ "react": "~19.2.3",
80
+ "react-dom": "~19.2.3",
81
+ "three": "^0.178.0",
82
+ "@dxos/react-ui": "0.8.4-staging.60fe92afc8",
83
+ "@dxos/storybook-utils": "0.8.4-staging.60fe92afc8",
84
+ "@dxos/ui-theme": "0.8.4-staging.60fe92afc8"
79
85
  },
80
86
  "peerDependencies": {
81
- "react": "^19.0.0",
82
- "react-dom": "^19.0.0",
83
- "@dxos/react-ui": "0.8.4-main.fffef41",
84
- "@dxos/react-ui-theme": "0.8.4-main.fffef41"
87
+ "react": "~19.2.3",
88
+ "react-dom": "~19.2.3",
89
+ "@dxos/react-ui": "0.8.4-staging.60fe92afc8",
90
+ "@dxos/ui-theme": "0.8.4-staging.60fe92afc8"
85
91
  },
86
92
  "publishConfig": {
87
93
  "access": "public"
@@ -5,54 +5,54 @@
5
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
6
6
  import { type FeatureCollection, type Geometry, type Position } from 'geojson';
7
7
  import { Leva } from 'leva';
8
- import React, { useMemo, useRef, useState } from 'react';
8
+ import React, { useMemo, useState } from 'react';
9
9
  import { type Topology } from 'topojson-specification';
10
10
 
11
11
  import { useAsyncState } from '@dxos/react-ui';
12
- import { withTheme } from '@dxos/react-ui/testing';
13
-
14
- import { type Vector, useDrag, useGlobeZoomHandler, useSpinner, useTour } from '../../hooks';
12
+ import { withLayout, withTheme } from '@dxos/react-ui/testing';
13
+
14
+ import { loadTopology } from '../../data';
15
+ import {
16
+ type GlobeController,
17
+ type Level,
18
+ type Vector,
19
+ useDrag,
20
+ useGlobeContext,
21
+ useGlobeZoomHandler,
22
+ useSpinner,
23
+ useTopology,
24
+ useTour,
25
+ useWheel,
26
+ } from '../../hooks';
15
27
  import { type LatLngLiteral } from '../../types';
16
28
  import { type StyleSet, closestPoint } from '../../util';
17
29
  import { type ControlProps } from '../Toolbar';
18
-
19
- import { Globe, type GlobeCanvasProps, type GlobeController, type GlobeRootProps } from './Globe';
20
-
21
- // TODO(burdon): Load from JSON at runtime?
22
- const useTopology = () => {
23
- return useAsyncState(async () => (await import('../../../data/countries-110m.ts')).default);
24
- };
30
+ import { Globe, type GlobeCanvasProps, type GlobeRootProps } from './Globe';
25
31
 
26
32
  const defaultStyles: StyleSet = {
27
33
  water: {
28
34
  fillStyle: '#0a0a0a',
29
35
  },
30
-
31
36
  land: {
32
37
  fillStyle: '#050505',
33
38
  strokeStyle: 'darkgreen',
34
39
  },
35
-
36
40
  graticule: {
37
41
  strokeStyle: '#111',
38
42
  },
39
-
40
43
  line: {
41
44
  lineWidth: 1,
42
45
  lineDash: [4, 16],
43
46
  strokeStyle: 'yellow',
44
47
  },
45
-
46
48
  point: {
47
49
  pointRadius: 2,
48
50
  fillStyle: 'red',
49
51
  },
50
-
51
52
  cursor: {
52
53
  fillStyle: 'orange',
53
54
  pointRadius: 2,
54
55
  },
55
-
56
56
  arc: {
57
57
  lineWidth: 2,
58
58
  strokeStyle: 'yellow',
@@ -64,17 +64,14 @@ const dotStyles: StyleSet = {
64
64
  fillStyle: '#444',
65
65
  pointRadius: 2,
66
66
  },
67
-
68
67
  point: {
69
68
  pointRadius: 2,
70
69
  fillStyle: 'red',
71
70
  },
72
-
73
71
  cursor: {
74
72
  fillStyle: 'orange',
75
73
  pointRadius: 2,
76
74
  },
77
-
78
75
  arc: {
79
76
  lineWidth: 2,
80
77
  strokeStyle: 'yellow',
@@ -128,16 +125,19 @@ const createTrip = (
128
125
  );
129
126
  };
130
127
 
131
- type StoryProps = Pick<GlobeRootProps, 'zoom' | 'translation' | 'rotation'> &
128
+ type DefaultStoryProps = Pick<GlobeRootProps, 'zoom' | 'translation' | 'rotation'> &
132
129
  Pick<GlobeCanvasProps, 'projection' | 'styles'> & {
133
130
  drag?: boolean;
134
131
  spin?: boolean;
135
132
  tour?: boolean;
136
- xAxis?: boolean;
133
+ wheel?: boolean;
134
+ lockTilt?: boolean;
135
+ mode?: 'linear' | 'versor';
136
+ level?: Level;
137
137
  };
138
138
 
139
139
  const DefaultStory = ({
140
- zoom: _zoom = 1,
140
+ zoom: zoomProp = 1,
141
141
  translation,
142
142
  rotation = [0, 0, 0],
143
143
  projection,
@@ -145,9 +145,12 @@ const DefaultStory = ({
145
145
  drag = false,
146
146
  spin = false,
147
147
  tour = false,
148
- xAxis = false,
149
- }: StoryProps) => {
150
- const controller = useRef<GlobeController>(null);
148
+ wheel = false,
149
+ lockTilt = false,
150
+ mode,
151
+ level = '110m',
152
+ }: DefaultStoryProps) => {
153
+ const [controller, setController] = useState<GlobeController | null>(null);
151
154
  const [dots] = useAsyncState(async () => {
152
155
  const points = (await import('../../../data/countries-dots-3.ts')).default;
153
156
  return {
@@ -155,7 +158,7 @@ const DefaultStory = ({
155
158
  objects: { dots: points },
156
159
  } as any as Topology;
157
160
  });
158
- const [topology] = useTopology();
161
+ const [topology] = useAsyncState(() => loadTopology(level), [level]);
159
162
  const [airports] = useAsyncState(async () => (await import('../../../data/airports.ts')).default);
160
163
 
161
164
  const features = useMemo(() => {
@@ -163,10 +166,11 @@ const DefaultStory = ({
163
166
  }, [airports, routes, dots]);
164
167
 
165
168
  // Control hooks.
166
- const [startSpinner, stopSpinner] = useSpinner(controller.current, { disabled: !spin });
167
- const [_running, setRunning] = useTour(controller.current, features?.points, { disabled: !tour, styles });
168
- useDrag(controller.current, {
169
- xAxis,
169
+ const [startSpinner, stopSpinner] = useSpinner(controller, { disabled: !spin });
170
+ const [_running, setRunning] = useTour(controller, features?.points, { disabled: !tour, styles });
171
+ useDrag(controller, {
172
+ lockTilt,
173
+ mode,
170
174
  disabled: !drag,
171
175
  onUpdate: (event) => {
172
176
  switch (event.type) {
@@ -178,6 +182,13 @@ const DefaultStory = ({
178
182
  }
179
183
  },
180
184
  });
185
+ useWheel(controller, {
186
+ disabled: !wheel,
187
+ onUpdate: () => {
188
+ stopSpinner();
189
+ setRunning(false);
190
+ },
191
+ });
181
192
 
182
193
  // TODO(burdon): Factor out handlers.
183
194
  const handleAction: ControlProps['onAction'] = (event) => {
@@ -192,31 +203,32 @@ const DefaultStory = ({
192
203
  break;
193
204
  }
194
205
  case 'zoom-in': {
195
- controller.current.setZoom((scale) => scale * 1.1);
206
+ controller?.setZoom((scale) => scale * 1.1);
196
207
  break;
197
208
  }
198
209
  case 'zoom-out': {
199
- controller.current.setZoom((scale) => scale * 0.9);
210
+ controller?.setZoom((scale) => scale * 0.9);
200
211
  break;
201
212
  }
202
213
  }
203
214
  };
204
215
 
205
216
  return (
206
- <Globe.Root classNames='absolute inset-0' zoom={_zoom} translation={translation} rotation={rotation}>
207
- <Globe.Canvas
208
- ref={controller}
209
- topology={styles?.dots ? dots : topology}
210
- projection={projection}
211
- styles={styles}
212
- features={tour ? { points: features?.points ?? [] } : features}
213
- />
214
- <Globe.Zoom onAction={handleAction} />
215
- <Globe.Action onAction={handleAction} />
216
- <Globe.Debug />
217
- <Globe.Panel position='topright' classNames='is-20 bs-20'>
218
- <Leva />
219
- </Globe.Panel>
217
+ <Globe.Root zoom={zoomProp} translation={translation} rotation={rotation} ref={setController}>
218
+ <Globe.Viewport>
219
+ <Globe.Canvas
220
+ topology={styles?.dots ? dots : topology}
221
+ projection={projection}
222
+ styles={styles}
223
+ features={tour ? { points: features?.points ?? [] } : features}
224
+ />
225
+ <Globe.Zoom onAction={handleAction} />
226
+ <Globe.Action onAction={handleAction} />
227
+ <Globe.Debug />
228
+ <Globe.Panel position='topright' classNames='w-20 h-20'>
229
+ <Leva />
230
+ </Globe.Panel>
231
+ </Globe.Viewport>
220
232
  </Globe.Root>
221
233
  );
222
234
  };
@@ -227,7 +239,7 @@ const meta = {
227
239
  title: 'ui/react-ui-geo/Globe',
228
240
  component: Globe.Root,
229
241
  render: DefaultStory,
230
- decorators: [withTheme],
242
+ decorators: [withTheme(), withLayout({ layout: 'fullscreen' })],
231
243
  parameters: {
232
244
  layout: 'fullscreen',
233
245
  },
@@ -235,31 +247,78 @@ const meta = {
235
247
 
236
248
  export default meta;
237
249
 
238
- export const Earth1 = () => {
239
- const [topology] = useTopology();
250
+ const Earth = ({ level }: { level: Level }) => {
251
+ const [topology] = useAsyncState(() => loadTopology(level), [level]);
240
252
  const [controller, setController] = useState<GlobeController | null>();
241
253
  const handleAction = useGlobeZoomHandler(controller);
242
254
  useDrag(controller);
255
+ useWheel(controller);
256
+
257
+ return (
258
+ <Globe.Root zoom={1.2} rotation={[0, 0, 0]} ref={setController}>
259
+ <Globe.Viewport>
260
+ <Globe.Canvas topology={topology} styles={defaultStyles} />
261
+ <Globe.Zoom onAction={handleAction} />
262
+ </Globe.Viewport>
263
+ </Globe.Root>
264
+ );
265
+ };
266
+
267
+ export const Topology110 = () => {
268
+ return <Earth level='110m' />;
269
+ };
243
270
 
271
+ export const Topology50 = () => {
272
+ return <Earth level='50m' />;
273
+ };
274
+
275
+ export const Topology10 = () => {
276
+ return <Earth level='10m' />;
277
+ };
278
+
279
+ /**
280
+ * Discrete-resolution LOD: swaps resolution by zoom via `useTopology(zoom)`. Each resolution is a
281
+ * code-split chunk fetched on demand the first time its tier is entered (default tiers: 110m / 50m).
282
+ * Reads the live zoom from the globe context, so it must render inside `Globe.Root`.
283
+ */
284
+ const DynamicCanvas = ({ controller }: { controller: GlobeController | null | undefined }) => {
285
+ const { zoom } = useGlobeContext();
286
+ const topology = useTopology(zoom);
287
+ const handleAction = useGlobeZoomHandler(controller);
288
+ useDrag(controller);
289
+ useWheel(controller);
244
290
  return (
245
- <Globe.Root zoom={1.2} rotation={[Math.random() * 360, 0, 0]}>
246
- <Globe.Canvas ref={setController} topology={topology} styles={defaultStyles} />
291
+ <Globe.Viewport>
292
+ <Globe.Canvas topology={topology} styles={defaultStyles} />
247
293
  <Globe.Zoom onAction={handleAction} />
294
+ <Globe.Debug />
295
+ </Globe.Viewport>
296
+ );
297
+ };
298
+
299
+ export const Dynamic = () => {
300
+ const [controller, setController] = useState<GlobeController | null>();
301
+ return (
302
+ <Globe.Root zoom={1.2} rotation={[0, 0, 0]} ref={setController}>
303
+ <DynamicCanvas controller={controller} />
248
304
  </Globe.Root>
249
305
  );
250
306
  };
251
307
 
252
- export const Earth2 = () => {
253
- const [topology] = useTopology();
308
+ export const Earthrise = () => {
309
+ const topology = useTopology();
254
310
  const [controller, setController] = useState<GlobeController | null>();
255
311
  const handleAction = useGlobeZoomHandler(controller);
256
312
  useDrag(controller);
313
+ useWheel(controller);
257
314
 
258
315
  return (
259
316
  <div className='absolute bottom-0 left-0 right-0 '>
260
- <Globe.Root classNames='h-[400px]' zoom={2.8} translation={{ x: 0, y: 400 }}>
261
- <Globe.Canvas ref={setController} topology={topology} styles={defaultStyles} />
262
- <Globe.Zoom onAction={handleAction} />
317
+ <Globe.Root zoom={2.8} translation={{ x: 0, y: 400 }} ref={setController}>
318
+ <Globe.Viewport classNames='h-[400px]'>
319
+ <Globe.Canvas topology={topology} styles={defaultStyles} />
320
+ <Globe.Zoom onAction={handleAction} />
321
+ </Globe.Viewport>
263
322
  </Globe.Root>
264
323
  </div>
265
324
  );
@@ -269,31 +328,31 @@ const monochrome: StyleSet = {
269
328
  water: {
270
329
  fillStyle: '#191919',
271
330
  },
272
-
273
331
  land: {
274
332
  fillStyle: '#444',
275
333
  strokeStyle: '#222',
276
334
  },
277
-
278
335
  border: {
279
336
  strokeStyle: '#111',
280
337
  },
281
-
282
338
  graticule: {
283
339
  strokeStyle: '#111',
284
340
  },
285
341
  };
286
342
 
287
343
  export const Mercator = () => {
288
- const [topology] = useTopology();
344
+ const topology = useTopology();
289
345
  const [controller, setController] = useState<GlobeController | null>();
290
346
  const handleAction = useGlobeZoomHandler(controller);
291
347
  useDrag(controller);
348
+ useWheel(controller);
292
349
 
293
350
  return (
294
- <Globe.Root classNames='flex grow overflow-hidden' zoom={0.7} rotation={initialRotation}>
295
- <Globe.Canvas ref={setController} topology={topology} projection='mercator' styles={monochrome} />
296
- <Globe.Zoom onAction={handleAction} />
351
+ <Globe.Root zoom={0.7} rotation={initialRotation} ref={setController}>
352
+ <Globe.Viewport>
353
+ <Globe.Canvas topology={topology} projection='mercator' styles={monochrome} />
354
+ <Globe.Zoom onAction={handleAction} />
355
+ </Globe.Viewport>
297
356
  </Globe.Root>
298
357
  );
299
358
  };
@@ -303,6 +362,7 @@ type Story = StoryObj<typeof DefaultStory>;
303
362
  export const Globe1: Story = {
304
363
  args: {
305
364
  drag: true,
365
+ wheel: true,
306
366
  projection: 'mercator',
307
367
  zoom: 0.8,
308
368
  rotation: initialRotation,
@@ -313,6 +373,7 @@ export const Globe1: Story = {
313
373
  export const Globe2: Story = {
314
374
  args: {
315
375
  drag: true,
376
+ wheel: true,
316
377
  projection: 'transverse-mercator',
317
378
  zoom: 0.8,
318
379
  rotation: initialRotation,
@@ -323,6 +384,7 @@ export const Globe2: Story = {
323
384
  export const Globe3: Story = {
324
385
  args: {
325
386
  drag: true,
387
+ wheel: true,
326
388
  spin: true,
327
389
  zoom: 1.5,
328
390
  rotation: initialRotation,
@@ -333,6 +395,7 @@ export const Globe3: Story = {
333
395
  export const Globe4: Story = {
334
396
  args: {
335
397
  drag: true,
398
+ wheel: true,
336
399
  tour: true,
337
400
  zoom: 2,
338
401
  rotation: initialRotation,
@@ -343,6 +406,7 @@ export const Globe4: Story = {
343
406
  export const Globe5: Story = {
344
407
  args: {
345
408
  drag: true,
409
+ wheel: true,
346
410
  tour: true,
347
411
  zoom: 0.9,
348
412
  rotation: initialRotation,
@@ -353,7 +417,8 @@ export const Globe5: Story = {
353
417
  export const Globe6: Story = {
354
418
  args: {
355
419
  drag: true,
356
- xAxis: true,
420
+ wheel: true,
421
+ lockTilt: true,
357
422
  tour: true,
358
423
  zoom: 2,
359
424
  translation: { x: 0, y: 600 },
@@ -361,3 +426,14 @@ export const Globe6: Story = {
361
426
  styles: dotStyles,
362
427
  },
363
428
  };
429
+
430
+ export const VersorDrag: Story = {
431
+ args: {
432
+ drag: true,
433
+ wheel: true,
434
+ mode: 'versor',
435
+ zoom: 1.5,
436
+ rotation: initialRotation,
437
+ styles: defaultStyles,
438
+ },
439
+ };