From 8158d3678e5c3ae04a55138a7710bd96a3bc4ed8 Mon Sep 17 00:00:00 2001
From: JMaylor <60825814+JMaylor@users.noreply.github.com>
Date: Wed, 28 Dec 2022 17:01:08 +0000
Subject: [PATCH] feat(useActiveElement): optionally ignore active
element
---
packages/core/useActiveElement/index.ts | 19 ++++++++++++++++---
packages/core/useFocusWithin/demo.vue | 10 ++++------
packages/core/useFocusWithin/index.ts | 5 +++--
3 files changed, 23 insertions(+), 11 deletions(-)
diff --git a/packages/core/useActiveElement/index.ts b/packages/core/useActiveElement/index.ts
index 62e0983a8f7..e556f9627a3 100644
--- a/packages/core/useActiveElement/index.ts
+++ b/packages/core/useActiveElement/index.ts
@@ -1,16 +1,21 @@
+import type { MaybeRef } from '@vueuse/shared'
import { computedWithControl } from '@vueuse/shared'
import { useEventListener } from '../useEventListener'
import type { ConfigurableWindow } from '../_configurable'
import { defaultWindow } from '../_configurable'
+export interface UseActiveElementOptions extends ConfigurableWindow {
+ ignoreBody?: MaybeRef
+}
+
/**
* Reactive `document.activeElement`
*
* @see https://vueuse.org/useActiveElement
* @param options
*/
-export function useActiveElement(options: ConfigurableWindow = {}) {
- const { window = defaultWindow } = options
+export function useActiveElement(options: UseActiveElementOptions = {}) {
+ const { window = defaultWindow, ignoreBody } = options
const activeElement = computedWithControl(
() => null,
() => window?.document.activeElement as T | null | undefined,
@@ -21,9 +26,17 @@ export function useActiveElement(options: ConfigurableWin
if (event.relatedTarget === null)
return
+ if (ignoreBody && window?.document.activeElement?.tagName === 'BODY')
+ return
+
+ activeElement.trigger()
+ }, true)
+ useEventListener(window, 'focus', () => {
+ if (ignoreBody && window?.document.activeElement?.tagName === 'BODY')
+ return
+
activeElement.trigger()
}, true)
- useEventListener(window, 'focus', activeElement.trigger, true)
}
return activeElement
diff --git a/packages/core/useFocusWithin/demo.vue b/packages/core/useFocusWithin/demo.vue
index 32a6c7edb55..d7f8e4648dd 100644
--- a/packages/core/useFocusWithin/demo.vue
+++ b/packages/core/useFocusWithin/demo.vue
@@ -4,22 +4,20 @@ import { useFocusWithin } from '@vueuse/core'
const target = ref()
-const { focused } = useFocusWithin(target)
+const { focused } = useFocusWithin(target, { ignoreBody: true })
-
- Focus in form:
+ Focus in form:
+
diff --git a/packages/core/useFocusWithin/index.ts b/packages/core/useFocusWithin/index.ts
index 2d166b3214c..49342ea5a72 100644
--- a/packages/core/useFocusWithin/index.ts
+++ b/packages/core/useFocusWithin/index.ts
@@ -2,8 +2,8 @@ import type { ComputedRef } from 'vue-demi'
import { computed } from 'vue-demi'
import type { MaybeElementRef } from '../unrefElement'
import { unrefElement } from '../unrefElement'
+import type { UseActiveElementOptions } from '../useActiveElement'
import { useActiveElement } from '../useActiveElement'
-import type { ConfigurableWindow } from '../_configurable'
export interface UseFocusWithinReturn {
/**
* True if the element or any of its descendants are focused
@@ -18,7 +18,8 @@ export interface UseFocusWithinReturn {
* @param target The target element to track
* @param options Focus within options
*/
-export function useFocusWithin(target: MaybeElementRef, options: ConfigurableWindow = {}): UseFocusWithinReturn {
+
+export function useFocusWithin(target: MaybeElementRef, options: UseActiveElementOptions = {}): UseFocusWithinReturn {
const activeElement = useActiveElement(options)
const targetElement = computed(() => unrefElement(target))
const focused = computed(() => targetElement.value && activeElement.value ? targetElement.value.contains(activeElement.value) : false)