@tamagui/sheet 2.3.3 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/cjs/SheetImplementationCustom.cjs +42 -29
  3. package/dist/cjs/SheetImplementationCustom.native.js +46 -33
  4. package/dist/cjs/SheetImplementationCustom.native.js.map +1 -1
  5. package/dist/cjs/SheetScrollView.cjs +64 -22
  6. package/dist/cjs/SheetScrollView.native.js +66 -23
  7. package/dist/cjs/SheetScrollView.native.js.map +1 -1
  8. package/dist/cjs/useGestureHandlerPan.cjs +61 -8
  9. package/dist/cjs/useGestureHandlerPan.native.js +64 -8
  10. package/dist/cjs/useGestureHandlerPan.native.js.map +1 -1
  11. package/dist/cjs/useSheetScrollViewGestures.cjs +13 -3
  12. package/dist/esm/SheetImplementationCustom.mjs +43 -32
  13. package/dist/esm/SheetImplementationCustom.mjs.map +1 -1
  14. package/dist/esm/SheetImplementationCustom.native.js +47 -36
  15. package/dist/esm/SheetImplementationCustom.native.js.map +1 -1
  16. package/dist/esm/SheetScrollView.mjs +64 -22
  17. package/dist/esm/SheetScrollView.mjs.map +1 -1
  18. package/dist/esm/SheetScrollView.native.js +66 -23
  19. package/dist/esm/SheetScrollView.native.js.map +1 -1
  20. package/dist/esm/useGestureHandlerPan.mjs +62 -9
  21. package/dist/esm/useGestureHandlerPan.mjs.map +1 -1
  22. package/dist/esm/useGestureHandlerPan.native.js +65 -9
  23. package/dist/esm/useGestureHandlerPan.native.js.map +1 -1
  24. package/dist/esm/useSheetScrollViewGestures.mjs +13 -3
  25. package/dist/esm/useSheetScrollViewGestures.mjs.map +1 -1
  26. package/dist/jsx/SheetImplementationCustom.mjs +43 -32
  27. package/dist/jsx/SheetImplementationCustom.mjs.map +1 -1
  28. package/dist/jsx/SheetImplementationCustom.native.js +46 -33
  29. package/dist/jsx/SheetImplementationCustom.native.js.map +1 -1
  30. package/dist/jsx/SheetScrollView.mjs +64 -22
  31. package/dist/jsx/SheetScrollView.mjs.map +1 -1
  32. package/dist/jsx/SheetScrollView.native.js +66 -23
  33. package/dist/jsx/SheetScrollView.native.js.map +1 -1
  34. package/dist/jsx/useGestureHandlerPan.mjs +62 -9
  35. package/dist/jsx/useGestureHandlerPan.mjs.map +1 -1
  36. package/dist/jsx/useGestureHandlerPan.native.js +64 -8
  37. package/dist/jsx/useGestureHandlerPan.native.js.map +1 -1
  38. package/dist/jsx/useSheetScrollViewGestures.mjs +13 -3
  39. package/dist/jsx/useSheetScrollViewGestures.mjs.map +1 -1
  40. package/package.json +20 -20
  41. package/src/SheetImplementationCustom.tsx +79 -47
  42. package/src/SheetScrollView.tsx +61 -13
  43. package/src/types.tsx +3 -0
  44. package/src/useGestureHandlerPan.tsx +64 -10
  45. package/src/useSheetScrollViewGestures.ts +17 -2
  46. package/types/SheetImplementationCustom.d.ts.map +1 -1
  47. package/types/SheetScrollView.d.ts.map +1 -1
  48. package/types/types.d.ts +1 -0
  49. package/types/types.d.ts.map +1 -1
  50. package/types/useGestureHandlerPan.d.ts.map +1 -1
  51. package/types/useSheetScrollViewGestures.d.ts +2 -1
  52. package/types/useSheetScrollViewGestures.d.ts.map +1 -1
@@ -207,6 +207,26 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
207
207
  // height would mismatch).
208
208
  const isWebKbSheet = isWeb && hasFit && moveOnKeyboardChange
209
209
 
