// https://github.com/vueuse/vueuse/blob/main/packages/core/_configurable.ts import type { ConfigurableWindow, MaybeElementRef, UseFocusWithinReturn } from "@vueuse/core"; import { unrefElement, useEventListener } from "@vueuse/core"; import { computedWithControl, isClient } from "@vueuse/shared"; import { computed } from "vue"; const defaultWindow = isClient ? window : undefined; /** * Reactive `document.activeElement` * * @see https://vueuse.org/useActiveElement * @param options */ export function useActiveElement(options: ConfigurableWindow = {}) { const { window = defaultWindow } = options; const activeElement = computedWithControl( () => null, () => window?.document.activeElement as T | null | undefined, ); if (window) { useEventListener( window, "blur", () => { const scheduler = window.requestAnimationFrame || window.setTimeout; scheduler(() => activeElement.trigger()); }, true, ); useEventListener(window, "focus", activeElement.trigger, true); } return activeElement; } /** * Track if focus is contained within the target element * * @see https://vueuse.org/useFocusWithin * @param target The target element to track * @param options Focus within options */ export function useFocusWithin(target: MaybeElementRef, options: ConfigurableWindow = {}): UseFocusWithinReturn { const activeElement = useActiveElement(options); const targetElement = computed(() => unrefElement(target)); const focused = computed(() => targetElement.value && activeElement.value ? targetElement.value.contains(activeElement.value) : false, ); return { focused }; }