-
Notifications
You must be signed in to change notification settings - Fork 87
Expand file tree
/
Copy pathScriptGoogleMapsInfoWindow.vue
More file actions
119 lines (104 loc) · 3.22 KB
/
ScriptGoogleMapsInfoWindow.vue
File metadata and controls
119 lines (104 loc) · 3.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
<script setup lang="ts">
import { inject, useTemplateRef, watch } from 'vue'
import { bindGoogleMapsEvents } from './bindGoogleMapsEvents'
import { ADVANCED_MARKER_ELEMENT_INJECTION_KEY, MAP_INJECTION_KEY, MARKER_INJECTION_KEY } from './injectionKeys'
import { useGoogleMapsResource } from './useGoogleMapsResource'
const props = defineProps<{
options?: google.maps.InfoWindowOptions
}>()
const emit = defineEmits<{
(event: typeof infoWindowEvents[number]): void
}>()
const infoWindowEvents = [
'close',
'closeclick',
'content_changed',
'domready',
'headercontent_changed',
'headerdisabled_changed',
'position_changed',
'visible',
'zindex_changed',
] as const
const mapContext = inject(MAP_INJECTION_KEY, undefined)
const markerContext = inject(MARKER_INJECTION_KEY, undefined)
const advancedMarkerElementContext = inject(ADVANCED_MARKER_ELEMENT_INJECTION_KEY, undefined)
const infoWindowContainer = useTemplateRef('info-window-container')
// Track click listener on parent marker so it can be removed on cleanup
let markerClickListener: google.maps.MapsEventListener | undefined
let gmpClickHandler: ((e: any) => void) | undefined
let isOpen = false
const infoWindow = useGoogleMapsResource<google.maps.InfoWindow>({
ready: () => !!infoWindowContainer.value,
create({ mapsApi, map }) {
const iw = new mapsApi.InfoWindow({
content: infoWindowContainer.value,
...props.options,
})
// Track open state for toggle behavior
iw.addListener('closeclick', () => {
isOpen = false
})
iw.addListener('close', () => {
isOpen = false
})
bindGoogleMapsEvents(iw, emit, { noPayload: infoWindowEvents })
const toggleOpen = (anchor: any) => {
if (isOpen) {
iw.close()
isOpen = false
}
else {
mapContext?.activateInfoWindow(iw)
iw.open({ anchor, map })
isOpen = true
}
}
if (markerContext?.marker.value) {
markerClickListener = markerContext.marker.value.addListener('click', () => {
toggleOpen(markerContext.marker.value)
})
}
else if (advancedMarkerElementContext?.advancedMarkerElement.value) {
const ame = advancedMarkerElementContext.advancedMarkerElement.value
ame.gmpClickable = true
gmpClickHandler = () => toggleOpen(ame)
ame.addEventListener('gmp-click', gmpClickHandler)
}
else {
iw.setPosition(props.options?.position)
iw.open(map)
isOpen = true
}
return iw
},
cleanup(iw, { mapsApi }) {
markerClickListener?.remove()
markerClickListener = undefined
if (gmpClickHandler && advancedMarkerElementContext?.advancedMarkerElement.value) {
advancedMarkerElementContext.advancedMarkerElement.value.removeEventListener('gmp-click', gmpClickHandler)
gmpClickHandler = undefined
}
mapsApi.event.clearInstanceListeners(iw)
iw.close()
isOpen = false
},
})
watch(() => props.options, (options) => {
if (infoWindow.value && options) {
infoWindow.value.setOptions(options)
}
}, { deep: true })
</script>
<template>
<div class="info-window-container">
<div ref="info-window-container">
<slot />
</div>
</div>
</template>
<style scoped>
.info-window-container {
display: none;
}
</style>