diff --git a/components/src/maplibre/Map/Map.stories.svelte b/components/src/maplibre/Map/Map.stories.svelte index 12be5e7d..5c24de83 100644 --- a/components/src/maplibre/Map/Map.stories.svelte +++ b/components/src/maplibre/Map/Map.stories.svelte @@ -1,6 +1,6 @@ - + { + const canvas = within(canvasElement); + const containerEl = canvas.getByTestId('map-container'); + const flyToBerlinButton = canvas.getByTestId('flyto-berlin'); + + await step('map renders', async () => { + const mapEl = containerEl.querySelector('.maplibregl-canvas'); + expect(mapEl).toBeTruthy(); + }); + await step('mapContext prop receives valid data', async () => { + expect(mapContext).toBeInstanceOf(MapContext); + }); + await step('external trigger map events', async () => { + await userEvent.click(flyToBerlinButton); + expect(onMoveStart).toHaveBeenCalled(); + // We'd like to expext.poll() for onMoveEnd.toHaveBeenCalled() + // here but that API doesn't exist in Storybook, see: + // https://github.com/storybookjs/storybook/issues/29060 + }); + }} +> +
+ + + + + + + +
+
+ -
+
- import maplibre, { type ProjectionSpecification, type StyleSpecification } from 'maplibre-gl'; + import maplibre, { + type MapLibreEvent, + type ProjectionSpecification, + type StyleSpecification + } from 'maplibre-gl'; import { onMount, onDestroy, type Snippet, getContext, hasContext } from 'svelte'; - import { createMapContext } from '../context.svelte.js'; + import { createMapContext, MapContext } from '../context.svelte.js'; import { type Location } from '../types'; import FallbackStyle from './FallbackStyle'; @@ -20,6 +24,9 @@ projection?: ProjectionSpecification; showDebug?: boolean; options?: any; + mapContext?: MapContext; + onmovestart?: (e: MapLibreEvent) => null; + onmoveend?: (e: MapLibreEvent) => null; children?: Snippet; } @@ -38,7 +45,12 @@ allowRotation = false, allowZoom = true, showDebug = false, - initialLocation: receivedInitialLocation + initialLocation: receivedInitialLocation, + // Future: This should become bindable.readonly when that becomes + // available, see: https://github.com/sveltejs/svelte/issues/7712 + mapContext = $bindable(), + onmoveend, + onmovestart }: MapProps = $props(); let container: HTMLElement; @@ -53,7 +65,7 @@ ...receivedInitialLocation }; - const mapContext = createMapContext(); + mapContext = createMapContext(); if (getContext('initialLocation') !== undefined && getContext('initialLocation') !== false) { initialLocation = getContext('initialLocation'); } @@ -85,6 +97,13 @@ pitch = mapContext.map?.getPitch(); bearing = mapContext.map?.getBearing(); }); + + if (onmoveend) { + mapContext.map.on('moveend', onmoveend); + } + if (onmovestart) { + mapContext.map.on('movestart', onmovestart); + } }); onDestroy(async () => { @@ -94,6 +113,7 @@ $effect(() => { if (mapContext.map) mapContext.map.setStyle(style); }); + $effect(() => { if (mapContext.styleLoaded) { mapContext.map?.setProjection(projection); diff --git a/components/src/maplibre/MapStyle/SWRDataLabLight.mdx b/components/src/maplibre/MapStyle/SWRDataLabLight.mdx index 946f44e6..5452bfce 100644 --- a/components/src/maplibre/MapStyle/SWRDataLabLight.mdx +++ b/components/src/maplibre/MapStyle/SWRDataLabLight.mdx @@ -11,8 +11,8 @@ Light-themed general-purpose basemap using SWR colours and typefaces based on [versatiles-greybeard](https://github.com/versatiles-org/versatiles-style). - Data sources - - Vector data: [versatiles-osm](https://download.versatiles.org/) in the [Shortbread schema](https://shortbread-tiles.org/) served from `tiles.versatiles.org` - - Building footprints with heights: [basemap-de](https://basemap.de/produkte-und-dienste/web-vektor/) vector tiles served from `sgx.geodatenzentrum.de` + - Vector data: [versatiles-osm](https://download.versatiles.org/) in the [Shortbread schema](https://shortbread-tiles.org/) served from `tiles.versatiles.org` ([License](https://docs.versatiles.org/basics/tilesets.html#license--attribution)) + - Building footprints with heights: [basemap-de](https://basemap.de/produkte-und-dienste/web-vektor/) vector tiles served from `sgx.geodatenzentrum.de` ([License](https://sgx.geodatenzentrum.de/web_public/gdz/lizenz/deu/Nutzungsbedingungen_basemapde.pdf)) - Typefaces: SWR Sans served from `https://static.datenhub.net/maps/fonts/`. - Layer count: {SWRDataLabLight({enableBuildingExtrusions: true}).layers.length} (including building extrusions) diff --git a/components/src/maplibre/Maplibre.mdx b/components/src/maplibre/Maplibre.mdx index 533e0dc9..33a2a17e 100644 --- a/components/src/maplibre/Maplibre.mdx +++ b/components/src/maplibre/Maplibre.mdx @@ -58,6 +58,8 @@ This example initialises a map using the SWRDataLabLight style, adds an addition ``` +- `mapContext` is [bindable](https://svelte.dev/docs/svelte/$bindable), so you can access MapLibre APIs from outside the `` component. This is useful if you want to control the map programatically, ie. in a scrollytelling application. + ## Available components ### Sources