Skip to content

Commit

Permalink
feat(onKeyStroke): new functions (#416)
Browse files Browse the repository at this point in the history
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
  • Loading branch information
yang and antfu committed Apr 4, 2021
1 parent d6775e4 commit 1f9c78c
Show file tree
Hide file tree
Showing 6 changed files with 265 additions and 0 deletions.
7 changes: 7 additions & 0 deletions indexes.json
Expand Up @@ -326,6 +326,13 @@
"category": "Sensors",
"description": "listen for clicks outside of an element"
},
{
"name": "onKeyStroke",
"package": "core",
"docs": "https://vueuse.org/core/onKeyStroke/",
"category": "Sensors",
"description": "listen for keyboard key being stroked"
},
{
"name": "onStartTyping",
"package": "core",
Expand Down
1 change: 1 addition & 0 deletions packages/core/index.ts
@@ -1,6 +1,7 @@
export * from './asyncComputed'
export * from './createGlobalState'
export * from './onClickOutside'
export * from './onKeyStroke'
export * from './onStartTyping'
export * from './templateRef'
export * from './unrefElement'
Expand Down
59 changes: 59 additions & 0 deletions packages/core/onKeyStroke/demo.vue
@@ -0,0 +1,59 @@
<script setup lang="ts">
import { ref } from 'vue-demi'
import { onKeyStroke } from '.'
const translateX = ref(0)
const translateY = ref(0)
onKeyStroke('ArrowUp', (e: KeyboardEvent) => {
translateY.value -= 10
e.preventDefault()
})
onKeyStroke('ArrowDown', (e: KeyboardEvent) => {
translateY.value += 10
e.preventDefault()
})
onKeyStroke('ArrowLeft', (e: KeyboardEvent) => {
translateX.value -= 10
e.preventDefault()
})
onKeyStroke('ArrowRight', (e: KeyboardEvent) => {
translateX.value += 10
e.preventDefault()
})
</script>

<template>
<div>
<div class="container">
<div class="ball" :style="{transform: `translate(${translateX}px, ${translateY}px)`}" />
</div>
<div class="text-center mt-4">
Use the arrow keys to control the movement of the ball.
</div>
</div>
</template>

<style scoped>
.container {
display: flex;
justify-content: center;
align-items: center;
width: 400px;
height: 100px;
margin: auto;
overflow: hidden;
border: 1px solid #a1a1a1;
}
.ball {
width: 16px;
height: 16px;
background: #a1a1a1;
border-radius: 50%;
}
</style>
121 changes: 121 additions & 0 deletions packages/core/onKeyStroke/index.md
@@ -0,0 +1,121 @@
---
category: Sensors
---

# onKeyStroke

Listen for keyboard key being stroked.

## Usage

```js
import { onKeyStroke } from '@vueuse/core'

onKeyStroke('ArrowDown', (e) => {
e.preventDefault()
})
```

See [this table](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values) for all key codes.

### Custom Event Target

```js
onKeyStroke('A', (e) => {
console.log('Key A pressed on document')
}, { target: document })
```

### Custom Keyboard Event

```js
onKeyStroke('Shift', (e) => {
console.log('Shift key up')
}, { eventName: 'keyUp' })
```

Or

```js
onKeyUp('Shift', () => console.log('Shift key up'))
```


## Alias

- `onKeyDown` - alias for `onKeyStroke(key, handler, {eventName: 'keydown'})`
- `onKeyPressed` - alias for `onKeyStroke(key, handler, {eventName: 'keypress'})`
- `onKeyUp` - alias for `onKeyStroke(key, handler, {eventName: 'keyup'})`

<!--FOOTER_STARTS-->
## Type Declarations

```typescript
export declare type KeyPredicate = (event: KeyboardEvent) => boolean
export declare type KeyFilter = null | undefined | string | KeyPredicate
export declare type KeyStrokeEventName = "keydown" | "keypress" | "keyup"
export declare type KeyStrokeOptions = {
eventName?: KeyStrokeEventName
target?: MaybeRef<EventTarget>
passive?: boolean
}
/**
* Listen for keyboard keys being stroked.
*
* @link https://vueuse.org/onKeyStroke
* @param key
* @param handler
* @param options
*/
export declare function onKeyStroke(
key: KeyFilter,
handler: (event: KeyboardEvent) => void,
options?: KeyStrokeOptions
): Fn
/**
* Listen to the keydown event of the given key.
*
* @link https://vueuse.org/onKeyStroke
* @param key
* @param handler
* @param options
*/
export declare function onKeyDown(
key: KeyFilter,
handler: (event: KeyboardEvent) => void,
options?: Omit<KeyStrokeOptions, "eventName">
): Fn
/**
* Listen to the keypress event of the given key.
*
* @link https://vueuse.org/onKeyStroke
* @param key
* @param handler
* @param options
*/
export declare function onKeyPressed(
key: KeyFilter,
handler: (event: KeyboardEvent) => void,
options?: Omit<KeyStrokeOptions, "eventName">
): Fn
/**
* Listen to the keyup event of the given key.
*
* @link https://vueuse.org/onKeyStroke
* @param key
* @param handler
* @param options
*/
export declare function onKeyUp(
key: KeyFilter,
handler: (event: KeyboardEvent) => void,
options?: Omit<KeyStrokeOptions, "eventName">
): Fn
```

## Source

[Source](https://github.com/vueuse/vueuse/blob/main/packages/core/onKeyStroke/index.ts) • [Demo](https://github.com/vueuse/vueuse/blob/main/packages/core/onKeyStroke/demo.vue) • [Docs](https://github.com/vueuse/vueuse/blob/main/packages/core/onKeyStroke/index.md)


<!--FOOTER_ENDS-->
76 changes: 76 additions & 0 deletions packages/core/onKeyStroke/index.ts
@@ -0,0 +1,76 @@
import { MaybeRef } from '@vueuse/shared'
import { useEventListener } from '../useEventListener'
import { defaultWindow } from '../_configurable'

export type KeyPredicate = (event: KeyboardEvent) => boolean
export type KeyFilter = null | undefined | string | KeyPredicate
export type KeyStrokeEventName = 'keydown' | 'keypress' | 'keyup'
export type KeyStrokeOptions = {
eventName?: KeyStrokeEventName
target?: MaybeRef<EventTarget>
passive?: boolean
}

const createKeyPredicate = (keyFilter: KeyFilter): KeyPredicate =>
typeof keyFilter === 'function'
? keyFilter
: typeof keyFilter === 'string'
? (event: KeyboardEvent) => event.key === keyFilter
: keyFilter
? () => true
: () => false

/**
* Listen for keyboard keys being stroked.
*
* @link https://vueuse.org/onKeyStroke
* @param key
* @param handler
* @param options
*/
export function onKeyStroke(key: KeyFilter, handler: (event: KeyboardEvent) => void, options: KeyStrokeOptions = {}) {
const { target = defaultWindow, eventName = 'keydown', passive = false } = options
const predicate = createKeyPredicate(key)
const listener = (e: KeyboardEvent) => {
if (predicate(e))
handler(e)
}

return useEventListener(target, eventName, listener, passive)
}

/**
* Listen to the keydown event of the given key.
*
* @link https://vueuse.org/onKeyStroke
* @param key
* @param handler
* @param options
*/
export function onKeyDown(key: KeyFilter, handler: (event: KeyboardEvent) => void, options: Omit<KeyStrokeOptions, 'eventName'> = {}) {
return onKeyStroke(key, handler, { ...options, eventName: 'keydown' })
}

/**
* Listen to the keypress event of the given key.
*
* @link https://vueuse.org/onKeyStroke
* @param key
* @param handler
* @param options
*/
export function onKeyPressed(key: KeyFilter, handler: (event: KeyboardEvent) => void, options: Omit<KeyStrokeOptions, 'eventName'> = {}) {
return onKeyStroke(key, handler, { ...options, eventName: 'keypress' })
}

/**
* Listen to the keyup event of the given key.
*
* @link https://vueuse.org/onKeyStroke
* @param key
* @param handler
* @param options
*/
export function onKeyUp(key: KeyFilter, handler: (event: KeyboardEvent) => void, options: Omit<KeyStrokeOptions, 'eventName'> = {}) {
return onKeyStroke(key, handler, { ...options, eventName: 'keyup' })
}
1 change: 1 addition & 0 deletions packages/functions.md
Expand Up @@ -56,6 +56,7 @@

### Sensors
- [`onClickOutside`](https://vueuse.org/core/onClickOutside/) — listen for clicks outside of an element
- [`onKeyStroke`](https://vueuse.org/core/onKeyStroke/) — listen for keyboard key being stroked
- [`onStartTyping`](https://vueuse.org/core/onStartTyping/) — fires when users start typing on non-editable elements
- [`useBattery`](https://vueuse.org/core/useBattery/) — reactive [Battery Status API](https://developer.mozilla.org/en-US/docs/Web/API/Battery_Status_API)
- [`useDeviceLight`](https://vueuse.org/core/useDeviceLight/) — reactive [DeviceLightEvent](https://developer.mozilla.org/en-US/docs/Web/API/DeviceLightEvent)
Expand Down

0 comments on commit 1f9c78c

Please sign in to comment.