import React from 'react'; import { cn } from '../../shared/utils'; import { mapOverlayPositionClasses } from '../map/map-overlay-position'; import type { MapOverlayPosition } from '../map/map.types'; import { niceScaleDistance } from './scale-distance'; import type { MapScaleUnits } from './units'; export interface MapScaleBarProps extends React.HTMLAttributes { /** * Ground distance one pixel covers. `` computes this from the current * zoom and latitude; pass it directly only when driving the bar yourself. */ metersPerPixel: number; /** @default 'metric' */ units?: MapScaleUnits; /** Longest the bar may be drawn, in pixels. @default 120 */ maxWidthPx?: number; /** @default 'bottom-right' */ position?: MapOverlayPosition; /** @default 'overlay' */ layout?: 'overlay' | 'inline'; } /** * Graphic scale bar. * * @description * No surveyed application had one, yet reports and dossiers circulate off * screen — and a static map with no scale cannot support a claim about * distance. Recomputed on every zoom change. * * @ai-rules * 1. Include it on any map that will be printed or exported. * 2. Prefer `` over mounting this directly; the map already knows its zoom and latitude. * 3. The bar is decorative to assistive tech — its label carries the information. */ export const MapScaleBar = React.forwardRef( ( { metersPerPixel, units = 'metric', maxWidthPx = 120, position = 'bottom-right', layout = 'overlay', className, ...props }, ref ) => { const scale = niceScaleDistance(metersPerPixel, maxWidthPx, units); if (!scale) return null; return (
{scale.label}
); } ); MapScaleBar.displayName = 'MapScaleBar';