/** * LeafletHeroMapInner * Minimal single-school map for the detail hero. Renders as a static preview * (all interaction disabled so it never traps page scroll); when `interactive` * flips true — i.e. the hero map has gone fullscreen — pan/zoom are enabled and * a zoom control appears. */ 'use client'; import { useEffect, useRef } from 'react'; import L from 'leaflet'; import 'leaflet/dist/leaflet.css'; interface LeafletHeroMapInnerProps { lat: number; lng: number; interactive: boolean; } // Coral teardrop pin with a soft halo — inline styles only, so it renders // reliably inside Leaflet's divIcon HTML string (no CSS-module dependency). const PIN_HTML = `
`; export default function LeafletHeroMapInner({ lat, lng, interactive }: LeafletHeroMapInnerProps) { const elRef = useRef(null); const mapRef = useRef(null); const zoomCtrlRef = useRef(null); // Create the map once. useEffect(() => { if (!elRef.current || mapRef.current) return; const map = L.map(elRef.current, { zoomControl: false, attributionControl: true, dragging: false, scrollWheelZoom: false, doubleClickZoom: false, boxZoom: false, keyboard: false, touchZoom: false, }).setView([lat, lng], 15); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors', maxZoom: 19, }).addTo(map); L.marker([lat, lng], { icon: L.divIcon({ className: '', iconSize: [26, 34], iconAnchor: [13, 30], html: PIN_HTML }), keyboard: false, }).addTo(map); mapRef.current = map; setTimeout(() => map.invalidateSize(), 60); return () => { map.remove(); mapRef.current = null; zoomCtrlRef.current = null; }; }, [lat, lng]); // Toggle interaction (and the zoom control) when entering/leaving fullscreen, // and re-measure since the container size changes. useEffect(() => { const map = mapRef.current; if (!map) return; const handlers = [ map.dragging, map.scrollWheelZoom, map.doubleClickZoom, map.boxZoom, map.keyboard, map.touchZoom, ]; handlers.forEach((h) => { if (h) { interactive ? h.enable() : h.disable(); } }); if (interactive && !zoomCtrlRef.current) { zoomCtrlRef.current = L.control.zoom({ position: 'topleft' }); zoomCtrlRef.current.addTo(map); } else if (!interactive && zoomCtrlRef.current) { zoomCtrlRef.current.remove(); zoomCtrlRef.current = null; } if (!interactive) map.setView([lat, lng], 15); setTimeout(() => map.invalidateSize(), 80); }, [interactive, lat, lng]); return
; }