@tileflow/react 0.1.0-alpha.29 → 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/README.md CHANGED
@@ -99,12 +99,25 @@ for assets.
99
99
  explicit light/dark mapping, which Streets supplies. Theme changes preserve the MapLibre instance,
100
100
  camera, and interactions, and roll back on failure. `onThemeChange` reports transitions.
101
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
+
102
108
  `themeTransition={{duration: 450}}` cross-fades theme changes over that many milliseconds.
103
109
  `themeBlend={{themes: ['night', 'dusk', 'day'], position}}` shows a continuous blend of the map's
104
110
  themes instead of `theme`: position 0 is the first theme and 1.5 is halfway from the second to the
105
111
  third. Moving the position updates the map at once. See
106
112
  [theme transitions and blends](https://github.com/tileflow/tileflow-sdk/blob/main/packages/core/docs/theme-transitions-and-blends.md).
107
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
+
108
121
  `mapOptions` accepts native MapLibre options except `container` and `style`. Direct camera props
109
122
  take priority over `mapOptions`, then the manifest view, then shared defaults. `Map` always selects
110
123
  a Tileflow map through its manifest; it has no renderer discriminator or direct-style mode.
package/dist/index.d.ts CHANGED
@@ -1,13 +1,15 @@
1
1
  import * as react from 'react';
2
2
  import { CSSProperties, ImgHTMLAttributes, ReactNode } from 'react';
3
3
  import { MapOptions, Map as Map$1 } from 'maplibre-gl';
4
- import { TileflowBrowserThemeBlendSelection, TileflowThemeTransitionOptions, TileflowThemeTransition } from '@tileflow/core/browser';
5
- import { TileflowRuntimeSource, TileflowThemeSelection, TileflowAnalytics } from '@tileflow/core/runtime';
4
+ import { TileflowBrowserThemeBlendSelection, TileflowThemeTransitionOptions, TileflowViewMode, TileflowThemeTransition } from '@tileflow/core/browser';
5
+ import { TileflowRuntimeSource, TileflowThemeSelection, TileflowTimeOfDay, TileflowAnalytics } from '@tileflow/core/runtime';
6
6
  import { TileflowAnnotation, TileflowInteractionState, TileflowAnnotationViewContext, TileflowInteractionBinding, TileflowInteractionViewContext, TileflowInteractionDiagnostic, TileflowInteractionEvent } from '@tileflow/interactions';
7
7
 
8
8
  type TileflowMapStyleSourceProps = {
9
9
  source: TileflowRuntimeSource;
10
10
  theme?: TileflowThemeSelection;
11
+ /** Optional artistic preset; ignored by maps without this capability. */
12
+ timeOfDay?: TileflowTimeOfDay;
11
13
  /**
12
14
  * Shows a continuous blend of the map's themes instead of `theme`. Moving `position` changes the
13
15
  * map at once; changing `themes` prepares a new blend. `hold` keeps labels, icons, and mixed
@@ -23,6 +25,8 @@ type TileflowMapOptions = Omit<MapOptions, 'container' | 'style'>;
23
25
  type TileflowAnnotationRenderer<TAnnotation extends TileflowAnnotation = TileflowAnnotation> = (context: TileflowAnnotationViewContext<TAnnotation>) => ReactNode;
24
26
  type TileflowInteractionRenderer<TAnnotation extends TileflowAnnotation = TileflowAnnotation> = (context: TileflowInteractionViewContext<TAnnotation>) => ReactNode;
25
27
  type MapSharedProps = {
28
+ vegetation?: boolean;
29
+ viewMode?: TileflowViewMode;
26
30
  captureId?: string;
27
31
  imageUrl?: string;
28
32
  alt?: string;
package/dist/index.js CHANGED
@@ -16,6 +16,7 @@ import {
16
16
  attachTileflowMapLifecycle,
17
17
  createTileflowSessionStarter,
18
18
  createTileflowThemeController,
19
+ createTileflowVegetation,
19
20
  createTileflowTransformRequest,
20
21
  getTileflowSystemColorScheme,
21
22
  loadTileflowStyleFonts,
@@ -171,6 +172,7 @@ import {
171
172
  validateTileflowBrowserThemeBlendSelection
172
173
  } from "@tileflow/core/browser";
173
174
  import {
175
+ isTileflowTimeOfDay,
174
176
  validateTileflowRuntimeSource,
175
177
  validateTileflowThemeSelection
176
178
  } from "@tileflow/core/runtime";
@@ -180,6 +182,9 @@ function validateTileflowMapStyleInputs(input) {
180
182
  if (input.theme !== void 0 && !validateTileflowThemeSelection(input.theme)) {
181
183
  return { error: 'theme must be a concrete portable theme name or "system"', ok: false };
182
184
  }
185
+ if (input.timeOfDay !== void 0 && !isTileflowTimeOfDay(input.timeOfDay)) {
186
+ return { error: "timeOfDay must be day, dawn, dusk, or night", ok: false };
187
+ }
183
188
  if (input.themeBlend !== void 0 && !validateTileflowBrowserThemeBlendSelection(input.themeBlend)) {
184
189
  return {
185
190
  error: "themeBlend must name two to eight concrete themes, a position from 0 to themes.length - 1, and an optional boolean hold",
@@ -260,8 +265,11 @@ function Map2(props) {
260
265
  mapOptions,
261
266
  analytics,
262
267
  theme,
268
+ timeOfDay,
263
269
  themeBlend,
264
270
  themeTransition,
271
+ vegetation,
272
+ viewMode = "2d",
265
273
  interactionState,
266
274
  interactions = defaultInteractions,
267
275
  onInteractionDiagnostic,
@@ -302,6 +310,13 @@ function Map2(props) {
302
310
  const containerRef = useRef(null);
303
311
  const imageRef = useRef(null);
304
312
  const mapRef = useRef(null);
313
+ const vegetationRef = useRef(void 0);
314
+ const vegetationInputsRef = useRef({ vegetation, viewMode });
315
+ vegetationInputsRef.current = { vegetation, viewMode };
316
+ useEffect(() => {
317
+ vegetationRef.current?.setVisible(vegetation);
318
+ vegetationRef.current?.setViewMode(viewMode);
319
+ }, [vegetation, viewMode]);
305
320
  const themeControllerRef = useRef(void 0);
306
321
  const runtimeStyleRef = useRef(null);
307
322
  const interactionRuntimeRef = useRef(
@@ -370,12 +385,17 @@ function Map2(props) {
370
385
  }
371
386
  return {
372
387
  error: false,
373
- name: resolveTileflowRuntimeTheme(manifestMap, selection, systemColorScheme).name
388
+ name: resolveTileflowRuntimeTheme(
389
+ manifestMap,
390
+ selection,
391
+ systemColorScheme,
392
+ themeBlendKey ? void 0 : timeOfDay
393
+ ).name
374
394
  };
375
395
  } catch {
376
396
  return { error: true, name: void 0 };
377
397
  }
378
- }, [blendThemeName, manifestMap, systemColorScheme, theme, themeBlendKey]);
398
+ }, [blendThemeName, manifestMap, systemColorScheme, theme, themeBlendKey, timeOfDay]);
379
399
  const resolvedThemeName = themeResolution.name;
380
400
  const manifestView = resolveTileflowRuntimeView({ manifestMap });
381
401
  const manifestCenter = useStableMapOptionValue(
@@ -795,6 +815,27 @@ function Map2(props) {
795
815
  }
796
816
  });
797
817
  }
818
+ const vegetationController = createTileflowVegetation({
819
+ map,
820
+ ...themeController ? { controller: themeController } : {},
821
+ visible: vegetationInputsRef.current.vegetation,
822
+ viewMode: vegetationInputsRef.current.viewMode,
823
+ // Direct tile readers use HTTP, not MapLibre's custom World protocol.
824
+ transformRequest: createTileflowTransformRequest({
825
+ getAnalytics: () => resolvedAnalyticsRef.current,
826
+ sessionController: session,
827
+ sessionId: session.sessionId,
828
+ transformRequest: (url) => stableMapOptions?.transformRequest?.(
829
+ url,
830
+ "Tile"
831
+ )
832
+ })
833
+ });
834
+ vegetationRef.current = vegetationController;
835
+ registerCleanup(() => {
836
+ vegetationController.dispose();
837
+ if (vegetationRef.current === vegetationController) vegetationRef.current = void 0;
838
+ });
798
839
  const browserWindow = container.ownerDocument.defaultView;
799
840
  if (!browserWindow) {
800
841
  throw new Error("Tileflow semantic interactions require a browser document.");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tileflow/react",
3
- "version": "0.1.0-alpha.29",
3
+ "version": "0.1.0-alpha.30",
4
4
  "license": "Apache-2.0",
5
5
  "description": "React components for rendering Tileflow maps with MapLibre.",
6
6
  "type": "module",
@@ -43,8 +43,8 @@
43
43
  "access": "public"
44
44
  },
45
45
  "dependencies": {
46
- "@tileflow/core": ">=0.1.0-alpha.32 <0.1.0-beta.0",
47
- "@tileflow/interactions": ">=0.1.0-alpha.4 <0.1.0-beta.0",
46
+ "@tileflow/core": ">=0.1.0-alpha.35 <0.1.0-beta.0",
47
+ "@tileflow/interactions": ">=0.1.0-alpha.5 <0.1.0-beta.0",
48
48
  "@tileflow/static": ">=0.1.0-alpha.28 <0.1.0-beta.0"
49
49
  },
50
50
  "peerDependencies": {