diff --git a/packages/radix-vue/src/DismissableLayer/utils.ts b/packages/radix-vue/src/DismissableLayer/utils.ts index 3a8358a50..fd48a820c 100644 --- a/packages/radix-vue/src/DismissableLayer/utils.ts +++ b/packages/radix-vue/src/DismissableLayer/utils.ts @@ -1,4 +1,5 @@ import { isClient } from '@vueuse/shared' +import { useEventListener } from '@vueuse/core' import { handleAndDispatchCustomEvent } from '@/shared' import { type Ref, nextTick, ref, watchEffect } from 'vue' @@ -30,12 +31,11 @@ function isLayerExist(layerElement: HTMLElement, targetElement: HTMLElement) { (targetLayer && mainLayer === targetLayer) || nodeList.indexOf(mainLayer) < nodeList.indexOf(targetLayer) - ) { + ) return true - } - else { + + else return false - } } /** @@ -53,6 +53,9 @@ export function usePointerDownOutside( const isPointerInsideDOMTree = ref(false) const handleClickRef = ref(() => {}) + let ownerDocumentClickCleanup: ReturnType + let ownerDocumentPointerdownCleanup: ReturnType + watchEffect((cleanupFn) => { if (!isClient) return @@ -93,7 +96,7 @@ export function usePointerDownOutside( if (event.pointerType === 'touch') { ownerDocument.removeEventListener('click', handleClickRef.value) handleClickRef.value = handleAndDispatchPointerDownOutsideEvent - ownerDocument.addEventListener('click', handleClickRef.value, { + ownerDocumentClickCleanup = useEventListener(ownerDocument, 'click', handleClickRef.value, { once: true, }) } @@ -104,7 +107,7 @@ export function usePointerDownOutside( else { // We need to remove the event listener in case the outside click has been canceled. // See: https://github.com/radix-ui/primitives/issues/2171 - ownerDocument.removeEventListener('click', handleClickRef.value) + ownerDocumentClickCleanup && ownerDocumentClickCleanup() } isPointerInsideDOMTree.value = false } @@ -122,13 +125,12 @@ export function usePointerDownOutside( * }); */ const timerId = window.setTimeout(() => { - ownerDocument.addEventListener('pointerdown', handlePointerDown) + ownerDocumentPointerdownCleanup = useEventListener(ownerDocument, 'pointerdown', handlePointerDown) }, 0) cleanupFn(() => { window.clearTimeout(timerId) - ownerDocument.removeEventListener('pointerdown', handlePointerDown) - ownerDocument.removeEventListener('click', handleClickRef.value) + ownerDocumentPointerdownCleanup && ownerDocumentPointerdownCleanup() }) }) @@ -148,6 +150,8 @@ export function useFocusOutside( const ownerDocument: Document = element?.value?.ownerDocument ?? globalThis?.document + let ownerDocumentFocusinCleanup: ReturnType + const isFocusInsideDOMTree = ref(false) watchEffect((cleanupFn) => { if (!isClient) @@ -170,9 +174,9 @@ export function useFocusOutside( } } - ownerDocument.addEventListener('focusin', handleFocus) + ownerDocumentFocusinCleanup = useEventListener(ownerDocument, 'focusin', handleFocus) - cleanupFn(() => ownerDocument.removeEventListener('focusin', handleFocus)) + cleanupFn(() => ownerDocumentFocusinCleanup()) }) return { diff --git a/packages/radix-vue/src/FocusScope/FocusScope.vue b/packages/radix-vue/src/FocusScope/FocusScope.vue index 38630a015..5c10ad91e 100644 --- a/packages/radix-vue/src/FocusScope/FocusScope.vue +++ b/packages/radix-vue/src/FocusScope/FocusScope.vue @@ -35,6 +35,7 @@ export interface FocusScopeProps extends PrimitiveProps { diff --git a/packages/radix-vue/src/ScrollArea/ScrollAreaScrollbarImpl.vue b/packages/radix-vue/src/ScrollArea/ScrollAreaScrollbarImpl.vue index 81a5c39dd..0ae71e739 100644 --- a/packages/radix-vue/src/ScrollArea/ScrollAreaScrollbarImpl.vue +++ b/packages/radix-vue/src/ScrollArea/ScrollAreaScrollbarImpl.vue @@ -11,8 +11,8 @@ export interface ScrollAreaScrollbarImplProps { diff --git a/packages/radix-vue/src/Select/SelectContentImpl.vue b/packages/radix-vue/src/Select/SelectContentImpl.vue index 99b515a3f..ffde01b90 100644 --- a/packages/radix-vue/src/Select/SelectContentImpl.vue +++ b/packages/radix-vue/src/Select/SelectContentImpl.vue @@ -85,7 +85,7 @@ import { watch, watchEffect, } from 'vue' -import { unrefElement } from '@vueuse/core' +import { unrefElement, useEventListener } from '@vueuse/core' import { injectSelectRootContext } from './SelectRoot.vue' import SelectItemAlignedPosition from './SelectItemAlignedPosition.vue' import SelectPopperPosition from './SelectPopperPosition.vue' @@ -130,7 +130,10 @@ watch(isPositioned, () => { // prevent selecting items on `pointerup` in some cases after opening from `pointerdown` // and close on `pointerup` outside. const { onOpenChange, triggerPointerDownPosRef } = rootContext -watchEffect((cleanupFn) => { + +let documentPointermoveCleanup: ReturnType + +watchEffect((onCleanup) => { if (!content.value) return let pointerMoveDelta = { x: 0, y: 0 } @@ -160,20 +163,20 @@ watchEffect((cleanupFn) => { if (!content.value?.contains(event.target as HTMLElement)) onOpenChange(false) } - document.removeEventListener('pointermove', handlePointerMove) + documentPointermoveCleanup = useEventListener(document, 'pointermove', handlePointerMove) triggerPointerDownPosRef.value = null } if (triggerPointerDownPosRef.value !== null) { - document.addEventListener('pointermove', handlePointerMove) + documentPointermoveCleanup = useEventListener(document, 'pointermove', handlePointerMove) document.addEventListener('pointerup', handlePointerUp, { capture: true, once: true, }) } - cleanupFn(() => { - document.removeEventListener('pointermove', handlePointerMove) + onCleanup(() => { + documentPointermoveCleanup && documentPointermoveCleanup() document.removeEventListener('pointerup', handlePointerUp, { capture: true, }) diff --git a/packages/radix-vue/src/Select/SelectScrollDownButton.vue b/packages/radix-vue/src/Select/SelectScrollDownButton.vue index 51c6192ae..40abb51a0 100644 --- a/packages/radix-vue/src/Select/SelectScrollDownButton.vue +++ b/packages/radix-vue/src/Select/SelectScrollDownButton.vue @@ -7,6 +7,7 @@ export interface SelectScrollDownButtonProps extends PrimitiveProps {}