map-gl-style-switcher 0.7.5 → 0.9.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.
- package/README.md +84 -522
- package/dist/index-CsaOV7jZ.d.ts +52 -0
- package/dist/index.d.ts +1 -117
- package/dist/index.js +1 -53
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +4 -55
- package/dist/index.umd.js.map +1 -1
- package/dist/react-map-gl.d.ts +68 -0
- package/dist/react-map-gl.js +55 -0
- package/dist/react-map-gl.js.map +1 -0
- package/dist/react.d.ts +52 -0
- package/dist/react.js +67 -0
- package/dist/react.js.map +1 -0
- package/package.json +20 -2
package/README.md
CHANGED
|
@@ -13,14 +13,17 @@ A TypeScript control for switching Mapbox GL / MapLibre GL map styles. Easily ad
|
|
|
13
13
|
|
|
14
14
|
- `StyleSwitcherControl` - Direct IControl implementation for Mapbox/MapLibre GL
|
|
15
15
|
- `MapGLStyleSwitcher` - React component for react-map-gl integration
|
|
16
|
+
_Live demo of the style switcher control in action_
|
|
16
17
|
|
|
17
18
|
**<a href="https://map-gl-style-switcher.netlify.app/" target="_blank">🌐 Live Demo</a>**
|
|
18
19
|
|
|
19
|
-
## Demo
|
|
20
|
+
## Animated Demo
|
|
20
21
|
|
|
21
22
|

|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
## Available Styles
|
|
25
|
+
|
|
26
|
+

