@react-x11/components 0.8.0 → 0.9.0
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.
- package/README.md +95 -34
- package/dist/charts/node.d.ts +1 -1
- package/dist/charts/node.d.ts.map +1 -1
- package/dist/charts/node.js +6 -2
- package/dist/charts/node.js.map +1 -1
- package/dist/embed/client.d.ts +48 -3
- package/dist/embed/client.d.ts.map +1 -1
- package/dist/embed/client.js +79 -5
- package/dist/embed/client.js.map +1 -1
- package/dist/embed/index.d.ts +1 -1
- package/dist/embed/index.d.ts.map +1 -1
- package/dist/embed/index.js +1 -1
- package/dist/embed/index.js.map +1 -1
- package/dist/html/node.d.ts +3 -1
- package/dist/html/node.d.ts.map +1 -1
- package/dist/html/node.js +7 -5
- package/dist/html/node.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/{markdown → internal/markdown}/ast.d.ts +12 -0
- package/dist/internal/markdown/ast.d.ts.map +1 -0
- package/dist/internal/markdown/ast.js +22 -0
- package/dist/internal/markdown/ast.js.map +1 -0
- package/dist/internal/markdown/parse.d.ts.map +1 -0
- package/dist/{markdown → internal/markdown}/parse.js +112 -22
- package/dist/internal/markdown/parse.js.map +1 -0
- package/dist/internal/markdown/stringify.d.ts +4 -0
- package/dist/internal/markdown/stringify.d.ts.map +1 -0
- package/dist/internal/markdown/stringify.js +684 -0
- package/dist/internal/markdown/stringify.js.map +1 -0
- package/dist/internal/markdown/tags.d.ts.map +1 -0
- package/dist/internal/markdown/tags.js.map +1 -0
- package/dist/internal/scroll.d.ts +3 -2
- package/dist/internal/scroll.d.ts.map +1 -1
- package/dist/internal/scroll.js +1 -0
- package/dist/internal/scroll.js.map +1 -1
- package/dist/maps/anchors.d.ts +98 -0
- package/dist/maps/anchors.d.ts.map +1 -0
- package/dist/maps/anchors.js +531 -0
- package/dist/maps/anchors.js.map +1 -0
- package/dist/maps/controller.d.ts +283 -0
- package/dist/maps/controller.d.ts.map +1 -0
- package/dist/maps/controller.js +743 -0
- package/dist/maps/controller.js.map +1 -0
- package/dist/maps/gl/buckets.d.ts +95 -0
- package/dist/maps/gl/buckets.d.ts.map +1 -0
- package/dist/maps/gl/buckets.js +362 -0
- package/dist/maps/gl/buckets.js.map +1 -0
- package/dist/maps/gl/build-worker.d.ts +13 -0
- package/dist/maps/gl/build-worker.d.ts.map +1 -0
- package/dist/maps/gl/build-worker.js +44 -0
- package/dist/maps/gl/build-worker.js.map +1 -0
- package/dist/maps/gl/color.d.ts +8 -0
- package/dist/maps/gl/color.d.ts.map +1 -0
- package/dist/maps/gl/color.js +57 -0
- package/dist/maps/gl/color.js.map +1 -0
- package/dist/maps/gl/cover.d.ts +51 -0
- package/dist/maps/gl/cover.d.ts.map +1 -0
- package/dist/maps/gl/cover.js +124 -0
- package/dist/maps/gl/cover.js.map +1 -0
- package/dist/maps/gl/index.d.ts +3 -0
- package/dist/maps/gl/index.d.ts.map +1 -0
- package/dist/maps/gl/index.js +20 -0
- package/dist/maps/gl/index.js.map +1 -0
- package/dist/maps/gl/markers.d.ts +28 -0
- package/dist/maps/gl/markers.d.ts.map +1 -0
- package/dist/maps/gl/markers.js +60 -0
- package/dist/maps/gl/markers.js.map +1 -0
- package/dist/maps/gl/overlays.d.ts +68 -0
- package/dist/maps/gl/overlays.d.ts.map +1 -0
- package/dist/maps/gl/overlays.js +300 -0
- package/dist/maps/gl/overlays.js.map +1 -0
- package/dist/maps/gl/pane.d.ts +12 -0
- package/dist/maps/gl/pane.d.ts.map +1 -0
- package/dist/maps/gl/pane.js +37 -0
- package/dist/maps/gl/pane.js.map +1 -0
- package/dist/maps/gl/placement.d.ts +111 -0
- package/dist/maps/gl/placement.d.ts.map +1 -0
- package/dist/maps/gl/placement.js +567 -0
- package/dist/maps/gl/placement.js.map +1 -0
- package/dist/maps/gl/renderer.d.ts +352 -0
- package/dist/maps/gl/renderer.d.ts.map +1 -0
- package/dist/maps/gl/renderer.js +1127 -0
- package/dist/maps/gl/renderer.js.map +1 -0
- package/dist/maps/gl/shaders.d.ts +120 -0
- package/dist/maps/gl/shaders.d.ts.map +1 -0
- package/dist/maps/gl/shaders.js +451 -0
- package/dist/maps/gl/shaders.js.map +1 -0
- package/dist/maps/gl/store.d.ts +115 -0
- package/dist/maps/gl/store.d.ts.map +1 -0
- package/dist/maps/gl/store.js +469 -0
- package/dist/maps/gl/store.js.map +1 -0
- package/dist/maps/gl/text.d.ts +154 -0
- package/dist/maps/gl/text.d.ts.map +1 -0
- package/dist/maps/gl/text.js +382 -0
- package/dist/maps/gl/text.js.map +1 -0
- package/dist/maps/gl/view.d.ts +54 -0
- package/dist/maps/gl/view.d.ts.map +1 -0
- package/dist/maps/gl/view.js +974 -0
- package/dist/maps/gl/view.js.map +1 -0
- package/dist/maps/index.d.ts +1 -1
- package/dist/maps/index.d.ts.map +1 -1
- package/dist/maps/index.js +216 -52
- package/dist/maps/index.js.map +1 -1
- package/dist/maps/labels.d.ts +37 -16
- package/dist/maps/labels.d.ts.map +1 -1
- package/dist/maps/labels.js +188 -119
- package/dist/maps/labels.js.map +1 -1
- package/dist/maps/node.d.ts +162 -56
- package/dist/maps/node.d.ts.map +1 -1
- package/dist/maps/node.js +607 -515
- package/dist/maps/node.js.map +1 -1
- package/dist/maps/overlay.d.ts +72 -9
- package/dist/maps/overlay.d.ts.map +1 -1
- package/dist/maps/overlay.js +108 -28
- package/dist/maps/overlay.js.map +1 -1
- package/dist/maps/paint.d.ts +3 -0
- package/dist/maps/paint.d.ts.map +1 -1
- package/dist/maps/paint.js.map +1 -1
- package/dist/maps/proj.d.ts +14 -0
- package/dist/maps/proj.d.ts.map +1 -1
- package/dist/maps/proj.js +28 -0
- package/dist/maps/proj.js.map +1 -1
- package/dist/maps/renderer.d.ts +69 -0
- package/dist/maps/renderer.d.ts.map +1 -0
- package/dist/maps/renderer.js +66 -0
- package/dist/maps/renderer.js.map +1 -0
- package/dist/maps/sources.d.ts +25 -3
- package/dist/maps/sources.d.ts.map +1 -1
- package/dist/maps/sources.js +17 -0
- package/dist/maps/sources.js.map +1 -1
- package/dist/maps/theme.d.ts +19 -0
- package/dist/maps/theme.d.ts.map +1 -0
- package/dist/maps/theme.js +44 -0
- package/dist/maps/theme.js.map +1 -0
- package/dist/maps/tiles.d.ts +117 -17
- package/dist/maps/tiles.d.ts.map +1 -1
- package/dist/maps/tiles.js +163 -30
- package/dist/maps/tiles.js.map +1 -1
- package/dist/maps/types.d.ts +188 -20
- package/dist/maps/types.d.ts.map +1 -1
- package/dist/markdown/expressions.d.ts +1 -1
- package/dist/markdown/expressions.d.ts.map +1 -1
- package/dist/markdown/expressions.js.map +1 -1
- package/dist/markdown/index.d.ts +7 -6
- package/dist/markdown/index.d.ts.map +1 -1
- package/dist/markdown/index.js +9 -7
- package/dist/markdown/index.js.map +1 -1
- package/dist/markdown/spans.d.ts +1 -1
- package/dist/markdown/spans.d.ts.map +1 -1
- package/dist/media-player/index.d.ts +11 -3
- package/dist/media-player/index.d.ts.map +1 -1
- package/dist/media-player/index.js +13 -2
- package/dist/media-player/index.js.map +1 -1
- package/dist/rich-text-editor/clipboard.d.ts +23 -0
- package/dist/rich-text-editor/clipboard.d.ts.map +1 -0
- package/dist/rich-text-editor/clipboard.js +307 -0
- package/dist/rich-text-editor/clipboard.js.map +1 -0
- package/dist/rich-text-editor/collab.d.ts +32 -0
- package/dist/rich-text-editor/collab.d.ts.map +1 -0
- package/dist/rich-text-editor/collab.js +55 -0
- package/dist/rich-text-editor/collab.js.map +1 -0
- package/dist/rich-text-editor/commands.d.ts +50 -0
- package/dist/rich-text-editor/commands.d.ts.map +1 -0
- package/dist/rich-text-editor/commands.js +376 -0
- package/dist/rich-text-editor/commands.js.map +1 -0
- package/dist/rich-text-editor/drag.d.ts +68 -0
- package/dist/rich-text-editor/drag.d.ts.map +1 -0
- package/dist/rich-text-editor/drag.js +148 -0
- package/dist/rich-text-editor/drag.js.map +1 -0
- package/dist/rich-text-editor/html.d.ts +145 -0
- package/dist/rich-text-editor/html.d.ts.map +1 -0
- package/dist/rich-text-editor/html.js +516 -0
- package/dist/rich-text-editor/html.js.map +1 -0
- package/dist/rich-text-editor/index.d.ts +263 -0
- package/dist/rich-text-editor/index.d.ts.map +1 -0
- package/dist/rich-text-editor/index.js +822 -0
- package/dist/rich-text-editor/index.js.map +1 -0
- package/dist/rich-text-editor/inline.d.ts +94 -0
- package/dist/rich-text-editor/inline.d.ts.map +1 -0
- package/dist/rich-text-editor/inline.js +252 -0
- package/dist/rich-text-editor/inline.js.map +1 -0
- package/dist/rich-text-editor/keymap.d.ts +71 -0
- package/dist/rich-text-editor/keymap.d.ts.map +1 -0
- package/dist/rich-text-editor/keymap.js +393 -0
- package/dist/rich-text-editor/keymap.js.map +1 -0
- package/dist/rich-text-editor/keys.d.ts +29 -0
- package/dist/rich-text-editor/keys.d.ts.map +1 -0
- package/dist/rich-text-editor/keys.js +93 -0
- package/dist/rich-text-editor/keys.js.map +1 -0
- package/dist/rich-text-editor/look.d.ts +71 -0
- package/dist/rich-text-editor/look.d.ts.map +1 -0
- package/dist/rich-text-editor/look.js +342 -0
- package/dist/rich-text-editor/look.js.map +1 -0
- package/dist/rich-text-editor/markdown.d.ts +18 -0
- package/dist/rich-text-editor/markdown.d.ts.map +1 -0
- package/dist/rich-text-editor/markdown.js +496 -0
- package/dist/rich-text-editor/markdown.js.map +1 -0
- package/dist/rich-text-editor/nodes.d.ts +135 -0
- package/dist/rich-text-editor/nodes.d.ts.map +1 -0
- package/dist/rich-text-editor/nodes.js +397 -0
- package/dist/rich-text-editor/nodes.js.map +1 -0
- package/dist/rich-text-editor/render.d.ts +68 -0
- package/dist/rich-text-editor/render.d.ts.map +1 -0
- package/dist/rich-text-editor/render.js +500 -0
- package/dist/rich-text-editor/render.js.map +1 -0
- package/dist/rich-text-editor/schema.d.ts +16 -0
- package/dist/rich-text-editor/schema.d.ts.map +1 -0
- package/dist/rich-text-editor/schema.js +386 -0
- package/dist/rich-text-editor/schema.js.map +1 -0
- package/dist/rich-text-editor/store.d.ts +11 -0
- package/dist/rich-text-editor/store.d.ts.map +1 -0
- package/dist/rich-text-editor/store.js +43 -0
- package/dist/rich-text-editor/store.js.map +1 -0
- package/dist/rich-text-editor/suggest.d.ts +127 -0
- package/dist/rich-text-editor/suggest.d.ts.map +1 -0
- package/dist/rich-text-editor/suggest.js +0 -0
- package/dist/rich-text-editor/suggest.js.map +1 -0
- package/dist/rich-text-editor/tables.d.ts +41 -0
- package/dist/rich-text-editor/tables.d.ts.map +1 -0
- package/dist/rich-text-editor/tables.js +204 -0
- package/dist/rich-text-editor/tables.js.map +1 -0
- package/dist/rich-text-editor/toolbar.d.ts +58 -0
- package/dist/rich-text-editor/toolbar.d.ts.map +1 -0
- package/dist/rich-text-editor/toolbar.js +548 -0
- package/dist/rich-text-editor/toolbar.js.map +1 -0
- package/dist/rich-text-editor/view.d.ts +368 -0
- package/dist/rich-text-editor/view.d.ts.map +1 -0
- package/dist/rich-text-editor/view.js +1968 -0
- package/dist/rich-text-editor/view.js.map +1 -0
- package/dist/rich-text-editor/virtual.d.ts +54 -0
- package/dist/rich-text-editor/virtual.d.ts.map +1 -0
- package/dist/rich-text-editor/virtual.js +262 -0
- package/dist/rich-text-editor/virtual.js.map +1 -0
- package/dist/richtext/node.d.ts +25 -2
- package/dist/richtext/node.d.ts.map +1 -1
- package/dist/richtext/node.js +46 -24
- package/dist/richtext/node.js.map +1 -1
- package/dist/terminal/backends.d.ts +4 -1
- package/dist/terminal/backends.d.ts.map +1 -1
- package/dist/terminal/backends.js.map +1 -1
- package/dist/terminal/index.d.ts +18 -7
- package/dist/terminal/index.d.ts.map +1 -1
- package/dist/terminal/index.js +28 -11
- package/dist/terminal/index.js.map +1 -1
- package/package.json +23 -4
- package/src/charts/node.ts +6 -2
- package/src/embed/client.ts +102 -8
- package/src/embed/index.ts +2 -0
- package/src/html/node.ts +7 -5
- package/src/index.ts +2 -0
- package/src/{markdown → internal/markdown}/ast.ts +24 -7
- package/src/{markdown → internal/markdown}/parse.ts +134 -24
- package/src/internal/markdown/stringify.ts +772 -0
- package/src/internal/scroll.ts +5 -3
- package/src/maps/anchors.ts +607 -0
- package/src/maps/controller.ts +999 -0
- package/src/maps/gl/buckets.ts +457 -0
- package/src/maps/gl/build-worker.ts +55 -0
- package/src/maps/gl/color.ts +62 -0
- package/src/maps/gl/cover.ts +170 -0
- package/src/maps/gl/index.ts +23 -0
- package/src/maps/gl/markers.ts +83 -0
- package/src/maps/gl/overlays.ts +379 -0
- package/src/maps/gl/pane.ts +42 -0
- package/src/maps/gl/placement.ts +816 -0
- package/src/maps/gl/renderer.ts +1576 -0
- package/src/maps/gl/shaders.ts +486 -0
- package/src/maps/gl/store.ts +566 -0
- package/src/maps/gl/text.ts +495 -0
- package/src/maps/gl/view.ts +1224 -0
- package/src/maps/index.ts +270 -81
- package/src/maps/labels.ts +214 -121
- package/src/maps/node.ts +763 -629
- package/src/maps/overlay.ts +148 -43
- package/src/maps/paint.ts +3 -0
- package/src/maps/proj.ts +31 -0
- package/src/maps/renderer.ts +155 -0
- package/src/maps/sources.ts +38 -3
- package/src/maps/theme.ts +51 -0
- package/src/maps/tiles.ts +191 -33
- package/src/maps/types.ts +188 -20
- package/src/markdown/expressions.ts +5 -1
- package/src/markdown/index.ts +14 -11
- package/src/markdown/spans.ts +1 -1
- package/src/media-player/index.ts +18 -4
- package/src/rich-text-editor/clipboard.ts +439 -0
- package/src/rich-text-editor/collab.ts +91 -0
- package/src/rich-text-editor/commands.ts +448 -0
- package/src/rich-text-editor/dom-globals.d.ts +23 -0
- package/src/rich-text-editor/drag.ts +211 -0
- package/src/rich-text-editor/html.ts +619 -0
- package/src/rich-text-editor/index.ts +1331 -0
- package/src/rich-text-editor/inline.ts +345 -0
- package/src/rich-text-editor/keymap.ts +510 -0
- package/src/rich-text-editor/keys.ts +119 -0
- package/src/rich-text-editor/look.ts +427 -0
- package/src/rich-text-editor/markdown.ts +653 -0
- package/src/rich-text-editor/nodes.ts +497 -0
- package/src/rich-text-editor/render.ts +800 -0
- package/src/rich-text-editor/schema.ts +431 -0
- package/src/rich-text-editor/store.ts +39 -0
- package/src/rich-text-editor/suggest.ts +597 -0
- package/src/rich-text-editor/tables.ts +272 -0
- package/src/rich-text-editor/toolbar.ts +724 -0
- package/src/rich-text-editor/view.ts +2287 -0
- package/src/rich-text-editor/virtual.ts +347 -0
- package/src/richtext/node.ts +59 -30
- package/src/terminal/backends.ts +4 -1
- package/src/terminal/index.ts +43 -15
- package/dist/markdown/ast.d.ts.map +0 -1
- package/dist/markdown/ast.js +0 -17
- package/dist/markdown/ast.js.map +0 -1
- package/dist/markdown/parse.d.ts.map +0 -1
- package/dist/markdown/parse.js.map +0 -1
- package/dist/markdown/tags.d.ts.map +0 -1
- package/dist/markdown/tags.js.map +0 -1
- /package/dist/{markdown → internal/markdown}/parse.d.ts +0 -0
- /package/dist/{markdown → internal/markdown}/tags.d.ts +0 -0
- /package/dist/{markdown → internal/markdown}/tags.js +0 -0
- /package/src/{markdown → internal/markdown}/tags.ts +0 -0
package/src/maps/index.ts
CHANGED
|
@@ -14,8 +14,9 @@
|
|
|
14
14
|
// until an application imports the component that needs it, so
|
|
15
15
|
// `sideEffects: false` stays honest. Do not move it into `../index.ts`
|
|
16
16
|
// (AGENTS.md, "Tree-shaking is a constraint").
|
|
17
|
-
import React, { useImperativeHandle, useRef } from 'react';
|
|
18
|
-
import type { ReactElement } from 'react';
|
|
17
|
+
import React, { useEffect, useImperativeHandle, useRef, useState } from 'react';
|
|
18
|
+
import type { ReactElement, ReactNode } from 'react';
|
|
19
|
+
import { useApp, useSupports, useTheme } from 'react-x11';
|
|
19
20
|
import { registerElement, registeredElements } from 'react-x11/host';
|
|
20
21
|
import { createStyles, flattenStyle } from 'react-x11/style';
|
|
21
22
|
// Loads the module the JSX augmentation at the bottom targets: nothing in
|
|
@@ -24,16 +25,25 @@ import { createStyles, flattenStyle } from 'react-x11/style';
|
|
|
24
25
|
// addition. Type-only, so it is erased.
|
|
25
26
|
import type {} from 'react-x11/jsx-runtime';
|
|
26
27
|
|
|
28
|
+
import { DEFAULT_CAMERA, MapController } from './controller.js';
|
|
27
29
|
import { ELEMENT, MapViewNode, SELF_DAMAGED_PROPS } from './node.js';
|
|
30
|
+
import {
|
|
31
|
+
chooseRenderer,
|
|
32
|
+
glRendererModule,
|
|
33
|
+
loadGlRenderer,
|
|
34
|
+
rendererFromEnv,
|
|
35
|
+
rendererRequest,
|
|
36
|
+
} from './renderer.js';
|
|
37
|
+
import type { GlRendererModule } from './renderer.js';
|
|
38
|
+
import { defaultStyleFor, isDarkTheme } from './theme.js';
|
|
28
39
|
import type {
|
|
29
|
-
FitBoundsOptions,
|
|
30
|
-
MapCamera,
|
|
31
|
-
MapHandle,
|
|
32
40
|
MapProps,
|
|
41
|
+
MapRenderer,
|
|
42
|
+
MapRendererReason,
|
|
33
43
|
MapViewProps,
|
|
34
44
|
} from './types.js';
|
|
35
|
-
|
|
36
|
-
|
|
45
|
+
|
|
46
|
+
const h = React.createElement;
|
|
37
47
|
|
|
38
48
|
if (!registeredElements().includes(ELEMENT)) {
|
|
39
49
|
registerElement(ELEMENT, {
|
|
@@ -65,8 +75,6 @@ const styles = createStyles({
|
|
|
65
75
|
fill: { flexGrow: 1 },
|
|
66
76
|
});
|
|
67
77
|
|
|
68
|
-
const DEFAULT_CAMERA: MapCamera = { center: { lon: 0, lat: 20 }, zoom: 2 };
|
|
69
|
-
|
|
70
78
|
/**
|
|
71
79
|
* A map.
|
|
72
80
|
*
|
|
@@ -91,87 +99,263 @@ const DEFAULT_CAMERA: MapCamera = { center: { lon: 0, lat: 20 }, zoom: 2 };
|
|
|
91
99
|
* controlled form, where the application owns where the map is looking.
|
|
92
100
|
*/
|
|
93
101
|
export function Map(props: MapProps): ReactElement {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
ref,
|
|
101
|
-
...rest
|
|
102
|
-
} = props;
|
|
103
|
-
|
|
104
|
-
const view = useRef<MapViewNode | null>(null);
|
|
105
|
-
const controlled = camera !== undefined;
|
|
106
|
-
|
|
107
|
-
useImperativeHandle(
|
|
108
|
-
ref,
|
|
109
|
-
(): MapHandle => ({
|
|
110
|
-
// Every method reads the node at call time rather than closing over
|
|
111
|
-
// it: the ref attaches after the commit that created the node, and a
|
|
112
|
-
// handle built once must still work for the whole mount.
|
|
113
|
-
getCamera: () => view.current?.getCamera() ?? DEFAULT_CAMERA,
|
|
114
|
-
setCamera: (next: Partial<MapCamera>) => view.current?.setCamera(next),
|
|
115
|
-
panBy: (dx: number, dy: number) => view.current?.panBy(dx, dy),
|
|
116
|
-
zoomIn: (step?: number) => view.current?.zoomIn(step),
|
|
117
|
-
zoomOut: (step?: number) => view.current?.zoomOut(step),
|
|
118
|
-
zoomTo: (zoom: number) => view.current?.zoomTo(zoom),
|
|
119
|
-
fitBounds: (bounds: LngLatBounds, options?: FitBoundsOptions) =>
|
|
120
|
-
view.current?.fitBounds(bounds, options),
|
|
121
|
-
fitMarkers: (ids?: readonly string[], options?: FitBoundsOptions) =>
|
|
122
|
-
view.current?.fitMarkers(ids, options),
|
|
123
|
-
getBounds: () =>
|
|
124
|
-
view.current?.getBounds() ?? {
|
|
125
|
-
west: -180,
|
|
126
|
-
south: -85,
|
|
127
|
-
east: 180,
|
|
128
|
-
north: 85,
|
|
129
|
-
},
|
|
130
|
-
project: (position: LngLat) =>
|
|
131
|
-
view.current?.project(position) ?? { x: 0, y: 0 },
|
|
132
|
-
unproject: (x: number, y: number) =>
|
|
133
|
-
view.current?.unproject(x, y) ?? { lon: 0, lat: 0 },
|
|
134
|
-
markerAt: (x: number, y: number): MapMarker | null =>
|
|
135
|
-
view.current?.markerAt(x, y) ?? null,
|
|
136
|
-
refresh: () => view.current?.refresh(),
|
|
137
|
-
stats: () => view.current?.stats() ?? null,
|
|
138
|
-
}),
|
|
139
|
-
[],
|
|
102
|
+
// One controller for the life of the mount: the camera, the gestures and
|
|
103
|
+
// the handle, which whichever renderer is drawing answers to (see
|
|
104
|
+
// `./controller.ts`). Seeded here, once — `defaultCamera` is read on the
|
|
105
|
+
// first render and never again, which is what makes it a *default*.
|
|
106
|
+
const [controller] = useState(
|
|
107
|
+
() => new MapController(props.defaultCamera ?? DEFAULT_CAMERA),
|
|
140
108
|
);
|
|
109
|
+
// Read at event and frame time, so the latest props are always the ones
|
|
110
|
+
// that count — and the controlled/uncontrolled fork is simply whether
|
|
111
|
+
// `camera` is among them.
|
|
112
|
+
controller.setProps(props);
|
|
113
|
+
// The controller's own handle, made once: the same object for the whole
|
|
114
|
+
// mount, whatever draws the map — across a renderer switch too.
|
|
115
|
+
useImperativeHandle(props.ref, () => controller.handle, [controller]);
|
|
116
|
+
useEffect(() => () => controller.dispose(), [controller]);
|
|
117
|
+
|
|
118
|
+
// A GL failure is the map's for the rest of its mount: an `'auto'` map
|
|
119
|
+
// that met one draws through the retained renderer from then on.
|
|
120
|
+
const [failure, setFailure] = useState<Error | null>(null);
|
|
121
|
+
const latest = useRef(props);
|
|
122
|
+
latest.current = props;
|
|
141
123
|
|
|
142
|
-
const flat = flattenStyle(style ?? null);
|
|
124
|
+
const flat = flattenStyle(props.style ?? null);
|
|
143
125
|
const sized =
|
|
144
126
|
flat.height !== undefined ||
|
|
145
127
|
flat.flexGrow !== undefined ||
|
|
146
128
|
flat.flexBasis !== undefined;
|
|
147
129
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
130
|
+
const { asked, forced } = rendererRequest(props.renderer, rendererFromEnv());
|
|
131
|
+
const pane =
|
|
132
|
+
asked === 'auto'
|
|
133
|
+
? h(AutoPane, {
|
|
134
|
+
key: 'auto',
|
|
135
|
+
map: props,
|
|
136
|
+
controller,
|
|
137
|
+
failed: failure !== null,
|
|
138
|
+
onFailure: setFailure,
|
|
139
|
+
})
|
|
140
|
+
: h(MapPane, {
|
|
141
|
+
key: asked,
|
|
142
|
+
renderer: asked,
|
|
143
|
+
reason: forced ? 'forced' : null,
|
|
144
|
+
map: props,
|
|
145
|
+
controller,
|
|
146
|
+
// Asked for by name: never a fallback, always the application's
|
|
147
|
+
// to hear about.
|
|
148
|
+
onFailure: (error: Error) => latest.current.onError?.(error),
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
return h(
|
|
155
152
|
'box',
|
|
156
|
-
{ style: sized ? [styles.clip, style] : [styles.pane, style] },
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
153
|
+
{ style: sized ? [styles.clip, props.style] : [styles.pane, props.style] },
|
|
154
|
+
pane,
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** Props `<Map>` reads itself, or that only the GL renderer reads — kept off
|
|
159
|
+
* the `<mapview>` element, which would take each as a prop of its own. */
|
|
160
|
+
const NOT_FOR_THE_ELEMENT: readonly string[] = [
|
|
161
|
+
'camera',
|
|
162
|
+
'defaultCamera',
|
|
163
|
+
'style',
|
|
164
|
+
'children',
|
|
165
|
+
'ref',
|
|
166
|
+
'renderer',
|
|
167
|
+
'onRendererChange',
|
|
168
|
+
'onError',
|
|
169
|
+
'levelFade',
|
|
170
|
+
'adaptive',
|
|
171
|
+
'buildWorkers',
|
|
172
|
+
'antialias',
|
|
173
|
+
'fillRule',
|
|
174
|
+
'onAfterDraw',
|
|
175
|
+
];
|
|
176
|
+
|
|
177
|
+
function elementProps(map: MapProps): MapViewProps {
|
|
178
|
+
const out: Record<string, unknown> = { ...map };
|
|
179
|
+
for (const name of NOT_FOR_THE_ELEMENT) delete out[name];
|
|
180
|
+
return out as MapViewProps;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
interface PaneProps {
|
|
184
|
+
map: MapProps;
|
|
185
|
+
controller: MapController;
|
|
186
|
+
onFailure: (error: Error) => void;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* `renderer="auto"`: GL where this connection draws through the direct
|
|
191
|
+
* backend, the retained renderer everywhere else — `./renderer.ts` is the
|
|
192
|
+
* decision, and this is where it reads the connection. Its own component so
|
|
193
|
+
* that a map that asked for a renderer by name never asks the connection: on
|
|
194
|
+
* the Cocoa backend the question is a GL runtime brought up to answer it.
|
|
195
|
+
*/
|
|
196
|
+
function AutoPane(props: PaneProps & { failed: boolean }): ReactElement {
|
|
197
|
+
const { map } = props;
|
|
198
|
+
const app = useApp();
|
|
199
|
+
const shaders = useSupports('shaders');
|
|
200
|
+
const probing = useDirectGlProbe(app, shaders);
|
|
201
|
+
const choice = chooseRenderer({
|
|
202
|
+
requested: 'auto',
|
|
203
|
+
shaders,
|
|
204
|
+
probing,
|
|
205
|
+
failed: props.failed,
|
|
206
|
+
});
|
|
207
|
+
return h(MapPane, {
|
|
208
|
+
renderer: choice.renderer,
|
|
209
|
+
reason: choice.reason,
|
|
210
|
+
map,
|
|
211
|
+
controller: props.controller,
|
|
212
|
+
onFailure: props.onFailure,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Whether this connection's answer to `useSupports('shaders')` is still to
|
|
218
|
+
* come. Under a policy that could choose direct GL, X11 settles it before
|
|
219
|
+
* `createRoot()` hands the app back; the Cocoa backend settles it on the
|
|
220
|
+
* first ask, which is this. Until it has, a map shows its background rather
|
|
221
|
+
* than drawing through the retained renderer for a few milliseconds and
|
|
222
|
+
* fetching the view's tiles twice.
|
|
223
|
+
*/
|
|
224
|
+
function useDirectGlProbe(app: unknown, shaders: boolean): boolean {
|
|
225
|
+
const mode = (app as { glPolicy?: { mode?: string } } | null)?.glPolicy?.mode;
|
|
226
|
+
const wants = mode === 'auto' || mode === 'direct';
|
|
227
|
+
const [settled, setSettled] = useState(false);
|
|
228
|
+
const pending = wants && !shaders && !settled;
|
|
229
|
+
useEffect(() => {
|
|
230
|
+
if (!pending) return;
|
|
231
|
+
const probe = (
|
|
232
|
+
app as { glCapabilities?(): Promise<unknown> } | null
|
|
233
|
+
)?.glCapabilities?.();
|
|
234
|
+
if (!probe) {
|
|
235
|
+
setSettled(true);
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
let live = true;
|
|
239
|
+
const done = (): void => {
|
|
240
|
+
if (live) setSettled(true);
|
|
241
|
+
};
|
|
242
|
+
probe.then(done, done);
|
|
243
|
+
return () => {
|
|
244
|
+
live = false;
|
|
245
|
+
};
|
|
246
|
+
}, [app, pending]);
|
|
247
|
+
return pending;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* The pane, drawn by the renderer chosen: the `<mapview>` element, the GL
|
|
252
|
+
* renderer once its module has loaded, or — while the connection's answer
|
|
253
|
+
* or the module is on its way — a box in the style's background. Whichever
|
|
254
|
+
* it is, it answers to the map's one controller.
|
|
255
|
+
*/
|
|
256
|
+
function MapPane(
|
|
257
|
+
props: PaneProps & {
|
|
258
|
+
renderer: MapRenderer | 'pending';
|
|
259
|
+
reason: MapRendererReason | null;
|
|
260
|
+
},
|
|
261
|
+
): ReactElement {
|
|
262
|
+
const { renderer, reason, map, controller } = props;
|
|
263
|
+
const theme = useTheme();
|
|
264
|
+
const overlay = useSupports('glOverlay');
|
|
265
|
+
|
|
266
|
+
// `onRendererChange`: whenever the map lands somewhere it did not ask for
|
|
267
|
+
// — its first renderer, or the one it falls back to.
|
|
268
|
+
const reported = useRef<MapRenderer | null>(null);
|
|
269
|
+
useEffect(() => {
|
|
270
|
+
if (renderer === 'pending') return;
|
|
271
|
+
const before = reported.current;
|
|
272
|
+
reported.current = renderer;
|
|
273
|
+
if (before === renderer || reason === null) return;
|
|
274
|
+
map.onRendererChange?.(renderer, reason);
|
|
275
|
+
}, [renderer, reason]);
|
|
276
|
+
|
|
277
|
+
const wantGl = renderer === 'gl';
|
|
278
|
+
const [gl, setGl] = useState<GlRendererModule | null>(glRendererModule);
|
|
279
|
+
useEffect(() => {
|
|
280
|
+
if (!wantGl || gl) return;
|
|
281
|
+
let live = true;
|
|
282
|
+
loadGlRenderer().then(
|
|
283
|
+
(module) => {
|
|
284
|
+
if (live) setGl(module);
|
|
285
|
+
},
|
|
286
|
+
(error: unknown) => {
|
|
287
|
+
if (!live) return;
|
|
288
|
+
props.onFailure(
|
|
289
|
+
error instanceof Error ? error : new Error(String(error)),
|
|
290
|
+
);
|
|
291
|
+
},
|
|
292
|
+
);
|
|
293
|
+
return () => {
|
|
294
|
+
live = false;
|
|
295
|
+
};
|
|
296
|
+
}, [wantGl, gl]);
|
|
297
|
+
|
|
298
|
+
const common = {
|
|
299
|
+
style: styles.fill,
|
|
300
|
+
role: map.role ?? 'group',
|
|
301
|
+
'aria-label': map['aria-label'] ?? 'Map',
|
|
302
|
+
'data-testname': map['data-testname'],
|
|
303
|
+
};
|
|
304
|
+
// What the application puts over the map is the pane's sibling, after
|
|
305
|
+
// it, rather than its child: a registered element's own drawing happens
|
|
306
|
+
// *after* `super.paint` has painted its children, so anything mounted
|
|
307
|
+
// inside `<mapview>` would be painted over by the map. `<Flow>` makes the
|
|
308
|
+
// same arrangement for the same reason. The one exception is a GL pane:
|
|
309
|
+
// a sibling is under its surface, so there they go inside the surface,
|
|
310
|
+
// whose children core draws above it.
|
|
311
|
+
const over = (pane: ReactElement, children: ReactNode): ReactElement =>
|
|
312
|
+
h(React.Fragment, null, pane, children);
|
|
313
|
+
if (renderer === 'retained') {
|
|
314
|
+
return over(
|
|
315
|
+
h(ELEMENT, {
|
|
316
|
+
...elementProps(map),
|
|
317
|
+
...common,
|
|
318
|
+
key: 'retained',
|
|
319
|
+
mapController: controller,
|
|
320
|
+
// The controlled/uncontrolled fork, and the whole of it.
|
|
321
|
+
// Controlled: the application's camera goes down and the element
|
|
322
|
+
// only ever *asks* to move. Uncontrolled: nothing goes down, the
|
|
323
|
+
// controller owns the camera, and a pan never reaches React —
|
|
324
|
+
// which is the difference between a drag that blits a strip and
|
|
325
|
+
// one that re-renders and re-claims the pane on every pointer
|
|
326
|
+
// step.
|
|
327
|
+
camera: map.camera,
|
|
328
|
+
} as MapViewProps),
|
|
329
|
+
map.children,
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
if (renderer === 'gl' && gl) {
|
|
333
|
+
return over(
|
|
334
|
+
h(
|
|
335
|
+
gl.GlMapPane,
|
|
336
|
+
{
|
|
337
|
+
...common,
|
|
338
|
+
key: 'gl',
|
|
339
|
+
controller,
|
|
340
|
+
map,
|
|
341
|
+
onFailure: props.onFailure,
|
|
342
|
+
},
|
|
343
|
+
overlay ? map.children : undefined,
|
|
344
|
+
),
|
|
345
|
+
overlay ? null : map.children,
|
|
346
|
+
);
|
|
347
|
+
}
|
|
348
|
+
const background = (map.mapStyle ?? defaultStyleFor(isDarkTheme(theme)))
|
|
349
|
+
.background;
|
|
350
|
+
return over(
|
|
351
|
+
h('box', {
|
|
352
|
+
...common,
|
|
353
|
+
key: 'pending',
|
|
354
|
+
style: background
|
|
355
|
+
? [styles.fill, { backgroundColor: background }]
|
|
356
|
+
: styles.fill,
|
|
173
357
|
}),
|
|
174
|
-
children,
|
|
358
|
+
map.children,
|
|
175
359
|
);
|
|
176
360
|
}
|
|
177
361
|
|
|
@@ -256,9 +440,14 @@ export { TileCache } from './tiles.js';
|
|
|
256
440
|
export type {
|
|
257
441
|
FitBoundsOptions,
|
|
258
442
|
MapFrameStats,
|
|
443
|
+
MapGlFrameStats,
|
|
444
|
+
MapGlProps,
|
|
259
445
|
MapHandle,
|
|
260
446
|
MapPointerEvent,
|
|
261
447
|
MapProps,
|
|
448
|
+
MapRenderer,
|
|
449
|
+
MapRendererReason,
|
|
450
|
+
MapRendererRequest,
|
|
262
451
|
MapViewProps,
|
|
263
452
|
} from './types.js';
|
|
264
453
|
export type {
|