fix: debouncing sync and other improvements
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
import { onMounted, onUnmounted, type Ref } from 'vue'
|
||||
|
||||
type OutsideHandler = (event: MouseEvent) => void
|
||||
|
||||
const handlers = new Set<OutsideHandler>()
|
||||
|
||||
function dispatch(event: MouseEvent) {
|
||||
for (const handler of handlers) {
|
||||
handler(event)
|
||||
}
|
||||
}
|
||||
|
||||
// Backs every call with a single shared `document` click listener instead of
|
||||
// one per component instance, so a page rendering many dismissable menus
|
||||
// (e.g. one per row in a list) doesn't fan out into one global listener per
|
||||
// row.
|
||||
export function useClickOutside(target: Ref<HTMLElement | null>, onOutside: () => void): void {
|
||||
function handler(event: MouseEvent) {
|
||||
if (target.value && !target.value.contains(event.target as Node)) {
|
||||
onOutside()
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
handlers.add(handler)
|
||||
if (handlers.size === 1) {
|
||||
document.addEventListener('click', dispatch)
|
||||
}
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
handlers.delete(handler)
|
||||
if (handlers.size === 0) {
|
||||
document.removeEventListener('click', dispatch)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { onMounted, onUnmounted } from 'vue'
|
||||
|
||||
type EscapeHandler = () => void
|
||||
|
||||
const handlers = new Set<EscapeHandler>()
|
||||
|
||||
function dispatch(event: KeyboardEvent) {
|
||||
if (event.key !== 'Escape') return
|
||||
for (const handler of handlers) {
|
||||
handler()
|
||||
}
|
||||
}
|
||||
|
||||
// Backs every call with a single shared `document` keydown listener instead
|
||||
// of one per component instance.
|
||||
export function useEscapeKey(onEscape: EscapeHandler): void {
|
||||
onMounted(() => {
|
||||
handlers.add(onEscape)
|
||||
if (handlers.size === 1) {
|
||||
document.addEventListener('keydown', dispatch)
|
||||
}
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
handlers.delete(onEscape)
|
||||
if (handlers.size === 0) {
|
||||
document.removeEventListener('keydown', dispatch)
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user