210
+ // NATIVE keyboard frame freeze. native fit sheets feed keyboardOccludedHeight
211
+ // into the ScrollView as scrollable tail padding so content can clear the
212
+ // keyboard. but that padding grows the fit content, which grows the frame,
213
+ // which grows the occluded height — a feedback loop that balloons the sheet
214
+ // to the full-screen cap. web breaks the loop by freezing geometry against
215
+ // effScreenSize; native has no such freeze, so we pin the ScrollView to the
216
+ // frame height measured while the keyboard was closed (preKeyboardFrameSize)
217
+ // via keyboardStableFrameHeight below. unlike web, the native keyboard is an
218
+ // overlay that never shrinks the measured screen, so screenSize stays live.
219
+ const isNativeKbFitSheet = !isWeb && hasFit && Boolean(moveOnKeyboardChange)
220
+
221
+ // snapshot the fit frame height while the keyboard is closed, so the pin above
222
+ // holds the pre-keyboard viewport rather than a mid-feedback-loop value.
223
+ const preKeyboardFrameSize = React.useRef(0)
224
+ React.useEffect(() => {
225
+ if (isNativeKbFitSheet && open && !isKeyboardVisible && frameSize > 0) {
226
+ preKeyboardFrameSize.current = frameSize
227
+ }
228
+ }, [isNativeKbFitSheet, open, isKeyboardVisible, frameSize])
229
+
210
230
  // the space the snap positions are built against. WEB: the stable layout
211
231
  // viewport (document.documentElement.clientHeight), which the soft keyboard
212
232
  // never shrinks (unlike the measured screenSize / visualViewport). NATIVE:
@@ -307,10 +327,13 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
307
327
  // smaller; this override keeps it at the full height so the frame translates
308
328
  // with the keyboard but never resizes. 0 = no override (use the consumer maxHeight).
309
329
  const keyboardStableFrameHeight =
310
- isWebKbSheet && isKeyboardVisible && frameSize > 0 ? frameSize : 0
330
+ isWebKbSheet && isKeyboardVisible && frameSize > 0
331
+ ? frameSize
332
+ : isNativeKbFitSheet && isKeyboardVisible && preKeyboardFrameSize.current > 0
333
+ ? preKeyboardFrameSize.current
334
+ : 0
311
335
 
312
- const { useAnimatedNumber, useAnimatedNumberStyle, useAnimatedNumberReaction } =
313
- animationDriver
336
+ const { useAnimatedNumber, useAnimatedNumberStyle } = animationDriver
314
337
  const AnimatedView = (animationDriver.View ?? TamaguiView) as typeof Animated.View
315
338
 
