This component wraps a MapLibre Marker object. He manages its life cycle and is
responsible for adding/removing it to the map. For this reason this component
must be a descendant of RMap
.
import { RMap, RMarker } from "maplibre-react-components";
import CustomMarker from "./CustomMarker";
const center: [number, number] = [-0.5, 47.5];
export default function App() {
return (
<RMap initialCenter={center}>
<RMarker longitude={-2.5} latitude={55} />
{/* with custom Element */}
<RMarker longitude={19} latitude={53.6} initialAnchor="bottom">
<CustomMarker />
</RMarker>
</RMap>
);
}
If you use a custom marker element don't forgot to memoize the component.
// CustomMarker.tsx
import { memo } from "react";
// https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.
const ICON = `M215.7 499.2C267 435 384 279.4 384 192C384 86 298 0 192 0S0 86 0 192c0 87.4 117 243 168.3 307.2c12.3 15.3 35.1 15.3 47.4 0zM192 128a64 64 0 1 1 0 128 64 64 0 1 1 0-128z`;
function CustomMarker() {
return (
<svg
height={30}
viewBox="0 0 384 512"
style={{ cursor: "pointer", fill: "#DBA726" }}
>
<path d={ICON} />
</svg>
);
}
export default memo(CustomMarker);
If your marker component is draggable, you need to register a handler for the dragend
or drag
event
to update the state.
import { type Marker } from "maplibre-gl";
import { Event, RMap, RMarker } from "maplibre-react-components";
import { useCallback, useState } from "react";
const center: [number, number] = [-0.5, 47.5];
export default function App() {
const [markerCoords, setMarkerCoords] = useState(center);
const handleDragEnd = useCallback((e: Event<Marker>) => {
setMarkerCoords(e.target.getLngLat().toArray());
}, []);
return (
<RMap initialCenter={center} initialZoom={2}>
{/* controlled marker */}
<RMarker
longitude={markerCoords[0]}
latitude={markerCoords[1]}
draggable={true}
onDragEnd={handleDragEnd}
/>
<div className="absolute bottom-4 left-4 rounded-2xl bg-gray-0 p-4">
Marker position : {markerCoords.map(Math.round).join(", ")}
</div>
</RMap>
);
}
Check the MapLibre MarkerOptions reference page for details of MarkerInitialOptions
and MarkerReactiveOptions
.
type RMarkerProps =
{
longitude: number;
latitude: number;
/**
* for custom element
*/
children?: ReactNode;
} &
/**
* Non reactive marker options (only used during instantiation)
* prefixed with "initial" + first letter uppercase
*/
MarkerInitialOptions &
/**
* Reactive marker options.
* they have the same name as in MarkerOptions
*/
MarkerReactiveOptions &
/**
* Listenners for marker events
* prefixed with "on" + first letter uppercase
*/
MarkerCallbacks;
type MarkerInitialOptions = {
initialAnchor?: PositionAnchor;
initialColor?: string;
initialScale?: number;
};
type MarkerReactiveOptions = {
className?: string;
offset?: PointLike;
draggable?: boolean;
clickTolerance?: number;
rotation?: number;
rotationAlignment?: Alignment;
pitchAlignment?: Alignment;
opacity?: string;
opacityWhenCovered?: string;
subpixelPositioning?: boolean; // v4.5.1+
};
import { Event } from "maplibre-react-components";
type MarkerCallbacks = {
onDragStart?: (e: Event<Marker>) => void;
onDrag?: (e: Event<Marker>) => void;
onDragEnd?: (e: Event<Marker>) => void;
// native DOM event
onClick?: (e: MouseEvent) => void;
}