Skip to content

Commit

Permalink
feat(useKeyModifier): new function (vitest-dev#698)
Browse files Browse the repository at this point in the history
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
  • Loading branch information
JMaylor and antfu committed Sep 2, 2021
1 parent 3816c29 commit 3b2d884
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 0 deletions.
34 changes: 34 additions & 0 deletions packages/core/useKeyModifier/demo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<script setup lang="ts">
import Key from '../useMagicKeys/Key.vue'
import { useKeyModifier } from '.'
const capsLock = useKeyModifier('CapsLock')
const numLock = useKeyModifier('NumLock')
const scrollLock = useKeyModifier('ScrollLock')
const shift = useKeyModifier('Shift')
const control = useKeyModifier('Control')
const alt = useKeyModifier('Alt')
</script>

<template>
<div class="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-6 gap-2">
<Key :value="capsLock || false">
capsLock
</Key>
<Key :value="numLock || false">
numLock
</Key>
<Key :value="scrollLock || false">
scrollLock
</Key>
<Key :value="shift || false">
shift
</Key>
<Key :value="control || false">
control
</Key>
<Key :value="alt || false">
alt
</Key>
</div>
</template>
45 changes: 45 additions & 0 deletions packages/core/useKeyModifier/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
category: Sensors
---

# useKeyModifier

Reactive [Modifier State](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/getModifierState). Tracks state of any of the [supported modifiers](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/getModifierState#browser_compatibility) - see Browser Compatibility notes.

## Usage

```ts
import { useKeyModifier } from '@vueuse/core'

const capsLockState = useKeyModifier('CapsLock')

console.log(capsLockState.value)
```

## Events

You can customize which events will prompt the state to update. By default, these are `mouseup`, `mousedown`, `keyup`, `keydown`. To customize these events:

```ts
import { useKeyModifier } from '@vueuse/core'

const capsLockState = useKeyModifier('CapsLock', { events: ['mouseup', 'mousedown'] })

console.log(capsLockState) // null

// Caps Lock turned on with key press
console.log(capsLockState) // null

// Mouse button clicked
console.log(capsLockState) // true
```

## Initial State

By default, the returned ref will be `Ref<null>` until the first event is received. You can explicitly pass the initial state to it via:

```ts
const capsLockState1 = useKeyModifier('CapsLock') // Ref<boolean | null>
const capsLockState2 = useKeyModifier('CapsLock', { initial: false }) // Ref<boolean>
```

43 changes: 43 additions & 0 deletions packages/core/useKeyModifier/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Ref, ref } from 'vue-demi'
import { useEventListener, WindowEventName } from '../useEventListener'
import { ConfigurableDocument, defaultDocument } from '../_configurable'

export type KeyModifier = 'Alt' | 'AltGraph' | 'CapsLock' | 'Control' | 'Fn' | 'FnLock' | 'Meta' | 'NumLock' | 'ScrollLock' | 'Shift' | 'Symbol' | 'SymbolLock'

const defaultEvents: WindowEventName[] = ['mousedown', 'mouseup', 'keydown', 'keyup']

export interface ModifierOptions<Initial> extends ConfigurableDocument {
/**
* Event names that will prompt update to modifier states
*
* @default ['mousedown', 'mouseup', 'keydown', 'keyup']
*/
events?: WindowEventName[]

/**
* Initial value of the returned ref
*
* @default null
*/
initial?: Initial
}

export function useKeyModifier<Initial extends boolean | null>(modifier: KeyModifier, options: ModifierOptions<Initial> = {}) {
const {
events = defaultEvents,
document = defaultDocument,
initial = null,
} = options

const state = ref(initial) as Ref<boolean>

if (document) {
events.forEach((listenerEvent) => {
useEventListener(document, listenerEvent, (evt: KeyboardEvent) => {
state.value = evt.getModifierState(modifier)
})
})
}

return state as Ref<Initial extends boolean ? boolean : boolean | null>
}

0 comments on commit 3b2d884

Please sign in to comment.