@smartnet360/svelte-components 0.0.54 → 0.0.55

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 (79) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/index.js +2 -2
  3. package/dist/map-v2/core/controls/MapStyleControl.svelte +289 -0
  4. package/dist/map-v2/core/controls/MapStyleControl.svelte.d.ts +24 -0
  5. package/dist/{map → map-v2/core}/hooks/useMapbox.d.ts +1 -1
  6. package/dist/{map → map-v2/core}/hooks/useMapbox.js +1 -1
  7. package/dist/map-v2/core/index.d.ts +11 -0
  8. package/dist/map-v2/core/index.js +14 -0
  9. package/dist/map-v2/core/providers/MapboxProvider.svelte +140 -0
  10. package/dist/map-v2/core/providers/MapboxProvider.svelte.d.ts +33 -0
  11. package/dist/{map → map-v2/core}/stores/mapStore.d.ts +2 -2
  12. package/dist/{map → map-v2/core}/stores/mapStore.js +2 -2
  13. package/dist/map-v2/core/types.d.ts +13 -0
  14. package/dist/map-v2/core/types.js +7 -0
  15. package/dist/map-v2/demo/DemoMap.svelte +63 -0
  16. package/dist/{map → map-v2}/demo/DemoMap.svelte.d.ts +3 -4
  17. package/dist/map-v2/demo/demo-data.d.ts +8 -0
  18. package/dist/map-v2/demo/demo-data.js +128 -0
  19. package/dist/map-v2/demo/index.d.ts +7 -0
  20. package/dist/map-v2/demo/index.js +9 -0
  21. package/dist/{map → map-v2/features/sites}/controls/SiteFilterControl.svelte +26 -40
  22. package/dist/{map → map-v2/features/sites}/controls/SiteFilterControl.svelte.d.ts +4 -6
  23. package/dist/map-v2/features/sites/controls/SiteSizeSlider.svelte +185 -0
  24. package/dist/map-v2/features/sites/controls/SiteSizeSlider.svelte.d.ts +20 -0
  25. package/dist/map-v2/features/sites/index.d.ts +14 -0
  26. package/dist/map-v2/features/sites/index.js +16 -0
  27. package/dist/map-v2/features/sites/layers/SitesLayer.svelte +277 -0
  28. package/dist/map-v2/features/sites/layers/SitesLayer.svelte.d.ts +12 -0
  29. package/dist/map-v2/features/sites/stores/siteStore.d.ts +18 -0
  30. package/dist/map-v2/features/sites/stores/siteStore.js +36 -0
  31. package/dist/map-v2/features/sites/stores/siteStoreContext.svelte.d.ts +29 -0
  32. package/dist/map-v2/features/sites/stores/siteStoreContext.svelte.js +73 -0
  33. package/dist/map-v2/features/sites/types.d.ts +36 -0
  34. package/dist/map-v2/features/sites/types.js +4 -0
  35. package/dist/map-v2/features/sites/utils/siteGeoJSON.d.ts +31 -0
  36. package/dist/map-v2/features/sites/utils/siteGeoJSON.js +34 -0
  37. package/dist/map-v2/features/sites/utils/siteTreeUtils.d.ts +14 -0
  38. package/dist/{map → map-v2/features/sites}/utils/siteTreeUtils.js +3 -50
  39. package/dist/map-v2/index.d.ts +10 -0
  40. package/dist/map-v2/index.js +22 -0
  41. package/dist/{map → map-v2/shared}/controls/MapControl.svelte +1 -1
  42. package/dist/map-v2/shared/index.d.ts +7 -0
  43. package/dist/map-v2/shared/index.js +9 -0
  44. package/package.json +1 -1
  45. package/dist/map/demo/DemoMap.svelte +0 -98
  46. package/dist/map/demo/demo-data.d.ts +0 -12
  47. package/dist/map/demo/demo-data.js +0 -220
  48. package/dist/map/hooks/useCellData.d.ts +0 -14
  49. package/dist/map/hooks/useCellData.js +0 -29
  50. package/dist/map/index.d.ts +0 -27
  51. package/dist/map/index.js +0 -47
  52. package/dist/map/layers/CellsLayer.svelte +0 -242
  53. package/dist/map/layers/CellsLayer.svelte.d.ts +0 -21
  54. package/dist/map/layers/CoverageLayer.svelte +0 -37
  55. package/dist/map/layers/CoverageLayer.svelte.d.ts +0 -9
  56. package/dist/map/layers/LayerBase.d.ts +0 -42
  57. package/dist/map/layers/LayerBase.js +0 -58
  58. package/dist/map/layers/SitesLayer.svelte +0 -282
  59. package/dist/map/layers/SitesLayer.svelte.d.ts +0 -19
  60. package/dist/map/providers/CellDataProvider.svelte +0 -43
  61. package/dist/map/providers/CellDataProvider.svelte.d.ts +0 -12
  62. package/dist/map/providers/MapboxProvider.svelte +0 -38
  63. package/dist/map/providers/MapboxProvider.svelte.d.ts +0 -9
  64. package/dist/map/providers/providerHelpers.d.ts +0 -17
  65. package/dist/map/providers/providerHelpers.js +0 -26
  66. package/dist/map/stores/cellDataStore.d.ts +0 -21
  67. package/dist/map/stores/cellDataStore.js +0 -53
  68. package/dist/map/stores/interactions.d.ts +0 -20
  69. package/dist/map/stores/interactions.js +0 -33
  70. package/dist/map/types.d.ts +0 -115
  71. package/dist/map/types.js +0 -10
  72. package/dist/map/utils/geojson.d.ts +0 -20
  73. package/dist/map/utils/geojson.js +0 -78
  74. package/dist/map/utils/math.d.ts +0 -40
  75. package/dist/map/utils/math.js +0 -95
  76. package/dist/map/utils/siteTreeUtils.d.ts +0 -27
  77. /package/dist/{map → map-v2/shared}/controls/MapControl.svelte.d.ts +0 -0
  78. /package/dist/{map → map-v2/shared}/utils/mapboxHelpers.d.ts +0 -0
  79. /package/dist/{map → map-v2/shared}/utils/mapboxHelpers.js +0 -0
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export * from './core/index.js';
2
- export * from './map/index.js';
2
+ export * from './map-v2/index.js';
3
3
  export * from './apps/index.js';
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // This approach keeps the main index clean and allows for easy expansion
3
3
  // Core components (Desktop orchestration + Charts + TreeView)
