@swr-data-lab/components 1.11.3 → 1.12.1

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.
Files changed (64) hide show
  1. package/.storybook/blocks/Mermaid.jsx +9 -0
  2. package/.storybook/main.ts +23 -17
  3. package/.storybook/preview.ts +42 -13
  4. package/package.json +72 -68
  5. package/src/DesignTokens/Tokens.ts +15 -12
  6. package/src/Select/Select.stories.svelte +3 -3
  7. package/src/Switcher/Switcher.svelte +1 -0
  8. package/src/index.js +12 -0
  9. package/src/maplibre/AttributionControl/AttributionControl.stories.svelte +29 -0
  10. package/src/maplibre/AttributionControl/AttributionControl.svelte +45 -0
  11. package/src/maplibre/AttributionControl/index.js +2 -0
  12. package/src/maplibre/GeocoderControl/GeocoderAPIs.ts +49 -0
  13. package/src/maplibre/GeocoderControl/GeocoderControl.stories.svelte +78 -0
  14. package/src/maplibre/GeocoderControl/GeocoderControl.svelte +207 -0
  15. package/src/maplibre/GeocoderControl/index.js +2 -0
  16. package/src/maplibre/Map/FallbackStyle.ts +18 -0
  17. package/src/maplibre/Map/Map.stories.svelte +118 -0
  18. package/src/maplibre/Map/Map.svelte +283 -0
  19. package/src/maplibre/Map/index.js +2 -0
  20. package/src/maplibre/MapControl/MapControl.mdx +12 -0
  21. package/src/maplibre/MapControl/MapControl.stories.svelte +56 -0
  22. package/src/maplibre/MapControl/MapControl.svelte +41 -0
  23. package/src/maplibre/MapControl/index.js +2 -0
  24. package/src/maplibre/MapStyle/SWRDataLabLight.mdx +86 -0
  25. package/src/maplibre/MapStyle/SWRDataLabLight.stories.svelte +41 -0
  26. package/src/maplibre/MapStyle/SWRDataLabLight.ts +72 -0
  27. package/src/maplibre/MapStyle/components/Admin.ts +173 -0
  28. package/src/maplibre/MapStyle/components/Buildings.ts +23 -0
  29. package/src/maplibre/MapStyle/components/Landuse.ts +499 -0
  30. package/src/maplibre/MapStyle/components/Natural.ts +1 -0
  31. package/src/maplibre/MapStyle/components/PlaceLabels.ts +199 -0
  32. package/src/maplibre/MapStyle/components/Roads.ts +2345 -0
  33. package/src/maplibre/MapStyle/components/Transit.ts +507 -0
  34. package/src/maplibre/MapStyle/components/Walking.ts +1538 -0
  35. package/src/maplibre/MapStyle/index.js +2 -0
  36. package/src/maplibre/MapStyle/tokens.ts +21 -0
  37. package/src/maplibre/Maplibre.mdx +91 -0
  38. package/src/maplibre/NavigationControl/NavigationControl.stories.svelte +39 -0
  39. package/src/maplibre/NavigationControl/NavigationControl.svelte +36 -0
  40. package/src/maplibre/NavigationControl/index.js +2 -0
  41. package/src/maplibre/ScaleControl/ScaleControl.stories.svelte +71 -0
  42. package/src/maplibre/ScaleControl/ScaleControl.svelte +25 -0
  43. package/src/maplibre/ScaleControl/index.js +2 -0
  44. package/src/maplibre/Source/MapSource.stories.svelte +9 -0
  45. package/src/maplibre/Source/MapSource.svelte +61 -0
  46. package/src/maplibre/Source/index.js +2 -0
  47. package/src/maplibre/Source/source.ts +89 -0
  48. package/src/maplibre/Tooltip/Tooltip.stories.svelte +192 -0
  49. package/src/maplibre/Tooltip/Tooltip.svelte +175 -0
  50. package/src/maplibre/Tooltip/index.js +2 -0
  51. package/src/maplibre/VectorLayer/VectorLayer.stories.svelte +65 -0
  52. package/src/maplibre/VectorLayer/VectorLayer.svelte +142 -0
  53. package/src/maplibre/VectorLayer/index.js +2 -0
  54. package/src/maplibre/VectorTileSource/VectorTileSource.mdx +19 -0
  55. package/src/maplibre/VectorTileSource/VectorTileSource.stories.svelte +46 -0
  56. package/src/maplibre/VectorTileSource/VectorTileSource.svelte +24 -0
  57. package/src/maplibre/VectorTileSource/index.js +2 -0
  58. package/src/maplibre/WithLinkLocation/WithLinkLocation.mdx +11 -0
  59. package/src/maplibre/WithLinkLocation/WithLinkLocation.stories.svelte +29 -0
  60. package/src/maplibre/WithLinkLocation/WithLinkLocation.svelte +83 -0
  61. package/src/maplibre/WithLinkLocation/index.js +2 -0
  62. package/src/maplibre/context.svelte.ts +89 -0
  63. package/src/maplibre/types.ts +12 -0
  64. package/src/maplibre/utils.ts +52 -0