316
339
  useIsomorphicLayoutEffect(() => {
@@ -346,42 +369,52 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
346
369
  // safety fallback timer for sheet close opacity
347
370
  const opacityFallbackTimer = React.useRef<ReturnType<typeof setTimeout> | null>(null)
348
371
 
349
- useAnimatedNumberReaction(
350
- {
351
- value: animatedNumber,
352
- hostRef: sheetRef,
353
- },
354
- React.useCallback(
355
- (value) => {
356
- at.current = value
357
- scrollBridge.paneY = value
358
- // update isAtTop for scroll enable/disable
359
- // activePositions[0] is the top snap point (keyboard-adjusted minY)
360
- const minY = activePositions[0]
361
- const wasAtTop = scrollBridge.isAtTop
362
- const nowAtTop = value <= minY + 5
363
- if (wasAtTop !== nowAtTop) {
364
- scrollBridge.isAtTop = nowAtTop
365
- // when reaching top, enable scroll; when leaving top, disable scroll
366
- // this preemptively sets scroll state before any gestures start
367
- if (nowAtTop) {
368
- // if scroll drifted during drag (e.g. fast swipe from position 1),
369
- // reset it to 0 before enabling free scroll
370
- if (scrollBridge.y > 0) {
371
- scrollBridge.forceScrollTo?.(0)
372
- scrollBridge.y = 0
373
- }
374
- scrollBridge.scrollLockY = undefined
375
- scrollBridge.setScrollEnabled?.(true)
376
- } else {
377
- scrollBridge.scrollLockY = 0
378
- scrollBridge.setScrollEnabled?.(false)
379
- }
372
+ const syncAnimatedPosition = useEvent((value: number) => {
373
+ at.current = value
374
+ scrollBridge.paneY = value
375
+
376
+ // update isAtTop for scroll enable/disable. activePositions[0] is the
377
+ // top snap point (keyboard-adjusted minY).
378
+ const minY = activePositions[0]
379
+ const wasAtTop = scrollBridge.isAtTop
380
+ const nowAtTop = value <= minY + 5
381
+ if (wasAtTop === nowAtTop) return
382
+
383
+ scrollBridge.isAtTop = nowAtTop
384
+ if (nowAtTop) {
385
+ if (scrollBridge.lockScrollAtTop) {
386
+ if (scrollBridge.y > 0) {
387
+ scrollBridge.forceScrollTo?.(0)
388
+ scrollBridge.y = 0
380
389
  }
381
- },
382
- [animationDriver, activePositions]
383
- )
384
- )
390
+ scrollBridge.scrollLockY = 0
391
+ scrollBridge.setScrollEnabled?.(false, 0)
392
+ return
393
+ }
394
+ // if scroll drifted during drag (e.g. fast swipe from position 1),
395
+ // reset it to 0 before enabling free scroll.
396
+ if (scrollBridge.y > 0) {
397
+ scrollBridge.forceScrollTo?.(0)
398
+ scrollBridge.y = 0
399
+ }
400
+ scrollBridge.scrollLockY = undefined
401
+ scrollBridge.setScrollEnabled?.(true)
402
+ } else {
403
+ scrollBridge.scrollLockY = 0
404
+ scrollBridge.setScrollEnabled?.(false)
405
+ }
406
+ })
407
+
408
+ const setAnimatedPositionDirect = useEvent((value: number) => {
409
+ syncAnimatedPosition(value)
410
+ animatedNumber.setValue(value, { type: 'direct' })
411
+ })
412
+
413
+ const getAnimatedPosition = useEvent(() => {
414
+ const value = animatedNumber.getValue()
415
+ syncAnimatedPosition(value)
416
+ return value
417
+ })
385
418
 
386
419
  function stopSpring() {
387
420
  animatedNumber.stop()
@@ -422,6 +455,7 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
422
455
  }
423
456
 
424
457
  const animationCompleteCallback = () => {
458
+ syncAnimatedPosition(toValue)
425
459
  if (opacityFallbackTimer.current) {
426
460
  clearTimeout(opacityFallbackTimer.current)
427
461
  opacityFallbackTimer.current = null
@@ -485,6 +519,7 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
485
519
  duration: 0,
486
520
  },
487
521
  () => {
522
+ syncAnimatedPosition(screenSize)
488
523
  // imperfect but struggling to render properly here
489
524
  setTimeout(() => {
490
525
  setDisableAnimation(false)
@@ -678,7 +713,7 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
678
713
  const grant = () => {
679
714
  setPanning(true)
680
715
  stopSpring()
681
- startY = at.current
716
+ startY = getAnimatedPosition()
682
717
  }
683
718
 
684
719
  let isExternalDrag = false
@@ -700,7 +735,7 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
700
735
  grant()
701
736
  }
702
737
  const to = dy + startY
703
- animatedNumber.setValue(resisted(to, minY), { type: 'direct' })
738
+ setAnimatedPositionDirect(resisted(to, minY))
704
739
  }
705
740
 
706
741
  scrollBridge.release = release
@@ -733,7 +768,7 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
733
768
  scrollBridge.setParentDragging(true)
734
769
  }
735
770
 
736
- animatedNumber.setValue(to, { type: 'direct' })
771
+ setAnimatedPositionDirect(to)
737
772
  },
738
773
  onPanResponderEnd: finish,
739
774
  onPanResponderTerminate: finish,
@@ -799,15 +834,12 @@ export const SheetImplementationCustom = React.forwardRef<View, SheetProps>(
799
834
  stopSpring,
800
835
  scrollBridge,
801
836
  setIsDragging,
802
- getCurrentPosition: () => at.current,
837
+ getCurrentPosition: getAnimatedPosition,
803
838
  resisted,
804
839
  disableDrag,
805
840
  isShowingInnerSheet,
806
- setAnimatedPosition: (val: number) => {
807
- // directly set the animated value for smooth dragging
808
- at.current = val
809
- animatedNumber.setValue(val, { type: 'direct' })
810
- },
841
+ // directly set the animated value for smooth dragging
842
+ setAnimatedPosition: setAnimatedPositionDirect,
811
843
  dismissOnSnapToBottom,
812
844
  snapPointsMode,
813
845
  isKeyboardVisible,
@@ -72,6 +72,7 @@ export const SheetScrollView = React.forwardRef<
72
72
  maxHeight: screenSize || undefined,
73
73
  }
74
74
  : { flex: 1 }
75
+ const contentContainerStyle = hasFit ? undefined : { minHeight: '100%' as const }
75
76
 
76
77
  // when the keyboard is open, pin the scroll view to the sheet's pre-keyboard
77
78
  // frame height (frozenFrameHeight), overriding any consumer maxHeight. on web
@@ -90,16 +91,28 @@ export const SheetScrollView = React.forwardRef<
90
91
 
91
92
  // RNGH scroll locking state
92
93
  const currentScrollOffset = useRef(0)
94
+ const lastEmittedScrollOffset = useRef(0)
93
95
  const lockedScrollY = useRef(0)
94
96
  const focusedInputScrollFrame = useRef(0)
95
97
 
96
98
  const setScrollEnabled = (next: boolean, lockTo?: number) => {
97
99
  if (!next) {
98
- const lockY = lockTo ?? currentScrollOffset.current
100
+ const lockY = lockTo ?? scrollBridge.scrollLockY ?? currentScrollOffset.current
101
+ if (scrollBridge.enabled === false && scrollBridge.scrollLockY === lockY) {
102
+ return
103
+ }
104
+ scrollBridge.enabled = false
99
105
  lockedScrollY.current = lockY
100
106
  scrollBridge.scrollLockY = lockY
101
- scrollRef.current?.scrollTo?.({ x: 0, y: lockY, animated: false })
107
+ if (currentScrollOffset.current !== lockY) {
108
+ scrollRef.current?.scrollTo?.({ x: 0, y: lockY, animated: false })
109
+ currentScrollOffset.current = lockY
110
+ }
102
111
  } else {
112
+ if (scrollBridge.enabled === true && scrollBridge.scrollLockY === undefined) {
113
+ return
114
+ }
115
+ scrollBridge.enabled = true
103
116
  lockedScrollY.current = currentScrollOffset.current
104
117
  scrollBridge.scrollLockY = undefined
105
118
  }
@@ -107,8 +120,36 @@ export const SheetScrollView = React.forwardRef<
107
120
 
108
121
  const forceScrollTo = (y: number) => {
109
122
  scrollRef.current?.scrollTo?.({ x: 0, y, animated: false })
123
+ currentScrollOffset.current = y
110
124
  }
111
125
 
126
+ const emitManualScroll = React.useCallback(
127
+ (node: HTMLElement, y: number) => {
128
+ currentScrollOffset.current = y
129
+ scrollBridge.y = y
130
+ if (y > 0) scrollBridge.scrollStartY = -1
131
+ lastEmittedScrollOffset.current = y
132
+ onScroll?.({
133
+ nativeEvent: {
134
+ contentOffset: {
135
+ x: node.scrollLeft,
136
+ y,
137
+ },
138
+ contentSize: {
139
+ height: node.scrollHeight,
140
+ width: node.scrollWidth,
141
+ },
142
+ layoutMeasurement: {
143
+ height: node.offsetHeight,
144
+ width: node.offsetWidth,
145
+ },
146
+ },
147
+ timeStamp: Date.now(),
148
+ } as any)
149
+ },
150
+ [onScroll, scrollBridge]
151
+ )
152
+
112
153
  const scrollFocusedInputClearOfKeyboard = React.useCallback(() => {
113
154
  if (!isWeb || !hasFit || !isKeyboardVisible || keyboardOccludedHeight <= 0) {
114
155
  return
@@ -206,6 +247,7 @@ export const SheetScrollView = React.forwardRef<
206
247
  hasScrollableContent,
207
248
  scrollEnabled,
208
249
  setScrollEnabled,
250
+ onManualScroll: emitManualScroll,
209
251
  })
210
252
 
211
253
  // content wrapper for measuring height
@@ -259,25 +301,30 @@ export const SheetScrollView = React.forwardRef<
259
301
  animated: false,
260
302
  })
261
303
  }
304
+ currentScrollOffset.current = scrollBridge.scrollLockY
262
305
  scrollBridge.y = scrollBridge.scrollLockY
263
- onScroll?.({
264
- ...e,
265
- nativeEvent: {
266
- ...e.nativeEvent,
267
- contentOffset: {
268
- ...e.nativeEvent.contentOffset,
269
- y: scrollBridge.scrollLockY,
306
+ if (lastEmittedScrollOffset.current !== scrollBridge.scrollLockY) {
307
+ lastEmittedScrollOffset.current = scrollBridge.scrollLockY
308
+ onScroll?.({
309
+ ...e,
310
+ nativeEvent: {
311
+ ...e.nativeEvent,
312
+ contentOffset: {
313
+ ...e.nativeEvent.contentOffset,
314
+ y: scrollBridge.scrollLockY,
315
+ },
270
316
  },
271
- },
272
- })
317
+ })
318
+ }
273
319
  return
274
320
  }
275
321
 
276
322
  scrollBridge.y = y
277
323
  if (y > 0) scrollBridge.scrollStartY = -1
324
+ lastEmittedScrollOffset.current = y
278
325
  onScroll?.(e)
279
326
  }}
