@neural-technologies-indonesia/react-mapbox
v1.4.3
Published
A React binding of Mapbox
Downloads
97
Readme
@neural-technologies-indonesia/react-mapbox
A lightweight and composable React wrapper for Mapbox GL JS using declarative components.
📦 Installation
Install via npm:
npm install @neural-technologies-indonesia/react-mapboxYou also need to install its peer dependencies:
npm install mapbox-gl @mapbox/mapbox-gl-draw @turf/turfThen import the required Mapbox CSS styles in your entry file:
import 'mapbox-gl/dist/mapbox-gl.css';
import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css';🚀 Basic Usage
Here’s a minimal example of how to use it in a React component:
import React, { useState } from 'react';
import {
MapContainer,
Geojson,
Layer,
FitBounds,
Center,
Search,
Draw,
} from '@neural-technologies-indonesia/react-mapbox';
import * as turf from "@turf/turf";
const App = () => {
const [search, setSearch] = useState("");
const [draws, setDraws] = useState<GeoJSON.FeatureCollection>({
type: "FeatureCollection",
features: [],
});
const handleDraw = useCallback((draw: any) => {
const data = draw.getAll();
const area = turf.area(data);
const rounded_area = Math.round(area * 100) / 100;
setDraws({
type: "FeatureCollection",
features: [],
});
if (rounded_area > 25_000_000) {
alert("out of max area");
} else {
setDraws(data);
}
}, []);
const geojsonData = {
type: "FeatureCollection",
features: [
{
type: "Feature",
properties: { name: "Location A" },
geometry: {
type: "Point",
coordinates: [106.8272, -6.1751],
},
},
],
};
const layers = useMemo<LayerProps["layers"]>(() => {
return [
{
id: "point-layer",
type: "circle",
paint: {
"circle-radius": 6,
"circle-color": "#007cbf",
},
getMapInstance(map, layerId) {
const popup = new mapboxgl.Popup({ closeButton: false });
map.on("click", layerId, () => {
popup
.setLngLat([106.83173906777137, -6.193283376086626])
.setHTML("<h1>test</h1>")
.addTo(map);
});
map.on("mousemove", layerId, (e) => {
const prevLonglat = popup.getLngLat();
const properties = e.features?.[0].properties;
let longlat = e.lngLat;
if (properties && "longitude" in properties && "latitude") {
longlat = {
lat: properties["latitude"],
lng: properties["longitude"],
} as any;
}
if (
prevLonglat?.lng === longlat.lng &&
prevLonglat?.lat === longlat.lat
)
return;
popup.remove();
popup.setLngLat(longlat).setHTML("<h1>test</h1>").addTo(map);
});
},
},
];
}, []);
return (
<MapContainer
accessToken="YOUR_MAPBOX_TOKEN"
height={400}
mapOption={{
container: "map",
style: "mapbox://styles/mapbox/streets-v11",
center: [106.83173906777137, -6.193283376086626],
zoom: 12,
}}
>
<Geojson id="geo-source" source={geojsonData}>
<Layer layers={layers}/>
</Geojson>
<Geojson id="draw" source={draws}>
<Layer layers={[
{
id: "fill-draw-layer",
type: "fill",
paint: {
"fill-color": "#3BB2D0",
"fill-opacity": 0.3,
},
}
]} />
</Geojson>
<Center center={[106.8272, -6.1751]} zoomLevel={12} />
<FitBounds
bounds={[
106.8272,
-6.1933,
106.8317,
-6.1751,
]}
/>
<Search
keyword={search}
onSearch={(features: any[]) => {
console.log(features)
}}
/>
<Draw onDraw={handleDraw} controls={{ polygon: true, trash: true }} />
</MapContainer>
);
};
export default App;📚 Available Components
| Component | Description |
|---------------|-------------|
| MapContainer | Root component that initializes the map and provides context. |
| Geojson | Provides and shares GeoJSON data via React Context. |
| Layer | Adds map layers declaratively, supports images and clustering. |
| Center | Sets the map center and zoom level declaratively. |
| FitBounds | Automatically fits the map view to the given bounds. |
| Search | Performs geocoding via Mapbox Places API using a keyword. |
| Draw | Adds interactive drawing tools (polygon, trash). |
| useSync | React hook to synchronize multiple maps’ position and zoom. |
🛠 Utility Functions
| Function | Description |
|----------------|-------------|
| dataParser | Merges external data into a GeoJSON FeatureCollection using a mapping key and optional custom property builder. |
