@sjvair/map-sdk 0.0.0-stage → 0.1.0-beta.10

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 (140) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +713 -2
  3. package/dist/core/basemap.svelte.d.ts +38 -0
  4. package/dist/core/basemap.svelte.js +163 -0
  5. package/dist/core/context.d.ts +5 -0
  6. package/dist/core/context.js +13 -0
  7. package/dist/core/create-map.svelte.d.ts +274 -0
  8. package/dist/core/create-map.svelte.js +591 -0
  9. package/dist/core/gl.d.ts +97 -0
  10. package/dist/core/gl.js +1 -0
  11. package/dist/core/interactions.svelte.d.ts +50 -0
  12. package/dist/core/interactions.svelte.js +330 -0
  13. package/dist/core/plugin-host.svelte.d.ts +71 -0
  14. package/dist/core/plugin-host.svelte.js +445 -0
  15. package/dist/core/plugin.d.ts +190 -0
  16. package/dist/core/plugin.js +1 -0
  17. package/dist/core/scoped-context.d.ts +7 -0
  18. package/dist/core/scoped-context.js +34 -0
  19. package/dist/core/shape-view.d.ts +27 -0
  20. package/dist/core/shape-view.js +323 -0
  21. package/dist/data/format.d.ts +10 -0
  22. package/dist/data/format.js +37 -0
  23. package/dist/data/index.d.ts +9 -0
  24. package/dist/data/index.js +9 -0
  25. package/dist/data/messages/en.json +61 -0
  26. package/dist/data/messages.d.ts +10 -0
  27. package/dist/data/messages.js +17 -0
  28. package/dist/data/metadata.d.ts +22 -0
  29. package/dist/data/metadata.js +110 -0
  30. package/dist/data/refs.d.ts +18 -0
  31. package/dist/data/refs.js +61 -0
  32. package/dist/data/scale-types.d.ts +7 -0
  33. package/dist/data/scale-types.js +1 -0
  34. package/dist/data/scale.d.ts +13 -0
  35. package/dist/data/scale.js +27 -0
  36. package/dist/data/selection.d.ts +13 -0
  37. package/dist/data/selection.js +52 -0
  38. package/dist/data/static-source.d.ts +4 -0
  39. package/dist/data/static-source.js +3 -0
  40. package/dist/data/types.d.ts +74 -0
  41. package/dist/data/types.js +1 -0
  42. package/dist/index.d.ts +59 -0
  43. package/dist/index.js +42 -0
  44. package/dist/plugins/icons.d.ts +21 -0
  45. package/dist/plugins/icons.js +73 -0
  46. package/dist/plugins/points-clusters.d.ts +60 -0
  47. package/dist/plugins/points-clusters.js +93 -0
  48. package/dist/plugins/points.svelte.d.ts +105 -0
  49. package/dist/plugins/points.svelte.js +502 -0
  50. package/dist/plugins/scale-resolution.svelte.d.ts +27 -0
  51. package/dist/plugins/scale-resolution.svelte.js +111 -0
  52. package/dist/plugins/shapes.svelte.d.ts +34 -0
  53. package/dist/plugins/shapes.svelte.js +325 -0
  54. package/dist/plugins/shared.d.ts +6 -0
  55. package/dist/plugins/shared.js +18 -0
  56. package/dist/plugins/style.d.ts +57 -0
  57. package/dist/plugins/style.js +193 -0
  58. package/dist/presets/CollocationTooltip.svelte +132 -0
  59. package/dist/presets/CollocationTooltip.svelte.d.ts +16 -0
  60. package/dist/presets/FireTooltip.svelte +70 -0
  61. package/dist/presets/FireTooltip.svelte.d.ts +13 -0
  62. package/dist/presets/MonitorClusterTooltip.svelte +168 -0
  63. package/dist/presets/MonitorClusterTooltip.svelte.d.ts +16 -0
  64. package/dist/presets/MonitorReadingBox.svelte +58 -0
  65. package/dist/presets/MonitorReadingBox.svelte.d.ts +12 -0
  66. package/dist/presets/MonitorTooltip.svelte +88 -0
  67. package/dist/presets/MonitorTooltip.svelte.d.ts +20 -0
  68. package/dist/presets/calheatscore.d.ts +24 -0
  69. package/dist/presets/calheatscore.js +22 -0
  70. package/dist/presets/cluster-area.d.ts +13 -0
  71. package/dist/presets/cluster-area.js +34 -0
  72. package/dist/presets/collocation-sites.d.ts +18 -0
  73. package/dist/presets/collocation-sites.js +67 -0
  74. package/dist/presets/fire-groups.d.ts +26 -0
  75. package/dist/presets/fire-groups.js +51 -0
  76. package/dist/presets/forecast-zones.d.ts +25 -0
  77. package/dist/presets/forecast-zones.js +23 -0
  78. package/dist/presets/hms-fire.d.ts +30 -0
  79. package/dist/presets/hms-fire.js +86 -0
  80. package/dist/presets/hms-smoke.d.ts +20 -0
  81. package/dist/presets/hms-smoke.js +22 -0
  82. package/dist/presets/monitors.d.ts +48 -0
  83. package/dist/presets/monitors.js +243 -0
  84. package/dist/presets/reactive-props.svelte.d.ts +4 -0
  85. package/dist/presets/reactive-props.svelte.js +7 -0
  86. package/dist/presets/regions.d.ts +24 -0
  87. package/dist/presets/regions.js +22 -0
  88. package/dist/stores/abort.d.ts +16 -0
  89. package/dist/stores/abort.js +52 -0
  90. package/dist/stores/collocation-store.svelte.d.ts +25 -0
  91. package/dist/stores/collocation-store.svelte.js +72 -0
  92. package/dist/stores/hms-stores.svelte.d.ts +38 -0
  93. package/dist/stores/hms-stores.svelte.js +97 -0
  94. package/dist/stores/index.d.ts +4 -0
  95. package/dist/stores/index.js +4 -0
  96. package/dist/stores/load-once.svelte.d.ts +25 -0
  97. package/dist/stores/load-once.svelte.js +93 -0
  98. package/dist/stores/monitors-store.svelte.d.ts +85 -0
  99. package/dist/stores/monitors-store.svelte.js +340 -0
  100. package/dist/theme.css +34 -0
  101. package/dist/ui/FeatureList.svelte +501 -0
  102. package/dist/ui/FeatureList.svelte.d.ts +14 -0
  103. package/dist/ui/Legend.svelte +214 -0
  104. package/dist/ui/Legend.svelte.d.ts +22 -0
  105. package/dist/ui/LegendBar.svelte +161 -0
  106. package/dist/ui/LegendBar.svelte.d.ts +11 -0
  107. package/dist/ui/MapControls.svelte +135 -0
  108. package/dist/ui/MapControls.svelte.d.ts +11 -0
  109. package/dist/ui/MapTooltip.svelte +397 -0
  110. package/dist/ui/MapTooltip.svelte.d.ts +37 -0
  111. package/dist/ui/PickNotice.svelte +56 -0
  112. package/dist/ui/PickNotice.svelte.d.ts +7 -0
  113. package/dist/ui/SelectionBar.svelte +123 -0
  114. package/dist/ui/SelectionBar.svelte.d.ts +10 -0
  115. package/dist/ui/TooltipItem.svelte +66 -0
  116. package/dist/ui/TooltipItem.svelte.d.ts +11 -0
  117. package/dist/ui/ViewSummary.svelte +97 -0
  118. package/dist/ui/ViewSummary.svelte.d.ts +7 -0
  119. package/dist/ui/card.d.ts +29 -0
  120. package/dist/ui/card.js +1 -0
  121. package/dist/ui/controls.css +45 -0
  122. package/dist/ui/data-credits.svelte.d.ts +9 -0
  123. package/dist/ui/data-credits.svelte.js +52 -0
  124. package/dist/ui/feature-list.d.ts +46 -0
  125. package/dist/ui/feature-list.js +115 -0
  126. package/dist/ui/legend-data.d.ts +41 -0
  127. package/dist/ui/legend-data.js +40 -0
  128. package/dist/ui/level-chip.d.ts +11 -0
  129. package/dist/ui/level-chip.js +15 -0
  130. package/dist/ui/value-format.d.ts +8 -0
  131. package/dist/ui/value-format.js +20 -0
  132. package/dist/ui/view-summary.d.ts +11 -0
  133. package/dist/ui/view-summary.js +33 -0
  134. package/dist/view/MapView.svelte +443 -0
  135. package/dist/view/MapView.svelte.d.ts +51 -0
  136. package/dist/view/create-gl-map.d.ts +34 -0
  137. package/dist/view/create-gl-map.js +186 -0
  138. package/dist/view/list-placement.d.ts +21 -0
  139. package/dist/view/list-placement.js +13 -0
  140. package/package.json +104 -5
