diff --git a/packages/core/src/composables/useKeyPress.ts b/packages/core/src/composables/useKeyPress.ts index 1c194cb3..0a55c75f 100644 --- a/packages/core/src/composables/useKeyPress.ts +++ b/packages/core/src/composables/useKeyPress.ts @@ -1,11 +1,12 @@ import type { MaybeRefOrGetter } from 'vue' -import { ref, toValue, watch } from 'vue' +import { onMounted, ref, toValue, watch } from 'vue' import type { KeyFilter, KeyPredicate } from '@vueuse/core' import { onKeyStroke, useEventListener } from '@vueuse/core' import { useWindow } from './useWindow' export interface UseKeyPressOptions { actInsideInputWithModifier?: MaybeRefOrGetter + target?: MaybeRefOrGetter } export function isInputDOMNode(event: KeyboardEvent): boolean { @@ -68,22 +69,19 @@ function useKeyOrCode(code: string, keysToWatch: string | string[]) { return keysToWatch.includes(code) ? 'code' : 'key' } +const window = useWindow() + /** - * Reactive key press state + * Composable that returns a boolean value if a key is pressed * - * todo: make this public? * @internal - * @param keyFilter - Can be a boolean, a string or an array of strings. If it's a boolean, it will always return that value. If it's a string, it will return true if the key is pressed. If it's an array of strings, it will return true if any of the keys are pressed, or a combination is pressed (e.g. ['ctrl+a', 'ctrl+b']) - * @param onChange - Callback function that will be called when the key state changes + * @param keyFilter - Can be a boolean, a string, an array of strings or a function that returns a boolean. If it's a boolean, it will act as if the key is always pressed. If it's a string, it will return true if a key matching that string is pressed. If it's an array of strings, it will return true if any of the strings match a key being pressed, or a combination (e.g. ['ctrl+a', 'ctrl+b']) * @param options - Options object */ export function useKeyPress( keyFilter: MaybeRefOrGetter, - onChange?: (keyPressed: boolean) => void, - options: UseKeyPressOptions = { actInsideInputWithModifier: true }, + options: UseKeyPressOptions = { actInsideInputWithModifier: true, target: window }, ) { - const window = useWindow() - const isPressed = ref(toValue(keyFilter) === true) let modifierPressed = false @@ -92,12 +90,6 @@ export function useKeyPress( let currentFilter = createKeyFilterFn(toValue(keyFilter)) - watch(isPressed, (isKeyPressed, wasPressed) => { - if (isKeyPressed !== wasPressed) { - onChange?.(isKeyPressed) - } - }) - watch( () => toValue(keyFilter), (nextKeyFilter, previousKeyFilter) => { @@ -113,10 +105,8 @@ export function useKeyPress( }, ) - useEventListener(window, 'blur', () => { - if (toValue(keyFilter) !== true) { - isPressed.value = false - } + onMounted(() => { + useEventListener(window, ['blur', 'contextmenu'], reset) }) onKeyStroke( @@ -134,7 +124,7 @@ export function useKeyPress( isPressed.value = true }, - { eventName: 'keydown' }, + { eventName: 'keydown', target: options.target }, ) onKeyStroke( @@ -150,11 +140,9 @@ export function useKeyPress( reset() } }, - { eventName: 'keyup' }, + { eventName: 'keyup', target: options.target }, ) - return isPressed - function reset() { modifierPressed = false @@ -184,4 +172,6 @@ export function useKeyPress( return keyFilter } + + return isPressed } diff --git a/packages/core/src/composables/useWindow.ts b/packages/core/src/composables/useWindow.ts index 812e140b..8c2a3fc1 100644 --- a/packages/core/src/composables/useWindow.ts +++ b/packages/core/src/composables/useWindow.ts @@ -8,12 +8,12 @@ type UseWindow = Window & typeof globalThis & { chrome?: any } export function useWindow(): UseWindow { if (typeof window !== 'undefined') { return window as UseWindow - } else { - return { - chrome: false, - addEventListener(..._: Parameters) { - // do nothing - }, - } as UseWindow } + + return { + chrome: false, + addEventListener(..._: Parameters) { + // do nothing + }, + } as UseWindow }