import { CRIME_RATE_COLORS } from "@/app/_utils/const/map"
import { ControlPosition, IControl, Map } from "mapbox-gl"
import { useControl } from "react-map-gl/mapbox"
import React, { useEffect } from "react"
import { createRoot } from "react-dom/client"
interface MapLegendProps {
position?: ControlPosition
isFullscreen?: boolean
}
// React component for legend content
const LegendContent = () => {
return (
)
}
class MapLegendControl implements IControl {
private container: HTMLElement;
private map?: Map;
private props: MapLegendProps;
private root: ReturnType | null = null;
private isUnmounting: boolean = false;
constructor(props: MapLegendProps) {
this.props = props;
this.container = document.createElement("div");
this.container.className = "mapboxgl-ctrl";
}
onAdd(map: Map): HTMLElement {
this.map = map;
this.container.className = 'mapboxgl-ctrl mapboxgl-ctrl-legend';
this.render();
return this.container;
}
onRemove(): void {
// Prevent multiple unmounting attempts
if (this.isUnmounting) return;
this.isUnmounting = true;
// Schedule unmounting to happen after current render cycle completes
requestAnimationFrame(() => {
if (this.root) {
this.root.unmount();
this.root = null;
}
if (this.container.parentNode) {
this.container.parentNode.removeChild(this.container);
}
this.map = undefined;
this.isUnmounting = false;
});
}
updateProps(props: MapLegendProps): void {
this.props = props;
this.render();
}
render(): void {
// Only render if in fullscreen or if isFullscreen prop is not provided
if (this.props.isFullscreen === false) {
if (this.container.style.display !== 'none') {
this.container.style.display = 'none';
}
return;
} else {
this.container.style.display = 'block';
}
// Create a root if it doesn't exist
if (!this.root) {
this.root = createRoot(this.container);
}
// Render using the createRoot API
this.root.render();
}
}
export function MapLegend({ position = 'bottom-right', isFullscreen }: MapLegendProps) {
const control = useControl(
() => new MapLegendControl({ position, isFullscreen }),
{ position }
);
// Update control when props change
useEffect(() => {
control.updateProps({ position, isFullscreen });
}, [control, position, isFullscreen]);
return null;
}