Skip to content

Commit

Permalink
feat(useEventListener): support multiple options
Browse files Browse the repository at this point in the history
  • Loading branch information
btea committed May 4, 2024
1 parent b7d8438 commit f16c5db
Showing 1 changed file with 22 additions and 10 deletions.
32 changes: 22 additions & 10 deletions packages/core/useEventListener/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Arrayable, Fn, MaybeRefOrGetter } from '@vueuse/shared'
import { isObject, noop, toValue, tryOnScopeDispose } from '@vueuse/shared'
import { watch } from 'vue-demi'
import type { Ref } from 'vue-demi'
import type { MaybeElementRef } from '../unrefElement'
import { unrefElement } from '../unrefElement'
import { defaultWindow } from '../_configurable'
Expand All @@ -12,6 +13,7 @@ interface InferEventTarget<Events> {

export type WindowEventName = keyof WindowEventMap
export type DocumentEventName = keyof DocumentEventMap
export type RefOrGetter<T> = Ref<T> | (() => T)

export interface GeneralEventListener<E = Event> {
(evt: E): void
Expand All @@ -30,7 +32,7 @@ export interface GeneralEventListener<E = Event> {
export function useEventListener<E extends keyof WindowEventMap>(
event: Arrayable<E>,
listener: Arrayable<(this: Window, ev: WindowEventMap[E]) => any>,
options?: MaybeRefOrGetter<boolean | AddEventListenerOptions>
options?: Arrayable<MaybeRefOrGetter<boolean | AddEventListenerOptions>>
): Fn

/**
Expand All @@ -48,7 +50,7 @@ export function useEventListener<E extends keyof WindowEventMap>(
target: Window,
event: Arrayable<E>,
listener: Arrayable<(this: Window, ev: WindowEventMap[E]) => any>,
options?: MaybeRefOrGetter<boolean | AddEventListenerOptions>
options?: Arrayable<MaybeRefOrGetter<boolean | AddEventListenerOptions>>
): Fn

/**
Expand All @@ -66,7 +68,7 @@ export function useEventListener<E extends keyof DocumentEventMap>(
target: DocumentOrShadowRoot,
event: Arrayable<E>,
listener: Arrayable<(this: Document, ev: DocumentEventMap[E]) => any>,
options?: MaybeRefOrGetter<boolean | AddEventListenerOptions>
options?: Arrayable<MaybeRefOrGetter<boolean | AddEventListenerOptions>>
): Fn

/**
Expand All @@ -84,7 +86,7 @@ export function useEventListener<E extends keyof HTMLElementEventMap>(
target: MaybeRefOrGetter<HTMLElement | null | undefined>,
event: Arrayable<E>,
listener: (this: HTMLElement, ev: HTMLElementEventMap[E]) => any,
options?: boolean | AddEventListenerOptions
options?: Arrayable<boolean | AddEventListenerOptions>
): () => void

/**
Expand All @@ -102,7 +104,7 @@ export function useEventListener<Names extends string, EventType = Event>(
target: InferEventTarget<Names>,
event: Arrayable<Names>,
listener: Arrayable<GeneralEventListener<EventType>>,
options?: MaybeRefOrGetter<boolean | AddEventListenerOptions>
options?: Arrayable<MaybeRefOrGetter<boolean | AddEventListenerOptions>>
): Fn

/**
Expand All @@ -120,14 +122,14 @@ export function useEventListener<EventType = Event>(
target: MaybeRefOrGetter<EventTarget | null | undefined>,
event: Arrayable<string>,
listener: Arrayable<GeneralEventListener<EventType>>,
options?: MaybeRefOrGetter<boolean | AddEventListenerOptions>
options?: Arrayable<MaybeRefOrGetter<boolean | AddEventListenerOptions>>
): Fn

export function useEventListener(...args: any[]) {
let target: MaybeRefOrGetter<EventTarget> | undefined
let events: Arrayable<string>
let listeners: Arrayable<Function>
let options: MaybeRefOrGetter<boolean | AddEventListenerOptions> | undefined
let options: Arrayable<MaybeRefOrGetter<boolean | AddEventListenerOptions>> | undefined

if (typeof args[0] === 'string' || Array.isArray(args[0])) {
[events, listeners, options] = args
Expand Down Expand Up @@ -163,11 +165,21 @@ export function useEventListener(...args: any[]) {
if (!el)
return

// create a clone of options, to avoid it being changed reactively on removal
const optionsClone = isObject(options) ? { ...options } : options
cleanups.push(
...(events as string[]).flatMap((event) => {
return (listeners as Function[]).map(listener => register(el, event, listener, optionsClone))
return (listeners as Function[]).map((listener, index) => {
let option: MaybeRefOrGetter<boolean | AddEventListenerOptions> | undefined
if (Array.isArray(options)) {
option = options[index]
if (option && isObject(option))
option = { ...option }
}
else {
// create a clone of options, to avoid it being changed reactively on removal
option = isObject(options) ? { ...(options as RefOrGetter<boolean> | MaybeRefOrGetter<AddEventListenerOptions>) } : options as boolean | undefined
}
return register(el, event, listener, option)
})
}),
)
},
Expand Down

0 comments on commit f16c5db

Please sign in to comment.