diff --git a/src/BottomSheet.tsx b/src/BottomSheet.tsx index 7aac5fad..58e658c2 100644 --- a/src/BottomSheet.tsx +++ b/src/BottomSheet.tsx @@ -477,6 +477,7 @@ export const BottomSheet = React.forwardRef< const handleDrag = ({ args: [{ closeOnTap = false, isContentDragging = false } = {}] = [], cancel, + canceled, direction: [, direction], down, first, @@ -486,6 +487,10 @@ export const BottomSheet = React.forwardRef< tap, velocity: [, velocity], }) => { + if (canceled) { + return memo + } + const my = _my * -1 // Cancel the drag operation if the canDrag state changed diff --git a/test/bottom-sheet.test.tsx b/test/bottom-sheet.test.tsx index 8cc31e85..72154c47 100644 --- a/test/bottom-sheet.test.tsx +++ b/test/bottom-sheet.test.tsx @@ -1,6 +1,6 @@ import { StrictMode, useRef } from 'react' import { describe, expect, it, vi } from 'vitest' -import { render, screen, waitFor, act } from '@testing-library/react' +import { render, screen, waitFor, act, fireEvent } from '@testing-library/react' import { BottomSheet } from '../src' import type { BottomSheetRef } from '../src' @@ -80,6 +80,44 @@ describe('BottomSheet', () => { expect(onDismiss).toHaveBeenCalledOnce() }) + it('dismisses once per backdrop tap', async () => { + const onDismiss = vi.fn() + render( + + {content} + + ) + await waitFor(() => expect(sheetState()).toBe('open'), { timeout: 4000 }) + + const backdrop = document.querySelector('[data-rsbs-backdrop]')! + const pointer = { pointerId: 1, buttons: 1, clientX: 10, clientY: 10 } + fireEvent.pointerDown(backdrop, pointer) + fireEvent.pointerUp(backdrop, { ...pointer, buttons: 0 }) + + await new Promise((resolve) => setTimeout(resolve, 50)) + expect(onDismiss).toHaveBeenCalledOnce() + }) + + it('dismisses once per swipe down', async () => { + const onDismiss = vi.fn() + render( + header}> + {content} + + ) + await waitFor(() => expect(sheetState()).toBe('open'), { timeout: 4000 }) + + const header = document.querySelector('[data-rsbs-header]')! + const pointer = { pointerId: 1, buttons: 1, clientX: 10 } + fireEvent.pointerDown(header, { ...pointer, clientY: 0 }) + fireEvent.pointerMove(header, { ...pointer, clientY: 150 }) + fireEvent.pointerMove(header, { ...pointer, clientY: 400 }) + fireEvent.pointerUp(header, { ...pointer, buttons: 0, clientY: 400 }) + + await new Promise((resolve) => setTimeout(resolve, 50)) + expect(onDismiss).toHaveBeenCalledOnce() + }) + it('reports the current height through the ref', async () => { let sheetRef: React.RefObject