Skip to content

Commit

Permalink
Improve SheetModal for mobile
Browse files Browse the repository at this point in the history
  • Loading branch information
sisou committed Aug 31, 2023
1 parent 99d9c7c commit 69da5b8
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/components/atoms/SheetModal.story.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const progress = ref(0)
<Story title="Modal Sheet">
<div class="relative h-screen bg-space/20">
<SheetModal
class="inset-x-0 bottom-0 mx-auto text-center text-white rounded-lg shadow bg-space overscroll-none"
class="inset-x-0 bottom-0 mx-auto text-center text-white rounded-lg shadow bg-space"
:progress="progress" :initial-height="171" :max-height="371" :initial-border-radius="8"
:initial-gap-to-screen="20" @update:progress="progress = $event"
>
Expand Down
32 changes: 20 additions & 12 deletions src/components/atoms/SheetModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,27 +28,36 @@ const emit = defineEmits({
'update:progress': (_: number) => true,
})
const dif = props.maxHeight - props.initialHeight
const heightDifference = props.maxHeight - props.initialHeight
let initialY = 0
let initialTime = 0
let initialX = 0
let initialOpen = false
const dragging = ref(false)
const container = ref<HTMLElement | null>(null)
const isOpen = computed(() => props.progress === 1)
function onStart(event: PointerEvent) {
dragging.value = true
initialTime = event.timeStamp
initialY = event.clientY
initialX = event.clientX
initialOpen = isOpen.value
container.value!.setPointerCapture(event.pointerId)
}
function onMove(event: PointerEvent) {
if (!dragging.value)
return
const yDelta = (initialY - event.clientY)
const startingPoint = isOpen.value ? yDelta + dif : yDelta
const newProgress = Math.max(0, Math.min(startingPoint / dif, 1))
const yDelta = initialY - event.clientY
let newProgress: number
if (initialOpen) {
// yDelta is negative for dragging down
newProgress = Math.min(Math.max(heightDifference + yDelta, 0), heightDifference) / heightDifference
}
else {
// yDelta is positive for dragging up
newProgress = Math.min(Math.max(yDelta, 0), heightDifference) / heightDifference
}
emit('update:progress', newProgress)
}
Expand All @@ -57,15 +66,14 @@ function onEnd(event: PointerEvent) {
container.value!.releasePointerCapture(event.pointerId)
animateShortly()
const timeDelta = event.timeStamp - initialTime
const isClick = timeDelta < 500
const isClick = Math.abs(initialY - event.clientY) < 10 && Math.abs(initialX - event.clientX) < 10
if (isClick && !isOpen.value) {
if (isClick && !initialOpen) {
open()
}
else {
if (isOpen.value)
if (initialOpen)
props.progress < 0.85 ? close() : open()
else
Expand All @@ -91,7 +99,7 @@ function onCardDrag(progress: number) {
const radius = (1 - progress) * props.initialBorderRadius
style.value = {
height: `${props.initialHeight + dif * progress}px`,
height: `${props.initialHeight + heightDifference * progress}px`,
marginBottom: `${(1 - progress) * props.initialGapToScreen}px`,
borderBottomRightRadius: `${radius}px`,
borderBottomLeftRadius: `${radius}px`,
Expand All @@ -115,7 +123,7 @@ onBeforeUnmount(() => {

<template>
<article
ref="container" class="absolute h-full touch-none sheet-transition will-change-auto"
ref="container" class="absolute h-full touch-pan-x sheet-transition will-change-auto"
:style="style" @pointerdown.prevent="onStart" @pointermove.prevent="onMove" @pointerup.prevent="onEnd"
>
<slot name="dragger">
Expand Down

0 comments on commit 69da5b8

Please sign in to comment.