MIF_E31221222/sigap-website/app/_components/map/map.tsx

75 lines
2.1 KiB
TypeScript

"use client"
import type React from "react"
import { useState, useCallback } from "react"
import { type ViewState, Map, type MapRef, NavigationControl, GeolocateControl } from "react-map-gl/mapbox"
import { FullscreenControl } from "react-map-gl/mapbox"
import { BASE_LATITUDE, BASE_LONGITUDE, BASE_ZOOM, MAPBOX_STYLES, type MapboxStyle } from "@/app/_utils/const/map"
import "mapbox-gl/dist/mapbox-gl.css"
interface MapViewProps {
children?: React.ReactNode
initialViewState?: Partial<ViewState>
mapStyle?: MapboxStyle
className?: string
width?: string | number
height?: string | number
mapboxApiAccessToken?: string
onMoveEnd?: (viewState: ViewState) => void
customControls?: React.ReactNode
}
export default function MapView({
children,
initialViewState,
mapStyle = MAPBOX_STYLES.Standard,
className = "w-full h-96",
width = "100%",
height = "100%",
mapboxApiAccessToken = process.env.NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN,
onMoveEnd,
}: MapViewProps) {
const [mapRef, setMapRef] = useState<MapRef | null>(null)
const defaultViewState: Partial<ViewState> = {
longitude: BASE_LONGITUDE,
latitude: BASE_LATITUDE,
zoom: BASE_ZOOM,
bearing: 0,
pitch: 0,
...initialViewState,
}
const handleMoveEnd = useCallback(
(event: any) => {
if (onMoveEnd) {
onMoveEnd(event.viewState)
}
},
[onMoveEnd],
)
return (
<div className={`relative ${className}`}>
<div className="flex h-full">
<div className="relative flex-grow h-full transition-all duration-300">
<Map
mapStyle={mapStyle}
mapboxAccessToken={mapboxApiAccessToken}
initialViewState={defaultViewState}
onMoveEnd={handleMoveEnd}
style={{ width: "100%", height: "100%" }}
attributionControl={false}
preserveDrawingBuffer={true} // This helps with fullscreen stability
>
<FullscreenControl position="top-right" />
<NavigationControl position="top-right" showCompass={false} />
{children}
</Map>
</div>
</div>
</div>
)
}