280
- contentContainerStyle={{ minHeight: '100%' }}
327
+ contentContainerStyle={contentContainerStyle}
281
328
  bounces={false}
282
329
  keyboardShouldPersistTaps="always"
283
330
  keyboardDismissMode="none"
@@ -306,9 +353,10 @@ export const SheetScrollView = React.forwardRef<
306
353
  currentScrollOffset.current = y
307
354
  scrollBridge.y = y
308
355
  if (y > 0) scrollBridge.scrollStartY = -1
356
+ lastEmittedScrollOffset.current = y
309
357
  onScroll?.(e)
310
358
  }}
311
- contentContainerStyle={{ minHeight: '100%' }}
359
+ contentContainerStyle={contentContainerStyle}
312
360
  {...gestureProps}
313
361
  {...props}
314
362
  {...keyboardFrozenOverride}
package/src/types.tsx CHANGED
@@ -126,6 +126,9 @@ export type ScrollBridge = {
126
126
  _lastTouchY?: number
127
127
  // scroll lock position for forcing scroll back when pan handles
128
128
  scrollLockY?: number
129
+ // keep scroll locked while a drag that started below the top snap is still
130
+ // deciding whether to hand off into content scrolling.
131
+ lockScrollAtTop?: boolean
129
132
  // force scroll to position (compensates for async setNativeProps)
130
133
  forceScrollTo?: (y: number) => void
131
134
  // whether sheet is at top position (for scroll enable/disable)
@@ -1,5 +1,5 @@
1
1
  import { isWeb } from '@tamagui/constants'
2
- import { useCallback, useMemo, useRef, type RefObject } from 'react'
2
+ import { useCallback, useEffect, useMemo, useRef, type RefObject } from 'react'
3
3
  import { getGestureHandlerState, isGestureHandlerEnabled } from './gestureState'
4
4
  import { getSheetReleasePosition } from './keyboardAvoidance'
5
5
  import type { ScrollBridge, SnapPointsMode } from './types'
@@ -7,6 +7,7 @@ import type { ScrollBridge, SnapPointsMode } from './types'
7
7
  // threshold in pixels for considering sheet "at top" position
8
8
  // allows for small measurement variations
9
9
  const AT_TOP_THRESHOLD = 5
10
+ const SCROLL_HANDOFF_THRESHOLD = 160
10
11
 
11
12
  interface GesturePanConfig {
12
13
  positions: number[]
@@ -104,18 +105,45 @@ export function useGestureHandlerPan(config: GesturePanConfig): GesturePanResult
104
105
  frozenIsKeyboardVisible: false,
105
106
  // whether pan gesture actually started (vs just a tap in onBegin)
106
107
  panStarted: false,
108
+ startedBelowTop: false,
109
+ upwardDragAfterTop: 0,
110
+ scrollUnlockedAfterTop: false,
111
+ keepScrollLockedAfterEnd: false,
107
112
  })
