Skip to content

Commit

Permalink
feat(v-touch-hold): add new directive
Browse files Browse the repository at this point in the history
resolves #5322
  • Loading branch information
johnleider committed Apr 16, 2024
1 parent 2abb221 commit 1d5b53d
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 1 deletion.
1 change: 1 addition & 0 deletions packages/vuetify/src/directives/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export { Ripple } from './ripple'
export { Scroll } from './scroll'
export { Touch } from './touch'
export { Tooltip } from './tooltip'
export { TouchHold } from './touch-hold'
55 changes: 55 additions & 0 deletions packages/vuetify/src/directives/touch-hold/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Types
import type { DirectiveBinding } from 'vue'

export type TouchHoldStoredHandlers = {
touchstart: (e: TouchEvent) => void
touchend: (e: TouchEvent) => void
}

function mounted (el: HTMLElement, binding: DirectiveBinding) {
const uid = binding.instance?.$.uid

if (!uid) return

let timeout: number

function touchstart () {
timeout = window.setTimeout(binding.value, 1000)
}

function touchend () {
window.clearTimeout(timeout)
}

el.addEventListener('mousedown', touchstart)
el.addEventListener('mouseup', touchend)
el.addEventListener('mouseleave', touchend)
el.addEventListener('touchstart', touchstart)
el.addEventListener('touchend', touchend)
el.addEventListener('touchcancel', touchend)

el._touchHandlers = el._touchHandlers ?? Object.create(null)
el._touchHandlers![uid] = { touchstart, touchend }
}

function unmounted (el: HTMLElement, binding: DirectiveBinding) {
const uid = binding.instance?.$.uid

if (!uid || !el._touchHandlers![uid]) return

const { touchstart, touchend } = el._touchHandlers![uid]

el.removeEventListener('mousedown', touchstart as any)
el.removeEventListener('mouseup', touchend as any)
el.removeEventListener('mouseleave', touchend as any)
el.removeEventListener('touchstart', touchstart)
el.removeEventListener('touchend', touchend)
el.removeEventListener('touchcancel', touchend)
}

export const TouchHold = {
mounted,
unmounted,
}

export default TouchHold
3 changes: 2 additions & 1 deletion packages/vuetify/src/globals.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'vue/jsx'
// Types
import type { Events, VNode } from 'vue'
import type { TouchStoredHandlers } from './directives/touch'
import type { TouchHoldStoredHandlers } from './directives/touch-hold'

declare global {
interface HTMLCollection {
Expand Down Expand Up @@ -41,7 +42,7 @@ declare global {
target?: EventTarget
} | undefined>
_touchHandlers?: {
[_uid: number]: TouchStoredHandlers
[_uid: number]: TouchStoredHandlers | TouchHoldStoredHandlers
}
_transitionInitialStyles?: {
position: string
Expand Down

0 comments on commit 1d5b53d

Please sign in to comment.