From 206669c4922b07f511bfd83353d375835132bfad Mon Sep 17 00:00:00 2001 From: Guillaume Fay Date: Wed, 18 Sep 2024 13:50:27 +0200 Subject: [PATCH] fix: map hover and selected --- .../DeploiementBAL/DeploiementMap.tsx | 94 +++++++++++-------- 1 file changed, 56 insertions(+), 38 deletions(-) diff --git a/src/components/DeploiementBAL/DeploiementMap.tsx b/src/components/DeploiementBAL/DeploiementMap.tsx index b9ad385d0..a1aa12782 100644 --- a/src/components/DeploiementBAL/DeploiementMap.tsx +++ b/src/components/DeploiementBAL/DeploiementMap.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react' +import React, { useCallback, useEffect, useState } from 'react' import styled from 'styled-components' import { MapMouseEvent, Popup, useMap } from 'react-map-gl/maplibre' import { toolsColors } from '@/theme/theme' @@ -172,8 +172,8 @@ interface DeploiementMapProps { export default function DeploiementMap({ center, zoom, filteredCodesCommmune, selectedPaintLayer }: DeploiementMapProps) { const { current: map } = useMap() - const router = useRouter() - const [highlighted, setHighlighted] = useState('') + const hoveredRef = React.useRef(null) + const selectedRef = React.useRef(null) const [popup, setPopup] = useState<{ latitude: number, longitude: number, properties: any } | null>(null) useEffect(() => { @@ -181,67 +181,86 @@ export default function DeploiementMap({ center, zoom, filteredCodesCommmune, se return } - const onMouseMove = (event: MapMouseEvent) => { - if (!map) { - return - } - - const canvas = map.getCanvas() - canvas.style.cursor = 'pointer' - - const [feature] = (event as any).features + map.setCenter(center) + map.setZoom(zoom) + }, [map, center, zoom]) - if (highlighted) { - map.setFeatureState({ source: 'data', id: highlighted }, { hover: false }) - } + const closePopup = useCallback(() => { + setPopup(null) + if (selectedRef.current) { + map?.setFeatureState({ source: 'data', id: selectedRef.current }, { hover: false }) + selectedRef.current = null + } + if (hoveredRef.current) { + map?.setFeatureState({ source: 'data', id: hoveredRef.current }, { hover: false }) + hoveredRef.current = null + } + }, [map]) - setHighlighted(feature.id) - map.setFeatureState({ source: 'data', id: highlighted }, { hover: true }) + useEffect(() => { + if (!map) { + return + } + const onClick = (event: MapMouseEvent) => { + const [feature] = (event as any).features if (filteredCodesCommmune.length === 0 || filteredCodesCommmune.includes(feature.properties.code)) { + closePopup() setPopup({ latitude: event.lngLat.lat, longitude: event.lngLat.lng, properties: feature.properties, }) - } - else { - setPopup(null) + selectedRef.current = feature.id + map.setFeatureState({ source: 'data', id: feature.id }, { hover: true }) } } - const onClick = (event: MapMouseEvent) => { - const [feature] = (event as any).features - router.push(`/commune/${feature.id}`) + map.on('click', 'bal-polygon-fill', onClick) + + return () => { + map.off('click', 'bal-polygon-fill', onClick) } + }, [map, filteredCodesCommmune, closePopup]) - const onMouseLeave = () => { + useEffect(() => { + if (!map) { + return + } + + const onMouseMove = (event: MapMouseEvent) => { if (!map) { return } - const canvas = map.getCanvas() - canvas.style.cursor = '' - if (highlighted) { - map.setFeatureState({ source: 'data', id: highlighted }, { hover: false }) + const [feature] = (event as any).features + + if (hoveredRef.current && hoveredRef.current !== selectedRef.current) { + map.setFeatureState({ source: 'data', id: hoveredRef.current }, { hover: false }) } - setPopup(null) + hoveredRef.current = feature.id + map.setFeatureState({ source: 'data', id: feature.id }, { hover: true }) } - map.setCenter(center) - map.setZoom(zoom) + const onMouseLeave = () => { + if (!map) { + return + } + + if (hoveredRef.current) { + map.setFeatureState({ source: 'data', id: hoveredRef.current }, { hover: false }) + } + } map.on('mousemove', 'bal-polygon-fill', onMouseMove) map.on('mouseleave', 'bal-polygon-fill', onMouseLeave) - map.on('click', 'bal-polygon-fill', onClick) return () => { map.off('mousemove', 'bal-polygon-fill', onMouseMove) map.off('mouseleave', 'bal-polygon-fill', onMouseLeave) - map.off('click', 'bal-polygon-fill', onClick) } - }, [center, zoom, map, filteredCodesCommmune, router]) + }, [map]) return ( @@ -263,14 +282,13 @@ export default function DeploiementMap({ center, zoom, filteredCodesCommmune, se } {popup && ( - +
-

- {popup.properties.nom} ({popup.properties.code}) -

+ {popup.properties.nom} ({popup.properties.code})
Nombre d’adresses : {popup.properties.nbNumeros}
{`${popup.properties.certificationPercentage ? `Taux de certification : ${popup.properties.certificationPercentage}%` : 'Aucune adresse n’est certifiée par la commune'}`}
{popup.properties.hasBAL ?
Déposé via : {popup.properties.nomClient}
:
Ne dispose pas d'une BAL
} + Voir la page commune
)}