@@ -0,0 +1,38 @@
1
+ import type { GlMapLike } from "./gl.js";
2
+ export interface BasemapConfig {
3
+ styles: Array<{
4
+ id: string;
5
+ style: unknown;
6
+ }>;
7
+ defaultId: string;
8
+ excludedLayers?: string[];
9
+ }
10
+ /**
11
+ * The map's current basemap, and switching it on a GL map.
12
+ *
13
+ * The GL map is created with the style of `current` (the map's creator does that), so `attach`
14
+ * calls `setStyle` for nothing. Later `select` calls load the new style. A newer `select`
15
+ * supersedes one still loading. If the style document fails, the map goes back to the last style
16
+ * that loaded and `current` reverts; if that fails too, the map stays unstyled until the next
17
+ * `select`. Right before each `setStyle`, `onStyleChange` is called (it tears the plugins down,
18
+ * so nothing touches the old style while the new one loads). After each successful load,
19
+ * `excludedLayers` are removed and `onStyleReady` is called (it sets the plugins up again). The
20
+ * map's first style is not announced: the plugin host already waits for it.
21
+ */
22
+ export declare class BasemapState {
23
+ #private;
24
+ constructor(config: BasemapConfig | undefined);
25
+ /** The selected basemap id. Reactive. */
26
+ get current(): string;
27
+ /** Unknown ids are ignored. While no map is attached, only `current` changes. */
28
+ select(id: string): void;
29
+ /**
30
+ * For MapView only (through the map context's `attach`): uses `gl` from now on, which must
31
+ * already show (or be loading) the style of `current`. `onStyleChange` runs right before each
32
+ * `setStyle`, `onStyleReady` once that style has loaded. Reads `current` untracked, so calling
33
+ * this in an effect doesn't make it depend on it.
34
+ */
35
+ attach(gl: GlMapLike, onStyleReady: () => void, onStyleChange?: () => void): void;
36
+ /** For MapView only (through the map context's `detach`): stops using the GL map. */
37
+ detach(): void;
38
+ }
@@ -0,0 +1,163 @@
1
+ import { untrack } from "svelte";
2
+ /** The first of these means the style of a map just created is ready. */
3
+ const STYLE_READY_EVENTS = ["style.load", "idle"];
4
+ /**
5
+ * The map's current basemap, and switching it on a GL map.
6
+ *
7
+ * The GL map is created with the style of `current` (the map's creator does that), so `attach`
8
+ * calls `setStyle` for nothing. Later `select` calls load the new style. A newer `select`
9
+ * supersedes one still loading. If the style document fails, the map goes back to the last style
10
+ * that loaded and `current` reverts; if that fails too, the map stays unstyled until the next
11
+ * `select`. Right before each `setStyle`, `onStyleChange` is called (it tears the plugins down,
12
+ * so nothing touches the old style while the new one loads). After each successful load,
13
+ * `excludedLayers` are removed and `onStyleReady` is called (it sets the plugins up again). The
14
+ * map's first style is not announced: the plugin host already waits for it.
15
+ */
16
+ export class BasemapState {
17
+ #current = $state("");
18
+ #config;
19
+ #gl = null;
20
+ #onStyleReady = null;
21
+ #onStyleChange = null;
22
+ /** The id last handed to `setStyle` (loaded or loading); null once a load failed with no fallback. */
23
+ #applied = null;
24
+ /** The id the map last finished loading, which a failed change falls back to. */
25
+ #loaded = "";
26
+ #stopWaiting = null;
27
+ constructor(config) {
28
+ this.#config = config;
29
+ this.#current = config?.defaultId ?? "";
30
+ }
31
+ /** The selected basemap id. Reactive. */
32
+ get current() {
33
+ return this.#current;
34
+ }
35
+ /** Unknown ids are ignored. While no map is attached, only `current` changes. */
36
+ select(id) {
37
+ if (!this.#entry(id))
38
+ return;
39
+ this.#current = id;
40
+ if (!this.#gl || id === this.#applied)
41
+ return;
42
+ this.#load(id);
43
+ }
44
+ /**
45
+ * For MapView only (through the map context's `attach`): uses `gl` from now on, which must
46
+ * already show (or be loading) the style of `current`. `onStyleChange` runs right before each
47
+ * `setStyle`, `onStyleReady` once that style has loaded. Reads `current` untracked, so calling
48
+ * this in an effect doesn't make it depend on it.
49
+ */
50
+ attach(gl, onStyleReady, onStyleChange) {
51
+ if (this.#gl === gl)
52
+ return;
53
+ if (this.#gl)
54
+ this.detach();
55
+ this.#gl = gl;
56
+ this.#onStyleReady = onStyleReady;
57
+ this.#onStyleChange = onStyleChange ?? null;
58
+ const id = untrack(() => this.#current);
59
+ this.#applied = id;
60
+ this.#loaded = id;
61
+ // The first style: drop the excluded layers, but leave the plugin host to set itself up.
62
+ this.#whenReady(gl, () => this.#removeExcluded(gl));
63
+ }
64
+ /** For MapView only (through the map context's `detach`): stops using the GL map. */
65
+ detach() {
66
+ this.#stopWaiting?.();
67
+ this.#gl = null;
68
+ this.#onStyleReady = null;
69
+ this.#onStyleChange = null;
70
+ }
71
+ #entry(id) {
72
+ return this.#config?.styles.find((s) => s.id === id);
73
+ }
74
+ /** Runs `fn` once `gl`'s style is ready, at once if it is. Cancelled by `#stopWaiting`. */
75
+ #whenReady(gl, fn) {
76
+ this.#stopWaiting?.();
77
+ if (gl.isStyleLoaded()) {
78
+ fn();
79
+ return;
80
+ }
81
+ const listener = () => {
82
+ stop();
83
+ fn();
84
+ };
85
+ const stop = () => {
86
+ for (const type of STYLE_READY_EVENTS)
87
+ gl.off(type, listener);
88
+ if (this.#stopWaiting === stop)
89
+ this.#stopWaiting = null;
90
+ };
91
+ this.#stopWaiting = stop;
92
+ for (const type of STYLE_READY_EVENTS)
93
+ gl.on(type, listener);
94
+ }
95
+ #removeExcluded(gl) {
96
+ for (const layerId of this.#config?.excludedLayers ?? []) {
97
+ try {
98
+ if (gl.getLayer(layerId))
99
+ gl.removeLayer(layerId);
100
+ }
101
+ catch (error) {
102
+ console.error(`map-sdk: removing basemap layer "${layerId}" failed`, error);
103
+ }
104
+ }
105
+ }
106
+ #load(id) {
107
+ const gl = this.#gl;
108
+ const entry = this.#entry(id);
109
+ if (!gl || !entry)
110
+ return;
111
+ // A newer change supersedes one still in flight.
112
+ this.#stopWaiting?.();
113
+ this.#applied = id;
114
+ const onLoad = () => {
115
+ stop();
116
+ this.#loaded = id;
117
+ this.#removeExcluded(gl);
118
+ this.#onStyleReady?.();
119
+ };
120
+ // "error" also fires for tiles, sprites and glyphs; only the style document failing means
121
+ // the change failed. That is matched by URL, so a style given as an object (not a URL
122
+ // string) can't be told apart and is never treated as failed.
123
+ const url = typeof entry.style === "string" ? entry.style : null;
124
+ const onError = (event) => {
125
+ if (url === null || !isRequestFor(event.error, url))
126
+ return;
127
+ stop();
128
+ this.#recover(id);
129
+ };
130
+ const stop = () => {
131
+ gl.off("style.load", onLoad);
132
+ gl.off("error", onError);
133
+ if (this.#stopWaiting === stop)
134
+ this.#stopWaiting = null;
135
+ };
136
+ this.#stopWaiting = stop;
137
+ gl.on("style.load", onLoad);
138
+ gl.on("error", onError);
139
+ this.#onStyleChange?.();
140
+ // No diffing: a diff keeps the plugins' sources and layers in some cases and not others.
141
+ gl.setStyle(entry.style, { diff: false });
142
+ }
143
+ /**
144
+ * A style that fails to load leaves the map with no style, so go back to the last one that
145
+ * loaded and make `current` say so. When that one fails too there is nothing to draw on, and
146
+ * the next `select` starts a fresh attempt.
147
+ */
148
+ #recover(failed) {
149
+ if (failed === this.#loaded) {
150
+ this.#applied = null;
151
+ return;
152
+ }
153
+ this.#current = this.#loaded;
154
+ this.#load(this.#loaded);
155
+ }
156
+ }
157
+ /** Whether a map "error" event's error is a failed request for `url`, ignoring the query. */
158
+ function isRequestFor(error, url) {
159
+ const failed = error?.url;
160
+ if (typeof failed !== "string")
161
+ return false;
162
+ return failed.split("?")[0] === url.split("?")[0];
163
+ }
@@ -0,0 +1,5 @@
1
+ import type { MapContext } from "./create-map.svelte.js";
2
+ /** Provides `ctx` to this component's descendants (MapView does this). */
3
+ export declare function setMapContext(ctx: MapContext): void;
4
+ /** The nearest `MapView`'s map. Throws outside one. */
5
+ export declare function getMapContext(): MapContext;
@@ -0,0 +1,13 @@
1
+ import { getContext, setContext } from "svelte";
2
+ const KEY = Symbol("map-sdk:map");
3
+ /** Provides `ctx` to this component's descendants (MapView does this). */
4
+ export function setMapContext(ctx) {
5
+ setContext(KEY, ctx);
6
+ }
7
+ /** The nearest `MapView`'s map. Throws outside one. */
8
+ export function getMapContext() {
9
+ const ctx = getContext(KEY);
10
+ if (!ctx)
11
+ throw new Error("map-sdk: no map context; use this inside a MapView");
12
+ return ctx;
13
+ }
@@ -0,0 +1,274 @@
1
+ import { type FormatProvider } from "../data/format.js";
2
+ import { type MessageProvider } from "../data/messages.js";
3
+ import { type MetadataProvider } from "../data/metadata.js";
4
+ import type { FeatureRef, SelectionMode, SpatialSelection } from "../data/types.js";
5
+ import { BasemapState, type BasemapConfig } from "./basemap.svelte.js";
6
+ import type { GlMapLike } from "./gl.js";
7
+ import { type Hovered } from "./interactions.svelte.js";
8
+ import type { FeatureHit, FeatureListItem, MapPlugin } from "./plugin.js";
9
+ export interface CameraState {
10
+ center: [number, number];
11
+ zoom: number;
12
+ bearing: number;
13
+ pitch: number;
14
+ }
15
+ export interface Bounds {
16
+ west: number;
17
+ south: number;
18
+ east: number;
19
+ north: number;
20
+ }
21
+ export interface MapConfig {
22
+ maptilerKey: string;
23
+ basemaps?: BasemapConfig;
24
+ initialView?: CameraState;
25
+ cooperativeGestures?: boolean;
26
+ /** Default `"mercator"`. `"globe"` draws the map on a globe when zoomed out. */
27
+ projection?: "mercator" | "globe";
28
+ /**
29
+ * Default `false`. A preset (monitor-map uses `{ preset: "milkyway" }`) draws space behind a
30
+ * globe.
31
+ */
32
+ space?: false | {
33
+ preset: string;
34
+ };
35
+ /**
36
+ * Default `true`: MapTiler's own default. `false` turns off MapTiler's telemetry (a usage
37
+ * report of the SDK version, the API key, and the session id, sent about 2 s after each map is
38
+ * created) before the GL map is created. It is a page-wide setting in MapTiler's SDK, so once
39
+ * one map turns it off it stays off for every map on the page. MapTiler's session id (`mtsid`)
40
+ * stays on: MapTiler bills SDK maps by session, and its tile cache needs sessions.
41
+ */
42
+ telemetry?: boolean;
43
+ }
44
+ export interface CreateMapOptions {
45
+ config: MapConfig;
46
+ metadata?: MetadataProvider;
47
+ messages?: MessageProvider;
48
+ format?: FormatProvider;
49
+ }
50
+ export interface PluginOptions {
51
+ /**
52
+ * Draw the plugin just below the plugin with this id (which must be added already). Without
53
+ * it the plugin goes on top.
54
+ */
55
+ before?: string;
56
+ selectionMode?: SelectionMode;
57
+ selection?: SpatialSelection | null;
58
+ onselectionchange?(sel: SpatialSelection | null): void;
59
+ /**
60
+ * `"click"` (default): today's rules (a click selects; Shift/⌘/Ctrl or a tap adds in
61
+ * `"multiple"` mode). `"modifier"`: a plain click or tap only pins the card (use it with
62
+ * `MapView`'s `card`), and Shift/⌘/Ctrl-click, or the list's Space or Shift+Enter, toggles the
63
+ * feature in the selection.
64
+ */
65
+ pickWith?: "click" | "modifier";
66
+ /**
67
+ * Called before a user's pick (a click, a list pick, or the card's `toggle`) changes the
68
+ * selection, with the selection it would produce. `true` lets it through; a string refuses it
69
+ * and is the message the map shows (`MapContext.notice`). Not called for `setSelection` or the
70
+ * selection bar's Clear.
71
+ */
72
+ canSelect?(next: SpatialSelection | null, ref: FeatureRef): true | string;
73
+ }
74
+ export type FeatureClickHandler = (e: {
75
+ pluginId: string;
76
+ ref: FeatureRef;
77
+ /**
78
+ * The click point. For a pick in the feature list, where the item's tooltip pins: its position,
79
+ * or for a shape whose label point is off-screen, a point of the shape in view.
80
+ */
81
+ lngLat: [number, number];
82
+ }) => void;
83
+ /** Where a camera move ends up. `zoom` wins over `minZoom`. */
84
+ export interface CameraTarget {
85
+ center: [number, number];
86
+ zoom?: number;
87
+ /** Zoom to at least this: the move's zoom is `max(current zoom, minZoom)`. */
88
+ minZoom?: number;
89
+ }
90
+ /** A map's state and services, independent of whether a GL map currently exists. */
91
+ export interface MapContext {
92
+ readonly uid: string;
93
+ readonly config: Readonly<MapConfig>;
94
+ readonly metadata: MetadataProvider;
95
+ readonly messages: MessageProvider;
96
+ readonly format: FormatProvider;
97
+ /** Reactive; updated by MapView on moveend. */
98
+ readonly camera: CameraState;
99
+ /** Reactive; `null` until a map reports its bounds. */
100
+ readonly bounds: Bounds | null;
101
+ readonly basemap: BasemapState;
102
+ /**
103
+ * In draw order, bottom first: later plugins draw above earlier ones, and each plugin's layers
104
+ * stay together. Reactive.
105
+ */
106
+ readonly plugins: readonly MapPlugin[];
107
+ /** Reactive. */
108
+ readonly attached: boolean;
109
+ /**
110
+ * Reactive. True once the attached map's style has loaded, the map has gone idle for the
111
+ * first time, and any queued plugin setups have run; false again on `detach()` and while a
112
+ * basemap switch reloads the style. Adding a plugin to a ready map leaves it true. A load
113
+ * screen can wait for it.
114
+ */
115
+ readonly ready: boolean;
116
+ /**
117
+ * Reactive. The attached GL map, or `null`. For markers and popups only (see `maptilerMap`);
118
+ * never add sources or layers through it.
119
+ */
120
+ readonly gl: GlMapLike | null;
121
+ /**
122
+ * @internal For `MapView` only; hosts never call it. Marks the attached map ready. Does
123
+ * nothing while detached.
124
+ */
125
+ markReady(): void;
126
+ /**
127
+ * Adds a plugin on top, or below `options.before`. Throws if a plugin with the same id is
128
+ * already added, if `before` names no added plugin, if the same plugin object is set up on
129
+ * another map (create one plugin per map), or after `destroy()`.
130
+ */
131
+ addPlugin(plugin: MapPlugin, options?: PluginOptions): void;
132
+ /**
133
+ * Moves a plugin and its layers to the top, or just below `options.before`. Does nothing for
134
+ * an unknown `id`; throws if `before` names no added plugin.
135
+ */
136
+ movePlugin(id: string, options?: {
137
+ before?: string;
138
+ }): void;
139
+ /** Tears the plugin down and forgets its selection, mode, and `onselectionchange`. */
140
+ removePlugin(id: string): void;
141
+ /**
142
+ * Host → map. Kept as given, including ids not in any data. Does not call
143
+ * `onselectionchange`.
144
+ */
145
+ setSelection(pluginId: string, selection: SpatialSelection | null): void;
146
+ /** Reactive. */
147
+ getSelection(pluginId: string): SpatialSelection | null;
148
+ setSelectionMode(pluginId: string, mode: SelectionMode): void;
149
+ /** Reactive. `"none"` for an unknown plugin. */
150
+ getSelectionMode(pluginId: string): SelectionMode;
151
+ /**
152
+ * Internal, for FeatureList: picks a listed feature exactly like a map click on it. Fires
153
+ * `featureclick`, then applies the same selection rules (`additive` adds or toggles in
154
+ * `multiple` mode), calling `onselectionchange` if the selection changes. An item that isn't
155
+ * selectable is still clicked but not selected. Does nothing for a refKey the plugin doesn't list.
156
+ */
157
+ pickFromList(pluginId: string, refKey: string, additive: boolean): void;
158
+ /**
159
+ * Internal, for the selection bar: the user clears a plugin's selection. Calls the plugin's
160
+ * `onselectionchange(null)` when it had a selection; does nothing otherwise.
161
+ */
162
+ clearSelection(pluginId: string): void;
163
+ /**
164
+ * Called for every feature click (the top hit), whatever the selection mode, before the
165
+ * selection changes. Returns an unsubscribe function.
166
+ */
167
+ on(event: "featureclick", handler: FeatureClickHandler): () => void;
168
+ /** Hits under a canvas point, topmost first. `[]` while detached. */
169
+ featuresAt(point: {
170
+ x: number;
171
+ y: number;
172
+ }): FeatureHit[];
173
+ /**
174
+ * The hit for a feature-list element: the nearest `[data-mapsdk-ref]` ancestor (or the element
175
+ * itself), looked up in the plugins' `features()`: in the row's `data-mapsdk-plugin` plugin when
176
+ * it names one, else the first plugin listing the refKey. Only rows inside this map's own root count:
177
+ * the row's nearest `[data-mapsdk-map]` ancestor must carry this map's `uid`, which MapView
178
+ * sets on its container and FeatureList on its root. `null` otherwise.
179
+ */
180
+ featureForElement(element: Element): FeatureHit | null;
181
+ /**
182
+ * The top feature under the pointer and where it is. Reactive, for the tooltip. Over a cluster
183
+ * bubble it is the bubble's own hit: a `{ kind: "feature", id: "cluster:…" }` ref no plugin
184
+ * lists, with the bubble's `properties`, never a feature beneath it.
185
+ */
186
+ readonly hovered: Hovered | null;
187
+ /**
188
+ * Reactive. The feature whose reading card is pinned, and where, while `MapView`'s `card` is
189
+ * on; `null` otherwise. A click on a feature pins it (selection and `featureclick` are
190
+ * unchanged), focusing a feature-list row pins that row's feature, and a click on nothing (or
191
+ * on a cluster bubble or a feature without a hover card) unpins.
192
+ */
193
+ readonly pinned: Hovered | null;
194
+ /** Reactive. The plugin's `pickWith`: `"click"` for an unknown plugin. */
195
+ getPickWith(pluginId: string): "click" | "modifier";
196
+ /**
197
+ * A user's toggle of `ref` (the card's Select/Remove): the modifier-click rule, with the
198
+ * plugin's `canSelect` and `onselectionchange`, in either `pickWith` mode.
199
+ */
200
+ togglePick(pluginId: string, ref: FeatureRef): void;
201
+ /**
202
+ * Reactive. The latest refused pick's message; `id` grows with each refusal, so the same
203
+ * message twice is announced again. Cleared by the next pick, `clearNotice()`, and detach.
204
+ */
205
+ readonly notice: {
206
+ message: string;
207
+ id: number;
208
+ } | null;
209
+ /** @internal For `PickNotice`: clears the notice. */
210
+ clearNotice(): void;
211
+ /** Closes the pinned card. Does nothing when nothing is pinned. */
212
+ unpin(): void;
213
+ /** @internal For `MapView` only: turns pinning on or off. Off also unpins. */
214
+ setCardEnabled(on: boolean): void;
215
+ /**
216
+ * Marks the feature focused and pans to it (no animation under reduced motion): the item in
217
+ * `pluginId`'s features when given, else the first plugin listing `refKey`. `null` clears the
218
+ * focus without moving the camera. Sets `focusedPluginId` to `pluginId` (or `null`). The pan
219
+ * centers the feature in the part of the map the feature list panel leaves clear.
220
+ */
221
+ focusFeature(refKey: string | null, pluginId?: string): void;
222
+ /**
223
+ * Eases the camera to `target` (no animation under reduced motion). Does nothing while
224
+ * detached.
225
+ */
226
+ easeTo(target: CameraTarget): void;
227
+ /** Like `easeTo`, with a flying animation. */
228
+ flyTo(target: CameraTarget): void;
229
+ /**
230
+ * Fits the camera to `bounds` (no animation under reduced motion). Does nothing while
231
+ * detached.
232
+ */
233
+ fitBounds(bounds: Bounds, options?: {
234
+ padding?: number;
235
+ maxZoom?: number;
236
+ }): void;
237
+ /** Reactive. */
238
+ readonly focusedKey: string | null;
239
+ /** Reactive. The plugin `focusFeature` was given with `focusedKey`, or `null`. */
240
+ readonly focusedPluginId: string | null;
241
+ /**
242
+ * Reactive. Where the focused feature's tooltip pins, set by `focusFeature` (`null` without
243
+ * focus): its `lngLat`, or for a shape that overlaps the view with its `lngLat` off-screen, a
244
+ * point of the shape in the part of the view the list panel leaves clear. Fixed at focus
245
+ * time, so it stays on the feature if the map then moves.
246
+ */
247
+ readonly focusedAnchor: [number, number] | null;
248
+ /**
249
+ * Where `item`'s tooltip pins in the current view, without moving the camera: its `lngLat`,
250
+ * or for a shape (`geometry`) with its `lngLat` off-screen, a point of the shape in view.
251
+ */
252
+ anchorFor(item: FeatureListItem): [number, number];
253
+ /** For MapView only: uses `gl` from now on. */
254
+ attach(gl: GlMapLike): void;
255
+ /** For MapView only: stops using the current GL map. */
256
+ detach(): void;
257
+ /**
258
+ * For MapView only: how many pixels at the map's left or right edge (`side`, default left)
259
+ * the open feature list panel covers (0 when closed), which `focusFeature` pans clear of.
260
+ */
261
+ setListInset(width: number, side?: "left" | "right"): void;
262
+ /** For MapView only: records the camera and bounds after a move. */
263
+ updateView(camera: CameraState, bounds: Bounds): void;
264
+ /**
265
+ * For MapView only: the host's theme changed, so plugins set up again and re-read the theme
266
+ * colors they bake into paint and images. Does nothing while detached. Sets plugins up
267
+ * synchronously, so never call it from inside an effect (see `PluginHost`).
268
+ */
269
+ themeChanged(): void;
270
+ /** Detaches, removes every plugin, and drops handlers. The context can't be used after. */
271
+ destroy(): void;
272
+ }
273
+ /** Creates a map's state and services. `MapView` attaches a GL map to it. */
274
+ export declare function createMap(options: CreateMapOptions): MapContext;