ReactJS maps without external dependencies - performance-first React-centric extendable map engine
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
The Map component is the core interactive map that displays tile layers, handles user interactions, and manages map state. It provides a full-featured mapping experience with support for animations, event handling, and coordinate transformations.
The main Map component that renders tiles and handles all map interactions.
/**
* Interactive map component with tile rendering and user interactions
* @param props - Map configuration and event handlers
* @returns JSX.Element representing the map
*/
function Map(props: MapProps): JSX.Element;
interface MapProps {
// Position and size configuration
center?: Point;
defaultCenter?: Point;
zoom?: number;
defaultZoom?: number;
width?: number;
height?: number;
defaultWidth?: number;
defaultHeight?: number;
// Tile provider configuration
provider?: (x: number, y: number, z: number, dpr?: number) => string;
dprs?: number[];
// Animation settings
animate?: boolean;
animateMaxScreens?: number;
// Zoom constraints
minZoom?: number;
maxZoom?: number;
// Interaction controls
metaWheelZoom?: boolean;
metaWheelZoomWarning?: string;
twoFingerDrag?: boolean;
twoFingerDragWarning?: string;
warningZIndex?: number;
// Display settings
attribution?: ReactElement | false;
attributionPrefix?: ReactElement | false;
zoomSnap?: boolean;
mouseEvents?: boolean;
touchEvents?: boolean;
limitBounds?: 'center' | 'edge';
boxClassname?: string;
tileComponent?: TileComponent;
// Event handlers
onClick?: (params: {
event: MouseEvent;
latLng: Point;
pixel: Point;
}) => void;
onBoundsChanged?: (params: {
center: Point;
zoom: number;
bounds: Bounds;
initial: boolean;
}) => void;
onAnimationStart?: () => void;
onAnimationStop?: () => void;
// Child elements
children?: React.ReactNode;
}
// Default props values
static defaultProps = {
animate: true,
metaWheelZoom: false,
metaWheelZoomWarning: 'Use META + wheel to zoom!',
twoFingerDrag: false,
twoFingerDragWarning: 'Use two fingers to move the map',
zoomSnap: true,
mouseEvents: true,
touchEvents: true,
warningZIndex: 100,
animateMaxScreens: 5,
minZoom: 1,
maxZoom: 18,
limitBounds: 'center',
dprs: []
};Usage Examples:
import React, { useState } from "react";
import { Map } from "pigeon-maps";
import { osm } from "pigeon-maps/providers";
// Basic map
function BasicMap() {
return (
<Map
height={400}
center={[50.879, 4.6997]}
zoom={11}
provider={osm}
/>
);
}
// Controlled map with events
function ControlledMap() {
const [center, setCenter] = useState([50.879, 4.6997]);
const [zoom, setZoom] = useState(11);
return (
<Map
height={400}
center={center}
zoom={zoom}
onBoundsChanged={({ center, zoom }) => {
setCenter(center);
setZoom(zoom);
}}
onClick={({ latLng }) => {
console.log('Clicked at:', latLng);
}}
/>
);
}
// Map with custom settings
function CustomMap() {
return (
<Map
height={400}
center={[50.879, 4.6997]}
zoom={11}
animate={true}
metaWheelZoom={true}
twoFingerDrag={true}
minZoom={5}
maxZoom={15}
zoomSnap={false}
attribution={false}
/>
);
}Methods for converting between geographic coordinates and pixel coordinates.
/**
* Convert pixel coordinates to latitude/longitude
* @param pixel - Pixel coordinates [x, y]
* @param center - Optional center point for calculation
* @param zoom - Optional zoom level for calculation
* @returns Geographic coordinates [lat, lng]
*/
pixelToLatLng(pixel: Point, center?: Point, zoom?: number): Point;
/**
* Convert latitude/longitude to pixel coordinates
* @param latLng - Geographic coordinates [lat, lng]
* @param center - Optional center point for calculation
* @param zoom - Optional zoom level for calculation
* @returns Pixel coordinates [x, y]
*/
latLngToPixel(latLng: Point, center?: Point, zoom?: number): Point;Methods for programmatically controlling the map.
/**
* Set the map center and zoom level programmatically
* @param center - New center coordinates or null to keep current
* @param zoom - New zoom level
* @param zoomAround - Optional point to zoom around
* @param animationDuration - Duration of animation in milliseconds
*/
setCenterZoom(
center: Point | null,
zoom: number,
zoomAround?: Point | null,
animationDuration?: number
): void;
/**
* Get the current map bounds
* @param center - Optional center for bounds calculation
* @param zoom - Optional zoom for bounds calculation
* @returns Current map bounds
*/
getBounds(center?: Point, zoom?: number): Bounds;/**
* Current map state passed to child components
*/
interface MapState {
bounds: Bounds;
zoom: number;
center: Point;
width: number;
height: number;
}
/**
* Map bounds definition
*/
interface Bounds {
ne: [number, number]; // northeast corner [lat, lng]
sw: [number, number]; // southwest corner [lat, lng]
}onClick?: (params: {
event: MouseEvent;
latLng: Point;
pixel: Point;
}) => void;The onClick handler receives the mouse event, the geographic coordinates where clicked, and the pixel coordinates.
onBoundsChanged?: (params: {
center: Point;
zoom: number;
bounds: Bounds;
initial: boolean;
}) => void;Fired when the map bounds change due to user interaction or programmatic changes. The initial flag indicates if this is the first bounds change event.
onAnimationStart?: () => void;
onAnimationStop?: () => void;Called when map animations (zoom/pan transitions) start and stop.
type TileComponent = (props: TileComponentProps) => ReactElement;
interface TileComponentProps {
tile: Tile;
tileLoaded: () => void;
}
interface Tile {
key: string;
url: string;
srcSet: string;
left: number;
top: number;
width: number;
height: number;
active: boolean;
}The map can show warning overlays when users try to interact incorrectly (e.g., trying to zoom without meta key when metaWheelZoom is enabled).
interface WarningProps {
metaWheelZoom?: boolean;
metaWheelZoomWarning?: string;
twoFingerDrag?: boolean;
twoFingerDragWarning?: string;
warningZIndex?: number;
}limitBounds?: 'center' | 'edge';'center': Limits the map so the center point stays within world bounds'edge': Limits the map so the visible edge stays within world boundsInstall with Tessl CLI
npx tessl i tessl/npm-pigeon-maps