From 75addac8902687a2cf0b292a4f04fc32dad7abf1 Mon Sep 17 00:00:00 2001 From: zernonia Date: Sat, 15 Jul 2023 23:21:23 +0800 Subject: [PATCH] add focus outside composables --- packages/radix-vue/src/shared/index.ts | 1 + .../radix-vue/src/shared/onFocusOutside.ts | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 packages/radix-vue/src/shared/onFocusOutside.ts diff --git a/packages/radix-vue/src/shared/index.ts b/packages/radix-vue/src/shared/index.ts index 7cc74fa1f..45c8c29f1 100644 --- a/packages/radix-vue/src/shared/index.ts +++ b/packages/radix-vue/src/shared/index.ts @@ -1,3 +1,4 @@ +export { onFocusOutside } from "./onFocusOutside"; export { useArrowNavigation } from "./useArrowNavigation"; export { useMouseInElement } from "./useMouseInElement"; export { useHoverDelay } from "./useHoverDelay"; diff --git a/packages/radix-vue/src/shared/onFocusOutside.ts b/packages/radix-vue/src/shared/onFocusOutside.ts new file mode 100644 index 000000000..05b4163d6 --- /dev/null +++ b/packages/radix-vue/src/shared/onFocusOutside.ts @@ -0,0 +1,27 @@ +import { type MaybeElementRef, unrefElement } from "@vueuse/core"; +import { onMounted, onUnmounted } from "vue"; + +export const onFocusOutside = ( + element: MaybeElementRef, + handler: (event: FocusEvent) => void +) => { + const handleFocusOut = (ev: FocusEvent) => { + const el = unrefElement(element); + const isFocusInsideElement = el?.contains(ev.relatedTarget as Node); + + if (!isFocusInsideElement) { + handler(ev); + } + }; + + onMounted(() => { + const el = unrefElement(element); + // @ts-ignore + el?.addEventListener("focusout", handleFocusOut); + }); + onUnmounted(() => { + const el = unrefElement(element); + // @ts-ignore + el?.removeEventListener("focusout", handleFocusOut); + }); +};