85 lines
1.9 KiB
Plaintext
85 lines
1.9 KiB
Plaintext
// @flow
|
|
|
|
import type { Evented } from 'leaflet'
|
|
import { Component } from 'react'
|
|
|
|
export const EVENTS_RE = /^on(.+)$/i
|
|
|
|
type EventHandler = (event: Event) => void
|
|
type EventsObject = { [key: string]: EventHandler }
|
|
|
|
export default class MapEvented<
|
|
LeafletElement: Evented,
|
|
Props: Object,
|
|
> extends Component<Props> {
|
|
_leafletEvents: EventsObject
|
|
leafletElement: LeafletElement
|
|
|
|
constructor(props: Props) {
|
|
super(props)
|
|
this._leafletEvents = this.extractLeafletEvents(props)
|
|
}
|
|
|
|
componentDidMount() {
|
|
this.bindLeafletEvents(this._leafletEvents)
|
|
}
|
|
|
|
componentDidUpdate(_prevProps: Props) {
|
|
this._leafletEvents = this.bindLeafletEvents(
|
|
this.extractLeafletEvents(this.props),
|
|
this._leafletEvents,
|
|
)
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
const el = this.leafletElement
|
|
if (!el) return
|
|
|
|
Object.keys(this._leafletEvents).forEach((ev) => {
|
|
el.off(ev, this._leafletEvents[ev])
|
|
})
|
|
}
|
|
|
|
extractLeafletEvents(props: Props): EventsObject {
|
|
return Object.keys(props).reduce((res, prop) => {
|
|
if (EVENTS_RE.test(prop)) {
|
|
if (props[prop] != null) {
|
|
const key = prop.replace(EVENTS_RE, (match, p) => p.toLowerCase())
|
|
res[key] = props[prop]
|
|
}
|
|
}
|
|
return res
|
|
}, {})
|
|
}
|
|
|
|
bindLeafletEvents(
|
|
next: EventsObject = {},
|
|
prev: EventsObject = {},
|
|
): EventsObject {
|
|
const el = this.leafletElement
|
|
if (el == null || el.on == null) return {}
|
|
|
|
const diff = { ...prev }
|
|
Object.keys(prev).forEach((ev) => {
|
|
if (next[ev] == null || prev[ev] !== next[ev]) {
|
|
delete diff[ev]
|
|
el.off(ev, prev[ev])
|
|
}
|
|
})
|
|
|
|
Object.keys(next).forEach((ev) => {
|
|
if (prev[ev] == null || next[ev] !== prev[ev]) {
|
|
diff[ev] = next[ev]
|
|
el.on(ev, next[ev])
|
|
}
|
|
})
|
|
|
|
return diff
|
|
}
|
|
|
|
fireLeafletEvent(type: string, data: ?any) {
|
|
const el = this.leafletElement
|
|
if (el) el.fire(type, data)
|
|
}
|
|
}
|