113
+ const unlockScrollTimer = useRef<ReturnType<typeof setTimeout> | null>(null)
114
+
115
+ useEffect(() => {
116
+ return () => {
117
+ if (unlockScrollTimer.current) {
118
+ clearTimeout(unlockScrollTimer.current)
119
+ unlockScrollTimer.current = null
120
+ }
121
+ }
122
+ }, [])
108
123
 
109
124
  const onStart = useCallback(() => {
110
125
  stopSpring()
111
126
  }, [stopSpring])
112
127
 
113
128
  const onEnd = useCallback(
114
- (closestPoint: number, animationOverride?: any) => {
129
+ (closestPoint: number, animationOverride?: any, keepScrollLocked = false) => {
130
+ if (unlockScrollTimer.current) {
131
+ clearTimeout(unlockScrollTimer.current)
132
+ unlockScrollTimer.current = null
133
+ }
115
134
  setIsDragging(false)
116
135
  scrollBridge.setParentDragging(false)
117
- // re-enable scroll when gesture ends
118
- scrollBridge.setScrollEnabled?.(true)
136
+ scrollBridge.lockScrollAtTop = false
137
+ if (keepScrollLocked) {
138
+ scrollBridge.setScrollEnabled?.(false, 0)
139
+ unlockScrollTimer.current = setTimeout(() => {
140
+ unlockScrollTimer.current = null
141
+ scrollBridge.setScrollEnabled?.(true)
142
+ }, 160)
143
+ } else {
144
+ // re-enable scroll when gesture ends
145
+ scrollBridge.setScrollEnabled?.(true)
146
+ }
119
147
  setPosition(closestPoint)
120
148
  animateTo(closestPoint, animationOverride)
121
149
  },
@@ -173,6 +201,15 @@ export function useGestureHandlerPan(config: GesturePanConfig): GesturePanResult
173
201
  gs.frozenPositions = [...positions]
174
202
  gs.frozenMinY = minY
175
203
  gs.frozenIsKeyboardVisible = releaseConfigRef.current.isKeyboardVisible
204
+ gs.startedBelowTop = !atTop
205
+ gs.upwardDragAfterTop = 0
206
+ gs.scrollUnlockedAfterTop = false
207
+ gs.keepScrollLockedAfterEnd = false
208
+ scrollBridge.lockScrollAtTop = false
209
+ if (unlockScrollTimer.current) {
210
+ clearTimeout(unlockScrollTimer.current)
211
+ unlockScrollTimer.current = null
212
+ }
176
213
 
177
214
  // if sheet not at top, DISABLE SCROLL immediately and lock to 0
178
215
  // this prevents scroll from firing before pan takes over
@@ -251,8 +288,18 @@ export function useGestureHandlerPan(config: GesturePanConfig): GesturePanResult
251
288
  // if there's scrollable content, let scroll handle so user can scroll into content
252
289
  // resistance only applies when there's NO scrollable content
253
290
  if (hasScrollableContent) {
254
- // content is scrollable - let scroll handle (user wants to scroll down into content)
255
- panHandles = false
291
+ if (gs.startedBelowTop && !gs.scrollUnlockedAfterTop) {
292
+ gs.upwardDragAfterTop += Math.max(0, -deltaY)
293
+ if (gs.upwardDragAfterTop >= SCROLL_HANDOFF_THRESHOLD) {
294
+ gs.scrollUnlockedAfterTop = true
295
+ panHandles = false
296
+ } else {
297
+ panHandles = true
298
+ }
299
+ } else {
300
+ // content is scrollable - let scroll handle (user wants to scroll down into content)
301
+ panHandles = false
302
+ }
256
303
  } else {
257
304
  // no scrollable content -> pan handles for resistance effect
258
305
  panHandles = true
@@ -261,6 +308,7 @@ export function useGestureHandlerPan(config: GesturePanConfig): GesturePanResult
261
308
  }
262
309
 
263
310
  if (panHandles) {
311
+ scrollBridge.lockScrollAtTop = gs.startedBelowTop && !gs.scrollUnlockedAfterTop
264
312
  // pan handles - disable scroll and move sheet
265
313
  // when swiping down at top after scroll was engaged: lock at current scroll position
266
314
  // (handoff from scroll to pan — preserve scroll offset)
@@ -278,17 +326,22 @@ export function useGestureHandlerPan(config: GesturePanConfig): GesturePanResult
278
326
  setAnimatedPosition(newPosition)
279
327
  scrollBridge.setParentDragging(newPosition > minY)
280
328
  } else {
329
+ scrollBridge.lockScrollAtTop = false
281
330
  // scroll handles - enable scroll so it can move freely
282
331
  scrollBridge.setScrollEnabled?.(true)
332
+ scrollBridge.setParentDragging(false)
283
333
  // don't accumulate offset when scroll is handling
284
334
  }
285
335
  })
