nuxt-start/composables/usePullToRefresh.ts
2026-01-02 19:19:19 +01:00

64 lines
1.5 KiB
TypeScript

export function usePullToRefresh(onRefresh: () => Promise<void> | void) {
const isPulling = ref(false)
const pullDistance = ref(0)
const isRefreshing = ref(false)
const threshold = 80
let startY = 0
let currentY = 0
const onTouchStart = (e: TouchEvent) => {
if (window.scrollY === 0) {
startY = e.touches[0].clientY
isPulling.value = true
}
}
const onTouchMove = (e: TouchEvent) => {
if (!isPulling.value || isRefreshing.value) return
currentY = e.touches[0].clientY
const diff = currentY - startY
if (diff > 0 && window.scrollY === 0) {
pullDistance.value = Math.min(diff * 0.5, threshold * 1.5)
if (diff > 10) {
e.preventDefault()
}
}
}
const onTouchEnd = async () => {
if (!isPulling.value) return
if (pullDistance.value >= threshold && !isRefreshing.value) {
isRefreshing.value = true
await onRefresh()
isRefreshing.value = false
}
isPulling.value = false
pullDistance.value = 0
startY = 0
}
onMounted(() => {
document.addEventListener('touchstart', onTouchStart, { passive: true })
document.addEventListener('touchmove', onTouchMove, { passive: false })
document.addEventListener('touchend', onTouchEnd)
})
onUnmounted(() => {
document.removeEventListener('touchstart', onTouchStart)
document.removeEventListener('touchmove', onTouchMove)
document.removeEventListener('touchend', onTouchEnd)
})
return {
isPulling,
pullDistance,
isRefreshing,
threshold
}
}