maplibre-gl-components 0.1.0
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/LICENSE +21 -0
- package/README.md +380 -0
- package/dist/HtmlControl-BbinjIOJ.cjs +1190 -0
- package/dist/HtmlControl-BbinjIOJ.cjs.map +1 -0
- package/dist/HtmlControl-iggZQwXP.js +1191 -0
- package/dist/HtmlControl-iggZQwXP.js.map +1 -0
- package/dist/index.cjs +86 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.mjs +86 -0
- package/dist/index.mjs.map +1 -0
- package/dist/maplibre-gl-components.css +243 -0
- package/dist/react.cjs +342 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.mjs +342 -0
- package/dist/react.mjs.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/lib/colormaps/diverging.d.ts +30 -0
- package/dist/types/lib/colormaps/diverging.d.ts.map +1 -0
- package/dist/types/lib/colormaps/index.d.ts +32 -0
- package/dist/types/lib/colormaps/index.d.ts.map +1 -0
- package/dist/types/lib/colormaps/misc.d.ts +38 -0
- package/dist/types/lib/colormaps/misc.d.ts.map +1 -0
- package/dist/types/lib/colormaps/sequential.d.ts +22 -0
- package/dist/types/lib/colormaps/sequential.d.ts.map +1 -0
- package/dist/types/lib/core/Colorbar.d.ts +122 -0
- package/dist/types/lib/core/Colorbar.d.ts.map +1 -0
- package/dist/types/lib/core/ColorbarReact.d.ts +34 -0
- package/dist/types/lib/core/ColorbarReact.d.ts.map +1 -0
- package/dist/types/lib/core/HtmlControl.d.ts +114 -0
- package/dist/types/lib/core/HtmlControl.d.ts.map +1 -0
- package/dist/types/lib/core/HtmlControlReact.d.ts +32 -0
- package/dist/types/lib/core/HtmlControlReact.d.ts.map +1 -0
- package/dist/types/lib/core/Legend.d.ts +136 -0
- package/dist/types/lib/core/Legend.d.ts.map +1 -0
- package/dist/types/lib/core/LegendReact.d.ts +34 -0
- package/dist/types/lib/core/LegendReact.d.ts.map +1 -0
- package/dist/types/lib/core/types.d.ts +238 -0
- package/dist/types/lib/core/types.d.ts.map +1 -0
- package/dist/types/lib/hooks/index.d.ts +4 -0
- package/dist/types/lib/hooks/index.d.ts.map +1 -0
- package/dist/types/lib/hooks/useColorbar.d.ts +36 -0
- package/dist/types/lib/hooks/useColorbar.d.ts.map +1 -0
- package/dist/types/lib/hooks/useHtmlControl.d.ts +33 -0
- package/dist/types/lib/hooks/useHtmlControl.d.ts.map +1 -0
- package/dist/types/lib/hooks/useLegend.d.ts +41 -0
- package/dist/types/lib/hooks/useLegend.d.ts.map +1 -0
- package/dist/types/lib/utils/color.d.ts +47 -0
- package/dist/types/lib/utils/color.d.ts.map +1 -0
- package/dist/types/lib/utils/helpers.d.ts +48 -0
- package/dist/types/lib/utils/helpers.d.ts.map +1 -0
- package/dist/types/lib/utils/index.d.ts +3 -0
- package/dist/types/lib/utils/index.d.ts.map +1 -0
- package/dist/types/react.d.ts +6 -0
- package/dist/types/react.d.ts.map +1 -0
- package/package.json +109 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Open Geospatial Solutions
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
# maplibre-gl-components
|
|
2
|
+
|
|
3
|
+
Legend, colorbar, and HTML control components for MapLibre GL JS maps.
|
|
4
|
+
|
|
5
|
+
[](https://badge.fury.io/js/maplibre-gl-components)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **Colorbar** - Continuous gradient legends with built-in matplotlib colormaps
|
|
11
|
+
- **Legend** - Categorical legends with color swatches and labels
|
|
12
|
+
- **HtmlControl** - Flexible HTML content control for custom info panels
|
|
13
|
+
- **React Support** - First-class React components and hooks
|
|
14
|
+
- **TypeScript** - Full type definitions included
|
|
15
|
+
- **20+ Built-in Colormaps** - viridis, plasma, terrain, jet, and more
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install maplibre-gl-components
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
### Vanilla JavaScript/TypeScript
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import maplibregl from 'maplibre-gl';
|
|
29
|
+
import { Colorbar, Legend, HtmlControl } from 'maplibre-gl-components';
|
|
30
|
+
import 'maplibre-gl-components/style.css';
|
|
31
|
+
|
|
32
|
+
const map = new maplibregl.Map({
|
|
33
|
+
container: 'map',
|
|
34
|
+
style: 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json',
|
|
35
|
+
center: [-98, 38.5],
|
|
36
|
+
zoom: 4,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Add a colorbar
|
|
40
|
+
const colorbar = new Colorbar({
|
|
41
|
+
colormap: 'viridis',
|
|
42
|
+
vmin: 0,
|
|
43
|
+
vmax: 100,
|
|
44
|
+
label: 'Temperature',
|
|
45
|
+
units: '°C',
|
|
46
|
+
orientation: 'vertical',
|
|
47
|
+
});
|
|
48
|
+
map.addControl(colorbar, 'bottom-right');
|
|
49
|
+
|
|
50
|
+
// Add a legend
|
|
51
|
+
const legend = new Legend({
|
|
52
|
+
title: 'Land Cover',
|
|
53
|
+
items: [
|
|
54
|
+
{ label: 'Forest', color: '#228B22' },
|
|
55
|
+
{ label: 'Water', color: '#4169E1' },
|
|
56
|
+
{ label: 'Urban', color: '#808080' },
|
|
57
|
+
],
|
|
58
|
+
collapsible: true,
|
|
59
|
+
});
|
|
60
|
+
map.addControl(legend, 'bottom-left');
|
|
61
|
+
|
|
62
|
+
// Add an HTML control
|
|
63
|
+
const htmlControl = new HtmlControl({
|
|
64
|
+
html: '<div><strong>Stats:</strong> 1,234 features</div>',
|
|
65
|
+
});
|
|
66
|
+
map.addControl(htmlControl, 'top-left');
|
|
67
|
+
|
|
68
|
+
// Update HTML dynamically
|
|
69
|
+
htmlControl.setHtml('<div><strong>Stats:</strong> 5,678 features</div>');
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### React
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
import { useState, useEffect, useRef } from 'react';
|
|
76
|
+
import maplibregl from 'maplibre-gl';
|
|
77
|
+
import { ColorbarReact, LegendReact, HtmlControlReact } from 'maplibre-gl-components/react';
|
|
78
|
+
import 'maplibre-gl-components/style.css';
|
|
79
|
+
|
|
80
|
+
function MyMap() {
|
|
81
|
+
const mapContainer = useRef<HTMLDivElement>(null);
|
|
82
|
+
const [map, setMap] = useState<maplibregl.Map | null>(null);
|
|
83
|
+
const [stats, setStats] = useState('Loading...');
|
|
84
|
+
|
|
85
|
+
useEffect(() => {
|
|
86
|
+
if (!mapContainer.current) return;
|
|
87
|
+
|
|
88
|
+
const mapInstance = new maplibregl.Map({
|
|
89
|
+
container: mapContainer.current,
|
|
90
|
+
style: 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json',
|
|
91
|
+
center: [-98, 38.5],
|
|
92
|
+
zoom: 4,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
mapInstance.on('load', () => setMap(mapInstance));
|
|
96
|
+
|
|
97
|
+
return () => mapInstance.remove();
|
|
98
|
+
}, []);
|
|
99
|
+
|
|
100
|
+
return (
|
|
101
|
+
<div style={{ width: '100%', height: '100vh' }}>
|
|
102
|
+
<div ref={mapContainer} style={{ width: '100%', height: '100%' }} />
|
|
103
|
+
|
|
104
|
+
{map && (
|
|
105
|
+
<>
|
|
106
|
+
<ColorbarReact
|
|
107
|
+
map={map}
|
|
108
|
+
colormap="viridis"
|
|
109
|
+
vmin={0}
|
|
110
|
+
vmax={100}
|
|
111
|
+
label="Temperature"
|
|
112
|
+
units="°C"
|
|
113
|
+
position="bottom-right"
|
|
114
|
+
/>
|
|
115
|
+
|
|
116
|
+
<LegendReact
|
|
117
|
+
map={map}
|
|
118
|
+
title="Categories"
|
|
119
|
+
items={[
|
|
120
|
+
{ label: 'Low', color: '#2166ac' },
|
|
121
|
+
{ label: 'High', color: '#b2182b' },
|
|
122
|
+
]}
|
|
123
|
+
position="bottom-left"
|
|
124
|
+
collapsible
|
|
125
|
+
/>
|
|
126
|
+
|
|
127
|
+
<HtmlControlReact
|
|
128
|
+
map={map}
|
|
129
|
+
html={`<div><strong>Stats:</strong> ${stats}</div>`}
|
|
130
|
+
position="top-left"
|
|
131
|
+
/>
|
|
132
|
+
</>
|
|
133
|
+
)}
|
|
134
|
+
</div>
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## API Reference
|
|
140
|
+
|
|
141
|
+
### Colorbar
|
|
142
|
+
|
|
143
|
+
A continuous gradient colorbar control.
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
interface ColorbarOptions {
|
|
147
|
+
colormap?: ColormapName | string[]; // Colormap name or custom colors
|
|
148
|
+
colorStops?: ColorStop[]; // Fine-grained color control
|
|
149
|
+
vmin?: number; // Minimum value (default: 0)
|
|
150
|
+
vmax?: number; // Maximum value (default: 1)
|
|
151
|
+
label?: string; // Title/label
|
|
152
|
+
units?: string; // Units suffix
|
|
153
|
+
orientation?: 'horizontal' | 'vertical';
|
|
154
|
+
position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
155
|
+
barThickness?: number; // Bar width/height in pixels
|
|
156
|
+
barLength?: number; // Bar length in pixels
|
|
157
|
+
ticks?: { count?: number; values?: number[]; format?: (v: number) => string };
|
|
158
|
+
visible?: boolean;
|
|
159
|
+
backgroundColor?: string;
|
|
160
|
+
opacity?: number;
|
|
161
|
+
fontSize?: number;
|
|
162
|
+
fontColor?: string;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Methods
|
|
166
|
+
colorbar.show()
|
|
167
|
+
colorbar.hide()
|
|
168
|
+
colorbar.update(options)
|
|
169
|
+
colorbar.getState()
|
|
170
|
+
colorbar.on(event, handler)
|
|
171
|
+
colorbar.off(event, handler)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Legend
|
|
175
|
+
|
|
176
|
+
A categorical legend control.
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
interface LegendOptions {
|
|
180
|
+
title?: string;
|
|
181
|
+
items?: LegendItem[]; // { label, color, shape?, icon? }
|
|
182
|
+
position?: ControlPosition;
|
|
183
|
+
visible?: boolean;
|
|
184
|
+
collapsible?: boolean;
|
|
185
|
+
collapsed?: boolean;
|
|
186
|
+
width?: number;
|
|
187
|
+
maxHeight?: number;
|
|
188
|
+
swatchSize?: number;
|
|
189
|
+
backgroundColor?: string;
|
|
190
|
+
opacity?: number;
|
|
191
|
+
fontSize?: number;
|
|
192
|
+
fontColor?: string;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
interface LegendItem {
|
|
196
|
+
label: string;
|
|
197
|
+
color: string;
|
|
198
|
+
shape?: 'square' | 'circle' | 'line';
|
|
199
|
+
strokeColor?: string;
|
|
200
|
+
icon?: string; // URL to icon image
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Methods
|
|
204
|
+
legend.show()
|
|
205
|
+
legend.hide()
|
|
206
|
+
legend.expand()
|
|
207
|
+
legend.collapse()
|
|
208
|
+
legend.toggle()
|
|
209
|
+
legend.setItems(items)
|
|
210
|
+
legend.addItem(item)
|
|
211
|
+
legend.removeItem(label)
|
|
212
|
+
legend.update(options)
|
|
213
|
+
legend.getState()
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### HtmlControl
|
|
217
|
+
|
|
218
|
+
A flexible HTML content control.
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
interface HtmlControlOptions {
|
|
222
|
+
html?: string; // HTML content
|
|
223
|
+
element?: HTMLElement; // Or provide a DOM element
|
|
224
|
+
position?: ControlPosition;
|
|
225
|
+
visible?: boolean;
|
|
226
|
+
backgroundColor?: string;
|
|
227
|
+
padding?: number;
|
|
228
|
+
borderRadius?: number;
|
|
229
|
+
opacity?: number;
|
|
230
|
+
maxWidth?: number;
|
|
231
|
+
maxHeight?: number;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Methods
|
|
235
|
+
htmlControl.show()
|
|
236
|
+
htmlControl.hide()
|
|
237
|
+
htmlControl.setHtml(html) // Update HTML content
|
|
238
|
+
htmlControl.setElement(element) // Set DOM element
|
|
239
|
+
htmlControl.getElement() // Get content container
|
|
240
|
+
htmlControl.update(options)
|
|
241
|
+
htmlControl.getState()
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Built-in Colormaps
|
|
245
|
+
|
|
246
|
+
### Sequential
|
|
247
|
+
- `viridis` - Perceptually uniform, colorblind-friendly
|
|
248
|
+
- `plasma` - Perceptually uniform
|
|
249
|
+
- `inferno` - Perceptually uniform
|
|
250
|
+
- `magma` - Perceptually uniform
|
|
251
|
+
- `cividis` - Colorblind-friendly
|
|
252
|
+
|
|
253
|
+
### Diverging
|
|
254
|
+
- `coolwarm` - Blue to red through white
|
|
255
|
+
- `bwr` - Blue-white-red
|
|
256
|
+
- `seismic` - Blue to red
|
|
257
|
+
- `RdBu` - Red to blue
|
|
258
|
+
- `RdYlBu` - Red-yellow-blue
|
|
259
|
+
- `RdYlGn` - Red-yellow-green
|
|
260
|
+
- `spectral` - Rainbow-like diverging
|
|
261
|
+
|
|
262
|
+
### Miscellaneous
|
|
263
|
+
- `jet` - Classic rainbow
|
|
264
|
+
- `rainbow` - Full spectrum
|
|
265
|
+
- `turbo` - Improved rainbow
|
|
266
|
+
- `terrain` - Elevation-like
|
|
267
|
+
- `ocean` - Ocean depths
|
|
268
|
+
- `hot` - Black-red-yellow-white
|
|
269
|
+
- `cool` - Cyan to magenta
|
|
270
|
+
- `gray` - Grayscale
|
|
271
|
+
- `bone` - Blue-tinted grayscale
|
|
272
|
+
|
|
273
|
+
### Custom Colors
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
// Use an array of colors
|
|
277
|
+
const colorbar = new Colorbar({
|
|
278
|
+
colormap: ['#0000ff', '#00ff00', '#ffff00', '#ff0000'],
|
|
279
|
+
vmin: 0,
|
|
280
|
+
vmax: 100,
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
// Or use color stops for precise control
|
|
284
|
+
const colorbar = new Colorbar({
|
|
285
|
+
colorStops: [
|
|
286
|
+
{ position: 0, color: '#0000ff' },
|
|
287
|
+
{ position: 0.3, color: '#00ff00' },
|
|
288
|
+
{ position: 0.7, color: '#ffff00' },
|
|
289
|
+
{ position: 1, color: '#ff0000' },
|
|
290
|
+
],
|
|
291
|
+
vmin: 0,
|
|
292
|
+
vmax: 100,
|
|
293
|
+
});
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## React Hooks
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
import { useColorbar, useLegend, useHtmlControl } from 'maplibre-gl-components/react';
|
|
300
|
+
|
|
301
|
+
function MyComponent() {
|
|
302
|
+
const colorbar = useColorbar({ colormap: 'viridis', vmin: 0, vmax: 100 });
|
|
303
|
+
const legend = useLegend({ items: [...] });
|
|
304
|
+
const htmlControl = useHtmlControl({ html: '...' });
|
|
305
|
+
|
|
306
|
+
return (
|
|
307
|
+
<>
|
|
308
|
+
<button onClick={() => colorbar.setColormap('plasma')}>
|
|
309
|
+
Change Colormap
|
|
310
|
+
</button>
|
|
311
|
+
<button onClick={() => legend.toggle()}>
|
|
312
|
+
Toggle Legend
|
|
313
|
+
</button>
|
|
314
|
+
<button onClick={() => htmlControl.setHtml('<div>Updated!</div>')}>
|
|
315
|
+
Update HTML
|
|
316
|
+
</button>
|
|
317
|
+
|
|
318
|
+
<ColorbarReact
|
|
319
|
+
map={map}
|
|
320
|
+
{...colorbar.state}
|
|
321
|
+
vmin={colorbar.state.vmin}
|
|
322
|
+
vmax={colorbar.state.vmax}
|
|
323
|
+
/>
|
|
324
|
+
</>
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
## Styling
|
|
330
|
+
|
|
331
|
+
The default styles can be customized using CSS:
|
|
332
|
+
|
|
333
|
+
```css
|
|
334
|
+
/* Override colorbar styles */
|
|
335
|
+
.maplibre-gl-colorbar {
|
|
336
|
+
background: rgba(0, 0, 0, 0.8);
|
|
337
|
+
color: white;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/* Override legend styles */
|
|
341
|
+
.maplibre-gl-legend {
|
|
342
|
+
font-size: 14px;
|
|
343
|
+
border-radius: 8px;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/* Override HTML control styles */
|
|
347
|
+
.maplibre-gl-html-control {
|
|
348
|
+
max-width: 400px;
|
|
349
|
+
}
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
## Examples
|
|
353
|
+
|
|
354
|
+
See the [examples](./examples/) directory for complete working examples:
|
|
355
|
+
|
|
356
|
+
- **Basic Example** - Vanilla TypeScript with all three components
|
|
357
|
+
- **React Example** - React with hooks and dynamic updates
|
|
358
|
+
|
|
359
|
+
## Development
|
|
360
|
+
|
|
361
|
+
```bash
|
|
362
|
+
# Install dependencies
|
|
363
|
+
npm install
|
|
364
|
+
|
|
365
|
+
# Start development server
|
|
366
|
+
npm run dev
|
|
367
|
+
|
|
368
|
+
# Run tests
|
|
369
|
+
npm test
|
|
370
|
+
|
|
371
|
+
# Build for production
|
|
372
|
+
npm run build
|
|
373
|
+
|
|
374
|
+
# Build examples
|
|
375
|
+
npm run build:examples
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
## License
|
|
379
|
+
|
|
380
|
+
MIT License - see [LICENSE](./LICENSE) for details.
|