@tileflow/svelte 0.1.0-alpha.23 → 0.1.0-alpha.24
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 +132 -147
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,211 +1,196 @@
|
|
|
1
1
|
# @tileflow/svelte
|
|
2
2
|
|
|
3
|
-
Svelte
|
|
3
|
+
Svelte components for interactive Tileflow maps, annotations, and existing-image display.
|
|
4
|
+
The component consumes prepared assets; it does not compile executable map configuration in the
|
|
5
|
+
browser.
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
> Related packages and guides: [documentation index](https://raw.githubusercontent.com/tileflow/tileflow-sdk/main/llms.txt).
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
<script lang="ts">
|
|
9
|
-
import {TileflowMap} from '@tileflow/svelte';
|
|
10
|
-
import 'maplibre-gl/dist/maplibre-gl.css';
|
|
11
|
-
</script>
|
|
9
|
+
## Install
|
|
12
10
|
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
cooperativeGestures: true,
|
|
20
|
-
maxZoom: 18,
|
|
21
|
-
}}
|
|
22
|
-
/>
|
|
11
|
+
Use an existing Svelte 5 application. Supported peers are Svelte `>=5 <6` and MapLibre GL JS
|
|
12
|
+
`>=6.4.1 <7`. The local build workflow below requires Node.js 22 or newer.
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
npm install @tileflow/svelte@alpha @tileflow/core@alpha @tileflow/maps@alpha "maplibre-gl@^6.4.1"
|
|
16
|
+
npm install --save-dev --save-exact tileflow@alpha
|
|
23
17
|
```
|
|
24
18
|
|
|
25
|
-
##
|
|
19
|
+
## Prepare a map
|
|
26
20
|
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
Create `tileflow.config.ts` at the application root:
|
|
22
|
+
|
|
23
|
+
<!-- docs:check -->
|
|
29
24
|
|
|
30
25
|
```ts
|
|
31
|
-
|
|
32
|
-
import
|
|
33
|
-
|
|
26
|
+
import {defineMap} from '@tileflow/core';
|
|
27
|
+
import {streets} from '@tileflow/maps';
|
|
28
|
+
|
|
29
|
+
export default defineMap({
|
|
30
|
+
id: 'madrid',
|
|
31
|
+
version: 1,
|
|
32
|
+
extends: streets,
|
|
33
|
+
view: {center: [-3.7038, 40.4168], zoom: 12},
|
|
34
|
+
});
|
|
35
|
+
```
|
|
34
36
|
|
|
35
|
-
|
|
37
|
+
For a Vite application serving `public/` at the URL root:
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
npx tileflow build --out public/tileflow
|
|
36
41
|
```
|
|
37
42
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
43
|
+
SvelteKit serves static files from `static/` by default; for that setup, build to `static/tileflow`
|
|
44
|
+
instead. Set the component's manifest URL to the final public URL when a base path changes it.
|
|
45
|
+
Rebuild after config/asset changes or use the
|
|
46
|
+
[Vite integration](https://github.com/tileflow/tileflow-sdk/blob/main/packages/vite/README.md)
|
|
47
|
+
for watched development and production output. Local preparation needs no API key; rendering can
|
|
48
|
+
still fetch configured remote resources.
|
|
49
|
+
|
|
50
|
+
## Configure the worker
|
|
41
51
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
52
|
+
In a Vite client entry, add the following before mounting the application:
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import workerUrl from 'maplibre-gl/dist/maplibre-gl-worker.mjs?worker&url';
|
|
56
|
+
import {configureTileflowMapLibre} from '@tileflow/svelte';
|
|
47
57
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
style object or URL; it has no Tileflow theme identity, `system` selection, switching, or manifest
|
|
51
|
-
traceability. Browser components do not compile `tileflow.config.ts`.
|
|
58
|
+
configureTileflowMapLibre({workerUrl});
|
|
59
|
+
```
|
|
52
60
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
61
|
+
Configure once before an interactive map mounts. In SvelteKit, place client-only setup in the
|
|
62
|
+
application's client initialization path rather than running browser setup in a server load
|
|
63
|
+
function. The `?worker&url` syntax is Vite-specific. Webpack users need the
|
|
64
|
+
[Webpack worker recipe](https://github.com/tileflow/tileflow-sdk/blob/main/packages/webpack/README.md).
|
|
65
|
+
The worker and shared module must match the application's installed MapLibre version.
|
|
57
66
|
|
|
58
|
-
|
|
59
|
-
explicit light/dark mapping. Switching preserves the MapLibre instance, camera, and interactions,
|
|
60
|
-
and rolls back a failed style. `onThemeChange` receives transition state.
|
|
67
|
+
## Render a map
|
|
61
68
|
|
|
62
69
|
```svelte
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
manifestUrl: 'https://cdn.example.com/tileflow/manifest.json',
|
|
68
|
-
}}
|
|
69
|
-
/>
|
|
70
|
+
<script lang="ts">
|
|
71
|
+
import 'maplibre-gl/dist/maplibre-gl.css';
|
|
72
|
+
import {TileflowMap} from '@tileflow/svelte';
|
|
73
|
+
</script>
|
|
70
74
|
|
|
71
75
|
<TileflowMap
|
|
72
|
-
source={{
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
+
source={{kind: 'tileflow', map: 'madrid'}}
|
|
77
|
+
theme="system"
|
|
78
|
+
center={[-3.7038, 40.4168]}
|
|
79
|
+
zoom={12}
|
|
80
|
+
mapOptions={{cooperativeGestures: true, maxZoom: 18}}
|
|
76
81
|
/>
|
|
77
82
|
```
|
|
78
83
|
|
|
79
|
-
|
|
80
|
-
|
|
84
|
+
Coordinates are `[longitude, latitude]`. `source.map` matches the config's portable ID, not a hosted
|
|
85
|
+
`map_...` identifier. The default manifest URL is exactly `/tileflow/manifest.json`. Set
|
|
86
|
+
`source.manifestUrl` for a subpath or external host; the browser does not infer bundler configuration.
|
|
87
|
+
|
|
88
|
+
Omitting `theme` uses `defaultTheme`. `system` needs an explicit light/dark mapping, which Streets
|
|
89
|
+
supplies. Theme changes keep the MapLibre instance, camera, and interactions, and roll back on
|
|
90
|
+
failure. `onThemeChange` reports transitions.
|
|
81
91
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
product locations. Missing or invalid Surface IDs become `default`; do not use URLs, branches,
|
|
87
|
-
random instance IDs, or user IDs.
|
|
88
|
-
Direct Tileflow World maps keep early `GRACE` silent, show a compact accessible owner-action pill
|
|
89
|
-
when late `GRACE` is activated, and show a stronger banner in `MANAGED_REQUIRED`. Missing tiles and
|
|
90
|
-
MapLibre failures do not remove that recovery path.
|
|
92
|
+
`mapOptions` accepts native MapLibre options except `container` and `style`. Direct props win over
|
|
93
|
+
those options, then the manifest view, then shared defaults. An unmanaged source with
|
|
94
|
+
`{kind: 'maplibre', style: styleUrl}` loads one style without Tileflow themes or manifest identity;
|
|
95
|
+
do not pass a Tileflow theme with it.
|
|
91
96
|
|
|
92
|
-
##
|
|
97
|
+
## Add annotations and native popup UI
|
|
93
98
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
99
|
+
Install the contract types used below:
|
|
100
|
+
|
|
101
|
+
```sh
|
|
102
|
+
npm install @tileflow/interactions@alpha
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
This Svelte 5 component uses the worker and CSS setup above:
|
|
97
106
|
|
|
98
107
|
```svelte
|
|
99
108
|
<script lang="ts">
|
|
100
|
-
import {TileflowMap} from '@tileflow/svelte';
|
|
101
109
|
import type {
|
|
102
110
|
TileflowAnnotation,
|
|
103
|
-
TileflowInteractionBinding,
|
|
104
111
|
TileflowInteractionState,
|
|
112
|
+
TileflowInteractionViewContext,
|
|
105
113
|
} from '@tileflow/interactions';
|
|
114
|
+
import {TileflowMap} from '@tileflow/svelte';
|
|
106
115
|
|
|
107
|
-
const annotations
|
|
116
|
+
const annotations = [
|
|
108
117
|
{
|
|
109
|
-
ariaLabel: 'Madrid',
|
|
110
|
-
coordinate: [-3.7038, 40.4168],
|
|
111
118
|
id: 'madrid',
|
|
112
119
|
kind: 'marker',
|
|
113
|
-
|
|
120
|
+
coordinate: [-3.7038, 40.4168],
|
|
121
|
+
ariaLabel: 'Madrid',
|
|
122
|
+
tooltip: {content: {kind: 'text', text: 'View Madrid'}},
|
|
114
123
|
popup: {content: {kind: 'view', name: 'city-card'}},
|
|
115
|
-
tooltip: {content: {kind: 'text', text: 'Open Madrid'}},
|
|
116
124
|
},
|
|
117
|
-
];
|
|
125
|
+
] satisfies readonly TileflowAnnotation[];
|
|
118
126
|
|
|
119
|
-
|
|
120
|
-
{
|
|
121
|
-
id: 'poi-details',
|
|
122
|
-
popup: {content: {kind: 'view', name: 'poi-card'}},
|
|
123
|
-
target: {categories: ['food-drink'], domain: 'poi', kind: 'semantic-feature'},
|
|
124
|
-
tooltip: {content: {field: 'name', fallback: 'Restaurant', kind: 'field'}},
|
|
125
|
-
},
|
|
126
|
-
];
|
|
127
|
-
|
|
128
|
-
let interactionState: TileflowInteractionState = {popup: null};
|
|
127
|
+
let state = $state<TileflowInteractionState>({popup: null});
|
|
129
128
|
</script>
|
|
130
129
|
|
|
131
|
-
{#snippet
|
|
132
|
-
<span>{context.annotation.ariaLabel}</span>
|
|
133
|
-
{/snippet}
|
|
134
|
-
|
|
135
|
-
{#snippet tooltip(context)}
|
|
130
|
+
{#snippet popup(context: TileflowInteractionViewContext)}
|
|
136
131
|
{#if context.target.kind === 'annotation'}
|
|
137
|
-
<
|
|
138
|
-
{:else}
|
|
139
|
-
<span>Point of interest</span>
|
|
140
|
-
{/if}
|
|
141
|
-
{/snippet}
|
|
142
|
-
|
|
143
|
-
{#snippet popup(context)}
|
|
144
|
-
<article>
|
|
145
|
-
{#if context.target.kind === 'annotation'}
|
|
132
|
+
<article>
|
|
146
133
|
<h2>{context.target.annotation.ariaLabel}</h2>
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
<button type="button" onclick={context.close}>Close</button>
|
|
151
|
-
</article>
|
|
134
|
+
<button type="button" onclick={context.close}>Close</button>
|
|
135
|
+
</article>
|
|
136
|
+
{/if}
|
|
152
137
|
{/snippet}
|
|
153
138
|
|
|
154
139
|
<TileflowMap
|
|
155
140
|
source={{kind: 'tileflow', map: 'madrid'}}
|
|
156
141
|
{annotations}
|
|
157
|
-
{
|
|
158
|
-
{
|
|
159
|
-
|
|
160
|
-
onInteractionEvent={(event) => console.log(event.type)}
|
|
161
|
-
onInteractionDiagnostic={(diagnostic) => console.error(diagnostic)}
|
|
162
|
-
{marker}
|
|
163
|
-
{tooltip}
|
|
142
|
+
interactionState={state}
|
|
143
|
+
onInteractionStateChange={(next) => (state = next)}
|
|
144
|
+
onInteractionDiagnostic={(diagnostic) => console.error(diagnostic.code)}
|
|
164
145
|
{popup}
|
|
165
146
|
/>
|
|
166
147
|
```
|
|
167
148
|
|
|
168
|
-
`
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
`poi` domain and optional categories rather than physical style-layer IDs.
|
|
149
|
+
Annotations need a stable `id`, singular `coordinate`, and non-empty `ariaLabel`; optional data must
|
|
150
|
+
be JSON-safe. `marker` receives annotation-only context. `tooltip` and `popup` receive the shared
|
|
151
|
+
interaction context; narrow `target.kind` before reading annotation or semantic feature data.
|
|
172
152
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
resolved content, the target, optional view name, and `close()`.
|
|
153
|
+
Use `interactions` with `target: {kind: 'semantic-feature', domain: 'poi'}` for POIs already rendered
|
|
154
|
+
by the style. Optional categories use Tileflow's taxonomy, such as `food-drink` or `retail`, not raw
|
|
155
|
+
source classes. Semantic bindings require compatible style metadata and avoid one DOM marker per
|
|
156
|
+
feature. Annotation and semantic overlays share one popup state.
|
|
178
157
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
158
|
+
Controlled `interactionState` and uncontrolled `defaultInteractionState` are mutually exclusive.
|
|
159
|
+
Do not change ownership during the component's lifetime. Updating annotations, bindings, state, or
|
|
160
|
+
snippets reconciles existing runtimes rather than recreating MapLibre.
|
|
182
161
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
`mode="image"` branch. Untyped JavaScript that supplies them still receives an
|
|
186
|
-
`UNSUPPORTED_MODE` diagnostic and capture readiness `error`, rather than pretending the static image
|
|
187
|
-
contains live overlays.
|
|
162
|
+
Text/field descriptors render as text. A `view` names an application snippet; it is not serialized
|
|
163
|
+
HTML. Keep tooltips non-interactive and put buttons, links, and forms in popups.
|
|
188
164
|
|
|
189
|
-
##
|
|
165
|
+
## Display an existing image
|
|
190
166
|
|
|
191
|
-
|
|
167
|
+
`mode="image"` displays an explicit `imageUrl` or a published manifest image without loading
|
|
168
|
+
MapLibre. A local style build does not generate that image. This mode does not submit or poll a
|
|
169
|
+
Static Maps operation; use the server-side
|
|
170
|
+
[Static Maps client](https://github.com/tileflow/tileflow-sdk/blob/main/packages/static/README.md)
|
|
171
|
+
for new renders, keeping privileged credentials off the browser.
|
|
192
172
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
173
|
+
Annotations, semantic bindings, interaction state, and interaction snippets are interactive-only.
|
|
174
|
+
Untyped callers that pass them to image mode receive `UNSUPPORTED_MODE` and capture readiness
|
|
175
|
+
`error`, not simulated live overlays.
|
|
176
|
+
|
|
177
|
+
## Capture, authorization, and troubleshooting
|
|
196
178
|
|
|
197
|
-
The root exposes `data-tileflow-map`,
|
|
198
|
-
`data-tileflow-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
present. Application capture selects exactly one ready target.
|
|
179
|
+
Use `captureId` to disambiguate repeated maps. The root exposes `data-tileflow-map`, resolved
|
|
180
|
+
`data-tileflow-theme`, optional `data-tileflow-capture-id`, and
|
|
181
|
+
`data-tileflow-state="loading|idle|error"`. Readiness includes MapLibre/image loading and committed
|
|
182
|
+
Svelte interaction views. Application capture needs exactly one ready target and the application's
|
|
183
|
+
normal loopback server.
|
|
203
184
|
|
|
204
|
-
|
|
185
|
+
For an error or blank map, check the manifest URL, map/theme IDs, imported CSS, and matching
|
|
186
|
+
worker/shared assets. The component does not guess a new manifest location after a 404.
|
|
205
187
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
188
|
+
Hosted maps acquire a short-lived session grant before eligible resource requests.
|
|
189
|
+
`analytics={{enabled: false}}` disables the optional beacon, not authorization. Use a stable product
|
|
190
|
+
`surfaceId`, not a URL or user identifier. Direct World maps can show owner-action notices when
|
|
191
|
+
managed delivery is required. Imports and the image path remain SSR-safe; interactive rendering
|
|
192
|
+
requires a browser with WebGL.
|
|
210
193
|
|
|
211
|
-
|
|
194
|
+
See the [interaction guide](https://github.com/tileflow/tileflow-sdk/blob/main/packages/interactions/README.md)
|
|
195
|
+
and [browser runtime contract](https://github.com/tileflow/tileflow-sdk/blob/main/docs/contracts/framework-browser-runtime.md).
|
|
196
|
+
Use the installed declarations and README for release-specific behavior; `main` may be newer than npm.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tileflow/svelte",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.24",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "Svelte component for rendering Tileflow maps with MapLibre.",
|
|
6
6
|
"type": "module",
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"access": "public"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@tileflow/core": ">=0.1.0-alpha.
|
|
48
|
-
"@tileflow/interactions": ">=0.1.0-alpha.
|
|
47
|
+
"@tileflow/core": ">=0.1.0-alpha.25 <0.1.0-beta.0",
|
|
48
|
+
"@tileflow/interactions": ">=0.1.0-alpha.4 <0.1.0-beta.0"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
51
|
"maplibre-gl": ">=6.4.1 <7",
|