Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ All notable changes follow Keep a Changelog.
published-package integration proofs to the documentation site.
- Preserved the upward touch-pan direction at the top boundary so scrollable
content can begin scrolling normally from its first row.
- Documented explicit pointer ownership for Pull to Refresh inside a draggable
bottom sheet.

## [0.1.0-alpha.0] - 2026-09-05

Expand Down
6 changes: 6 additions & 0 deletions docs/INTEGRATIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ element explicitly:
ref={scrollRef}
className="sheet-scroll"
onRefresh={refresh}
onPointerDown={(event) => event.stopPropagation()}
scrollContainer={scrollRef}
>
<PullToRefresh.Content>{/* feed */}</PullToRefresh.Content>
Expand All @@ -54,6 +55,11 @@ Make the root itself scrollable. Do not place a default PTR root—with its
mechanical overflow containment—inside a second element that is expected to
receive chained scrolling.

Stop pointer-down propagation from the feed when the sheet handle is the only
surface that should drag the sheet. This leaves the browser default untouched,
so ordinary list scrolling still works, while preventing the sheet and PTR
from racing to capture the same downward gesture at the top boundary.

The documentation proof uses the published v5 package. Desktop automation
verifies that the sheet opens, scrolls the dedicated root, and closes.
Combined drag feel on iOS and Android remains manual pending; the alpha does not
Expand Down
31 changes: 31 additions & 0 deletions e2e/gesture.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,37 @@ test('sheet content keeps the native scroll direction available at its top bound
.toBeGreaterThan(0)
})

test('sheet feed owns a gradual downward pull before the sheet can claim it', async ({
page,
}) => {
await page.goto('/#integrations')
await page.getByRole('button', { name: 'Open bottom sheet proof' }).click()

const sheet = page.getByRole('dialog')
await expect(sheet).toHaveAttribute('data-rsbs-state', 'open')
const initialPosition = await sheet.evaluate((node) =>
node.style.getPropertyValue('--rsbs-position'),
)
const root = page.getByTestId('sheet-ptr')
const box = await root.boundingBox()
if (!box) throw new Error('Sheet PTR root has no box')
const x = box.x + box.width / 2
const y = box.y + 80

await page.mouse.move(x, y)
await page.mouse.down()
await page.mouse.move(x, y + 2)
await page.mouse.move(x, y + 30, { steps: 6 })

await expect(root).toHaveAttribute('data-state', 'pulling')
await expect
.poll(() =>
sheet.evaluate((node) => node.style.getPropertyValue('--rsbs-position')),
)
.toBe(initialPosition)
await page.mouse.up()
})

test('Swipe Actions owns a horizontal row trace', async ({ page }) => {
await page.goto('/#integrations')
const row = page.locator('.swipe-actions-root').first()
Expand Down
1 change: 1 addition & 0 deletions website/src/demos.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ export function BottomSheetProof() {
className="sheet-scroll"
data-testid="sheet-ptr"
scrollContainer={scrollRef}
onPointerDown={(event) => event.stopPropagation()}
onRefresh={() =>
new Promise((resolve) => window.setTimeout(resolve, 400))
}
Expand Down