fix: freehand drawing, click highlight, mobile toolbar visibility

Freehand drawing fix:
- Disable dragPan when in freehand mode (was only disabling dblclick
  zoom). Without this, clicks were interpreted as pan gestures.
- Re-enable dragPan when exiting freehand mode.

Click highlight:
- Clicking a parcel in "off" mode now highlights it with the selection
  layer (amber fill + orange outline). Clicking empty space clears it.
- Provides visual feedback for which parcel was clicked.

Mobile toolbar:
- Moved selection toolbar higher (bottom-12 on mobile) with z-20
  to ensure it's above MapLibre attribution bar.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
AI Assistant
2026-03-25 07:11:16 +02:00
parent 45d4d1bf40
commit 8acafe958b
2 changed files with 21 additions and 4 deletions
+2 -2
View File
@@ -1597,8 +1597,8 @@ function HartaContent() {
)} )}
</div> </div>
{/* Bottom: selection toolbar — centered on mobile, above attribution */} {/* Bottom: selection toolbar — centered, above attribution */}
<div className="absolute bottom-8 left-1/2 -translate-x-1/2 sm:left-3 sm:translate-x-0 z-10"> <div className="absolute bottom-12 sm:bottom-8 left-1/2 -translate-x-1/2 sm:left-3 sm:translate-x-0 z-20">
<SelectionToolbar <SelectionToolbar
selectedFeatures={selectedFeatures} selectedFeatures={selectedFeatures}
selectionMode={selectionMode} selectionMode={selectionMode}
@@ -495,6 +495,11 @@ export const MapViewer = forwardRef<MapViewerHandle, MapViewerProps>(
}); });
if (features.length === 0) { if (features.length === 0) {
// Clear highlight when clicking empty space
try {
map.setFilter(LAYER_IDS.selectionFill, ["==", "object_id", "__NONE__"]);
map.setFilter(LAYER_IDS.selectionLine, ["==", "object_id", "__NONE__"]);
} catch { /* noop */ }
onFeatureClick?.(null as unknown as ClickedFeature); // close panel onFeatureClick?.(null as unknown as ClickedFeature); // close panel
return; return;
} }
@@ -519,8 +524,16 @@ export const MapViewer = forwardRef<MapViewerHandle, MapViewerProps>(
return; return;
} }
// Feature click — notify parent (no popup) — only when off or click mode on non-terenuri // Feature click — notify parent (no popup) — only when off
if (mode === "off") { if (mode === "off") {
// Highlight clicked parcel with selection layer
const objectId = String(props.object_id ?? "");
if (objectId && sourceLayer === SOURCES.terenuri) {
try {
map.setFilter(LAYER_IDS.selectionFill, ["==", "object_id", objectId]);
map.setFilter(LAYER_IDS.selectionLine, ["==", "object_id", objectId]);
} catch { /* noop */ }
}
onFeatureClick?.({ onFeatureClick?.({
layerId: first.layer?.id ?? "", layerId: first.layer?.id ?? "",
sourceLayer, sourceLayer,
@@ -734,14 +747,18 @@ export const MapViewer = forwardRef<MapViewerHandle, MapViewerProps>(
mapRef.current.flyTo({ center, zoom: zoom ?? mapRef.current.getZoom(), duration: 1500 }); mapRef.current.flyTo({ center, zoom: zoom ?? mapRef.current.getZoom(), duration: 1500 });
}, [center, zoom, mapReady]); }, [center, zoom, mapReady]);
/* ---- Disable double-click zoom when in freehand mode ---- */ /* ---- Disable interactions when in drawing modes ---- */
useEffect(() => { useEffect(() => {
const map = mapRef.current; const map = mapRef.current;
if (!map) return; if (!map) return;
if (selectionType === "freehand") { if (selectionType === "freehand") {
map.doubleClickZoom.disable(); map.doubleClickZoom.disable();
map.dragPan.disable();
} else if (selectionType === "rect") {
// rect handles dragPan itself in mousedown/mouseup
} else { } else {
map.doubleClickZoom.enable(); map.doubleClickZoom.enable();
map.dragPan.enable();
} }
}, [selectionType, mapReady]); }, [selectionType, mapReady]);