@tileflow/react 0.1.0-alpha.3 → 0.1.0-alpha.30
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/LICENSE +201 -0
- package/README.md +273 -7
- package/dist/index.d.ts +75 -33
- package/dist/index.js +1308 -354
- package/dist/static.d.ts +8 -4
- package/dist/static.js +202 -49
- package/package.json +21 -16
package/LICENSE
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright [yyyy] [name of copyright owner]
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|
package/README.md
CHANGED
|
@@ -1,22 +1,288 @@
|
|
|
1
1
|
# @tileflow/react
|
|
2
2
|
|
|
3
|
-
React components for
|
|
3
|
+
React components for interactive Tileflow maps, annotations, and static-image display.
|
|
4
|
+
Interactive maps use MapLibre GL JS; browser components read prepared assets rather than compiling
|
|
5
|
+
`tileflow.config.ts`.
|
|
6
|
+
|
|
7
|
+
> Related packages and guides: [documentation index](https://raw.githubusercontent.com/tileflow/tileflow-sdk/main/llms.txt).
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
Use an existing React 18 or 19 application with matching `react-dom`. The following local build
|
|
12
|
+
workflow needs Node.js 22 or newer:
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
npm install @tileflow/react@alpha @tileflow/core@alpha @tileflow/maps@alpha "maplibre-gl@^6.4.1"
|
|
16
|
+
npm install --save-dev --save-exact tileflow@alpha
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The supported peer ranges are React/React DOM 18–19 and MapLibre GL JS `>=6.4.1 <7`. The worker
|
|
20
|
+
must come from the same MapLibre installation as the main module.
|
|
21
|
+
|
|
22
|
+
## Prepare a map
|
|
23
|
+
|
|
24
|
+
Create `tileflow.config.ts` at the application root:
|
|
25
|
+
|
|
26
|
+
<!-- docs:check -->
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import {defineMap} from '@tileflow/core';
|
|
30
|
+
import {streets} from '@tileflow/maps';
|
|
31
|
+
|
|
32
|
+
export default defineMap({
|
|
33
|
+
id: 'madrid',
|
|
34
|
+
version: 1,
|
|
35
|
+
extends: streets,
|
|
36
|
+
view: {center: [-3.7038, 40.4168], zoom: 12},
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Build the assets into the application's public directory:
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
npx tileflow build --out public/tileflow
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
This assumes the application serves `public/` at its URL root. Rebuild after config or asset
|
|
47
|
+
changes, or use the [Vite](https://github.com/tileflow/tileflow-sdk/blob/main/packages/vite/README.md),
|
|
48
|
+
[Next.js](https://github.com/tileflow/tileflow-sdk/blob/main/packages/next/README.md), or
|
|
49
|
+
[Webpack](https://github.com/tileflow/tileflow-sdk/blob/main/packages/webpack/README.md) integration
|
|
50
|
+
for watched development and production builds. Do not use both workflows to overwrite the same
|
|
51
|
+
hosted manifest.
|
|
52
|
+
|
|
53
|
+
## Configure the worker
|
|
54
|
+
|
|
55
|
+
In a Vite application's client entry, add this before mounting React:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import workerUrl from 'maplibre-gl/dist/maplibre-gl-worker.mjs?worker&url';
|
|
59
|
+
import {configureTileflowMapLibre} from '@tileflow/react';
|
|
60
|
+
|
|
61
|
+
configureTileflowMapLibre({workerUrl});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
This import syntax is specific to Vite. Use the Next.js or Webpack guide linked above for that
|
|
65
|
+
bundler's worker-delivery recipe. Configure the worker once, outside component rendering. Do not
|
|
66
|
+
use a CDN worker from another MapLibre version. Next.js interactive components belong behind a
|
|
67
|
+
`'use client'` boundary.
|
|
68
|
+
|
|
69
|
+
## Render a map
|
|
70
|
+
|
|
71
|
+
Import MapLibre's CSS once in the application. After the worker and assets are ready, render:
|
|
72
|
+
|
|
73
|
+
<!-- docs:check -->
|
|
4
74
|
|
|
5
75
|
```tsx
|
|
76
|
+
import 'maplibre-gl/dist/maplibre-gl.css';
|
|
6
77
|
import {Map} from '@tileflow/react';
|
|
7
78
|
|
|
8
79
|
export function App() {
|
|
9
|
-
return
|
|
80
|
+
return (
|
|
81
|
+
<Map
|
|
82
|
+
source={{map: 'madrid'}}
|
|
83
|
+
theme="system"
|
|
84
|
+
center={[-3.7038, 40.4168]}
|
|
85
|
+
zoom={12}
|
|
86
|
+
mapOptions={{cooperativeGestures: true, maxZoom: 18}}
|
|
87
|
+
/>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Coordinates are `[longitude, latitude]`. `source` is one object, `{map, manifestUrl?}`.
|
|
93
|
+
`source.map` must match the config's portable map ID, not a hosted `map_...` identifier.
|
|
94
|
+
The default manifest URL is exactly `/tileflow/manifest.json`. For a subpath or external host,
|
|
95
|
+
provide `manifestUrl` in the source; the component does not infer bundler configuration or search
|
|
96
|
+
for assets.
|
|
97
|
+
|
|
98
|
+
`theme` selects a published concrete theme. Omission uses `defaultTheme`; `system` requires an
|
|
99
|
+
explicit light/dark mapping, which Streets supplies. Theme changes preserve the MapLibre instance,
|
|
100
|
+
camera, and interactions, and roll back on failure. `onThemeChange` reports transitions.
|
|
101
|
+
|
|
102
|
+
Add `timeOfDay="dusk"` beside `theme` to select a map's optional `day`, `dawn`, `dusk`, or
|
|
103
|
+
`night` preset. For Streets, `theme="light"` with this preset selects the existing `dusk` palette.
|
|
104
|
+
Maps without this capability ignore the option; omitting it keeps the selected theme unchanged.
|
|
105
|
+
Changing it uses the existing theme transition. `themeBlend` takes precedence. See the
|
|
106
|
+
[authoring contract](https://github.com/tileflow/tileflow-sdk/blob/main/packages/core/README.md#style-with-themes-and-semantic-modules).
|
|
107
|
+
|
|
108
|
+
`themeTransition={{duration: 450}}` cross-fades theme changes over that many milliseconds.
|
|
109
|
+
`themeBlend={{themes: ['night', 'dusk', 'day'], position}}` shows a continuous blend of the map's
|
|
110
|
+
themes instead of `theme`: position 0 is the first theme and 1.5 is halfway from the second to the
|
|
111
|
+
third. Moving the position updates the map at once. See
|
|
112
|
+
[theme transitions and blends](https://github.com/tileflow/tileflow-sdk/blob/main/packages/core/docs/theme-transitions-and-blends.md).
|
|
113
|
+
|
|
114
|
+
Interactive maps automatically render the map's vegetation. `vegetation` overrides visibility
|
|
115
|
+
(omitting it uses the map default); false hides models and flat artwork alike. `viewMode` is `2d`
|
|
116
|
+
by default and may be `3d`: only maps with `vegetation.mode: 'auto'` switch representation.
|
|
117
|
+
Streets uses model trees in either view. Changing either prop updates the existing map immediately.
|
|
118
|
+
These props do not change camera pitch, buildings or lighting and do not apply in image mode. See
|
|
119
|
+
[vegetation controls](https://github.com/tileflow/tileflow-sdk/blob/main/packages/core/docs/trees-3d.md#visibility-and-representation).
|
|
120
|
+
|
|
121
|
+
`mapOptions` accepts native MapLibre options except `container` and `style`. Direct camera props
|
|
122
|
+
take priority over `mapOptions`, then the manifest view, then shared defaults. `Map` always selects
|
|
123
|
+
a Tileflow map through its manifest; it has no renderer discriminator or direct-style mode.
|
|
124
|
+
The obsolete source fields `kind` and `style` are rejected. For a completely unmanaged map, use
|
|
125
|
+
`maplibre-gl` directly rather than a Tileflow component.
|
|
126
|
+
|
|
127
|
+
## Add annotations and popups
|
|
128
|
+
|
|
129
|
+
Install the contract package when importing its types directly:
|
|
130
|
+
|
|
131
|
+
```sh
|
|
132
|
+
npm install @tileflow/interactions@alpha
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Annotations are small, application-owned marker sets. Every annotation has a stable `id`, singular
|
|
136
|
+
`coordinate`, and non-empty `ariaLabel`. Data must be JSON-safe. Native React renderers use portals
|
|
137
|
+
into hosts managed by the interaction runtime:
|
|
138
|
+
|
|
139
|
+
<!-- docs:check -->
|
|
140
|
+
|
|
141
|
+
```tsx
|
|
142
|
+
import {useState} from 'react';
|
|
143
|
+
import type {TileflowAnnotation, TileflowInteractionState} from '@tileflow/interactions';
|
|
144
|
+
import {Map} from '@tileflow/react';
|
|
145
|
+
|
|
146
|
+
type Property = {price: number; title: string};
|
|
147
|
+
|
|
148
|
+
const annotations = [
|
|
149
|
+
{
|
|
150
|
+
id: 'property-42',
|
|
151
|
+
kind: 'marker',
|
|
152
|
+
coordinate: [-3.7038, 40.4168],
|
|
153
|
+
ariaLabel: 'Apartment in Madrid',
|
|
154
|
+
data: {price: 320_000, title: 'Apartment in Madrid'},
|
|
155
|
+
tooltip: {content: {kind: 'field', field: 'title'}},
|
|
156
|
+
popup: {content: {kind: 'view', name: 'property-card'}},
|
|
157
|
+
},
|
|
158
|
+
] satisfies readonly TileflowAnnotation<Property>[];
|
|
159
|
+
|
|
160
|
+
export function PropertyMap() {
|
|
161
|
+
const [state, setState] = useState<TileflowInteractionState>({popup: null});
|
|
162
|
+
|
|
163
|
+
return (
|
|
164
|
+
<Map
|
|
165
|
+
source={{map: 'madrid'}}
|
|
166
|
+
annotations={annotations}
|
|
167
|
+
interactionState={state}
|
|
168
|
+
onInteractionStateChange={setState}
|
|
169
|
+
onInteractionDiagnostic={(diagnostic) => console.error(diagnostic.code)}
|
|
170
|
+
renderPopup={({annotation, close}) => (
|
|
171
|
+
<article>
|
|
172
|
+
<h2>{annotation.data.title}</h2>
|
|
173
|
+
<p>EUR {annotation.data.price.toLocaleString()}</p>
|
|
174
|
+
<button type="button" onClick={close}>
|
|
175
|
+
Close
|
|
176
|
+
</button>
|
|
177
|
+
</article>
|
|
178
|
+
)}
|
|
179
|
+
/>
|
|
180
|
+
);
|
|
10
181
|
}
|
|
11
182
|
```
|
|
12
183
|
|
|
13
|
-
|
|
184
|
+
This uses the worker/CSS setup from the preceding sections. Omit controlled `interactionState` and
|
|
185
|
+
use `defaultInteractionState` for uncontrolled state; never supply both or switch ownership during
|
|
186
|
+
the component's lifetime. Updating annotations, renderers, callbacks, or state does not recreate
|
|
187
|
+
the map. Reusing an annotation ID preserves a compatible marker host.
|
|
188
|
+
|
|
189
|
+
Use `interactions` with `target: {kind: 'semantic-feature', domain: 'poi'}` for POIs already in the
|
|
190
|
+
compiled map instead of creating a DOM marker for every feature. Optional categories use Tileflow's
|
|
191
|
+
semantic taxonomy, such as `food-drink` or `retail`, not raw source classes. The style must contain
|
|
192
|
+
compatible interaction metadata. With semantic bindings, narrow `context.target.kind` in
|
|
193
|
+
`renderTooltip` or `renderPopup` before accessing annotation or feature data. `renderMarker` remains
|
|
194
|
+
annotation-only. See the
|
|
195
|
+
[interaction guide](https://github.com/tileflow/tileflow-sdk/blob/main/packages/interactions/README.md).
|
|
196
|
+
|
|
197
|
+
Text/field content uses safe text defaults. A `view` is an application renderer name, not HTML.
|
|
198
|
+
Keep tooltips non-interactive; put buttons, links, and forms in popups.
|
|
199
|
+
|
|
200
|
+
## Display an image or create a render
|
|
201
|
+
|
|
202
|
+
`<Map mode="image">` displays an explicit `imageUrl` or derives an image URL from the selected
|
|
203
|
+
manifest map's `mapId`, `apiUrl`, concrete theme and view. It still requires a valid Tileflow source.
|
|
204
|
+
It does not create a static render, poll an operation, or load MapLibre. A local style build alone
|
|
205
|
+
does not create that image. Annotations, semantic bindings, and interaction state are not supported
|
|
206
|
+
in image mode.
|
|
207
|
+
|
|
208
|
+
To request a new static render, use `StaticMap` from `@tileflow/react/static`. First install the
|
|
209
|
+
shared client/types used by this example:
|
|
210
|
+
|
|
211
|
+
```sh
|
|
212
|
+
npm install @tileflow/static@alpha
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
The application must implement an authorized `/api/static-maps` endpoint that forwards the normalized
|
|
216
|
+
scene and idempotency key to the hosted service and returns its result contract. Keep privileged
|
|
217
|
+
Tileflow credentials on that server, not in React props or a browser bundle.
|
|
218
|
+
|
|
219
|
+
<!-- docs:check -->
|
|
14
220
|
|
|
15
221
|
```tsx
|
|
16
|
-
|
|
222
|
+
import {useState} from 'react';
|
|
223
|
+
import {StaticMap} from '@tileflow/react/static';
|
|
224
|
+
import type {StaticMapAttributionEntry} from '@tileflow/static/client';
|
|
225
|
+
|
|
226
|
+
export function StaticPreview({idempotencyKey}: {idempotencyKey: string}) {
|
|
227
|
+
const [entries, setEntries] = useState<readonly StaticMapAttributionEntry[]>([]);
|
|
228
|
+
|
|
229
|
+
return (
|
|
230
|
+
<figure>
|
|
231
|
+
<StaticMap
|
|
232
|
+
map="madrid"
|
|
233
|
+
theme="dark"
|
|
234
|
+
alt="Map of central Madrid"
|
|
235
|
+
camera={{type: 'center', center: [-3.7038, 40.4168], zoom: 12}}
|
|
236
|
+
size={{width: 1200, height: 800}}
|
|
237
|
+
attribution={{mode: 'external'}}
|
|
238
|
+
createUrl="/api/static-maps"
|
|
239
|
+
idempotencyKey={idempotencyKey}
|
|
240
|
+
onReady={(result) => {
|
|
241
|
+
if ('attribution' in result) setEntries(result.attribution.entries);
|
|
242
|
+
}}
|
|
243
|
+
/>
|
|
244
|
+
<figcaption>
|
|
245
|
+
{entries.map((entry, index) => (
|
|
246
|
+
<p key={index}>
|
|
247
|
+
{entry.text}{' '}
|
|
248
|
+
{entry.links.map((link) => (
|
|
249
|
+
<a key={link.url} href={link.url}>
|
|
250
|
+
{link.label}
|
|
251
|
+
</a>
|
|
252
|
+
))}
|
|
253
|
+
</p>
|
|
254
|
+
))}
|
|
255
|
+
</figcaption>
|
|
256
|
+
</figure>
|
|
257
|
+
);
|
|
258
|
+
}
|
|
17
259
|
```
|
|
18
260
|
|
|
19
|
-
|
|
20
|
-
|
|
261
|
+
Create the key with `createStaticMapIdempotencyKey()` once per intentional render action and retain
|
|
262
|
+
it in the owning application state across retries and remounts. Pass it into this component; do not
|
|
263
|
+
regenerate it on every render. A new scene is a new action and needs a new key.
|
|
264
|
+
|
|
265
|
+
Hosted results have `resultVersion: 1` and attribution. `onReady` also supports existing-image
|
|
266
|
+
results, which have no attribution field; narrow the union before reading it. External attribution
|
|
267
|
+
must remain visible beside the image. Omitted attribution uses embedded automatic placement.
|
|
268
|
+
See the [Static Maps guide](https://github.com/tileflow/tileflow-sdk/blob/main/packages/static/README.md)
|
|
269
|
+
for server transport, errors, overlays, and limits.
|
|
270
|
+
|
|
271
|
+
## Capture, authorization, and errors
|
|
272
|
+
|
|
273
|
+
`captureId` disambiguates repeated maps on a page. The root exposes `data-tileflow-map`, the resolved
|
|
274
|
+
`data-tileflow-theme`, optional `data-tileflow-capture-id`, and `data-tileflow-state="loading|idle|error"`.
|
|
275
|
+
Capture waits for MapLibre/image readiness and committed custom interaction views. Manifest 404s,
|
|
276
|
+
unknown maps/themes, and missing styles or images enter the error state rather than silently using
|
|
277
|
+
another map.
|
|
278
|
+
|
|
279
|
+
Hosted interactive maps acquire a short-lived session grant before eligible resource requests.
|
|
280
|
+
`analytics={{enabled: false}}` disables the optional beacon, not hosted authorization. A stable
|
|
281
|
+
`surfaceId`, such as `store-locator`, identifies a product location; do not use user IDs or URLs.
|
|
282
|
+
Existing request transforms remain application-owned, and direct World use can display an
|
|
283
|
+
owner-action notice when managed delivery is required.
|
|
21
284
|
|
|
22
|
-
|
|
285
|
+
The image/SSR path does not load MapLibre. Interactive rendering needs a browser with WebGL and the
|
|
286
|
+
matching worker assets. For release-specific APIs, use the installed declarations and README;
|
|
287
|
+
source `main` may be ahead of npm. Report defects in the
|
|
288
|
+
[issue tracker](https://github.com/tileflow/tileflow-sdk/issues).
|
package/dist/index.d.ts
CHANGED
|
@@ -1,37 +1,34 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { CSSProperties, ImgHTMLAttributes } from 'react';
|
|
3
|
-
import { Map as Map$1 } from 'maplibre-gl';
|
|
4
|
-
import {
|
|
2
|
+
import { CSSProperties, ImgHTMLAttributes, ReactNode } from 'react';
|
|
3
|
+
import { MapOptions, Map as Map$1 } from 'maplibre-gl';
|
|
4
|
+
import { TileflowBrowserThemeBlendSelection, TileflowThemeTransitionOptions, TileflowViewMode, TileflowThemeTransition } from '@tileflow/core/browser';
|
|
5
|
+
import { TileflowRuntimeSource, TileflowThemeSelection, TileflowTimeOfDay, TileflowAnalytics } from '@tileflow/core/runtime';
|
|
6
|
+
import { TileflowAnnotation, TileflowInteractionState, TileflowAnnotationViewContext, TileflowInteractionBinding, TileflowInteractionViewContext, TileflowInteractionDiagnostic, TileflowInteractionEvent } from '@tileflow/interactions';
|
|
5
7
|
|
|
6
|
-
type
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
type TileflowMapStyleSourceProps = {
|
|
9
|
+
source: TileflowRuntimeSource;
|
|
10
|
+
theme?: TileflowThemeSelection;
|
|
11
|
+
/** Optional artistic preset; ignored by maps without this capability. */
|
|
12
|
+
timeOfDay?: TileflowTimeOfDay;
|
|
13
|
+
/**
|
|
14
|
+
* Shows a continuous blend of the map's themes instead of `theme`. Moving `position` changes the
|
|
15
|
+
* map at once; changing `themes` prepares a new blend. `hold` keeps labels, icons, and mixed
|
|
16
|
+
* artwork back during a camera move; clearing it brings them in at once.
|
|
17
|
+
*/
|
|
18
|
+
themeBlend?: TileflowBrowserThemeBlendSelection;
|
|
19
|
+
/** Cross-fades theme changes, including entering and leaving a blend. */
|
|
20
|
+
themeTransition?: TileflowThemeTransitionOptions;
|
|
11
21
|
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
styleId?: string;
|
|
22
|
-
};
|
|
23
|
-
type MapProps = {
|
|
24
|
-
map?: string;
|
|
25
|
-
mode?: 'interactive' | 'image';
|
|
26
|
-
config?: TileflowConfig;
|
|
27
|
-
style?: MapLibreStyle;
|
|
28
|
-
styleUrl?: string;
|
|
22
|
+
|
|
23
|
+
type TileflowMapSource = TileflowRuntimeSource;
|
|
24
|
+
type TileflowMapOptions = Omit<MapOptions, 'container' | 'style'>;
|
|
25
|
+
type TileflowAnnotationRenderer<TAnnotation extends TileflowAnnotation = TileflowAnnotation> = (context: TileflowAnnotationViewContext<TAnnotation>) => ReactNode;
|
|
26
|
+
type TileflowInteractionRenderer<TAnnotation extends TileflowAnnotation = TileflowAnnotation> = (context: TileflowInteractionViewContext<TAnnotation>) => ReactNode;
|
|
27
|
+
type MapSharedProps = {
|
|
28
|
+
vegetation?: boolean;
|
|
29
|
+
viewMode?: TileflowViewMode;
|
|
30
|
+
captureId?: string;
|
|
29
31
|
imageUrl?: string;
|
|
30
|
-
styleBaseUrl?: string;
|
|
31
|
-
tileBaseUrl?: string;
|
|
32
|
-
themes?: Record<string, TileflowThemeConfig>;
|
|
33
|
-
manifestUrl?: string;
|
|
34
|
-
preferLocalDev?: boolean;
|
|
35
32
|
alt?: string;
|
|
36
33
|
center?: [number, number];
|
|
37
34
|
zoom?: number;
|
|
@@ -39,10 +36,55 @@ type MapProps = {
|
|
|
39
36
|
height?: CSSProperties['height'];
|
|
40
37
|
imageLoading?: ImgHTMLAttributes<HTMLImageElement>['loading'];
|
|
41
38
|
interactive?: boolean;
|
|
42
|
-
|
|
39
|
+
mapOptions?: TileflowMapOptions;
|
|
43
40
|
analytics?: TileflowAnalytics;
|
|
44
41
|
onLoad?: (map: Map$1) => void;
|
|
42
|
+
onThemeChange?: (transition: TileflowThemeTransition) => void;
|
|
43
|
+
};
|
|
44
|
+
type TileflowInteractionStateInputProps = Readonly<{
|
|
45
|
+
defaultInteractionState?: never;
|
|
46
|
+
interactionState?: TileflowInteractionState;
|
|
47
|
+
}> | Readonly<{
|
|
48
|
+
defaultInteractionState?: TileflowInteractionState;
|
|
49
|
+
interactionState?: never;
|
|
50
|
+
}>;
|
|
51
|
+
type TileflowInteractionRendererProps<TAnnotation extends TileflowAnnotation> = Readonly<{
|
|
52
|
+
interactions?: never;
|
|
53
|
+
renderPopup?: TileflowAnnotationRenderer<TAnnotation>;
|
|
54
|
+
renderTooltip?: TileflowAnnotationRenderer<TAnnotation>;
|
|
55
|
+
}> | Readonly<{
|
|
56
|
+
interactions: readonly TileflowInteractionBinding[];
|
|
57
|
+
renderPopup?: TileflowInteractionRenderer<TAnnotation>;
|
|
58
|
+
renderTooltip?: TileflowInteractionRenderer<TAnnotation>;
|
|
59
|
+
}>;
|
|
60
|
+
type MapInteractiveProps<TAnnotation extends TileflowAnnotation> = MapSharedProps & TileflowInteractionStateInputProps & TileflowInteractionRendererProps<TAnnotation> & {
|
|
61
|
+
annotations?: readonly TAnnotation[];
|
|
62
|
+
mode?: 'interactive';
|
|
63
|
+
onInteractionDiagnostic?: (diagnostic: TileflowInteractionDiagnostic) => void;
|
|
64
|
+
onInteractionEvent?: (event: TileflowInteractionEvent<TAnnotation>) => void;
|
|
65
|
+
onInteractionStateChange?: (state: TileflowInteractionState) => void;
|
|
66
|
+
renderMarker?: TileflowAnnotationRenderer<TAnnotation>;
|
|
45
67
|
};
|
|
46
|
-
|
|
68
|
+
type MapImageProps = MapSharedProps & {
|
|
69
|
+
annotations?: never;
|
|
70
|
+
defaultInteractionState?: never;
|
|
71
|
+
interactionState?: never;
|
|
72
|
+
interactions?: never;
|
|
73
|
+
mode: 'image';
|
|
74
|
+
onInteractionDiagnostic?: never;
|
|
75
|
+
onInteractionEvent?: never;
|
|
76
|
+
onInteractionStateChange?: never;
|
|
77
|
+
renderMarker?: never;
|
|
78
|
+
renderPopup?: never;
|
|
79
|
+
renderTooltip?: never;
|
|
80
|
+
};
|
|
81
|
+
type MapProps<TAnnotation extends TileflowAnnotation = TileflowAnnotation> = (MapInteractiveProps<TAnnotation> | MapImageProps) & TileflowMapStyleSourceProps;
|
|
82
|
+
declare function Map<TAnnotation extends TileflowAnnotation = TileflowAnnotation>(props: MapProps<TAnnotation>): react.JSX.Element;
|
|
83
|
+
|
|
84
|
+
type TileflowMapLibreConfiguration = Readonly<{
|
|
85
|
+
workerUrl: string;
|
|
86
|
+
}>;
|
|
87
|
+
/** Configure the application-owned worker before mounting an interactive Tileflow map. */
|
|
88
|
+
declare function configureTileflowMapLibre(configuration: TileflowMapLibreConfiguration): void;
|
|
47
89
|
|
|
48
|
-
export { Map, type
|
|
90
|
+
export { Map, type MapProps, type TileflowAnnotationRenderer, type TileflowInteractionRenderer, type TileflowMapLibreConfiguration, type TileflowMapOptions, type TileflowMapSource, configureTileflowMapLibre };
|