4
4
  export * from './core/index.js';
5
- // Map components (Mapbox cellular visualization)
6
- export * from './map/index.js';
5
+ // Map components (Mapbox cellular visualization - v2)
6
+ export * from './map-v2/index.js';
7
7
  // Complete applications
8
8
  export * from './apps/index.js';
@@ -0,0 +1,289 @@
1
+ <script lang="ts">
2
+ /**
3
+ * MapStyleControl - Control for switching map styles
4
+ *
5
+ * Self-contained control that displays available map styles and allows switching.
6
+ * Persists selection to localStorage.
7
+ *
8
+ * Usage:
9
+ * <MapStyleControl position="top-right" namespace="my-app" />
10
+ */
11
+ import { onMount } from 'svelte';
12
+ import type mapboxgl from 'mapbox-gl';
13
+ import MapControl from '../../shared/controls/MapControl.svelte';
14
+ import { useMapbox } from '../hooks/useMapbox';
15
+
16
+ interface MapStyle {
17
+ id: string;
18
+ name: string;
19
+ url: string;
20
+ description?: string;
21
+ icon?: string;
22
+ }
23
+
24
+ const DEFAULT_STYLES: MapStyle[] = [
25
+ {
26
+ id: 'streets',
27
+ name: 'Streets',
28
+ url: 'mapbox://styles/mapbox/streets-v12',
29
+ description: 'General purpose street map',
30
+ icon: 'map'
31
+ },
32
+ {
33
+ id: 'outdoors',
34
+ name: 'Outdoors',
35
+ url: 'mapbox://styles/mapbox/outdoors-v12',
36
+ description: 'Hiking, biking, and terrain',
37
+ icon: 'tree'
38
+ },
39
+ {
40
+ id: 'light',
41
+ name: 'Light',
42
+ url: 'mapbox://styles/mapbox/light-v11',
43
+ description: 'Minimal light background',
44
+ icon: 'sun'
45
+ },
46
+ {
47
+ id: 'dark',
48
+ name: 'Dark',
49
+ url: 'mapbox://styles/mapbox/dark-v11',
50
+ description: 'Minimal dark background',
51
+ icon: 'moon-stars'
52
+ },
53
+ {
54
+ id: 'satellite',
55
+ name: 'Satellite',
56
+ url: 'mapbox://styles/mapbox/satellite-v9',
57
+ description: 'Satellite imagery',
58
+ icon: 'globe'
59
+ },
60
+ {
61
+ id: 'satellite-streets',
62
+ name: 'Satellite Streets',
63
+ url: 'mapbox://styles/mapbox/satellite-streets-v12',
64
+ description: 'Satellite with street overlay',
65
+ icon: 'globe-americas'
66
+ },
67
+ // {
68
+ // id: 'navigation-day',
69
+ // name: 'Navigation Day',
70
+ // url: 'mapbox://styles/mapbox/navigation-day-v1',
71
+ // description: 'Optimized for navigation',
72
+ // icon: 'compass'
73
+ // },
74
+ // {
75
+ // id: 'navigation-night',
76
+ // name: 'Navigation Night',
77
+ // url: 'mapbox://styles/mapbox/navigation-night-v1',
78
+ // description: 'Night mode navigation',
79
+ // icon: 'moon'
80
+ // }
81
+ ];
82
+
83
+ interface Props {
84
+ /** Control position on map */
85
+ position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
86
+ /** Control title */
87
+ title?: string;
88
+ /** Initially collapsed? */
89
+ initiallyCollapsed?: boolean;
90
+ /** Storage namespace for persistence */
91
+ namespace?: string;
92
+ /** Custom available styles (default: built-in Mapbox styles) */
93
+ availableStyles?: MapStyle[];
94
+ /** Default style ID */
95
+ defaultStyleId?: string;
96
+ }
97
+
98
+ let {
99
+ position = 'top-right',
100
+ title = 'Map Style',
101
+ initiallyCollapsed = false,
102
+ namespace = 'map',
103
+ availableStyles = DEFAULT_STYLES,
104
+ defaultStyleId = 'streets'
105
+ }: Props = $props();
106
+
107
+ const mapStore = useMapbox();
108
+ let map: mapboxgl.Map | null = null;
109
+ const storageKey = `${namespace}:mapStyle`;
110
+
111
+ // Load persisted style or use default
112
+ const loadPersistedStyle = (): MapStyle => {
113
+ if (typeof window === 'undefined') {
114
+ return availableStyles.find(s => s.id === defaultStyleId) || availableStyles[0];
115
+ }
116
+
117
+ try {
118
+ const stored = localStorage.getItem(storageKey);
119
+ if (stored) {
120
+ const styleId = JSON.parse(stored);
121
+ const style = availableStyles.find(s => s.id === styleId);
122
+ if (style) return style;
123
+ }
124
+ } catch (e) {
125
+ console.warn('Failed to load persisted map style:', e);
126
+ }
127
+
128
+ return availableStyles.find(s => s.id === defaultStyleId) || availableStyles[0];
129
+ };
130
+
131
+ let currentStyle = $state<MapStyle>(loadPersistedStyle());
132
+
133
+ onMount(() => {
134
+ const unsub = mapStore.subscribe((m: mapboxgl.Map | null) => {
135
+ if (!m) return;
136
+ map = m;
137
+
138
+ // Apply persisted style when map becomes available if it differs
139
+ // Check if current map style URL matches our persisted style
140
+ if (currentStyle) {
141
+ const mapStyle = map.getStyle();
142
+ // Compare the style URL/source, not the name
143
+ // mapStyle.sprite contains the base URL we can check against
144
+ const currentMapStyleUrl = mapStyle?.sprite || '';
145
+ const needsStyleChange = !currentMapStyleUrl.includes(currentStyle.id);
146
+
147
+ if (needsStyleChange) {
148
+ console.log('Applying persisted style:', currentStyle.id);
149
+ map.setStyle(currentStyle.url);
150
+ }
151
+ }
152
+ });
153
+ return unsub;
154
+ });
155
+
156
+ function handleStyleChange(styleId: string): void {
157
+ const style = availableStyles.find(s => s.id === styleId);
158
+ if (!style) {
159
+ console.warn(`Style with id "${styleId}" not found`);
160
+ return;
161
+ }
162
+
163
+ // Update local state
164
+ currentStyle = style;
165
+
166
+ // Persist to localStorage
167
+ if (typeof window !== 'undefined') {
168
+ try {
169
+ localStorage.setItem(storageKey, JSON.stringify(styleId));
170
+ } catch (e) {
171
+ console.warn('Failed to persist map style:', e);
172
+ }
173
+ }
174
+
175
+ // Update map directly
176
+ if (map) {
177
+ map.setStyle(style.url);
178
+ }
179
+ }
180
+ </script>
181
+
182
+ <MapControl {position} {title} collapsible={true} {initiallyCollapsed}>
183
+ <div class="map-style-controls">
184
+ <div class="style-grid">
185
+ {#each availableStyles as style (style.id)}
186
+ <button
187
+ class="style-option"
188
+ class:active={currentStyle.id === style.id}
189
+ onclick={() => handleStyleChange(style.id)}
190
+ title={style.description}
191
+ >
192
+ <i class="bi bi-{style.icon || 'map'}"></i>
193
+ <!-- {#if currentStyle.id === style.id}
194
+ <div class="style-checkmark">
195
+ <i class="bi bi-check-circle-fill"></i>
196
+ </div>
197
+ {/if} -->
198
+ </button>
199
+ {/each}
200
+ </div>
201
+
202
+ {#if currentStyle.description}
203
+ <div class="current-style-info">
204
+ <small class="text-muted">
205
+ <i class="bi bi-info-circle"></i>
206
+ {currentStyle.description}
207
+ </small>
208
+ </div>
209
+ {/if}
210
+ </div>
211
+ </MapControl>
212
+
213
+ <style>
214
+ .map-style-controls {
215
+ min-width: 240px;
216
+ }
217
+
218
+ .style-grid {
219
+ display: grid;
220
+ grid-template-columns: repeat(2, 1fr);
221
+ gap: 4px;
222
+ margin-bottom: 8px;
223
+ }
224
+
225
+ .style-option {
226
+ position: relative;
227
+ display: flex;
228
+ align-items: center;
229
+ justify-content: center;
230
+ padding: 8px;
231
+ border: 2px solid #ddd;
232
+ border-radius: 6px;
233
+ background: white;
234
+ cursor: pointer;
235
+ transition: all 0.2s;
236
+ font-size: 24px;
237
+ color: #6c757d;
238
+ }
239
+
240
+ .style-option:hover {
241
+ border-color: #0d6efd;
242
+ box-shadow: 0 2px 8px rgba(13, 110, 253, 0.2);
243
+ transform: translateY(-1px);
244
+ }
245
+
246
+ .style-option.active {
247
+ border-color: #0d6efd;
248
+ background: #e7f1ff;
249
+ color: #0d6efd;
250
+ }
251
+
252
+ .style-name {
253
+ font-size: 12px;
254
+ font-weight: 500;
255
+ text-align: center;
256
+ color: #333;
257
+ }
258
+
259
+ .style-option.active .style-name {
260
+ color: #0d6efd;
261
+ font-weight: 600;
262
+ }
263
+
264
+ .style-checkmark {
265
+ position: absolute;
266
+ top: 4px;
267
+ right: 4px;
268
+ color: #0d6efd;
269
+ font-size: 18px;
270
+ background: white;
271
+ border-radius: 50%;
272
+ line-height: 1;
273
+ }
274
+
275
+ .current-style-info {
276
+ padding: 8px;
277
+ background: #f8f9fa;
278
+ border-radius: 4px;
279
+ text-align: center;
280
+ }
281
+
282
+ .current-style-info small {
283
+ display: flex;
284
+ align-items: center;
285
+ justify-content: center;
286
+ gap: 4px;
287
+ font-size: 11px;
288
+ }
289
+ </style>
@@ -0,0 +1,24 @@
1
+ interface MapStyle {
2
+ id: string;
3
+ name: string;
4
+ url: string;
5
+ description?: string;
6
+ icon?: string;
7
+ }
8
+ interface Props {
9
+ /** Control position on map */
10
+ position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
11
+ /** Control title */
12
+ title?: string;
13
+ /** Initially collapsed? */
14
+ initiallyCollapsed?: boolean;
15
+ /** Storage namespace for persistence */
16
+ namespace?: string;
17
+ /** Custom available styles (default: built-in Mapbox styles) */
18
+ availableStyles?: MapStyle[];
19
+ /** Default style ID */
20
+ defaultStyleId?: string;
21
+ }
22
+ declare const MapStyleControl: import("svelte").Component<Props, {}, "">;
23
+ type MapStyleControl = ReturnType<typeof MapStyleControl>;
24
+ export default MapStyleControl;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Hook to safely access the Mapbox instance from context
2
+ * Hook to access the Mapbox instance from context
3
3
  */
4
4
  import type { MapStore } from '../types';
5
5
  /**
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Hook to safely access the Mapbox instance from context
2
+ * Hook to access the Mapbox instance from context
3
3
  */
4
4
  import { getContext } from 'svelte';
5
5
  import { MAP_CONTEXT_KEY } from '../types';
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Core Infrastructure - Public API
3
+ *
4
+ * Exports core map types, providers, stores, and hooks
5
+ */
6
+ export type { MapStore } from './types';
7
+ export { MAP_CONTEXT_KEY } from './types';
8
+ export { default as MapboxProvider } from './providers/MapboxProvider.svelte';
9
+ export { default as MapStyleControl } from './controls/MapStyleControl.svelte';
10
+ export { createMapStore } from './stores/mapStore';
11
+ export { useMapbox, tryUseMapbox } from './hooks/useMapbox';
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Core Infrastructure - Public API
3
+ *
4
+ * Exports core map types, providers, stores, and hooks
5
+ */
6
+ export { MAP_CONTEXT_KEY } from './types';
7
+ // Providers
8
+ export { default as MapboxProvider } from './providers/MapboxProvider.svelte';
9
+ // Controls
10
+ export { default as MapStyleControl } from './controls/MapStyleControl.svelte';
11
+ // Stores
12
+ export { createMapStore } from './stores/mapStore';
13
+ // Hooks
14
+ export { useMapbox, tryUseMapbox } from './hooks/useMapbox';
@@ -0,0 +1,140 @@
1
+ <script lang="ts">
2
+ /**
3
+ * MapboxProvider - Initializes and provides Mapbox GL JS map instance to child components
4
+ *
5
+ * Handles complete map lifecycle:
6
+ * - Map initialization with configuration
7
+ * - Style loading
8
+ * - Optional built-in controls (navigation, scale, etc.)
9
+ * - Context distribution to child components
10
+ * - Cleanup on unmount
11
+ */
12
+ import { setContext, onMount, onDestroy } from 'svelte';
13
+ import mapboxgl, { type Map as MapboxMap, type StyleSpecification } from 'mapbox-gl';
14
+ import { MAP_CONTEXT_KEY } from '../types';
15
+ import { createMapStore } from '../stores/mapStore';
16
+ import 'mapbox-gl/dist/mapbox-gl.css';
17
+
18
+ interface Props {
19
+ /** Mapbox access token */
20
+ accessToken: string;
21
+ /** Map style URL or style object (default: streets-v12) */
22
+ style?: string | StyleSpecification;
23
+ /** Initial map center [lng, lat] */
24
+ center?: [number, number];
25
+ /** Initial zoom level */
26
+ zoom?: number;
27
+ /** Initial bearing (rotation) */
28
+ bearing?: number;
29
+ /** Initial pitch (tilt) */
30
+ pitch?: number;
31
+ /** Minimum zoom level */
32
+ minZoom?: number;
33
+ /** Maximum zoom level */
34
+ maxZoom?: number;
35
+ /** Built-in controls to add */
36
+ controls?: Array<'navigation' | 'scale' | 'fullscreen' | 'geolocate'>;
37
+ /** Position for navigation control */
38
+ navigationPosition?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
39
+ /** Position for scale control */
40
+ scalePosition?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
41
+ /** Custom CSS class for container */
42
+ class?: string;
43
+ /** Optional child content (layers, controls, etc.) */
44
+ children?: import('svelte').Snippet;
45
+ }
46
+
47
+ let {
48
+ accessToken,
49
+ style = 'mapbox://styles/mapbox/streets-v12',
50
+ center = [0, 0],
51
+ zoom = 2,
52
+ bearing = 0,
53
+ pitch = 0,
54
+ minZoom,
55
+ maxZoom,
56
+ controls = [],
57
+ navigationPosition = 'top-right',
58
+ scalePosition = 'bottom-left',
59
+ class: className = '',
60
+ children
61
+ }: Props = $props();
62
+
63
+ // Create and set the map store in context
64
+ const mapStore = createMapStore();
65
+ setContext(MAP_CONTEXT_KEY, mapStore);
66
+
67
+ let mapContainer: HTMLDivElement;
68
+ let map: MapboxMap | null = null;
69
+
70
+ onMount(() => {
71
+ // Set access token
72
+ mapboxgl.accessToken = accessToken;
73
+
74
+ // Initialize map
75
+ map = new mapboxgl.Map({
76
+ container: mapContainer,
77
+ style,
78
+ center,
79
+ zoom,
80
+ bearing,
81
+ pitch,
82
+ minZoom,
83
+ maxZoom
84
+ });
85
+
86
+ // Add built-in controls
87
+ if (controls.includes('navigation')) {
88
+ map.addControl(new mapboxgl.NavigationControl(), navigationPosition);
89
+ }
90
+ if (controls.includes('scale')) {
91
+ map.addControl(new mapboxgl.ScaleControl(), scalePosition);
92
+ }
93
+ if (controls.includes('fullscreen')) {
94
+ map.addControl(new mapboxgl.FullscreenControl());
95
+ }
96
+ if (controls.includes('geolocate')) {
97
+ map.addControl(
98
+ new mapboxgl.GeolocateControl({
99
+ positionOptions: {
100
+ enableHighAccuracy: true
101
+ },
102
+ trackUserLocation: true
103
+ })
104
+ );
105
+ }
106
+
107
+ // Wait for style to load before distributing map
108
+ const onStyleLoad = () => {
109
+ mapStore.set(map);
110
+ };
111
+
112
+ if (map.isStyleLoaded()) {
113
+ mapStore.set(map);
114
+ } else {
115
+ map.once('style.load', onStyleLoad);
116
+ }
117
+ });
118
+
119
+ onDestroy(() => {
120
+ if (map) {
121
+ map.remove();
122
+ map = null;
123
+ }
124
+ mapStore.set(null);
125
+ });
126
+ </script>
127
+
128
+ <div bind:this={mapContainer} class="mapbox-container {className}"></div>
129
+
130
+ {#if children}
131
+ {@render children()}
132
+ {/if}
133
+
134
+ <style>
135
+ .mapbox-container {
136
+ width: 100%;
137
+ height: 100%;
138
+ position: relative;
139
+ }
140
+ </style>
@@ -0,0 +1,33 @@
1
+ import { type StyleSpecification } from 'mapbox-gl';
2
+ import 'mapbox-gl/dist/mapbox-gl.css';
3
+ interface Props {
4
+ /** Mapbox access token */
5
+ accessToken: string;
6
+ /** Map style URL or style object (default: streets-v12) */
7
+ style?: string | StyleSpecification;
8
+ /** Initial map center [lng, lat] */
9
+ center?: [number, number];
10
+ /** Initial zoom level */
11
+ zoom?: number;
12
+ /** Initial bearing (rotation) */
13
+ bearing?: number;
14
+ /** Initial pitch (tilt) */
15
+ pitch?: number;
16
+ /** Minimum zoom level */
17
+ minZoom?: number;
18
+ /** Maximum zoom level */
19
+ maxZoom?: number;
20
+ /** Built-in controls to add */
21
+ controls?: Array<'navigation' | 'scale' | 'fullscreen' | 'geolocate'>;
22
+ /** Position for navigation control */
23
+ navigationPosition?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
24
+ /** Position for scale control */
25
+ scalePosition?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
26
+ /** Custom CSS class for container */
27
+ class?: string;
28
+ /** Optional child content (layers, controls, etc.) */
29
+ children?: import('svelte').Snippet;
30
+ }
31
+ declare const MapboxProvider: import("svelte").Component<Props, {}, "">;
32
+ type MapboxProvider = ReturnType<typeof MapboxProvider>;
33
+ export default MapboxProvider;
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Store factory and utilities for Mapbox instance
2
+ * Map store - Writable store for Mapbox map instance
3
3
  */
4
4
  import type { MapStore } from '../types';
5
5
  /**
6
- * Creates a writable store for the Mapbox instance
6
+ * Creates a writable store for the Mapbox map instance
7
7
  */
8
8
  export declare function createMapStore(): MapStore;
@@ -1,9 +1,9 @@
1
1
  /**
2
- * Store factory and utilities for Mapbox instance
2
+ * Map store - Writable store for Mapbox map instance
3
3
  */
4
4
  import { writable } from 'svelte/store';
5
5
  /**
6
- * Creates a writable store for the Mapbox instance
6
+ * Creates a writable store for the Mapbox map instance
7
7
  */
8
8
  export function createMapStore() {
9
9
  return writable(null);
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Core map types
3
+ */
4
+ import type { Map as MapboxMap } from 'mapbox-gl';
5
+ import type { Writable } from 'svelte/store';
6
+ /**
7
+ * Map store type - writable store containing the Mapbox instance
8
+ */
9
+ export type MapStore = Writable<MapboxMap | null>;
10
+ /**
11
+ * Context key for MapboxProvider
12
+ */
13
+ export declare const MAP_CONTEXT_KEY: unique symbol;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Core map types
3
+ */
4
+ /**
5
+ * Context key for MapboxProvider
6
+ */
7
+ export const MAP_CONTEXT_KEY = Symbol('mapbox-context');
@@ -0,0 +1,63 @@
1
+ <script lang="ts">
2
+ /**
3
+ * DemoMap - Complete demo of map-v2 site feature
4
+ *
5
+ * Demonstrates:
6
+ * - Simplified MapboxProvider with automatic initialization
7
+ * - Dynamic map style switching with persistence
8
+ * - SitesLayer rendering sites from store
9
+ * - SiteFilterControl for hierarchical filtering
10
+ * - SiteSizeSlider for visual property adjustment
11
+ */
12
+ import MapboxProvider from '../core/providers/MapboxProvider.svelte';
13
+ import MapStyleControl from '../core/controls/MapStyleControl.svelte';
14
+ import SitesLayer from '../features/sites/layers/SitesLayer.svelte';
15
+ import SiteFilterControl from '../features/sites/controls/SiteFilterControl.svelte';
16
+ import SiteSizeSlider from '../features/sites/controls/SiteSizeSlider.svelte';
17
+ import { createSiteStoreContext } from '../features/sites/stores/siteStoreContext.svelte';
18
+ import { demoSites } from './demo-data';
19
+
20
+ interface Props {
21
+ /** Mapbox access token */
22
+ accessToken: string;
23
+ /** Initial map center [lng, lat] (default: San Francisco) */
24
+ center?: [number, number];
25
+ /** Initial zoom level (default: 12) */
26
+ zoom?: number;
27
+ }
28
+
29
+ let {
30
+ accessToken,
31
+ center = [-122.4194, 37.7749],
32
+ zoom = 12
33
+ }: Props = $props();
34
+
35
+ // Create site store with demo data
36
+ const siteStore = createSiteStoreContext(demoSites);
37
+
38
+ </script>
39
+
40
+ <!-- // controls={['navigation', 'scale']} -->
41
+ <div class="demo-map-container">
42
+ <MapboxProvider {accessToken} {center} {zoom}>
43
+ <!-- Site layer - renders circles from store -->
44
+ <SitesLayer store={siteStore} namespace="demo-sites" />
45
+
46
+ <!-- Map style control - switch between map styles -->
47
+ <MapStyleControl position="top-right" initiallyCollapsed={true} namespace="demo-map" />
48
+
49
+ <!-- Site filter control - updates store.filteredSites -->
50
+ <SiteFilterControl store={siteStore} position="top-left" title="Site Filter" />
51
+
52
+ <!-- Site size control - updates store visual properties -->
53
+ <SiteSizeSlider store={siteStore} position="bottom-right" title="Site Display" />
54
+ </MapboxProvider>
55
+ </div>
56
+
57
+ <style>
58
+ .demo-map-container {
59
+ position: relative;
60
+ width: 100%;
61
+ height: 100%;
62
+ }
63
+ </style>
@@ -1,10 +1,9 @@
1
- import 'mapbox-gl/dist/mapbox-gl.css';
2
1
  interface Props {
3
2
  /** Mapbox access token */
4
- accessToken?: string;
5
- /** Initial center coordinates [lng, lat] */
3
+ accessToken: string;
4
+ /** Initial map center [lng, lat] (default: San Francisco) */
6
5
  center?: [number, number];
7
- /** Initial zoom level */
6
+ /** Initial zoom level (default: 12) */
8
7
  zoom?: number;
9
8
  }
10
9
  declare const DemoMap: import("svelte").Component<Props, {}, "">;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Demo cellular data for testing map-v2 site feature
3
+ */
4
+ import type { Site } from '../features/sites/types';
5
+ /**
6
+ * Sample cellular sites (San Francisco area)
7
+ */
8
+ export declare const demoSites: Site[];