📄 index.ts¶
📊 Analysis Summary¶
| Metric | Count |
|---|---|
| 🔧 Functions | 5 |
| 📦 Imports | 13 |
| 📊 Variables & Constants | 5 |
| 🟢 Vue Composition API | 6 |
| 📐 Interfaces | 2 |
📚 Table of Contents¶
🛠️ File Location:¶
📂 packages/core/usePointerSwipe/index.ts
📦 Imports¶
| Name | Source |
|---|---|
ComputedRef |
vue |
MaybeRefOrGetter |
vue |
ShallowRef |
vue |
PointerType |
../types |
Position |
../types |
UseSwipeDirection |
../useSwipe |
toRef |
@vueuse/shared |
tryOnMounted |
@vueuse/shared |
computed |
vue |
reactive |
vue |
readonly |
vue |
shallowRef |
vue |
useEventListener |
../useEventListener |
Variables & Constants¶
| Name | Type | Kind | Value | Exported |
|---|---|---|---|---|
isReleasingButton |
boolean |
const | e.buttons === 0 |
✗ |
isPrimaryButton |
boolean |
const | e.buttons === 1 |
✗ |
listenerOptions |
{ passive: boolean; } |
const | { passive: true } |
✗ |
eventTarget |
HTMLElement |
const | e.target as HTMLElement | undefined |
✗ |
stops |
(() => void)[] |
const | `[ | |
| useEventListener(target, 'pointerdown', (e: PointerEvent) => { | ||||
| if (!eventIsAllowed(e)) | ||||
| return | ||||
| isPointerDown.value = true | ||||
| // Future pointer events will be retargeted to target until pointerup/cancel | ||||
| const eventTarget = e.target as HTMLElement | undefined | |||
| eventTarget?.setPointerCapture(e.pointerId) | ||||
| const { clientX: x, clientY: y } = e | ||||
| updatePosStart(x, y) | ||||
| updatePosEnd(x, y) | ||||
| onSwipeStart?.(e) | ||||
| }, listenerOptions), |
useEventListener(target, 'pointermove', (e: PointerEvent) => {
if (!eventIsAllowed(e))
return
if (!isPointerDown.value)
return
const { clientX: x, clientY: y } = e
updatePosEnd(x, y)
if (!isSwiping.value && isThresholdExceeded.value)
isSwiping.value = true
if (isSwiping.value)
onSwipe?.(e)
}, listenerOptions),
useEventListener(target, 'pointerup', (e: PointerEvent) => {
if (!eventIsAllowed(e))
return
if (isSwiping.value)
onSwipeEnd?.(e, direction.value)
isPointerDown.value = false
isSwiping.value = false
}, listenerOptions),
]` | ✗ |
Vue Composition API¶
| Name | Type | Reactive Variables | Composables |
|---|---|---|---|
reactive |
reactive | none | none |
reactive |
reactive | none | none |
computed |
computed | none | none |
computed |
computed | none | none |
computed |
computed | none | none |
computed |
computed | none | none |
Functions¶
usePointerSwipe(target: MaybeRefOrGetter<HTMLElement | null | undefined>, options: UsePointerSwipeOptions): UsePointerSwipeReturn¶
Code
export function usePointerSwipe(
target: MaybeRefOrGetter<HTMLElement | null | undefined>,
options: UsePointerSwipeOptions = {},
): UsePointerSwipeReturn {
const targetRef = toRef(target)
const {
threshold = 50,
onSwipe,
onSwipeEnd,
onSwipeStart,
disableTextSelect = false,
} = options
const posStart = reactive<Position>({ x: 0, y: 0 })
const updatePosStart = (x: number, y: number) => {
posStart.x = x
posStart.y = y
}
const posEnd = reactive<Position>({ x: 0, y: 0 })
const updatePosEnd = (x: number, y: number) => {
posEnd.x = x
posEnd.y = y
}
const distanceX = computed(() => posStart.x - posEnd.x)
const distanceY = computed(() => posStart.y - posEnd.y)
const { max, abs } = Math
const isThresholdExceeded = computed(() => max(abs(distanceX.value), abs(distanceY.value)) >= threshold)
const isSwiping = shallowRef(false)
const isPointerDown = shallowRef(false)
const direction = computed(() => {
if (!isThresholdExceeded.value)
return 'none'
if (abs(distanceX.value) > abs(distanceY.value)) {
return distanceX.value > 0
? 'left'
: 'right'
}
else {
return distanceY.value > 0
? 'up'
: 'down'
}
})
const eventIsAllowed = (e: PointerEvent): boolean => {
const isReleasingButton = e.buttons === 0
const isPrimaryButton = e.buttons === 1
return options.pointerTypes?.includes(e.pointerType as PointerType) ?? (isReleasingButton || isPrimaryButton) ?? true
}
const listenerOptions = { passive: true }
const stops = [
useEventListener(target, 'pointerdown', (e: PointerEvent) => {
if (!eventIsAllowed(e))
return
isPointerDown.value = true
// Future pointer events will be retargeted to target until pointerup/cancel
const eventTarget = e.target as HTMLElement | undefined
eventTarget?.setPointerCapture(e.pointerId)
const { clientX: x, clientY: y } = e
updatePosStart(x, y)
updatePosEnd(x, y)
onSwipeStart?.(e)
}, listenerOptions),
useEventListener(target, 'pointermove', (e: PointerEvent) => {
if (!eventIsAllowed(e))
return
if (!isPointerDown.value)
return
const { clientX: x, clientY: y } = e
updatePosEnd(x, y)
if (!isSwiping.value && isThresholdExceeded.value)
isSwiping.value = true
if (isSwiping.value)
onSwipe?.(e)
}, listenerOptions),
useEventListener(target, 'pointerup', (e: PointerEvent) => {
if (!eventIsAllowed(e))
return
if (isSwiping.value)
onSwipeEnd?.(e, direction.value)
isPointerDown.value = false
isSwiping.value = false
}, listenerOptions),
]
tryOnMounted(() => {
// Allow vertical scrolling, disable horizontal scrolling by touch
targetRef.value?.style?.setProperty('touch-action', 'pan-y')
if (disableTextSelect) {
// Disable text selection on swipe
targetRef.value?.style?.setProperty('-webkit-user-select', 'none')
targetRef.value?.style?.setProperty('-ms-user-select', 'none')
targetRef.value?.style?.setProperty('user-select', 'none')
}
})
const stop = () => stops.forEach(s => s())
return {
isSwiping: readonly(isSwiping),
direction: readonly(direction),
posStart: readonly(posStart),
posEnd: readonly(posEnd),
distanceX,
distanceY,
stop,
}
}
-
JSDoc:
-
Parameters:
target: MaybeRefOrGetter<HTMLElement | null | undefined>options: UsePointerSwipeOptions- Return Type:
UsePointerSwipeReturn - Calls:
toRef (from @vueuse/shared)reactive (from vue)computed (from vue)maxabsshallowRef (from vue)options.pointerTypes?.includesuseEventListener (from ../useEventListener)eventIsAllowedeventTarget?.setPointerCaptureupdatePosStartupdatePosEndonSwipeStartonSwipeonSwipeEndtryOnMounted (from @vueuse/shared)targetRef.value?.style?.setPropertystops.forEachsreadonly (from vue)- Internal Comments:
updatePosStart(x: number, y: number): void¶
- Parameters:
x: numbery: number- Return Type:
void
updatePosEnd(x: number, y: number): void¶
- Parameters:
x: numbery: number- Return Type:
void
eventIsAllowed(e: PointerEvent): boolean¶
Code
- Parameters:
e: PointerEvent- Return Type:
boolean - Calls:
options.pointerTypes?.includes
stop(): void¶
- Return Type:
void - Calls:
stops.forEach
Interfaces¶
UsePointerSwipeOptions¶
Interface Code
export interface UsePointerSwipeOptions {
/**
* @default 50
*/
threshold?: number
/**
* Callback on swipe start.
*/
onSwipeStart?: (e: PointerEvent) => void
/**
* Callback on swipe move.
*/
onSwipe?: (e: PointerEvent) => void
/**
* Callback on swipe end.
*/
onSwipeEnd?: (e: PointerEvent, direction: UseSwipeDirection) => void
/**
* Pointer types to listen to.
*
* @default ['mouse', 'touch', 'pen']
*/
pointerTypes?: PointerType[]
/**
* Disable text selection on swipe.
*
* @default false
*/
disableTextSelect?: boolean
}
Properties¶
| Name | Type | Optional | Description |
|---|---|---|---|
threshold |
number |
✓ | |
onSwipeStart |
(e: PointerEvent) => void |
✓ | |
onSwipe |
(e: PointerEvent) => void |
✓ | |
onSwipeEnd |
(e: PointerEvent, direction: UseSwipeDirection) => void |
✓ | |
pointerTypes |
PointerType[] |
✓ | |
disableTextSelect |
boolean |
✓ |
UsePointerSwipeReturn¶
Interface Code
Properties¶
| Name | Type | Optional | Description |
|---|---|---|---|
isSwiping |
ShallowRef<boolean> |
✗ | |
direction |
Readonly<ShallowRef<UseSwipeDirection>> |
✗ | |
posStart |
Position |
✗ | |
posEnd |
Position |
✗ | |
distanceX |
Readonly<ComputedRef<number>> |
✗ | |
distanceY |
Readonly<ComputedRef<number>> |
✗ | |
stop |
() => void |
✗ |