@sjvair/map-sdk 0.1.0-beta.1 → 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.
- package/README.md +243 -17
- package/dist/core/create-map.svelte.d.ts +72 -5
- package/dist/core/create-map.svelte.js +229 -14
- package/dist/core/gl.d.ts +5 -0
- package/dist/core/interactions.svelte.d.ts +11 -3
- package/dist/core/interactions.svelte.js +128 -11
- package/dist/core/plugin-host.svelte.d.ts +30 -5
- package/dist/core/plugin-host.svelte.js +93 -14
- package/dist/core/plugin.d.ts +44 -2
- package/dist/core/shape-view.d.ts +27 -0
- package/dist/core/shape-view.js +323 -0
- package/dist/data/format.d.ts +1 -1
- package/dist/data/format.js +16 -3
- package/dist/data/messages/en.json +12 -2
- package/dist/data/selection.d.ts +6 -0
- package/dist/data/selection.js +21 -0
- package/dist/data/types.d.ts +5 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -0
- package/dist/plugins/points.svelte.d.ts +14 -2
- package/dist/plugins/points.svelte.js +34 -5
- package/dist/plugins/shapes.svelte.d.ts +5 -0
- package/dist/plugins/shapes.svelte.js +20 -2
- package/dist/presets/FireTooltip.svelte +70 -0
- package/dist/presets/FireTooltip.svelte.d.ts +13 -0
- package/dist/presets/MonitorClusterTooltip.svelte +21 -2
- package/dist/presets/cluster-area.d.ts +13 -0
- package/dist/presets/cluster-area.js +34 -0
- package/dist/presets/hms-fire.d.ts +11 -7
- package/dist/presets/hms-fire.js +16 -17
- package/dist/presets/hms-smoke.d.ts +2 -1
- package/dist/presets/hms-smoke.js +4 -2
- package/dist/stores/hms-stores.svelte.d.ts +6 -3
- package/dist/stores/hms-stores.svelte.js +4 -4
- package/dist/ui/FeatureList.svelte +17 -17
- package/dist/ui/Legend.svelte +58 -16
- package/dist/ui/Legend.svelte.d.ts +9 -0
- package/dist/ui/MapTooltip.svelte +253 -14
- package/dist/ui/MapTooltip.svelte.d.ts +9 -0
- package/dist/ui/PickNotice.svelte +56 -0
- package/dist/ui/PickNotice.svelte.d.ts +7 -0
- package/dist/ui/TooltipItem.svelte +12 -12
- package/dist/ui/card.d.ts +29 -0
- package/dist/ui/card.js +1 -0
- package/dist/ui/feature-list.d.ts +17 -2
- package/dist/ui/feature-list.js +45 -10
- package/dist/ui/value-format.d.ts +3 -2
- package/dist/ui/value-format.js +9 -2
- package/dist/view/MapView.svelte +72 -2
- package/dist/view/MapView.svelte.d.ts +8 -0
- package/dist/view/create-gl-map.js +4 -0
- package/package.json +2 -1
package/dist/view/MapView.svelte
CHANGED
|
@@ -11,8 +11,10 @@
|
|
|
11
11
|
import type { SortBy } from "../ui/feature-list.js";
|
|
12
12
|
import MapControls from "../ui/MapControls.svelte";
|
|
13
13
|
import MapTooltip from "../ui/MapTooltip.svelte";
|
|
14
|
+
import type { CardOptions } from "../ui/card.js";
|
|
14
15
|
import SelectionBar from "../ui/SelectionBar.svelte";
|
|
15
16
|
import ViewSummary from "../ui/ViewSummary.svelte";
|
|
17
|
+
import PickNotice from "../ui/PickNotice.svelte";
|
|
16
18
|
import { createDataCredits } from "../ui/data-credits.svelte.js";
|
|
17
19
|
import { createGlMap, setDataCredits, watchTheme } from "./create-gl-map.js";
|
|
18
20
|
import {
|
|
@@ -56,6 +58,13 @@
|
|
|
56
58
|
* Keyboard focus from the feature list always shows it pinned.
|
|
57
59
|
*/
|
|
58
60
|
tooltip?: "pinned" | "pointer";
|
|
61
|
+
/**
|
|
62
|
+
* `true`: a click or tap on a feature pins its reading card, which takes the pointer and
|
|
63
|
+
* closes with Esc, its Close button, or a click elsewhere on the map; focusing a
|
|
64
|
+
* feature-list row shows the same card. Selection and `featureclick` are unchanged.
|
|
65
|
+
* `{ actions }` also puts the host's buttons on the card (see `CardContext`).
|
|
66
|
+
*/
|
|
67
|
+
card?: boolean | CardOptions;
|
|
59
68
|
}
|
|
60
69
|
|
|
61
70
|
let {
|
|
@@ -67,9 +76,50 @@
|
|
|
67
76
|
featureList = true,
|
|
68
77
|
selectionBar = true,
|
|
69
78
|
controls = "mapsdk",
|
|
70
|
-
tooltip = "pinned"
|
|
79
|
+
tooltip = "pinned",
|
|
80
|
+
card = false
|
|
71
81
|
}: Props = $props();
|
|
72
82
|
|
|
83
|
+
// Pinning only, no plugin setup, so it's safe in an effect.
|
|
84
|
+
// Boolean(): an untyped host's `null` is off, like `false`.
|
|
85
|
+
const cardOn = $derived(Boolean(card));
|
|
86
|
+
const cardActions = $derived(card && typeof card === "object" ? card.actions : undefined);
|
|
87
|
+
|
|
88
|
+
$effect(() => {
|
|
89
|
+
map.setCardEnabled(cardOn);
|
|
90
|
+
return () => map.setCardEnabled(false);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Esc outside the card closes it when focus is in this map or nowhere (the body), so a key
|
|
95
|
+
* pressed in another map, or elsewhere on the page, leaves this card alone.
|
|
96
|
+
*/
|
|
97
|
+
function onWindowKeydown(e: KeyboardEvent) {
|
|
98
|
+
if (e.key !== "Escape" || e.defaultPrevented || !map.pinned) return;
|
|
99
|
+
const active = document.activeElement;
|
|
100
|
+
if (active && active !== document.body && !root.contains(active)) return;
|
|
101
|
+
// Focus nowhere: only the most recently pinned card on the page closes.
|
|
102
|
+
if (!active || active === document.body) {
|
|
103
|
+
let latest: HTMLElement | null = null;
|
|
104
|
+
for (const el of document.querySelectorAll<HTMLElement>("[data-mapsdk-pinned-at]")) {
|
|
105
|
+
if (!latest || Number(el.dataset.mapsdkPinnedAt) > Number(latest.dataset.mapsdkPinnedAt)) {
|
|
106
|
+
latest = el;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (latest && latest !== root) return;
|
|
110
|
+
}
|
|
111
|
+
e.preventDefault();
|
|
112
|
+
map.unpin();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// When this map's card was pinned, so Esc with focus nowhere closes the latest card only.
|
|
116
|
+
$effect(() => {
|
|
117
|
+
const pinned = map.pinned;
|
|
118
|
+
if (!root) return;
|
|
119
|
+
if (pinned) root.dataset.mapsdkPinnedAt = String(performance.now());
|
|
120
|
+
else delete root.dataset.mapsdkPinnedAt;
|
|
121
|
+
});
|
|
122
|
+
|
|
73
123
|
const list = $derived(resolveFeatureList(featureList));
|
|
74
124
|
const sides = $derived(list ? cornerSides(list.position) : null);
|
|
75
125
|
|
|
@@ -148,6 +198,12 @@
|
|
|
148
198
|
function onListKeydown(e: KeyboardEvent) {
|
|
149
199
|
if (e.key !== "Escape") return;
|
|
150
200
|
e.preventDefault();
|
|
201
|
+
// The card closes first (and the focused row's card with it); the next Esc closes the panel.
|
|
202
|
+
if (cardOn && (map.pinned || map.focusedKey)) {
|
|
203
|
+
map.unpin();
|
|
204
|
+
map.focusFeature(null);
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
151
207
|
listOpen = false;
|
|
152
208
|
listButton?.focus();
|
|
153
209
|
}
|
|
@@ -242,6 +298,8 @@
|
|
|
242
298
|
});
|
|
243
299
|
</script>
|
|
244
300
|
|
|
301
|
+
<svelte:window onkeydown={onWindowKeydown} />
|
|
302
|
+
|
|
245
303
|
<div
|
|
246
304
|
bind:this={root}
|
|
247
305
|
bind:clientWidth={width}
|
|
@@ -250,9 +308,9 @@
|
|
|
250
308
|
role="region"
|
|
251
309
|
aria-label={label ?? map.messages("mapsdk_map_label")}
|
|
252
310
|
data-mapsdk-map={map.uid}
|
|
311
|
+
style:--mapsdk-map-width={width > 0 ? `${width}px` : undefined}
|
|
253
312
|
>
|
|
254
313
|
<div class="mapsdk-gl" bind:this={glContainer}></div>
|
|
255
|
-
<MapTooltip {map} {project} {width} {height} mode={tooltip} gl={projector} />
|
|
256
314
|
{#if list && sides}
|
|
257
315
|
<div
|
|
258
316
|
class="mapsdk-list-panel"
|
|
@@ -282,11 +340,23 @@
|
|
|
282
340
|
{/if}
|
|
283
341
|
</div>
|
|
284
342
|
{/if}
|
|
343
|
+
<!-- After the list, so Tab from a list row reaches the pinned card's Close button. -->
|
|
344
|
+
<MapTooltip
|
|
345
|
+
{map}
|
|
346
|
+
{project}
|
|
347
|
+
{width}
|
|
348
|
+
{height}
|
|
349
|
+
mode={tooltip}
|
|
350
|
+
gl={projector}
|
|
351
|
+
card={cardOn}
|
|
352
|
+
actions={cardActions}
|
|
353
|
+
/>
|
|
285
354
|
<!-- After the list, so Tab reaches the List button first. -->
|
|
286
355
|
{#if selectionBar}
|
|
287
356
|
<SelectionBar {map} clearRight={list?.position === "top-right" && controls === "none"} />
|
|
288
357
|
{/if}
|
|
289
358
|
<ViewSummary {map} />
|
|
359
|
+
<PickNotice {map} />
|
|
290
360
|
{#if controls === "mapsdk"}
|
|
291
361
|
<MapControls {map} gl={projector} />
|
|
292
362
|
{/if}
|
|
@@ -2,6 +2,7 @@ import "@maptiler/sdk/dist/maptiler-sdk.css";
|
|
|
2
2
|
import "../ui/controls.css";
|
|
3
3
|
import type { Snippet } from "svelte";
|
|
4
4
|
import type { MapContext } from "../core/create-map.svelte.js";
|
|
5
|
+
import type { CardOptions } from "../ui/card.js";
|
|
5
6
|
import { type FeatureListOptions } from "./list-placement.js";
|
|
6
7
|
interface Props {
|
|
7
8
|
/** The map to show. Fixed for the component's life. */
|
|
@@ -37,6 +38,13 @@ interface Props {
|
|
|
37
38
|
* Keyboard focus from the feature list always shows it pinned.
|
|
38
39
|
*/
|
|
39
40
|
tooltip?: "pinned" | "pointer";
|
|
41
|
+
/**
|
|
42
|
+
* `true`: a click or tap on a feature pins its reading card, which takes the pointer and
|
|
43
|
+
* closes with Esc, its Close button, or a click elsewhere on the map; focusing a
|
|
44
|
+
* feature-list row shows the same card. Selection and `featureclick` are unchanged.
|
|
45
|
+
* `{ actions }` also puts the host's buttons on the card (see `CardContext`).
|
|
46
|
+
*/
|
|
47
|
+
card?: boolean | CardOptions;
|
|
40
48
|
}
|
|
41
49
|
declare const MapView: import("svelte").Component<Props, {}, "">;
|
|
42
50
|
type MapView = ReturnType<typeof MapView>;
|
|
@@ -128,6 +128,10 @@ function recordView(gl, ctx) {
|
|
|
128
128
|
*/
|
|
129
129
|
export function createGlMap(container, ctx, engineControls = false) {
|
|
130
130
|
const { camera, style } = untrack(() => ({ camera: ctx.camera, style: styleOf(ctx) }));
|
|
131
|
+
// Before the map exists, so its telemetry timer finds it off. Sessions stay on: MapTiler
|
|
132
|
+
// bills SDK maps by session, and without one every tile request counts on its own.
|
|
133
|
+
if (ctx.config.telemetry === false)
|
|
134
|
+
maptilerConfig.telemetry = false;
|
|
131
135
|
const gl = new GlMap({
|
|
132
136
|
container,
|
|
133
137
|
style,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sjvair/map-sdk",
|
|
3
3
|
"description": "Svelte 5 map components for SJVAir air-quality data",
|
|
4
|
-
"version": "0.1.0-beta.
|
|
4
|
+
"version": "0.1.0-beta.10",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
65
|
"@maptiler/sdk": "~4.2.0",
|
|
66
|
+
"@turf/area": "^7.4.0",
|
|
66
67
|
"@turf/clusters-dbscan": "^7.4.0",
|
|
67
68
|
"@turf/helpers": "^7.4.0",
|
|
68
69
|
"@types/geojson": "^7946.0.16",
|