'use client' import { memo } from 'react' import { Pentagon, Ruler, Spline, Trash2 } from 'lucide-react' import { cn } from '@djangocfg/ui-core/lib' import { Tooltip, TooltipContent, TooltipTrigger, } from '@djangocfg/ui-core/components' import { MapSource, MapLayer } from './MapSource' import { useMeasure, type MeasureMode } from '../hooks/useMeasure' import { createLineLayer } from '../layers/line' import { createPolygonLayer, createPolygonOutlineLayer } from '../layers/polygon' export interface MeasureControlProps { /** Corner the control toolbar is pinned to. @default 'top-left' */ position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' /** Mode the tool starts in. @default 'distance' */ defaultMode?: MeasureMode /** Accent color for the measure overlay (line stroke / polygon fill). */ accentColor?: string className?: string } const positionStyles: Record< NonNullable, React.CSSProperties > = { 'top-left': { top: 12, left: 12 }, 'top-right': { top: 12, right: 12 }, 'bottom-left': { bottom: 12, left: 12 }, 'bottom-right': { bottom: 12, right: 12 }, } // Same floating-chrome chip style MapContainer uses for its map controls // (semantic `popover` tokens — reads like maplibre's own controls in light // and dark themes). Kept in sync with MAP_CONTROL_CLASS there. const MAP_CONTROL_CLASS = cn( 'inline-flex items-center justify-center rounded-lg', 'bg-popover/95 text-popover-foreground backdrop-blur-sm shadow-sm border border-border', 'hover:bg-popover transition-colors', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring', ) const SOURCE_ID = 'measure-source' /** * On-map measure control — click to measure a path's length (km) or a * polygon's area (m²/km²), with a live total readout and a clear button. * * Drop it as a child of `MapContainer` / `MapView` (inside the * `MapProvider`), alongside `MapLegend` / `LayerSwitcher`: * * ```tsx * * * * ``` * * Renders the measure geometry through the existing `createLineLayer` / * `createPolygonLayer` factories — no bespoke layer code. */ function MeasureControlComponent({ position = 'top-left', defaultMode = 'distance', accentColor = '#f97316', className = '', }: MeasureControlProps) { const { mode, setMode, geojson, totalLabel, points, clear, active, setActive } = useMeasure(defaultMode) const hasMeasurement = points.length > 0 return ( <> {/* Overlay geometry — reuses the existing line / polygon factories. */} {mode === 'area' ? ( <> ) : ( )} {/* Toolbar — a single popover chip, same chrome as the map controls. */}
{active ? 'Stop measuring' : 'Measure'} {/* Mode switch — distance / area. */} Distance Area {/* Live total readout. */} {totalLabel} {/* Clear. */} Clear
) } export const MeasureControl = memo(MeasureControlComponent)