Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | 1x 1x 1x 1x 1x 1x 55x 55x 55x 55x 36x 36x 36x 36x 36x 36x 36x 36x 36x 36x 36x 36x 36x 36x 36x 36x 36x 36x 36x 55x 55x 55x 55x 55x 55x 55x 1x | /**
* useMapbox Hook
*
* Custom React hook for initializing and managing Mapbox GL JS map instance.
*/
import { useEffect, useRef, useState } from 'react';
import mapboxgl from 'mapbox-gl';
export interface MapConfig {
container: string | HTMLElement;
style?: string;
center?: [number, number];
zoom?: number;
accessToken?: string;
}
export interface UseMapboxResult {
map: mapboxgl.Map | null;
isLoaded: boolean;
error: string | null;
}
const DEFAULT_STYLE = 'mapbox://styles/mapbox/satellite-v9';
const DEFAULT_CENTER: [number, number] = [9.0, 44.5]; // Northwestern Italy
const DEFAULT_ZOOM = 8;
/**
* Initialize and manage a Mapbox GL JS map
*
* @param config - Map configuration
* @returns Map instance, loading state, and error
*/
export function useMapbox(config: MapConfig): UseMapboxResult {
const mapRef = useRef<mapboxgl.Map | null>(null);
const [isLoaded, setIsLoaded] = useState(false);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
// Get access token from environment or config
const token = config.accessToken || import.meta.env.VITE_MAPBOX_TOKEN;
if (!token || token === 'your_mapbox_api_token_here') {
setError('Mapbox access token not configured. Please set VITE_MAPBOX_TOKEN in .env file.');
return;
}
// Set access token
mapboxgl.accessToken = token;
try {
// Initialize map
const map = new mapboxgl.Map({
container: config.container,
style: config.style || DEFAULT_STYLE,
center: config.center || DEFAULT_CENTER,
zoom: config.zoom || DEFAULT_ZOOM,
attributionControl: true,
});
// Add navigation controls
map.addControl(new mapboxgl.NavigationControl(), 'top-right');
// Add fullscreen control
map.addControl(new mapboxgl.FullscreenControl(), 'top-right');
// Add scale control
map.addControl(new mapboxgl.ScaleControl(), 'bottom-left');
// Handle load event
map.on('load', () => {
setIsLoaded(true);
setError(null);
});
// Handle error event
map.on('error', (e) => {
console.error('Mapbox error:', e);
setError(e.error?.message || 'Map error occurred');
});
mapRef.current = map;
// Cleanup function
return () => {
if (mapRef.current) {
mapRef.current.remove();
mapRef.current = null;
}
setIsLoaded(false);
};
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Failed to initialize map';
setError(errorMessage);
console.error('Failed to initialize Mapbox:', err);
}
}, [config.container, config.style, config.center, config.zoom, config.accessToken]);
return {
map: mapRef.current,
isLoaded,
error,
};
}
export default useMapbox;
|