286
336
  .onEnd((event: { velocityY: number }) => {
287
337
  const { velocityY } = event
288
338
  const currentPos = gs.startY + gs.accumulatedOffset
339
+ const keepScrollLockedAfterEnd = gs.startedBelowTop && !gs.scrollUnlockedAfterTop
289
340
 
290
341
  // clear scroll lock
291
- scrollBridge.scrollLockY = undefined
342
+ scrollBridge.lockScrollAtTop = false
343
+ scrollBridge.scrollLockY = keepScrollLockedAfterEnd ? 0 : undefined
344
+ gs.keepScrollLockedAfterEnd = keepScrollLockedAfterEnd
292
345
 
293
346
  // use frozen positions from gesture start — keyboard may have dismissed
294
347
  // during drag (input blur), reverting activePositions. Frozen positions
@@ -301,7 +354,7 @@ export function useGestureHandlerPan(config: GesturePanConfig): GesturePanResult
301
354
 
302
355
  // if sheet is at top and scroll is engaged, just stay at top
303
356
  if (currentPos <= snapMinY + AT_TOP_THRESHOLD && scrollBridge.y > 0) {
304
- onEnd(0)
357
+ onEnd(0, undefined, keepScrollLockedAfterEnd)
305
358
  return
306
359
  }
307
360
 
@@ -321,11 +374,12 @@ export function useGestureHandlerPan(config: GesturePanConfig): GesturePanResult
321
374
  isWeb,
322
375
  })
323
376
 
324
- onEnd(closestPoint)
377
+ onEnd(closestPoint, undefined, keepScrollLockedAfterEnd)
325
378
  })
