import * as React from 'react'; import * as ReactDOM from 'react-dom'; import * as PropTypes from 'prop-types'; import * as L from 'leaflet'; import { Component } from 'react'; import { Children, Circle, CircleMarker, FeatureGroup, LayerGroup, LayersControl, Map, MapControl, MapControlProps, MapProps, Marker, MarkerProps, Path, Pane, Polygon, PolygonProps, Polyline, Popup, PopupProps, Rectangle, TileLayer, SVGOverlay, Tooltip, WMSTileLayer, ZoomControl, LeafletProvider, withLeaflet, Viewport, useLeaflet, GeoJSON, GeoJSONProps } from 'react-leaflet'; const { BaseLayer, Overlay } = LayersControl; /// animate.js interface AnimateExampleState { animate: boolean; hasLocation: boolean; latlng: L.LatLngExpression; } export class AnimateExample extends Component { state = { animate: false, hasLocation: false, latlng: { lat: 51.505, lng: -0.09, }, }; handleClick = (e: L.LeafletMouseEvent) => { this.setState({ latlng: e.latlng, }); } toggleAnimate = () => { this.setState({ animate: !this.state.animate, }); } render() { const marker = this.state.hasLocation ? ( You are here ) : null; return (
{marker}
); } } // bounds.js const outer: L.LatLngBoundsLiteral = [ [50.505, -29.09], [52.505, 29.09], ]; const inner: L.LatLngBoundsLiteral = [ [49.505, -2.09], [53.505, 2.09], ]; interface BoundsExampleState { bounds: L.LatLngBoundsLiteral; } export class BoundsExample extends Component { state = { bounds: outer, }; onClickInner = () => { this.setState({ bounds: inner }); } onClickOuter = () => { this.setState({ bounds: outer }); } render() { return ( ); } } // custom-component.js interface MyPopupMarkerProps { children: Children; position: L.LatLngExpression; } interface MyMarker extends MyPopupMarkerProps { key: string; } const MyPopupMarker = ({ children, position }: MyPopupMarkerProps) => ( {children} ); interface MyMarkersListProps { markers: MyMarker[]; } const MyMarkersList = ({ markers }: MyMarkersListProps) => { const items = markers.map(({ key, ...props }) => ( )); return
{items}
; }; interface CustomComponentState { lat: number; lng: number; zoom: number; } export class CustomComponent extends Component { state = { lat: 51.505, lng: -0.09, zoom: 13, }; render() { const center: L.LatLngExpression = [this.state.lat, this.state.lng]; const markers: MyMarker[] = [ { key: 'marker1', position: [51.5, -0.1], children: 'My first popup' }, { key: 'marker2', position: [51.51, -0.1], children: 'My second popup' }, { key: 'marker3', position: [51.49, -0.05], children: 'My third popup' }, ]; return ( ); } } // Similar to custom-icons.js export class MarkerWithDivIconExample extends Component { render() { return ( ); } } // draggable-marker.js interface DraggableExampleState { center: L.LatLngLiteral; marker: L.LatLngLiteral; zoom: number; draggable: boolean; } export class DraggableExample extends Component { state = { center: { lat: 51.505, lng: -0.09, }, marker: { lat: 51.505, lng: -0.09, }, zoom: 13, draggable: true, }; toggleDraggable = () => { this.setState({ draggable: !this.state.draggable }); } updatePosition = () => { const { lat, lng, } = (this.refs.marker as Marker).leafletElement.getLatLng(); this.setState({ marker: { lat, lng }, }); } render() { const position: L.LatLngExpression = [this.state.center.lat, this.state.center.lng]; const markerPosition: L.LatLngExpression = [this.state.marker.lat, this.state.marker.lng]; return ( {this.state.draggable ? 'DRAG MARKER' : 'MARKER FIXED'} ); } } // events.js interface EventsExampleState { hasLocation: boolean; latlng: L.LatLngLiteral; } export class EventsExample extends Component { state = { hasLocation: false, latlng: { lat: 51.505, lng: -0.09, }, }; handleClick = () => { (this.refs.map as Map).leafletElement.locate(); } handleLocationFound = (e: L.LocationEvent) => { this.setState({ hasLocation: true, latlng: e.latlng, }); } render() { const marker = this.state.hasLocation ? ( You are here ) : null; return ( {marker} ); } } // layers-control.js export class LayersControlExample extends Component { render() { const center: L.LatLngExpression = [51.505, -0.09]; const rectangle: L.LatLngBoundsExpression = [ [51.49, -0.08], [51.5, -0.06], ]; return ( A pretty CSS3 popup.
Easily customizable.
Popup in FeatureGroup
); } } // other-layers.js export class OtherLayersExample extends Component { render() { const center: L.LatLngExpression = [51.505, -0.09]; const rectangle: L.LatLngBoundsExpression = [ [51.49, -0.08], [51.5, -0.06], ]; return ( Popup in FeatureGroup ); } } // pane.js interface PaneExampleState { render: boolean; } export class PaneExample extends Component { state = { render: true, }; componentDidMount() { setInterval(() => { this.setState({ render: !this.state.render, }); }, 5000); } render() { return ( {this.state.render ? ( ) : null} ); } } // simple.js interface SimpleExampleState { lat: number; lng: number; zoom: number; } export class SimpleExample extends Component { state = { lat: 51.505, lng: -0.09, zoom: 13, }; render() { const position: L.LatLngExpression = [this.state.lat, this.state.lng]; return ( A pretty CSS3 popup.
Easily customizable.
); } } // svg-overlay.js export default class SVGOverlayExample extends Component { render() { return ( text ); } } // tooltip.js interface TooltipExampleState { clicked: number; } export class TooltipExample extends Component { state = { clicked: 0, }; onClickCircle = () => { this.setState({ clicked: this.state.clicked + 1 }); } render() { const center: L.LatLngExpression = [51.505, -0.09]; const multiPolygon: L.LatLngExpression[][] = [ [[51.51, -0.12], [51.51, -0.13], [51.53, -0.13]], [[51.51, -0.05], [51.51, -0.07], [51.53, -0.07]], ]; const rectangle: L.LatLngBoundsExpression = [ [51.49, -0.08], [51.5, -0.06], ]; const clickedText = this.state.clicked === 0 ? 'Click this Circle to change the Tooltip text' : `Circle click: ${this.state.clicked}`; return ( {clickedText} Tooltip for CircleMarker Popup for Marker Tooltip for Marker sticky Tooltip for Polygon permanent Tooltip for Rectangle ); } } // vector-layers.js export class VectorLayersExample extends Component { render() { const center: L.LatLngExpression = [51.505, -0.09]; const polyline: L.LatLngExpression[] = [ [51.505, -0.09], [51.51, -0.1], [51.51, -0.12], ]; const multiPolyline: L.LatLngExpression[][] = [ [[51.5, -0.1], [51.5, -0.12], [51.52, -0.12]], [[51.5, -0.05], [51.5, -0.06], [51.52, -0.06]], ]; const polygon: L.LatLngExpression[] = [ [51.515, -0.09], [51.52, -0.1], [51.52, -0.12], ]; const multiPolygon: L.LatLngExpression[][] = [ [[51.51, -0.12], [51.51, -0.13], [51.53, -0.13]], [[51.51, -0.05], [51.51, -0.07], [51.53, -0.07]], ]; const rectangle: L.LatLngBoundsExpression = [ [51.49, -0.08], [51.5, -0.06], ]; return ( Popup in CircleMarker ); } } // viewport.js const DEFAULT_VIEWPORT: Viewport = { center: [51.505, -0.09], zoom: 13, }; interface ViewportExampleState { viewport: Viewport; } class ViewportExample extends Component { state = { viewport: DEFAULT_VIEWPORT, }; onClickReset = () => { this.setState({ viewport: DEFAULT_VIEWPORT }); } onViewportChanged = (viewport: Viewport) => { this.setState({ viewport }); } render() { return ( ); } } // wms-tile-layer.js interface WMSTileLayerExampleState { lat: number; lng: number; zoom: number; bluemarble: boolean; } export class WMSTileLayerExample extends Component { state = { lat: 51.505, lng: -0.09, zoom: 5, bluemarble: false, }; onClick = () => { this.setState({ bluemarble: !this.state.bluemarble, }); } render() { return ( ); } } // zoom-control.js const ZoomControlExample = () => ( ); // MapControl https://github.com/PaulLeCam/react-leaflet/issues/130 class CenterControl extends MapControl { // note we're extending MapControl from react-leaflet, not Component from react componentWillMount() { const centerControl = new L.Control({ position: 'bottomright' }); // see http://leafletjs.com/reference.html#control-positions for other positions const jsx = ( // PUT YOUR JSX FOR THE COMPONENT HERE:
{/* add your JSX */}
); centerControl.onAdd = (map) => { const div = L.DomUtil.create('div', ''); ReactDOM.render(jsx, div); return div; }; this.leafletElement = centerControl; } } const mapControlCenter: L.LatLngExpression = [51.505, -0.09]; const CenterControlExample = () => ( ); class LegendControl extends MapControl { componentWillMount() { const legend = new L.Control({ position: 'bottomright' }); const jsx = (
{this.props.children}
); legend.onAdd = (map) => { const div = L.DomUtil.create('div', ''); ReactDOM.render(jsx, div); return div; }; this.leafletElement = legend; } } const legendControlComponent = withLeaflet(LegendControl); const LegendControlExample = () => (
  • Strong Support
  • Weak Support
  • Weak Oppose
  • Strong Oppose
); class CustomPolygon extends Path { createLeafletElement(props: PolygonProps) { const el = new L.Polygon(props.positions, this.getOptions(props)); this.contextValue = { ...props.leaflet, popupContainer: el }; return el; } updateLeafletElement(fromProps: PolygonProps, toProps: PolygonProps) { if (toProps.positions !== fromProps.positions) { this.leafletElement.setLatLngs(toProps.positions); } this.setStyleIfChanged(fromProps, toProps); } render() { const { children } = this.props; return children == null || this.contextValue == null ? null : ( {children} ); } } const leafletComponent = withLeaflet(CustomPolygon); // $ExpectType LeafletContext useLeaflet(); const northDakota: GeoJSON.Feature = { type: "Feature", properties: {name: "North Dakota"}, geometry: { type: "Polygon", coordinates: [[ [-104.05, 48.99], [-97.22, 48.98], [-96.58, 45.94], [-104.03, 45.94], [-104.05, 48.99] ]] } }; const colorado: GeoJSON.Feature = { type: "Feature", properties: {name: "Colorado"}, geometry: { type: "Polygon", coordinates: [[ [-109.05, 41.00], [-102.06, 40.99], [-102.03, 36.99], [-109.04, 36.99], [-109.05, 41.00] ]] } }; // GeoJSON export class GeoJSONExample extends Component { polygons: GeoJSON.GeoJsonObject[] = [northDakota, colorado]; vp: Viewport = { center: [-102, 40], zoom: 10 }; render() { return ( ); } }