75 lines
2.1 KiB
TypeScript
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>
|
|
)
|
|
}
|