326
379
  .onFinalize(() => {
327
380
  // clear scroll lock on finalize too (safety)
328
- scrollBridge.scrollLockY = undefined
381
+ scrollBridge.lockScrollAtTop = false
382
+ scrollBridge.scrollLockY = gs.keepScrollLockedAfterEnd ? 0 : undefined
329
383
  if (gs.panStarted) {
330
384
  // real pan gesture — reset isDragging (also un-pauses keyboard handler + flushes)
331
385
  setIsDragging(false)
@@ -20,12 +20,14 @@ interface UseSheetScrollViewGesturesProps {
20
20
  hasScrollableContent: boolean
21
21
  scrollEnabled: boolean
22
22
  setScrollEnabled: (enabled: boolean, lockTo?: number) => void
23
+ onManualScroll?: (node: HTMLElement, y: number) => void
23
24
  }
24
25
 
25
26
  export function useSheetScrollViewGestures({
26
27
  scrollRef,
27
28
  scrollBridge,
28
29
  hasScrollableContent,
30
+ onManualScroll,
29
31
  }: UseSheetScrollViewGesturesProps) {
30
32
  const state = useRef<GestureState>({
31
33
  startY: 0,
@@ -36,6 +38,11 @@ export function useSheetScrollViewGestures({
36
38
  dys: [],
37
39
  scrollYAtGestureStart: 0,
38
40
  })
41
+ const onManualScrollRef = useRef(onManualScroll)
42
+
43
+ useEffect(() => {
44
+ onManualScrollRef.current = onManualScroll
45
+ }, [onManualScroll])
39
46
 
40
47
  useEffect(() => {
41
48
  if (!scrollRef.current) return
@@ -61,6 +68,13 @@ export function useSheetScrollViewGestures({
61
68
  node.style.overflowY = originalOverflow
62
69
  }
63
70
 
71
+ const setScrollTop = (nextScrollY: number) => {
72
+ if (node.scrollTop === nextScrollY) return
73
+
74
+ node.scrollTop = nextScrollY
75
+ onManualScrollRef.current?.(node, nextScrollY)
76
+ }
77
+
64
78
  const handleTouchStart = (e: TouchEvent) => {
65
79
  const touch = e.touches[0]
66
80
  if (!touch) return
@@ -97,7 +111,8 @@ export function useSheetScrollViewGestures({
97
111
 
98
112
  const isDraggingDown = dy > 0
99
113
  const currentScrollY = node.scrollTop
100
- const isPaneAtTop = scrollBridge.paneY <= scrollBridge.paneMinY + 5
114
+ const isPaneAtTop =
115
+ scrollBridge.isAtTop ?? scrollBridge.paneY <= scrollBridge.paneMinY + 5
101
116
 
102
117
  scrollBridge.y = currentScrollY
103
118
 
@@ -161,7 +176,7 @@ export function useSheetScrollViewGestures({
161
176
  const maxScrollY = node.scrollHeight - node.clientHeight
162
177
  const newScrollY = Math.max(0, Math.min(maxScrollY, currentScrollY + scrollDelta))
163
178
  if (newScrollY !== currentScrollY) {
164
- node.scrollTop = newScrollY
179
+ setScrollTop(newScrollY)
165
180
  scrollBridge.y = newScrollY
166
181
  if (newScrollY > 0) scrollBridge.scrollStartY = -1
167
182
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SheetImplementationCustom.d.ts","sourceRoot":"","sources":["../src/SheetImplementationCustom.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAmB,MAAM,OAAO,CAAA;AAOvC,OAAO,EAA4B,IAAI,EAAE,MAAM,cAAc,CAAA;AAmB7D,OAAO,KAAK,EAAc,cAAc,EAAE,MAAM,SAAS,CAAA;AAmCzD,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BAo9BrC,CAAA"}
1
+ {"version":3,"file":"SheetImplementationCustom.d.ts","sourceRoot":"","sources":["../src/SheetImplementationCustom.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAmB,MAAM,OAAO,CAAA;AAOvC,OAAO,EAA4B,IAAI,EAAE,MAAM,cAAc,CAAA;AAmB7D,OAAO,KAAK,EAAc,cAAc,EAAE,MAAM,SAAS,CAAA;AAmCzD,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BAo/BrC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"SheetScrollView.d.ts","sourceRoot":"","sources":["../src/SheetScrollView.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAsC,MAAM,OAAO,CAAA;AAC1D,OAAO,KAAK,EAAE,UAAU,IAAI,YAAY,EAAE,MAAM,cAAc,CAAA;AAgB9D,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wCAyS3B,CAAA"}
1
+ {"version":3,"file":"SheetScrollView.d.ts","sourceRoot":"","sources":["../src/SheetScrollView.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAsC,MAAM,OAAO,CAAA;AAC1D,OAAO,KAAK,EAAE,UAAU,IAAI,YAAY,EAAE,MAAM,cAAc,CAAA;AAgB9D,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wCAyV3B,CAAA"}
package/types/types.d.ts CHANGED
@@ -102,6 +102,7 @@ export type ScrollBridge = {
102
102
  setScrollEnabled?: (enabled: boolean, lockTo?: number) => void;
103
103
  _lastTouchY?: number;
104
104
  scrollLockY?: number;
105
+ lockScrollAtTop?: boolean;
105
106
  forceScrollTo?: (y: number) => void;
106
107
  isAtTop?: boolean;
107
108
  snapToPosition?: (positionIndex: number) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"useGestureHandlerPan.d.ts","sourceRoot":"","sources":["../src/useGestureHandlerPan.tsx"],"names":[],"mappings":"AACA,OAAO,EAAgC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAGpE,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAM3D,UAAU,gBAAgB;IACxB,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,GAAG,KAAK,IAAI,CAAA;IACzD,UAAU,EAAE,MAAM,IAAI,CAAA;IACtB,YAAY,EAAE,YAAY,CAAA;IAC1B,aAAa,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,kBAAkB,EAAE,MAAM,MAAM,CAAA;IAChC,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;IAC/C,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAE3B,mBAAmB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;IAE1C,gBAAgB,CAAC,EAAE,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,CAAA;IAExC,oBAAoB,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,CAAA;CAC1C;AAED,UAAU,gBAAgB;IACxB,UAAU,EAAE,GAAG,GAAG,IAAI,CAAA;IACtB,aAAa,EAAE,SAAS,CAAC,GAAG,CAAC,CAAA;IAC7B,qBAAqB,EAAE,OAAO,CAAA;CAC/B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,CAuT/E"}
1
+ {"version":3,"file":"useGestureHandlerPan.d.ts","sourceRoot":"","sources":["../src/useGestureHandlerPan.tsx"],"names":[],"mappings":"AACA,OAAO,EAA2C,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAG/E,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAO3D,UAAU,gBAAgB;IACxB,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,GAAG,KAAK,IAAI,CAAA;IACzD,UAAU,EAAE,MAAM,IAAI,CAAA;IACtB,YAAY,EAAE,YAAY,CAAA;IAC1B,aAAa,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,kBAAkB,EAAE,MAAM,MAAM,CAAA;IAChC,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;IAC/C,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAE3B,mBAAmB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;IAE1C,gBAAgB,CAAC,EAAE,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,CAAA;IAExC,oBAAoB,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,CAAA;CAC1C;AAED,UAAU,gBAAgB;IACxB,UAAU,EAAE,GAAG,GAAG,IAAI,CAAA;IACtB,aAAa,EAAE,SAAS,CAAC,GAAG,CAAC,CAAA;IAC7B,qBAAqB,EAAE,OAAO,CAAA;CAC/B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,CA4W/E"}
@@ -6,7 +6,8 @@ interface UseSheetScrollViewGesturesProps {
6
6
  hasScrollableContent: boolean;
7
7
  scrollEnabled: boolean;
8
8
  setScrollEnabled: (enabled: boolean, lockTo?: number) => void;
9
+ onManualScroll?: (node: HTMLElement, y: number) => void;
9
10
  }
10
- export declare function useSheetScrollViewGestures({ scrollRef, scrollBridge, hasScrollableContent, }: UseSheetScrollViewGesturesProps): {};
11
+ export declare function useSheetScrollViewGestures({ scrollRef, scrollBridge, hasScrollableContent, onManualScroll, }: UseSheetScrollViewGesturesProps): {};
11
12
  export {};
12
13
  //# sourceMappingURL=useSheetScrollViewGestures.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useSheetScrollViewGestures.d.ts","sourceRoot":"","sources":["../src/useSheetScrollViewGestures.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,IAAI,YAAY,EAAE,MAAM,cAAc,CAAA;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAc3C,UAAU,+BAA+B;IACvC,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,YAAY,GAAG,IAAI,CAAC,CAAA;IAC/C,YAAY,EAAE,YAAY,CAAA;IAC1B,oBAAoB,EAAE,OAAO,CAAA;IAC7B,aAAa,EAAE,OAAO,CAAA;IACtB,gBAAgB,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9D;AAED,wBAAgB,0BAA0B,CAAC,EACzC,SAAS,EACT,YAAY,EACZ,oBAAoB,GACrB,EAAE,+BAA+B,MAqMjC"}
1
+ {"version":3,"file":"useSheetScrollViewGestures.d.ts","sourceRoot":"","sources":["../src/useSheetScrollViewGestures.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,IAAI,YAAY,EAAE,MAAM,cAAc,CAAA;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAc3C,UAAU,+BAA+B;IACvC,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,YAAY,GAAG,IAAI,CAAC,CAAA;IAC/C,YAAY,EAAE,YAAY,CAAA;IAC1B,oBAAoB,EAAE,OAAO,CAAA;IAC7B,aAAa,EAAE,OAAO,CAAA;IACtB,gBAAgB,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IAC7D,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;CACxD;AAED,wBAAgB,0BAA0B,CAAC,EACzC,SAAS,EACT,YAAY,EACZ,oBAAoB,EACpB,cAAc,GACf,EAAE,+BAA+B,MAkNjC"}