|
|
24
27
|
|
|
25
28
|
## Features
|
|
26
29
|
|
|
@@ -33,7 +36,7 @@ _Live demo of the style switcher control in action_
|
|
|
33
36
|
- RTL text support for Arabic scripts
|
|
34
37
|
- Configurable display options (show/hide labels and images)
|
|
35
38
|
- Callbacks for before/after style change
|
|
36
|
-
- Fully customizable CSS
|
|
39
|
+
- Fully customizable CSS classe's
|
|
37
40
|
- TypeScript support
|
|
38
41
|
- Accessibility features (ARIA labels, keyboard navigation)
|
|
39
42
|
- Comprehensive test coverage
|
|
@@ -51,166 +54,49 @@ yarn add map-gl-style-switcher
|
|
|
51
54
|
pnpm add map-gl-style-switcher
|
|
52
55
|
```
|
|
53
56
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
For quick prototyping or when you don't want to use a build system, you can include the package directly from a CDN:
|
|
57
|
-
|
|
58
|
-
### unpkg CDN
|
|
59
|
-
|
|
60
|
-
```html
|
|
61
|
-
<!DOCTYPE html>
|
|
62
|
-
<html>
|
|
63
|
-
<head>
|
|
64
|
-
<!-- MapLibre GL CSS -->
|
|
65
|
-
<link href="https://unpkg.com/maplibre-gl@4/dist/maplibre-gl.css" rel="stylesheet" />
|
|
66
|
-
|
|
67
|
-
<!-- Style Switcher CSS -->
|
|
68
|
-
<link rel="stylesheet" href="https://unpkg.com/map-gl-style-switcher@latest/dist/map-gl-style-switcher.css">
|
|
69
|
-
</head>
|
|
70
|
-
<body>
|
|
71
|
-
<div id="map" style="width: 100%; height: 100vh;"></div>
|
|
72
|
-
|
|
73
|
-
<!-- MapLibre GL JS -->
|
|
74
|
-
<script src="https://unpkg.com/maplibre-gl@4/dist/maplibre-gl.js"></script>
|
|
75
|
-
|
|
76
|
-
<!-- Style Switcher UMD -->
|
|
77
|
-
<script src="https://unpkg.com/map-gl-style-switcher@latest/dist/index.umd.js"></script>
|
|
78
|
-
|
|
79
|
-
<script>
|
|
80
|
-
// StyleSwitcherControl is available globally as MapGLStyleSwitcher.StyleSwitcherControl
|
|
81
|
-
const { StyleSwitcherControl } = MapGLStyleSwitcher;
|
|
82
|
-
|
|
83
|
-
const styles = [
|
|
84
|
-
{
|
|
85
|
-
id: 'voyager',
|
|
86
|
-
name: 'Voyager',
|
|
87
|
-
image: 'https://unpkg.com/map-gl-style-switcher@latest/public/voyager.png',
|
|
88
|
-
styleUrl: 'https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json',
|
|
89
|
-
description: 'Voyager style from Carto',
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
id: 'positron',
|
|
93
|
-
name: 'Positron',
|
|
94
|
-
image: 'https://unpkg.com/map-gl-style-switcher@latest/public/positron.png',
|
|
95
|
-
styleUrl: 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json',
|
|
96
|
-
description: 'Positron style from Carto',
|
|
97
|
-
}
|
|
98
|
-
];
|
|
99
|
-
|
|
100
|
-
const map = new maplibregl.Map({
|
|
101
|
-
container: 'map',
|
|
102
|
-
style: styles[0].styleUrl,
|
|
103
|
-
center: [0, 0],
|
|
104
|
-
zoom: 2
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
const styleSwitcher = new StyleSwitcherControl({
|
|
108
|
-
styles: styles,
|
|
109
|
-
theme: 'auto',
|
|
110
|
-
activeStyleId: styles[0].id,
|
|
111
|
-
onAfterStyleChange: (from, to) => {
|
|
112
|
-
map.setStyle(to.styleUrl);
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
map.addControl(styleSwitcher, 'bottom-left');
|
|
117
|
-
</script>
|
|
118
|
-
</body>
|
|
119
|
-
</html>
|
|
120
|
-
```
|
|
57
|
+
### Basic Map Instance
|
|
121
58
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
```html
|
|
125
|
-
<!DOCTYPE html>
|
|
126
|
-
<html>
|
|
127
|
-
<head>
|
|
128
|
-
<!-- MapLibre GL CSS -->
|
|
129
|
-
<link href="https://cdn.jsdelivr.net/npm/maplibre-gl@4/dist/maplibre-gl.css" rel="stylesheet" />
|
|
130
|
-
|
|
131
|
-
<!-- Style Switcher CSS -->
|
|
132
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/map-gl-style-switcher@latest/dist/map-gl-style-switcher.css">
|
|
133
|
-
</head>
|
|
134
|
-
<body>
|
|
135
|
-
<div id="map" style="width: 100%; height: 100vh;"></div>
|
|
136
|
-
|
|
137
|
-
<!-- MapLibre GL JS -->
|
|
138
|
-
<script src="https://cdn.jsdelivr.net/npm/maplibre-gl@4/dist/maplibre-gl.js"></script>
|
|
139
|
-
|
|
140
|
-
<!-- Style Switcher UMD -->
|
|
141
|
-
<script src="https://cdn.jsdelivr.net/npm/map-gl-style-switcher@latest/dist/index.umd.js"></script>
|
|
142
|
-
|
|
143
|
-
<script>
|
|
144
|
-
// Same JavaScript code as above
|
|
145
|
-
const { StyleSwitcherControl } = MapGLStyleSwitcher;
|
|
146
|
-
// ... rest of the code
|
|
147
|
-
</script>
|
|
148
|
-
</body>
|
|
149
|
-
</html>
|
|
150
|
-
```
|
|
59
|
+
For React applications where you manage the map instance yourself (e.g., with `useEffect`), use the `useStyleSwitcher` hook:
|
|
151
60
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
// Your code here
|
|
161
|
-
const styleSwitcher = new StyleSwitcherControl({
|
|
162
|
-
styles: styles,
|
|
163
|
-
theme: 'auto'
|
|
164
|
-
});
|
|
165
|
-
</script>
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
### Specific Version
|
|
169
|
-
|
|
170
|
-
To use a specific version instead of `@latest`:
|
|
171
|
-
|
|
172
|
-
```html
|
|
173
|
-
<!-- Replace @latest with specific version, e.g., @0.7.2 -->
|
|
174
|
-
<link rel="stylesheet" href="https://unpkg.com/map-gl-style-switcher@0.7.2/dist/map-gl-style-switcher.css">
|
|
175
|
-
<script src="https://unpkg.com/map-gl-style-switcher@0.7.2/dist/index.umd.js"></script>
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
## Usage
|
|
179
|
-
|
|
180
|
-
### Basic MapLibre GL Integration
|
|
181
|
-
|
|
182
|
-
```ts
|
|
183
|
-
import maplibregl from 'maplibre-gl';
|
|
184
|
-
import { StyleSwitcherControl } from 'map-gl-style-switcher';
|
|
61
|
+
```tsx
|
|
62
|
+
import React, { useEffect, useRef } from 'react';
|
|
63
|
+
import * as maplibregl from 'maplibre-gl';
|
|
64
|
+
import { StyleSwitcherControl, type StyleItem } from 'map-gl-style-switcher';
|
|
65
|
+
// Custom hook
|
|
66
|
+
// import { useStyleSwitcher } from 'map-gl-style-switcher/react';
|
|
67
|
+
import 'maplibre-gl/dist/maplibre-gl.css';
|
|
185
68
|
import 'map-gl-style-switcher/dist/map-gl-style-switcher.css';
|
|
186
69
|
|
|
187
|
-
|
|
188
|
-
const styles = [
|
|
70
|
+
const mapStyles: StyleItem[] = [
|
|
189
71
|
{
|
|
190
72
|
id: 'voyager',
|
|
191
73
|
name: 'Voyager',
|
|
192
|
-
image:
|
|
74
|
+
image:
|
|
75
|
+
'https://raw.githubusercontent.com/muimsd/map-gl-style-switcher/refs/heads/main/public/voyager.png',
|
|
193
76
|
styleUrl: 'https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json',
|
|
194
77
|
description: 'Voyager style from Carto',
|
|
195
78
|
},
|
|
196
79
|
{
|
|
197
80
|
id: 'positron',
|
|
198
81
|
name: 'Positron',
|
|
199
|
-
image:
|
|
82
|
+
image:
|
|
83
|
+
'https://raw.githubusercontent.com/muimsd/map-gl-style-switcher/refs/heads/main/public/positron.png',
|
|
200
84
|
styleUrl: 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json',
|
|
201
85
|
description: 'Positron style from Carto',
|
|
202
86
|
},
|
|
203
87
|
{
|
|
204
88
|
id: 'dark-matter',
|
|
205
89
|
name: 'Dark Matter',
|
|
206
|
-
image:
|
|
90
|
+
image:
|
|
91
|
+
'https://raw.githubusercontent.com/muimsd/map-gl-style-switcher/refs/heads/main/public/dark.png',
|
|
207
92
|
styleUrl: 'https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json',
|
|
208
93
|
description: 'Dark style from Carto',
|
|
209
94
|
},
|
|
210
95
|
{
|
|
211
96
|
id: 'arcgis-hybrid',
|
|
212
97
|
name: 'ArcGIS Hybrid',
|
|
213
|
-
image:
|
|
98
|
+
image:
|
|
99
|
+
'https://raw.githubusercontent.com/muimsd/map-gl-style-switcher/refs/heads/main/public/arcgis-hybrid.png',
|
|
214
100
|
styleUrl:
|
|
215
101
|
'https://raw.githubusercontent.com/go2garret/maps/main/src/assets/json/arcgis_hybrid.json',
|
|
216
102
|
description: 'Hybrid Satellite style from ESRI',
|
|
@@ -218,301 +104,88 @@ const styles = [
|
|
|
218
104
|
{
|
|
219
105
|
id: 'osm',
|
|
220
106
|
name: 'OSM',
|
|
221
|
-
image:
|
|
107
|
+
image:
|
|
108
|
+
'https://raw.githubusercontent.com/muimsd/map-gl-style-switcher/refs/heads/main/public/osm.png',
|
|
222
109
|
styleUrl:
|
|
223
110
|
'https://raw.githubusercontent.com/go2garret/maps/main/src/assets/json/openStreetMap.json',
|
|
224
111
|
description: 'OSM style',
|
|
225
112
|
},
|
|
226
113
|
];
|
|
227
|
-
const defaultStyle = styles[0];
|
|
228
|
-
// Create map
|
|
229
|
-
const map = new maplibregl.Map({
|
|
230
|
-
container: 'map',
|
|
231
|
-
style: defaultStyle.styleUrl,
|
|
232
|
-
center: [0, 0],
|
|
233
|
-
zoom: 2,
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
// Add style switcher control
|
|
237
|
-
const styleSwitcher = new StyleSwitcherControl({
|
|
238
|
-
styles: styles,
|
|
239
|
-
theme: 'light', // 'light', 'dark', or 'auto'
|
|
240
|
-
showLabels: true,
|
|
241
|
-
showImages: true,
|
|
242
|
-
activeStyleId: defaultStyle.id,
|
|
243
|
-
onBeforeStyleChange: (from, to) => {
|
|
244
|
-
console.log(`Switching from ${from.name} to ${to.name}`);
|
|
245
|
-
},
|
|
246
|
-
onAfterStyleChange: (from, to) => {
|
|
247
|
-
map.setStyle(to.styleUrl);
|
|
248
|
-
},
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
map.addControl(styleSwitcher, 'bottom-left');
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
### React Integration with react-map-gl
|
|
255
114
|
|
|
256
|
-
|
|
115
|
+
export default function App() {
|
|
116
|
+
const mapContainer = useRef<HTMLDivElement | null>(null)
|
|
257
117
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
118
|
+
useEffect(() => {
|
|
119
|
+
if (!mapContainer.current) {
|
|
120
|
+
console.error('Map container not found!');
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const currentStyle = mapStyles[0];
|
|
124
|
+
const map = new maplibregl.Map({
|
|
125
|
+
container: mapContainer.current,
|
|
126
|
+
// Use a simple, reliable style first
|
|
127
|
+
style: currentStyle.styleUrl,
|
|
128
|
+
// Center on Dubai, UAE
|
|
129
|
+
center: [55.2708, 25.2048],
|
|
130
|
+
zoom: 10,
|
|
131
|
+
});
|
|
263
132
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
id: 'dark-matter',
|
|
281
|
-
name: 'Dark Matter',
|
|
282
|
-
image: './dark.png',
|
|
283
|
-
styleUrl: 'https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json',
|
|
284
|
-
description: 'Dark style from Carto',
|
|
285
|
-
},
|
|
286
|
-
{
|
|
287
|
-
id: 'arcgis-hybrid',
|
|
288
|
-
name: 'ArcGIS Hybrid',
|
|
289
|
-
image: './arcgis-hybrid.png',
|
|
290
|
-
styleUrl:
|
|
291
|
-
'https://raw.githubusercontent.com/go2garret/maps/main/src/assets/json/arcgis_hybrid.json',
|
|
292
|
-
description: 'Hybrid Satellite style from ESRI',
|
|
293
|
-
},
|
|
294
|
-
{
|
|
295
|
-
id: 'osm',
|
|
296
|
-
name: 'OSM',
|
|
297
|
-
image: './osm.png',
|
|
298
|
-
styleUrl:
|
|
299
|
-
'https://raw.githubusercontent.com/go2garret/maps/main/src/assets/json/openStreetMap.json',
|
|
300
|
-
description: 'OSM style',
|
|
301
|
-
},
|
|
302
|
-
];
|
|
133
|
+
// Add style switcher control
|
|
134
|
+
const styleSwitcher = new StyleSwitcherControl({
|
|
135
|
+
styles: mapStyles,
|
|
136
|
+
theme: 'auto',
|
|
137
|
+
showLabels: true,
|
|
138
|
+
showImages: true,
|
|
139
|
+
activeStyleId: currentStyle.id,
|
|
140
|
+
onBeforeStyleChange: (from, to) => {
|
|
141
|
+
console.log('Changing style from', from.name, 'to', to.name);
|
|
142
|
+
},
|
|
143
|
+
onAfterStyleChange: (_from, to) => {
|
|
144
|
+
map.setStyle(to.styleUrl);
|
|
145
|
+
console.log('Style changed to', to.name);
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
map.addControl(styleSwitcher, 'bottom-left');
|
|
303
149
|
|
|
304
|
-
|
|
305
|
-
|
|
150
|
+
return () => {
|
|
151
|
+
map.remove();
|
|
152
|
+
};
|
|
153
|
+
}, []); // Empty dependency array
|
|
154
|
+
|
|
155
|
+
// Add style switcher control to the map
|
|
156
|
+
// useStyleSwitcher(map.current, {
|
|
157
|
+
// styles,
|
|
158
|
+
// theme: 'auto',
|
|
159
|
+
// position: 'top-right',
|
|
160
|
+
// onAfterStyleChange: (from, to) => {
|
|
161
|
+
// if (map.current) {
|
|
162
|
+
// map.current.setStyle(to.styleUrl);
|
|
163
|
+
// }
|
|
164
|
+
// },
|
|
165
|
+
// });
|
|
306
166
|
|
|
307
167
|
return (
|
|
308
|
-
<
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
zoom: 2,
|
|
168
|
+
<div
|
|
169
|
+
ref={mapContainer}
|
|
170
|
+
style={{
|
|
171
|
+
width: '100%',
|
|
172
|
+
height: '500px',
|
|
314
173
|
}}
|
|
315
|
-
|
|
316
|
-
mapStyle={mapStyle}
|
|
317
|
-
>
|
|
318
|
-
<MapGLStyleSwitcher
|
|
319
|
-
styles={styles}
|
|
320
|
-
activeStyleId={styles[0].id}
|
|
321
|
-
theme="auto"
|
|
322
|
-
showLabels={true}
|
|
323
|
-
showImages={true}
|
|
324
|
-
onStyleChange={setMapStyle}
|
|
325
|
-
position="bottom-left"
|
|
326
|
-
/>
|
|
327
|
-
</Map>
|
|
174
|
+
/>
|
|
328
175
|
);
|
|
329
|
-
};
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
**Installation for React:**
|
|
333
|
-
|
|
334
|
-
```sh
|
|
335
|
-
npm install react-map-gl maplibre-gl map-gl-style-switcher
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
#### MapGLStyleSwitcher Props
|
|
339
|
-
|
|
340
|
-
```tsx
|
|
341
|
-
interface MapGLStyleSwitcherProps {
|
|
342
|
-
styles: StyleItem[]; // Array of map styles (required)
|
|
343
|
-
activeStyleId?: string; // Currently active style ID
|
|
344
|
-
theme?: 'light' | 'dark' | 'auto'; // UI theme (default: 'light')
|
|
345
|
-
showLabels?: boolean; // Show style names (default: true)
|
|
346
|
-
showImages?: boolean; // Show style thumbnails (default: true)
|
|
347
|
-
position?:
|
|
348
|
-
| 'top-left'
|
|
349
|
-
| 'top-right' // Control position (default: 'bottom-left')
|
|
350
|
-
| 'bottom-left'
|
|
351
|
-
| 'bottom-right';
|
|
352
|
-
animationDuration?: number; // Animation duration in ms (default: 200)
|
|
353
|
-
maxHeight?: number; // Max height of expanded list (default: 300)
|
|
354
|
-
rtl?: boolean; // Enable RTL layout (default: false)
|
|
355
|
-
classNames?: Partial<{
|
|
356
|
-
// Custom CSS classes
|
|
357
|
-
container: string;
|
|
358
|
-
list: string;
|
|
359
|
-
item: string;
|
|
360
|
-
itemSelected: string;
|
|
361
|
-
itemHideLabel: string;
|
|
362
|
-
dark: string;
|
|
363
|
-
light: string;
|
|
364
|
-
}>;
|
|
365
|
-
onBeforeStyleChange?: (from: StyleItem, to: StyleItem) => void; // Callback before style change
|
|
366
|
-
onAfterStyleChange?: (from: StyleItem, to: StyleItem) => void; // Callback after style change
|
|
367
|
-
onStyleChange?: (styleUrl: string) => void; // Simplified callback for style URL
|
|
368
176
|
}
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
#### Advanced React Usage
|
|
372
|
-
|
|
373
|
-
For more complex scenarios, you can use both callbacks:
|
|
374
|
-
|
|
375
|
-
```tsx
|
|
376
|
-
const MapComponent = () => {
|
|
377
|
-
const [mapStyle, setMapStyle] = useState(styles[0].styleUrl);
|
|
378
|
-
const [loading, setLoading] = useState(false);
|
|
379
177
|
|
|
380
|
-
const handleBeforeStyleChange = (from: StyleItem, to: StyleItem) => {
|
|
381
|
-
console.log(`Switching from ${from.name} to ${to.name}`);
|
|
382
|
-
setLoading(true);
|
|
383
|
-
};
|
|
384
|
-
|
|
385
|
-
const handleAfterStyleChange = (from: StyleItem, to: StyleItem) => {
|
|
386
|
-
console.log(`Style changed to ${to.name}`);
|
|
387
|
-
setLoading(false);
|
|
388
|
-
};
|
|
389
|
-
|
|
390
|
-
const handleStyleChange = (styleUrl: string) => {
|
|
391
|
-
setMapStyle(styleUrl);
|
|
392
|
-
};
|
|
393
|
-
|
|
394
|
-
return (
|
|
395
|
-
<Map mapStyle={mapStyle} /* ...other props */>
|
|
396
|
-
<MapGLStyleSwitcher
|
|
397
|
-
styles={styles}
|
|
398
|
-
activeStyleId="voyager"
|
|
399
|
-
theme="auto"
|
|
400
|
-
onBeforeStyleChange={handleBeforeStyleChange}
|
|
401
|
-
onAfterStyleChange={handleAfterStyleChange}
|
|
402
|
-
onStyleChange={handleStyleChange}
|
|
403
|
-
position="bottom-left"
|
|
404
|
-
/>
|
|
405
|
-
{loading && <div className="loading-indicator">Switching style...</div>}
|
|
406
|
-
</Map>
|
|
407
|
-
);
|
|
408
|
-
};
|
|
409
178
|
```
|
|
410
179
|
|
|
411
180
|
## Examples
|
|
412
181
|
|
|
413
|
-
### React
|
|
414
|
-
|
|
415
|
-
A complete working example is available in the `examples/react-map-gl` directory:
|
|
416
|
-
|
|
417
|
-
```bash
|
|
418
|
-
cd examples/react-map-gl
|
|
419
|
-
npm install
|
|
420
|
-
npm run dev
|
|
421
|
-
```
|
|
422
|
-
|
|
423
|
-
This example demonstrates:
|
|
424
|
-
|
|
425
|
-
- React 19 with TypeScript and Vite 7
|
|
426
|
-
- MapLibre GL integration with react-map-gl
|
|
427
|
-
- MapGLStyleSwitcher component usage
|
|
428
|
-
- Multiple basemap styles with thumbnails
|
|
429
|
-
- Responsive design with auto theme detection
|
|
430
|
-
- Style switching with smooth transitions
|
|
431
|
-
|
|
432
|
-
[View the complete example →](examples/react-map-gl/)
|
|
433
|
-
|
|
434
|
-
### Vanilla JavaScript Example
|
|
435
|
-
|
|
436
|
-
The main demo at the root level demonstrates vanilla JavaScript usage:
|
|
437
|
-
|
|
438
|
-
```bash
|
|
439
|
-
npm install
|
|
440
|
-
npm run dev
|
|
441
|
-
```
|
|
442
|
-
|
|
443
|
-
This example shows:
|
|
444
|
-
|
|
445
|
-
- Pure TypeScript/JavaScript implementation
|
|
446
|
-
- MapLibre GL integration
|
|
447
|
-
- StyleSwitcherControl direct usage
|
|
448
|
-
- Multiple themes and configuration options
|
|
449
|
-
|
|
450
|
-
## Available Styles
|
|
451
|
-
|
|
452
|
-

|
|
453
|
-
|
|
454
|
-
The style switcher supports various map styles. Here are some popular options you can use:
|
|
455
|
-
|
|
456
|
-
### Carto Basemaps
|
|
457
|
-
|
|
458
|
-
- **Voyager** - A balanced, colorful style perfect for data visualization and general mapping applications
|
|
459
|
-
- **Positron** - A clean, minimal light basemap ideal for overlaying data with maximum contrast
|
|
460
|
-
- **Dark Matter** - A dark theme basemap excellent for creating striking data visualizations and night mode interfaces
|
|
182
|
+
### React Map GL Example
|
|
461
183
|
|
|
462
|
-
|
|
184
|
+
[View the maplibre example →](examples/maplibre/)
|
|
463
185
|
|
|
464
|
-
|
|
465
|
-
- **Satellite** - High-resolution satellite imagery for detailed geographic analysis
|
|
466
|
-
|
|
467
|
-
### OpenStreetMap
|
|
468
|
-
|
|
469
|
-
- **OSM (OpenStreetMap)** - Community-driven open-source mapping with detailed street-level information
|
|
470
|
-
|
|
471
|
-
### Example Styles Configuration
|
|
472
|
-
|
|
473
|
-
```ts
|
|
474
|
-
const styles = [
|
|
475
|
-
{
|
|
476
|
-
id: 'voyager',
|
|
477
|
-
name: 'Voyager',
|
|
478
|
-
image: './voyager.png',
|
|
479
|
-
styleUrl: 'https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json',
|
|
480
|
-
description: 'Voyager style from Carto',
|
|
481
|
-
},
|
|
482
|
-
{
|
|
483
|
-
id: 'positron',
|
|
484
|
-
name: 'Positron',
|
|
485
|
-
image: './positron.png',
|
|
486
|
-
styleUrl: 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json',
|
|
487
|
-
description: 'Positron style from Carto',
|
|
488
|
-
},
|
|
489
|
-
{
|
|
490
|
-
id: 'dark-matter',
|
|
491
|
-
name: 'Dark Matter',
|
|
492
|
-
image: './dark.png',
|
|
493
|
-
styleUrl: 'https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json',
|
|
494
|
-
description: 'Dark style from Carto',
|
|
495
|
-
},
|
|
496
|
-
{
|
|
497
|
-
id: 'arcgis-hybrid',
|
|
498
|
-
name: 'ArcGIS Hybrid',
|
|
499
|
-
image: './arcgis-hybrid.png',
|
|
500
|
-
styleUrl:
|
|
501
|
-
'https://raw.githubusercontent.com/go2garret/maps/main/src/assets/json/arcgis_hybrid.json',
|
|
502
|
-
description: 'Hybrid Satellite style from ESRI',
|
|
503
|
-
},
|
|
504
|
-
{
|
|
505
|
-
id: 'osm',
|
|
506
|
-
name: 'OSM',
|
|
507
|
-
image: './osm.png',
|
|
508
|
-
styleUrl:
|
|
509
|
-
'https://raw.githubusercontent.com/go2garret/maps/main/src/assets/json/openStreetMap.json',
|
|
510
|
-
description: 'OSM style',
|
|
511
|
-
},
|
|
512
|
-
];
|
|
513
|
-
```
|
|
186
|
+
### React Map GL Example
|
|
514
187
|
|
|
515
|
-
|
|
188
|
+
[View the react-map-gl example →](examples/react-map-gl/)
|
|
516
189
|
|
|
517
190
|
## Configuration Options
|
|
518
191
|
|
|
@@ -587,100 +260,6 @@ const styleSwitcher = new StyleSwitcherControl({
|
|
|
587
260
|
|
|
588
261
|
See the default class names in the `StyleSwitcherControl` source for all available keys.
|
|
589
262
|
|
|
590
|
-
## File Structure
|
|
591
|
-
|
|
592
|
-
```
|
|
593
|
-
map-gl-style-switcher/
|
|
594
|
-
├── src/
|
|
595
|
-
│ ├── components/
|
|
596
|
-
│ │ ├── StyleSwitcherControl.ts # Main IControl implementation
|
|
597
|
-
│ │ └── MapGLStyleSwitcher.tsx # React component for react-map-gl
|
|
598
|
-
│ ├── styles/
|
|
599
|
-
│ │ └── style-switcher.css # Control styles (themes, RTL support)
|
|
600
|
-
│ ├── types/
|
|
601
|
-
│ │ ├── index.ts # TypeScript type definitions
|
|
602
|
-
│ │ └── css.d.ts # CSS module declarations
|
|
603
|
-
│ ├── tests/
|
|
604
|
-
│ │ ├── StyleSwitcherControl.test.ts # Core control test suite
|
|
605
|
-
│ │ ├── MapGLStyleSwitcher.test.tsx # React component test suite
|
|
606
|
-
│ │ └── test-setup.ts # Jest test setup
|
|
607
|
-
│ ├── demo/
|
|
608
|
-
│ │ ├── main.tsx # Demo entry point
|
|
609
|
-
│ │ ├── App.tsx # Demo component
|
|
610
|
-
│ │ └── index.css # Demo-specific styles
|
|
611
|
-
│ └── index.ts # Package entry point
|
|
612
|
-
├── examples/
|
|
613
|
-
│ └── react-map-gl/ # Complete React example
|
|
614
|
-
│ ├── src/
|
|
615
|
-
│ │ ├── App.tsx # Example React application
|
|
616
|
-
│ │ └── main.tsx # React entry point
|
|
617
|
-
│ ├── package.json # Example dependencies
|
|
618
|
-
│ └── vite.config.ts # Vite configuration
|
|
619
|
-
├── dist/ # Built package output
|
|
620
|
-
│ ├── index.js # ES Module
|
|
621
|
-
│ ├── index.umd.js # UMD Module
|
|
622
|
-
│ ├── index.d.ts # TypeScript declarations
|
|
623
|
-
│ └── map-gl-style-switcher.css # Bundled CSS
|
|
624
|
-
├── package.json # Package configuration
|
|
625
|
-
├── rollup.config.js # Production build configuration
|
|
626
|
-
├── vite.config.ts # Development build configuration
|
|
627
|
-
├── jest.config.js # Test configuration
|
|
628
|
-
├── tsconfig.json # TypeScript configuration
|
|
629
|
-
└── README.md # Documentation
|
|
630
|
-
```
|
|
631
|
-
|
|
632
|
-
## Development
|
|
633
|
-
|
|
634
|
-
This project uses npm for dependency management.
|
|
635
|
-
|
|
636
|
-
### Prerequisites
|
|
637
|
-
|
|
638
|
-
```sh
|
|
639
|
-
# Ensure you have Node.js 16+ and npm 8+ installed
|
|
640
|
-
node --version
|
|
641
|
-
npm --version
|
|
642
|
-
```
|
|
643
|
-
|
|
644
|
-
### Quick Start
|
|
645
|
-
|
|
646
|
-
```sh
|
|
647
|
-
# Install dependencies
|
|
648
|
-
npm install
|
|
649
|
-
|
|
650
|
-
# Start development server
|
|
651
|
-
npm run dev
|
|
652
|
-
|
|
653
|
-
# Build for production
|
|
654
|
-
npm run build
|
|
655
|
-
|
|
656
|
-
# Run tests
|
|
657
|
-
npm test
|
|
658
|
-
|
|
659
|
-
# Lint and format code
|
|
660
|
-
npm run lint
|
|
661
|
-
npm run format
|
|
662
|
-
|
|
663
|
-
# Validate before publishing
|
|
664
|
-
npm run validate
|
|
665
|
-
```
|
|
666
|
-
|
|
667
|
-
## Build for npm
|
|
668
|
-
|
|
669
|
-
The project uses Rollup for optimized production builds, generating:
|
|
670
|
-
|
|
671
|
-
- `dist/index.js` - ES module format
|
|
672
|
-
- `dist/index.umd.js` - UMD format for browser usage
|
|
673
|
-
- `dist/index.d.ts` - TypeScript declarations
|
|
674
|
-
- `dist/map-gl-style-switcher.css` - Minified CSS styles
|
|
675
|
-
|
|
676
|
-
```sh
|
|
677
|
-
# Standard build
|
|
678
|
-
npm run build
|
|
679
|
-
|
|
680
|
-
# Production build with full validation
|
|
681
|
-
npm run build:prod
|
|
682
|
-
```
|
|
683
|
-
|
|
684
263
|
## Contributing
|
|
685
264
|
|
|
686
265
|
We welcome contributions! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
|
|
@@ -719,23 +298,6 @@ We welcome contributions! Please feel free to submit a Pull Request. For major c
|
|
|
719
298
|
|
|
720
299
|
6. **Submit a pull request**
|
|
721
300
|
|
|
722
|
-
### Available Scripts
|
|
723
|
-
|
|
724
|
-
- `npm run dev` - Start development server with hot reload
|
|
725
|
-
- `npm run build` - Build library with Rollup (ES modules, UMD, TypeScript declarations, and CSS)
|
|
726
|
-
- `npm run build:prod` - Production build with validation (type-check, lint, and build)
|
|
727
|
-
- `npm run build:watch` - Build in watch mode with Rollup
|
|
728
|
-
- `npm test` - Run tests
|
|
729
|
-
- `npm run test:watch` - Run tests in watch mode
|
|
730
|
-
- `npm run test:coverage` - Run tests with coverage
|
|
731
|
-
- `npm run lint` - Lint code
|
|
732
|
-
- `npm run lint:fix` - Lint and auto-fix issues
|
|
733
|
-
- `npm run format` - Format code with Prettier
|
|
734
|
-
- `npm run format:check` - Check code formatting
|
|
735
|
-
- `npm run validate` - Run all validation checks
|
|
736
|
-
- `npm run type-check` - Type check TypeScript
|
|
737
|
-
- `npm run clean` - Clean build artifacts
|
|
738
|
-
|
|
739
301
|
### Guidelines
|
|
740
302
|
|
|
741
303
|
- Use npm for dependency management
|