@@ -0,0 +1,41 @@
1
+ <script lang="ts">
2
+ import { type Snippet } from 'svelte';
3
+ import { type ControlPosition, type IControl } from 'maplibre-gl';
4
+ import { getMapContext } from '../context.svelte.js';
5
+
6
+ interface MapControlProps {
7
+ position: ControlPosition;
8
+ control?: IControl;
9
+ className?: string;
10
+ children?: Snippet;
11
+ }
12
+
13
+ let { position, control, className, children }: MapControlProps = $props();
14
+ let el: HTMLDivElement | undefined = $state();
15
+
16
+ const { map } = $derived(getMapContext());
17
+
18
+ let ctrl = $derived.by(() => {
19
+ return control
20
+ ? control
21
+ : {
22
+ onAdd: () => el!,
23
+ onRemove: () => el?.parentNode?.removeChild(el)
24
+ };
25
+ });
26
+
27
+ $effect(() => {
28
+ if (map && ctrl) {
29
+ map.addControl(ctrl, position);
30
+ }
31
+ return () => {
32
+ map?.removeControl(control);
33
+ };
34
+ });
35
+ </script>
36
+
37
+ <div bind:this={el} class={`maplibregl-ctrl ${className}`}>
38
+ {#if children}
39
+ {@render children()}
40
+ {/if}
41
+ </div>
@@ -0,0 +1,2 @@
1
+ import MapControl from './MapControl.svelte';
2
+ export default MapControl;
@@ -0,0 +1,86 @@
1
+ import { Story, Meta, Primary, Controls, Stories } from '@storybook/addon-docs/blocks';
2
+ import Mermaid from '../../../.storybook/blocks/Mermaid';
3
+ import SWRDataLabLight from './SWRDataLabLight';
4
+ import * as MapStyleStories from './SWRDataLabLight.stories.svelte';
5
+
6
+ <Meta of={MapStyleStories} />
7
+
8
+ # SWR Data Lab Light
9
+
10
+ Light-themed general-purpose basemap using SWR colours and typefaces based on
11
+ [versatiles-greybeard](https://github.com/versatiles-org/versatiles-style).
12
+
13
+ - Data sources
14
+ - Vector data: [versatiles-osm](https://download.versatiles.org/) in the [Shortbread schema](https://shortbread-tiles.org/) served from `tiles.versatiles.org`
15
+ - Typefaces: SWR Sans served from `https://static.datenhub.net/maps/fonts/`.
16
+ - Layer count: {SWRDataLabLight.layers.length}
17
+
18
+ <Story of={MapStyleStories.Default} />
19
+
20
+ <br />
21
+
22
+ ### Design Notes
23
+
24
+ We take a two-step design approach:
25
+
26
+ 1. Sort the geographic data we want to present into semantic groups like "Admin Boundaries", "Roads" or "Transit" (inspired by Mapbox's [Style Components](https://docs.mapbox.com/studio-manual/guides/components/)).
27
+ 2. Derive physical layers (ie. `MapLayerSpecification`) from these groups and interleave them to produce a convincing image
28
+ 3. Use shared design tokens to style each physical layer
29
+
30
+ <Mermaid chart={`
31
+ block-beta
32
+ columns 10
33
+
34
+ classDef admin fill:#e5dbf5;
35
+ classDef buildings fill:#FFBA35;
36
+ classDef roads fill:#FFD584;
37
+ classDef transit fill:#C5F0B1;
38
+ classDef walking fill:#65D62B;
39
+ classDef landuse fill:#eee;
40
+
41
+ block:semantic:6
42
+ columns 1
43
+ columns 1
44
+ s_admin["Admin"]
45
+ s_buildings["Buildings"]
46
+ s_roads["Roads"]
47
+ s_transit["Transit"]
48
+ s_walking["Walking + Cycling"]
49
+ s_landuse["Landuse"]
50
+ end
51
+
52
+ block:actual:10
53
+ columns 1
54
+ a_admin_labels["Admin Labels"]
55
+ a_walking_labels["Walking (Labels)"]
56
+ a_transit_labels["Transit (Labels)"]
57
+ a_roads_labels["Roads (Labels)"]
58
+ a_admin0["Admin 0 (Countries)"]
59
+ a_admin1["Admin 1 (States/Provinces)"]
60
+ a_admin2["Admin 2 (Districts)"]
61
+ a_buildings["Buildings"]
62
+ a_walking_bridge["Walking (Bridge)"]
63
+ a_transit_bridge["Transit (Bridge)"]
64
+ a_roads_bridge["Roads (Bridge)"]
65
+ a_walking_surface["Walking (Surface)"]
66
+ a_transit_surface["Transit (Surface)"]
67
+ a_roads_surface["Roads (Surface)"]
68
+ a_walking_tunnel["Walking (Tunnel)"]
69
+ a_transit_tunnel["Transit (Tunnel)"]
70
+ a_roads_tunnel["Roads (Tunnel)"]
71
+ a_land["Land"]
72
+ a_ocean["Ocean"]
73
+ a_background["Background"]
74
+ end
75
+
76
+ class s_admin,a_admin0,a_admin1,a_admin2,a_admin_labels admin
77
+ class s_buildings,a_buildings buildings
78
+ class s_roads,a_roads_bridge,a_roads_surface,a_roads_tunnel,a_roads_labels roads
79
+ class s_transit,a_transit_bridge,a_transit_surface,a_transit_tunnel,a_transit_labels transit
80
+ class s_walking,a_walking_bridge,a_walking_surface,a_walking_tunnel,a_walking_labels walking
81
+ class s_landuse,a_land,a_ocean,a_background landuse
82
+ `}/>
83
+
84
+ ### References
85
+
86
+ - [Foundational Map Design | BUILD with Mapbox ](https://www.youtube.com/watch?v=QDfj9oGVZmE)
@@ -0,0 +1,41 @@
1
+ <script context="module" lang="ts">
2
+ import { defineMeta } from '@storybook/addon-svelte-csf';
3
+ import Map from '../Map/Map.svelte';
4
+ import DesignTokens from '../../DesignTokens/DesignTokens.svelte';
5
+ import AttributionControl from '../AttributionControl/AttributionControl.svelte';
6
+ import GeocoderControl from '../GeocoderControl/GeocoderControl.svelte';
7
+
8
+ import { SWRDataLabLight } from './index';
9
+ const { Story } = defineMeta({
10
+ title: 'Maplibre/Style/SWR Data Lab Light',
11
+ component: Map
12
+ });
13
+ </script>
14
+
15
+ <Story asChild name="Default">
16
+ <DesignTokens>
17
+ <div class="grid">
18
+ <div class="container">
19
+ <Map
20
+ style={SWRDataLabLight}
21
+ initialLocation={{ lng: 8.239451072800875, lat: 48.75692609731408, zoom: 14.99 }}
22
+ >
23
+ <GeocoderControl languages="de" service="maptiler" key="V32kPHZjMa0Mkn6YvSzA" />
24
+ <AttributionControl position="bottom-left" />
25
+ </Map>
26
+ </div>
27
+ </div>
28
+ </DesignTokens>
29
+ </Story>
30
+
31
+ <style>
32
+ .grid {
33
+ display: grid;
34
+ grid-template-columns: repeat(1, 1fr);
35
+ grid-template-rows: auto;
36
+ height: 700px;
37
+ }
38
+ .container {
39
+ overflow: hidden;
40
+ }
41
+ </style>
@@ -0,0 +1,72 @@
1
+ import type { StyleSpecification } from 'maplibre-gl';
2
+
3
+ import makeAdmin from './components/Admin';
4
+ import makeBuildings from './components/Buildings';
5
+ import makeLanduse from './components/Landuse';
6
+ import makeTransit from './components/Transit';
7
+ import makePlaceLabels from './components/PlaceLabels';
8
+ import makeWalking from './components/Walking';
9
+ import makeRoads from './components/Roads';
10
+
11
+ const { buildings } = makeBuildings();
12
+ const { landuse } = makeLanduse();
13
+ const { placeLabels } = makePlaceLabels();
14
+ const { admin } = makeAdmin();
15
+ const { airports, transitBridges, transitSurface, transitTunnels } = makeTransit();
16
+ const { walkingLabels, walkingTunnels, walkingSurface, walkingBridges } = makeWalking();
17
+ const { roadLabels, roadBridges, roadSurface, roadTunnels } = makeRoads();
18
+
19
+ const style: StyleSpecification = {
20
+ version: 8,
21
+ name: 'swr-datalab-light',
22
+ metadata: { license: 'https://creativecommons.org/publicdomain/zero/1.0/' },
23
+ glyphs: 'https://static.datenhub.net/maps/fonts/{fontstack}/{range}.pbf',
24
+ sources: {
25
+ 'versatiles-osm': {
26
+ attribution:
27
+ '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
28
+ tiles: ['https://tiles.versatiles.org/tiles/osm/{z}/{x}/{y}'],
29
+ bounds: [-180, -85.0511287798066, 180, 85.0511287798066],
30
+ type: 'vector',
31
+ scheme: 'xyz',
32
+ minzoom: 0,
33
+ maxzoom: 14
34
+ }
35
+ },
36
+ sky: {
37
+ 'atmosphere-blend': ['interpolate', ['linear'], ['zoom'], 0, 0.1, 5, 0.1, 7, 0]
38
+ },
39
+ layers: [
40
+ // 1. Landuse
41
+ ...landuse,
42
+ ...airports,
43
+
44
+ // 2. Buildings
45
+ ...buildings,
46
+
47
+ // 3. Tunnels
48
+ ...walkingTunnels,
49
+ ...roadTunnels,
50
+ ...transitTunnels,
51
+
52
+ // 4. Surface ways
53
+ ...walkingSurface,
54
+ ...roadSurface,
55
+ ...transitSurface,
56
+
57
+ // 5. Bridges ways
58
+ ...walkingBridges,
59
+ ...roadBridges,
60
+ ...transitBridges,
61
+
62
+ // 6. Admin boundaries
63
+ ...admin,
64
+
65
+ // 7. Labels
66
+ ...walkingLabels,
67
+ ...roadLabels,
68
+ ...placeLabels
69
+ ]
70
+ };
71
+
72
+ export default style;
@@ -0,0 +1,173 @@
1
+ import tokens from '../tokens';
2
+ import { type Layer } from '../../types';
3
+
4
+ export default function makeAdmin(): any {
5
+ const admin: Layer[] = [
6
+ {
7
+ id: 'boundary-country:outline',
8
+ filter: [
9
+ 'all',
10
+ ['==', 'admin_level', 2],
11
+ ['!=', 'maritime', true],
12
+ ['!=', 'disputed', true],
13
+ ['!=', 'coastline', true]
14
+ ],
15
+ paint: {
16
+ 'line-color': tokens.background,
17
+ 'line-blur': 1,
18
+ 'line-width': {
19
+ stops: [
20
+ [2, 0],
21
+ [3, 2],
22
+ [10, 8]
23
+ ]
24
+ },
25
+ 'line-opacity': 0.75
26
+ },
27
+ layout: {
28
+ 'line-cap': 'round',
29
+ 'line-join': 'round'
30
+ }
31
+ },
32
+ {
33
+ id: 'boundary-country-disputed:outline',
34
+ filter: [
35
+ 'all',
36
+ ['==', 'admin_level', 2],
37
+ ['==', 'disputed', true],
38
+ ['!=', 'maritime', true],
39
+ ['!=', 'coastline', true]
40
+ ],
41
+ paint: {
42
+ 'line-width': {
43
+ stops: [
44
+ [2, 0],
45
+ [3, 2],
46
+ [10, 8]
47
+ ]
48
+ },
49
+ 'line-opacity': 0.75,
50
+ 'line-color': tokens.background
51
+ }
52
+ },
53
+ {
54
+ id: 'boundary-state:outline',
55
+ filter: [
56
+ 'all',
57
+ ['==', 'admin_level', 4],
58
+ ['!=', 'maritime', true],
59
+ ['!=', 'disputed', true],
60
+ ['!=', 'coastline', true]
61
+ ],
62
+ paint: {
63
+ 'line-color': tokens.background,
64
+ 'line-blur': 1,
65
+ 'line-width': {
66
+ stops: [
67
+ [7, 0],
68
+ [8, 2],
69
+ [10, 4]
70
+ ]
71
+ },
72
+ 'line-opacity': 0.75
73
+ },
74
+ layout: {
75
+ 'line-cap': 'round',
76
+ 'line-join': 'round'
77
+ }
78
+ },
79
+ {
80
+ id: 'boundary-country',
81
+ filter: [
82
+ 'all',
83
+ ['==', 'admin_level', 2],
84
+ ['!=', 'maritime', true],
85
+ ['!=', 'disputed', true],
86
+ ['!=', 'coastline', true]
87
+ ],
88
+ paint: {
89
+ 'line-color': {
90
+ stops: [
91
+ [7, '#cecdcd'],
92
+ [10, 'black']
93
+ ]
94
+ },
95
+
96
+ 'line-width': {
97
+ stops: [
98
+ [2, 0],
99
+ [5, 1],
100
+ [8, 1],
101
+ [12, 3]
102
+ ]
103
+ }
104
+ },
105
+ layout: {
106
+ 'line-cap': 'round',
107
+ 'line-join': 'round'
108
+ }
109
+ },
110
+ {
111
+ id: 'boundary-country-disputed',
112
+ filter: [
113
+ 'all',
114
+ ['==', 'admin_level', 2],
115
+ ['==', 'disputed', true],
116
+ ['!=', 'maritime', true],
117
+ ['!=', 'coastline', true]
118
+ ],
119
+ paint: {
120
+ 'line-width': {
121
+ stops: [
122
+ [2, 0],
123
+ [3, 1],
124
+ [10, 4]
125
+ ]
126
+ },
127
+ 'line-color': 'hsl(246,0%,77%)',
128
+ 'line-dasharray': [2, 1]
129
+ },
130
+ layout: {
131
+ 'line-cap': 'square'
132
+ }
133
+ },
134
+ {
135
+ id: 'boundary-state',
136
+ filter: [
137
+ 'all',
138
+ ['==', 'admin_level', 4],
139
+ ['!=', 'maritime', true],
140
+ ['!=', 'disputed', true],
141
+ ['!=', 'coastline', true]
142
+ ],
143
+ paint: {
144
+ 'line-color': 'hsl(37, 34%, 79%)',
145
+ 'line-width': {
146
+ stops: [
147
+ [7, 1],
148
+ [8, 1.5]
149
+ ]
150
+ },
151
+ 'line-opacity': {
152
+ stops: [
153
+ [7, 0],
154
+ [8, 1]
155
+ ]
156
+ }
157
+ },
158
+ layout: {
159
+ 'line-cap': 'round',
160
+ 'line-join': 'round'
161
+ }
162
+ }
163
+ ].map((el) => {
164
+ return {
165
+ source: 'versatiles-osm',
166
+ 'source-layer': 'boundaries',
167
+ type: 'line',
168
+ ...el
169
+ } as Layer;
170
+ });
171
+
172
+ return { admin };
173
+ }
@@ -0,0 +1,23 @@
1
+ import { type Layer } from '../../types';
2
+
3
+ export default function makeBuildings(): any {
4
+ const buildings: Layer[] = [
5
+ {
6
+ id: 'building-fill',
7
+ type: 'fill',
8
+ source: 'versatiles-osm',
9
+ 'source-layer': 'buildings',
10
+ paint: {
11
+ 'fill-color': 'hsl(240, 4%, 95%)',
12
+ 'fill-opacity': {
13
+ stops: [
14
+ [14, 0],
15
+ [15, 1]
16
+ ]
17
+ }
18
+ }
19
+ }
20
+ ];
21
+
22
+ return { buildings };
23
+ }