From d60a14d991ee53d7e1b196ea209fe0225e3c198e Mon Sep 17 00:00:00 2001 From: Michael Underwood Date: Thu, 15 Jun 2023 21:20:28 -0600 Subject: [PATCH 1/2] Add back fall-through attrs not added as listeners Resolves #287 --- CHANGELOG.md | 4 ++-- src/components/LCircle.vue | 2 +- src/components/LCircleMarker.vue | 2 +- src/components/LFeatureGroup.vue | 2 +- src/components/LGeoJson.vue | 2 +- src/components/LGridLayer.vue | 2 +- src/components/LIcon.vue | 2 +- src/components/LImageOverlay.vue | 2 +- src/components/LLayerGroup.vue | 2 +- src/components/LMap.vue | 32 ++++++++++++++++++-------------- src/components/LMarker.vue | 2 +- src/components/LPolygon.vue | 2 +- src/components/LPolyline.vue | 2 +- src/components/LPopup.vue | 2 +- src/components/LRectangle.vue | 2 +- src/components/LTileLayer.vue | 2 +- src/components/LTooltip.vue | 2 +- src/components/LWmsTileLayer.vue | 2 +- src/utils.ts | 16 ++++++++++++---- 19 files changed, 48 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07865b0..9e50490 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,11 +14,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Playground now works again after upgrade to TypeScript. -- Fixed LMap event-handlers. Original issue here:(https://github.com/vue-leaflet/vue-leaflet/issues/287) +- Fixed LMap event-handlers, closing [#287 Click event not working with 0.9.0](https://github.com/vue-leaflet/vue-leaflet/issues/287). ### Changed -- **Breaking:** `src/` folder is no longer included in the build. Please use the new exported keys if you wanna access the injection keys or any function. +- **Breaking:** The `src/` folder is no longer included in the build. Please use the new exports to access the injection keys and libary functions. ## [0.9.0] - 2023-03-12 diff --git a/src/components/LCircle.vue b/src/components/LCircle.vue index e83c8d8..5fcb0ca 100644 --- a/src/components/LCircle.vue +++ b/src/components/LCircle.vue @@ -44,7 +44,7 @@ export default defineComponent({ leafletObject.value = markRaw(circle(props.latLng, options)); - const listeners = remapEvents(context.attrs); + const { listeners } = remapEvents(context.attrs); leafletObject.value.on(listeners); propsBinder(methods, leafletObject.value, props); diff --git a/src/components/LCircleMarker.vue b/src/components/LCircleMarker.vue index 83d045f..0a67f9f 100644 --- a/src/components/LCircleMarker.vue +++ b/src/components/LCircleMarker.vue @@ -53,7 +53,7 @@ export default defineComponent({ circleMarker(props.latLng, options) ); - const listeners = remapEvents(context.attrs); + const { listeners } = remapEvents(context.attrs); leafletObject.value.on(listeners); propsBinder(methods, leafletObject.value, props); diff --git a/src/components/LFeatureGroup.vue b/src/components/LFeatureGroup.vue index b415667..9ec17f6 100644 --- a/src/components/LFeatureGroup.vue +++ b/src/components/LFeatureGroup.vue @@ -49,7 +49,7 @@ export default defineComponent({ featureGroup(undefined, options) ); - const listeners = remapEvents(context.attrs); + const { listeners } = remapEvents(context.attrs); leafletObject.value.on(listeners); propsBinder(methods, leafletObject.value, props); diff --git a/src/components/LGeoJson.vue b/src/components/LGeoJson.vue index feb7e0d..4eac095 100644 --- a/src/components/LGeoJson.vue +++ b/src/components/LGeoJson.vue @@ -40,7 +40,7 @@ export default defineComponent({ leafletObject.value = markRaw(geoJSON(props.geojson, options)); - const listeners = remapEvents(context.attrs); + const { listeners } = remapEvents(context.attrs); leafletObject.value.on(listeners); propsBinder(methods, leafletObject.value, props); diff --git a/src/components/LGridLayer.vue b/src/components/LGridLayer.vue index 3533f76..01aed27 100644 --- a/src/components/LGridLayer.vue +++ b/src/components/LGridLayer.vue @@ -59,7 +59,7 @@ export default defineComponent({ ); leafletObject.value = markRaw(new GLayer(options)); - const listeners = remapEvents(context.attrs); + const { listeners } = remapEvents(context.attrs); leafletObject.value.on(listeners); propsBinder(methods, leafletObject.value, props); diff --git a/src/components/LIcon.vue b/src/components/LIcon.vue index fa8add0..cb1daf1 100644 --- a/src/components/LIcon.vue +++ b/src/components/LIcon.vue @@ -50,7 +50,7 @@ export default defineComponent({ return; } - const listeners = remapEvents(context.attrs); + const { listeners } = remapEvents(context.attrs); if (iconObject) { offDomEvent(iconObject, listeners); } diff --git a/src/components/LImageOverlay.vue b/src/components/LImageOverlay.vue index 153056a..62cb6df 100644 --- a/src/components/LImageOverlay.vue +++ b/src/components/LImageOverlay.vue @@ -52,7 +52,7 @@ export default defineComponent({ imageOverlay(props.url, props.bounds, options) ); - const listeners = remapEvents(context.attrs); + const { listeners } = remapEvents(context.attrs); leafletObject.value.on(listeners); propsBinder(methods, leafletObject.value, props); addLayer({ diff --git a/src/components/LLayerGroup.vue b/src/components/LLayerGroup.vue index dbdce06..117e45b 100644 --- a/src/components/LLayerGroup.vue +++ b/src/components/LLayerGroup.vue @@ -41,7 +41,7 @@ export default defineComponent({ layerGroup(undefined, props.options) ); - const listeners = remapEvents(context.attrs); + const { listeners } = remapEvents(context.attrs); leafletObject.value.on(listeners); propsBinder(methods, leafletObject.value, props); diff --git a/src/components/LMap.vue b/src/components/LMap.vue index 3414971..0df8ec0 100644 --- a/src/components/LMap.vue +++ b/src/components/LMap.vue @@ -30,6 +30,7 @@ import type { IMapOptions, } from "@src/types/interfaces"; import { + type Data, WINDOW_OR_GLOBAL, bindEventHandlers, cancelDebounces, @@ -41,6 +42,8 @@ import { updateLeafletWrapper, } from "@src/utils.js"; +type StyleableAttrs = Data & { style: Data }; + const mapProps = { ...componentProps, /** @@ -174,6 +177,7 @@ export default defineComponent({ mapProps, componentOptions ); + const { listeners, attrs } = remapEvents(context.attrs); const addLayer = provideLeafletWrapper(AddLayerInjection); const removeLayer = provideLeafletWrapper(RemoveLayerInjection); @@ -246,16 +250,10 @@ export default defineComponent({ if (props.useGlobalLeaflet) { WINDOW_OR_GLOBAL.L = WINDOW_OR_GLOBAL.L || (await import("leaflet")); } - const { - map, - CRS, - Icon, - latLngBounds, - latLng, - stamp, - }: typeof L = props.useGlobalLeaflet - ? WINDOW_OR_GLOBAL.L - : await import("leaflet/dist/leaflet-src.esm"); + const { map, CRS, Icon, latLngBounds, latLng, stamp }: typeof L = + props.useGlobalLeaflet + ? WINDOW_OR_GLOBAL.L + : await import("leaflet/dist/leaflet-src.esm"); try { // TODO: Is beforeMapMount still needed? @@ -384,7 +382,6 @@ export default defineComponent({ blueprint.leafletRef = markRaw(map(root.value!, options)); propsBinder(methods, blueprint.leafletRef, props); - const listeners: any = remapEvents(context.attrs); // TODO: proper typing bindEventHandlers(blueprint.leafletRef, eventHandlers); bindEventHandlers(blueprint.leafletRef, listeners); @@ -403,12 +400,19 @@ export default defineComponent({ const leafletObject = computed(() => blueprint.leafletRef); const ready = computed(() => blueprint.ready); - return { root, ready, leafletObject }; + return { root, ready, leafletObject, attrs }; }, - render() { + render({ attrs }: { attrs: StyleableAttrs }) { + attrs.style ??= {}; + attrs.style["width"] ??= "100%"; + attrs.style["height"] ??= "100%"; + return h( "div", - { style: { width: "100%", height: "100%" }, ref: "root" }, + { + ...attrs, + ref: "root", + }, this.ready && this.$slots.default ? this.$slots.default() : {} ); }, diff --git a/src/components/LMarker.vue b/src/components/LMarker.vue index 95f75cf..a9122f1 100644 --- a/src/components/LMarker.vue +++ b/src/components/LMarker.vue @@ -79,7 +79,7 @@ export default defineComponent({ } leafletObject.value = markRaw(marker(props.latLng, options)); - const listeners = remapEvents(context.attrs); + const { listeners } = remapEvents(context.attrs); leafletObject.value.on(listeners); leafletObject.value.on("move", eventHandlers.moveHandler); diff --git a/src/components/LPolygon.vue b/src/components/LPolygon.vue index 63f6860..573073d 100644 --- a/src/components/LPolygon.vue +++ b/src/components/LPolygon.vue @@ -44,7 +44,7 @@ export default defineComponent({ leafletObject.value = markRaw(polygon(props.latLngs, options)); - const listeners = remapEvents(context.attrs); + const { listeners } = remapEvents(context.attrs); leafletObject.value.on(listeners); propsBinder(methods, leafletObject.value, props); diff --git a/src/components/LPolyline.vue b/src/components/LPolyline.vue index a9f4b72..0a0cab5 100644 --- a/src/components/LPolyline.vue +++ b/src/components/LPolyline.vue @@ -46,7 +46,7 @@ export default defineComponent({ polyline(props.latLngs, options) ); - const listeners = remapEvents(context.attrs); + const { listeners } = remapEvents(context.attrs); leafletObject.value.on(listeners); propsBinder(methods, leafletObject.value, props); diff --git a/src/components/LPopup.vue b/src/components/LPopup.vue index e657034..325e746 100644 --- a/src/components/LPopup.vue +++ b/src/components/LPopup.vue @@ -52,7 +52,7 @@ export default defineComponent({ } propsBinder(methods, leafletObject.value, props); - const listeners = remapEvents(context.attrs); + const { listeners } = remapEvents(context.attrs); leafletObject.value.on(listeners); leafletObject.value.setContent(props.content || root.value || ""); bindPopup(leafletObject.value); diff --git a/src/components/LRectangle.vue b/src/components/LRectangle.vue index 5a522d8..c9b1f9d 100644 --- a/src/components/LRectangle.vue +++ b/src/components/LRectangle.vue @@ -47,7 +47,7 @@ export default defineComponent({ : latLngBounds(props.latLngs || []); leafletObject.value = markRaw(rectangle(bounds, options)); - const listeners = remapEvents(context.attrs); + const { listeners } = remapEvents(context.attrs); leafletObject.value.on(listeners); propsBinder(methods, leafletObject.value, props); diff --git a/src/components/LTileLayer.vue b/src/components/LTileLayer.vue index 41ac39f..e9b182f 100644 --- a/src/components/LTileLayer.vue +++ b/src/components/LTileLayer.vue @@ -38,7 +38,7 @@ export default defineComponent({ leafletObject.value = markRaw(tileLayer(props.url, options)); - const listeners = remapEvents(context.attrs); + const { listeners } = remapEvents(context.attrs); leafletObject.value.on(listeners); propsBinder(methods, leafletObject.value, props); diff --git a/src/components/LTooltip.vue b/src/components/LTooltip.vue index 812d3b7..7cbde77 100644 --- a/src/components/LTooltip.vue +++ b/src/components/LTooltip.vue @@ -45,7 +45,7 @@ export default defineComponent({ leafletObject.value = markRaw(tooltip(options)); propsBinder(methods, leafletObject.value, props); - const listeners = remapEvents(context.attrs); + const { listeners } = remapEvents(context.attrs); leafletObject.value.on(listeners); leafletObject.value.setContent(props.content || root.value || ""); bindTooltip(leafletObject.value); diff --git a/src/components/LWmsTileLayer.vue b/src/components/LWmsTileLayer.vue index e95e7a0..1ea49b1 100644 --- a/src/components/LWmsTileLayer.vue +++ b/src/components/LWmsTileLayer.vue @@ -47,7 +47,7 @@ export default defineComponent({ tileLayer.wms(props.url, options) ); - const listeners = remapEvents(context.attrs); + const { listeners } = remapEvents(context.attrs); leafletObject.value.on(listeners); propsBinder(methods, leafletObject.value, props); diff --git a/src/utils.ts b/src/utils.ts index 941ac7a..8f44682 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -2,6 +2,10 @@ import type L from "leaflet"; import { type InjectionKey, inject, provide, ref, watch } from "vue"; export declare type Data = Record; +export declare type ListenersAndAttrs = { + listeners: L.LeafletEventHandlerFnMap; + attrs: Data; +}; export const bindEventHandlers = ( leafletObject: L.Evented, @@ -73,8 +77,9 @@ export const propsToLeafletOptions = ( return output as T; }; -export const remapEvents = (contextAttrs: Data): L.LeafletEventHandlerFnMap => { - const result = {}; +export const remapEvents = (contextAttrs: Data): ListenersAndAttrs => { + const listeners: L.LeafletEventHandlerFnMap = {}; + const attrs: Data = {}; for (const attrName in contextAttrs) { if ( attrName.startsWith("on") && @@ -82,10 +87,13 @@ export const remapEvents = (contextAttrs: Data): L.LeafletEventHandlerFnMap => { attrName !== "onReady" ) { const eventName = attrName.slice(2).toLocaleLowerCase(); - result[eventName] = contextAttrs[attrName]; + listeners[eventName] = contextAttrs[attrName]; + } else { + attrs[attrName] = contextAttrs[attrName]; } } - return result; + + return { listeners, attrs }; }; export const resetWebpackIcon = async (Icon) => { From 7582288e453d5e69bd913e76a3100be601933d1f Mon Sep 17 00:00:00 2001 From: Michael Underwood Date: Thu, 15 Jun 2023 22:16:00 -0600 Subject: [PATCH 2/2] Drop nullish coalescing assignment --- src/components/LMap.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/LMap.vue b/src/components/LMap.vue index 0df8ec0..9678e31 100644 --- a/src/components/LMap.vue +++ b/src/components/LMap.vue @@ -403,9 +403,9 @@ export default defineComponent({ return { root, ready, leafletObject, attrs }; }, render({ attrs }: { attrs: StyleableAttrs }) { - attrs.style ??= {}; - attrs.style["width"] ??= "100%"; - attrs.style["height"] ??= "100%"; + if (!attrs.style) attrs.style = {}; + if (!attrs.style.width) attrs.style.width = "100%"; + if (!attrs.style.height) attrs.style.height = "100%"; return h( "div",