import type { PlacesInstance, StaticOptions, ReconfigurableOptions, PlacesEventsHandlers, } from 'places.js' import { Ref, watch, ref, onUnmounted } from '@vue/composition-api' type EventType = keyof PlacesEventsHandlers export function usePlaceSearch (container: Ref, options?: StaticOptions & ReconfigurableOptions) { const autocomplete = ref(null) if (!process.env.ALGOLIA_PLACES_ID) { console.error('ALGOLIA_PLACES_ID env variable not defined') } if (!process.env.ALGOLIA_PLACES_KEY) { console.error('ALGOLIA_PLACES_KEY env variable not defined') } watch(container, value => { destroy() if (!value || typeof window === 'undefined') return // Conditional require // eslint-disable-next-line @typescript-eslint/no-var-requires const places = require('places.js') const instance = autocomplete.value = places({ appId: process.env.ALGOLIA_PLACES_ID, apiKey: process.env.ALGOLIA_PLACES_KEY, container: value, ...options, }) handle(instance, 'change') handle(instance, 'suggestions') handle(instance, 'cursorchanged') handle(instance, 'clear') handle(instance, 'limit') handle(instance, 'error') }) onUnmounted(() => { destroy() }) function destroy () { if (autocomplete.value) { autocomplete.value.destroy() } } // Events const eventHandlers: { [key in EventType]: PlacesEventsHandlers[key][] } = { change: [], suggestions: [], cursorchanged: [], clear: [], limit: [], error: [], } function handle (target: PlacesInstance, eventType: EventType) { target.on(eventType, (e) => { eventHandlers[eventType].forEach(handler => handler(e)) }) } function on (eventType: T) { return (handler: PlacesEventsHandlers[T]) => { const handlers = eventHandlers[eventType] as PlacesEventsHandlers[T][] handlers.push(handler) return () => { const index = handlers.indexOf(handler) if (index !== -1) handlers.splice(index, 1) } } } return { autocomplete, onChange: on('change'), onSuggestions: on('suggestions'), onCursorChanged: on('cursorchanged'), onClear: on('clear'), onLimit: on('limit'), onError: on('error'), } }