Leaflet.Path.Drag is a plugin to the Leaflet library. It works by patching the global L
instance that Leaflet adds to the window. This mechanism works fine when Leaflet and the plugin are incorporated in an app via script tags. But in a modern TS/React app that uses ES6 modules, simply installing the two packages and then importing them doesn't achieve the needed plugin integration. To get the plugin to work I've tried the following in my Reach Leaflet app, as recommended here:
// Import Leaflet into L
import * as L from 'leaflet';
// Import the plugin library so it will modify L
import 'leaflet-path-drag';
const createDraggablePolygon = () => {
const geometry = {
type: "Polygon",
coordinates: [[[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]]
}
const geoJson = L.geoJSON(geometry, {});
// plugin should add 'dragging' property to the GeoJSON object
assert("dragging" in geoJson);
}
This doesn't work either (the assertion fails). Suggestions?
One clarification: I am not trying to build a plugin for React Leaflet (at least if I can avoid it). In my case it's fine if the behaviors exposed by the plugin are only available through Leaflet elements and not through the React Leaflet library.
I found the problem. The solution above actually patches the Leaflet library correctly. The reason the geoJSON
layer didn't have the dragging
property was that it extends LayerGroup
so you need to include an onEachFeature
function in the options. The layers that Leaflet passes into that function are the ones that have been patched with the dragging
property. So I needed something like this:
// Import Leaflet into L
import * as L from 'leaflet';
// Import the plugin library so it will modify L
import 'leaflet-path-drag';
const initDraggableLayer = (feature, layer) => {
// plugin adds 'dragging' property to this layer
assert("draggable" in layer);
}
const createDraggablePolygon = () => {
const geometry = {
type: "Polygon",
coordinates: [[[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]]
}
const geoJson = L.geoJSON(geometry, {
onEachFeature: initDraggableLayer
});
}