Creates a control wrapper around a React element
npm install react-leaflet-custom-control
A React wrapper to create a custom control for react-leaflet using ReactDOM's Portal capabilities
The current version of this package supports React Leaflet v3
NOTE
||
|--|
|Version ^1.2.3 (which adds this note to the README) has updated peer dependencies for React v18. This may be a breaking change depending on your environment. If you are still running React v17 then install version 1.2.2.|
|Version ^1.4.0 now has a dependency on react-leaflet@^4.2.1. This allows for the useMap() hook. This also requires that this Control component MUST be a child of your MapContainer|
|Version ^1.5.0 has updated react dependencies to include ^react@19.0.0|
bash
#npm
npm install --save react-leaflet-custom-control#yarn
yarn add react-leaflet-custom-control
`Usage
`jsx
import { MapContainer, TileLayer } from 'react-leaflet'
import Control from 'react-leaflet-custom-control'
import { Button } from '@mui/material'
import { Search as SearchIcon } from '@mui/icons-material'
import 'leaflet.css'
attribution="Esri, DigitalGlobe, GeoEye, Earthstar Geographics, CNES/Airbus DS, USDA, USGS, AeroGRID, IGN, and the GIS User Community"
className="basemap"
maxNativeZoom={19}
maxZoom={19}
subdomains={["clarity"]}
url="https://{s}.maptiles.arcgis.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"
/>
`
Order Matters!
Because this uses React.createPortal which inherently appends the portal, DOM manipulation is used to append or prepend a container element to the portal target. Because of this, the order of your custom controls matter! The last Control element to be prepended to a control position will be at the very top while the last Control element to be appended to a control position will be at the very bottom. If mixing with default React Leaflet controls, they will be in between your custom controls.$3
However, because of the way that the portal works and re-renders, multiple control elements will shift order after renders, so it's recommended to have a wrapping element be the child of the Control to prevent re-ordering each render$3
`jsx
import { MapContainer, TileLayer, ZoomControl } from 'react-leaflet'
import Control from 'react-leaflet-custom-control'
import { Button, Stack } from '@mui/material'
import {
Add as AddIcon,
Delete as DeleteIcon,
Search as SearchIcon
} from '@mui/icons-material'
import 'leaflet.css'
attribution="Esri, DigitalGlobe, GeoEye, Earthstar Geographics, CNES/Airbus DS, USDA, USGS, AeroGRID, IGN, and the GIS User Community"
className="basemap"
maxNativeZoom={19}
maxZoom={19}
subdomains={["clarity"]}
url="https://{s}.maptiles.arcgis.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"
/>
{/ Search control is the very top right control /}
{/ This control will be below the default zoom control. Note the wrapping Stack component /}
`Props
| Name | Type | Default | Description |
|----------------|----------------------------------------------------------------------|------------------|------------------------------------|
| position | ControlOptions | required | The position of the control |
| children? | any | undefined | Child element to the control |
| ~~style?~~ | ~~React.CSSProperties~~ | ~~undefined~~ | ~~CSS Styles to override the control~~ |
| container? | React.HTMLAttributes | undefined | The target root container for the portal |
| prepend? | boolean | undefined | Whether the control should be prepended or appended to the position|Thanks
Huge thanks to @davetapley for contributing to @1.3.0 and helping to work some of the issues.
Thanks to @samiamlabs for contributing to @1.3.2 for fixing the infinite div` issue.