Skip to content

Commit

Permalink
feat(onLongPress): added modifiers (#1719)
Browse files Browse the repository at this point in the history
  • Loading branch information
chaii3 committed Jul 6, 2022
1 parent 00d7323 commit f047267
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 9 deletions.
2 changes: 1 addition & 1 deletion packages/core/onLongPress/directive.ts
Expand Up @@ -17,7 +17,7 @@ BindingValueFunction | BindingValueArray
> = {
[directiveHooks.mounted](el, binding) {
if (typeof binding.value === 'function')
onLongPress(el, binding.value)
onLongPress(el, binding.value, { modifiers: binding.modifiers })
else
onLongPress(el, ...binding.value)
},
Expand Down
20 changes: 17 additions & 3 deletions packages/core/onLongPress/index.md
Expand Up @@ -6,6 +6,13 @@ category: Sensors

Listen for a long press on an element.

Function provides modifiers in options
* stop
* once
* prevent
* capture
* self

## Usage

```html
Expand All @@ -23,7 +30,11 @@ const resetHook = () => {
longPressedHook.value = false
}
onLongPress(htmlRefHook, onLongPressCallbackHook)
onLongPress(
htmlRefHook,
onLongPressCallbackHook,
{ modifiers: { prevent: true } }
)
</script>

<template>
Expand Down Expand Up @@ -93,11 +104,14 @@ const resetDirective = () => {
<template>
<p>Long Pressed: {{ longPressedDirective }}</p>

<button v-on-long-press="onLongPressCallbackDirective" class="ml-2 button small">
<button v-on-long-press.prevent="onLongPressCallbackDirective" class="ml-2 button small">
Press long
</button>

<button v-on-long-press="[onLongPressCallbackDirective, {delay: 1000}]" class="ml-2 button small">
<button
v-on-long-press="[onLongPressCallbackDirective, {delay: 1000, modifiers: { stop: true }}]"
class="ml-2button small"
>
Press long (with options)
</button>

Expand Down
37 changes: 35 additions & 2 deletions packages/core/onLongPress/index.test.ts
Expand Up @@ -3,13 +3,14 @@ import type { Ref } from 'vue-demi'
import { ref } from 'vue-demi'
import { onLongPress } from '.'

const pointerdownEvent = new PointerEvent('pointerdown')

describe('onLongPress', () => {
let element: Ref<HTMLElement>
let pointerdownEvent: PointerEvent

beforeEach(() => {
element = ref(document.createElement('div'))

pointerdownEvent = new PointerEvent('pointerdown', { cancelable: true, bubbles: true })
})

it('should be defined', () => {
Expand Down Expand Up @@ -38,6 +39,22 @@ describe('onLongPress', () => {
await promiseTimeout(500)
expect(onLongPressCallback).toHaveBeenCalledTimes(1)
})

it('should work with once and prevent modefiers', async () => {
const onLongPressCallback = vi.fn()
onLongPress(element, onLongPressCallback, { modifiers: { once: true, prevent: true } })

element.value.dispatchEvent(pointerdownEvent)

await promiseTimeout(500)

expect(onLongPressCallback).toHaveBeenCalledTimes(1)
expect(pointerdownEvent.defaultPrevented).toBe(true)

await promiseTimeout(500)

expect(onLongPressCallback).toHaveBeenCalledTimes(1)
})
})
})

Expand All @@ -63,6 +80,22 @@ describe('onLongPress', () => {
await promiseTimeout(500)
expect(onLongPressCallback).toHaveBeenCalledTimes(1)
})

it('should work with once and prevent modefiers', async () => {
const onLongPressCallback = vi.fn()
onLongPress(element.value, onLongPressCallback, { modifiers: { once: true, prevent: true } })

element.value.dispatchEvent(pointerdownEvent)

await promiseTimeout(500)

expect(onLongPressCallback).toHaveBeenCalledTimes(1)
expect(pointerdownEvent.defaultPrevented).toBe(true)

await promiseTimeout(500)

expect(onLongPressCallback).toHaveBeenCalledTimes(1)
})
})
})
})
31 changes: 28 additions & 3 deletions packages/core/onLongPress/index.ts
Expand Up @@ -12,6 +12,16 @@ export interface OnLongPressOptions {
* @default 500
*/
delay?: number

modifiers?: OnLongPressModifiers
}

export interface OnLongPressModifiers {
stop?: boolean
once?: boolean
prevent?: boolean
capture?: boolean
self?: boolean
}

export function onLongPress(
Expand All @@ -31,14 +41,29 @@ export function onLongPress(
}

function onDown(ev: PointerEvent) {
if (options?.modifiers?.self && ev.target !== elementRef.value)
return

clear()

if (options?.modifiers?.prevent)
ev.preventDefault()

if (options?.modifiers?.stop)
ev.stopPropagation()

timeout = setTimeout(
() => handler(ev),
options?.delay ?? DEFAULT_DELAY,
) as unknown as number
}

useEventListener(elementRef, 'pointerdown', onDown)
useEventListener(elementRef, 'pointerup', clear)
useEventListener(elementRef, 'pointerleave', clear)
const listenerOptions: AddEventListenerOptions = {
capture: options?.modifiers?.capture,
once: options?.modifiers?.once,
}

useEventListener(elementRef, 'pointerdown', onDown, listenerOptions)
useEventListener(elementRef, 'pointerup', clear, listenerOptions)
useEventListener(elementRef, 'pointerleave', clear, listenerOptions)
}

0 comments on commit f047267

Please sign in to comment.