/** * Author: Simon-Pierre Boucher * Contact: contact@spboucher.ai * Project: Groupe Ka / Ka Maps * * — la carte « fiche » : une seule propriété, caméra 3D * serrée sur l'adresse, et le bâtiment concerné mis en évidence (empreinte * 3D du featureset « buildings » de Mapbox Standard, coloré via * `buildingColor`). Fond réaliste par défaut (pleine couleur, repères 3D). * Gestes coopératifs : la fiche reste défilable au-dessus de la carte. */ import { useEffect, useRef, type CSSProperties, type ReactElement, type ReactNode } from "react"; import type { KaBasemapOptions } from "../styles/kaBaseStyle.js"; import type { KaMapMode, KaMapTheme } from "../theming/tokens.js"; import type { MapProperty } from "../types/index.js"; import { KaMapView, useKaMap } from "./KaMapView.js"; /** Rouge signal — l'immeuble de la fiche ressort du premier coup d'œil. */ const DEFAULT_BUILDING_COLOR = "#e03131"; const DEFAULT_ZOOM = 17.1; const DEFAULT_PITCH = 62; function SpotlightBridge({ property, color, zoom, pitch, }: { property: MapProperty; color: string; zoom: number; pitch: number; }) { const map = useKaMap(); const firstRun = useRef(true); useEffect(() => { if (!map) return; const at = { lng: property.longitude, lat: property.latitude }; // Premier rendu : la caméra est déjà posée par le constructeur ; // navigations suivantes (fiche → fiche) : glissement doux. if (firstRun.current) firstRun.current = false; else map.flyTo(at, { zoom, pitch }); map.focusBuilding(at, { color }); return () => map.focusBuilding(null); // eslint-disable-next-line react-hooks/exhaustive-deps }, [map, property.id, property.longitude, property.latitude, color]); return null; } export interface KaSpotlightMapProps { theme: KaMapTheme; mapboxToken: string; /** La propriété de la fiche — pastille de prix + bâtiment en évidence. */ property: MapProperty; mode?: KaMapMode; className?: string; style?: CSSProperties; /** Couleur de l'empreinte 3D du bâtiment. Défaut : rouge signal. */ buildingColor?: string; zoom?: number; pitch?: number; /** Surcharge du fond (défaut spotlight : pleine couleur + repères 3D). */ basemap?: KaBasemapOptions; children?: ReactNode; } export function KaSpotlightMap({ theme, mapboxToken, property, mode, className, style, buildingColor = DEFAULT_BUILDING_COLOR, zoom = DEFAULT_ZOOM, pitch = DEFAULT_PITCH, basemap, children, }: KaSpotlightMapProps): ReactElement { const properties = useRef([]); if (properties.current[0]?.id !== property.id) properties.current = [property]; return ( {children} ); }