@tamagui/sheet 1.0.1-beta.113 → 1.0.1-beta.116

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.
package/src/Sheet.tsx CHANGED
@@ -4,12 +4,15 @@ import {
4
4
  Slot,
5
5
  TamaguiElement,
6
6
  Theme,
7
+ composeEventHandlers,
7
8
  isClient,
8
9
  isWeb,
9
10
  mergeEvent,
10
11
  styled,
11
12
  themeable,
13
+ useConstant,
12
14
  useEvent,
15
+ useIsomorphicLayoutEffect,
13
16
  useThemeName,
14
17
  withStaticProperties,
15
18
  } from '@tamagui/core'
@@ -26,7 +29,6 @@ import React, {
26
29
  useCallback,
27
30
  useContext,
28
31
  useEffect,
29
- useLayoutEffect,
30
32
  useMemo,
31
33
  useRef,
32
34
  useState,
@@ -34,8 +36,12 @@ import React, {
34
36
  import {
35
37
  Animated,
36
38
  GestureResponderEvent,
39
+ NativeScrollEvent,
40
+ NativeSyntheticEvent,
37
41
  PanResponder,
38
42
  PanResponderGestureState,
43
+ ScrollView,
44
+ ScrollViewProps,
39
45
  View,
40
46
  } from 'react-native'
41
47
 
@@ -72,6 +78,14 @@ type PositionChangeHandler = (position: number) => void
72
78
 
73
79
  type OpenChangeHandler = ((open: boolean) => void) | React.Dispatch<React.SetStateAction<boolean>>
74
80
 
81
+ type ScrollBridge = {
82
+ enabled: boolean
83
+ y: number
84
+ scrollStartY: number
85
+ drag: (dy: number) => void
86
+ release: (state: { dy: number; vy: number }) => void
87
+ }
88
+
75
89
  type SheetContextValue = Required<
76
90
  Pick<SheetProps, 'open' | 'position' | 'snapPoints' | 'dismissOnOverlayPress'>
77
91
  > & {
@@ -81,6 +95,8 @@ type SheetContextValue = Required<
81
95
  allowPinchZoom: RemoveScrollProps['allowPinchZoom']
82
96
  contentRef: React.RefObject<TamaguiElement>
83
97
  dismissOnSnapToBottom: boolean
98
+ scrollBridge: ScrollBridge
99
+ modal: boolean
84
100
  }
85
101
 
86
102
  const [createSheetContext, createSheetScope] = createContextScope(SHEET_NAME)
@@ -89,6 +105,10 @@ const [SheetProvider, useSheetContext] = createSheetContext<SheetContextValue>(
89
105
  {} as any
90
106
  )
91
107
 
108
+ /* -------------------------------------------------------------------------------------------------
109
+ * SheetHandle
110
+ * -----------------------------------------------------------------------------------------------*/
111
+
92
112
  export const SheetHandleFrame = styled(XStack, {
93
113
  name: SHEET_HANDLE_NAME,
94
114
  height: 10,
@@ -132,6 +152,10 @@ export const SheetHandle = SheetHandleFrame.extractable(
132
152
  }
133
153
  )
134
154
 
155
+ /* -------------------------------------------------------------------------------------------------
156
+ * SheetOverlay
157
+ * -----------------------------------------------------------------------------------------------*/
158
+
135
159
  const SHEET_OVERLAY_NAME = 'SheetOverlay'
136
160
 
137
161
  export const SheetOverlayFrame = styled(YStack, {
@@ -163,7 +187,7 @@ export const SheetOverlay = SheetOverlayFrame.extractable(
163
187
  const context = useSheetContext(SHEET_OVERLAY_NAME, __scopeSheet)
164
188
  return (
165
189
  <RemoveScroll
166
- enabled={context.open}
190
+ enabled={context.open && context.modal}
167
191
  as={Slot}
168
192
  allowPinchZoom={context.allowPinchZoom}
169
193
  shards={[context.contentRef]}
@@ -187,6 +211,92 @@ export const SheetOverlay = SheetOverlayFrame.extractable(
187
211
  }
188
212
  )
189
213
 
214
+ /* -------------------------------------------------------------------------------------------------
215
+ * SheetScrollView
216
+ * -----------------------------------------------------------------------------------------------*/
217
+
218
+ const SHEET_SCROLL_VIEW_NAME = 'SheetScrollView'
219
+
220
+ export const SheetScrollView = forwardRef<ScrollView, ScrollViewProps>(
221
+ ({ __scopeSheet, ...props }: SheetScopedProps<ScrollViewProps>, ref) => {
222
+ const { scrollBridge } = useSheetContext(SHEET_SCROLL_VIEW_NAME, __scopeSheet)
223
+ const [scrollEnabled, setScrollEnabled] = useState(true)
224
+ const state = useRef({
225
+ dy: 0,
226
+ // store a few recent dys to get velocity on release
227
+ dys: [] as number[],
228
+ })
229
+
230
+ const release = () => {
231
+ setScrollEnabled(true)
232
+ const recentDys = state.current.dys.slice(-10)
233
+ const dist = recentDys.length
234
+ ? recentDys.reduce((a, b, i) => a + b - (recentDys[i - 1] ?? recentDys[0]), 0)
235
+ : 0
236
+ const avgDy = dist / recentDys.length
237
+ const vy = avgDy * 0.075
238
+ state.current.dys = []
239
+ scrollBridge.release({
240
+ dy: state.current.dy,
241
+ vy,
242
+ })
243
+ }
244
+
245
+ return (
246
+ <ScrollView
247
+ ref={ref}
248
+ scrollEventThrottle={16} // todo release we can just grab the last dY and estimate vY using a sample of last dYs
249
+ {...props}
250
+ scrollEnabled={props.scrollEnabled || scrollEnabled}
251
+ onScroll={composeEventHandlers<NativeSyntheticEvent<NativeScrollEvent>>(
252
+ props.onScroll,
253
+ (e) => {
254
+ const { y } = e.nativeEvent.contentOffset
255
+ scrollBridge.y = y
256
+ if (y > 0) {
257
+ scrollBridge.scrollStartY = -1
258
+ }
259
+ }
260
+ )}
261
+ onResponderMove={composeEventHandlers(props.onResponderMove, (e) => {
262
+ const { pageY } = e.nativeEvent
263
+ if (scrollBridge.y <= 0) {
264
+ if (scrollBridge.scrollStartY === -1) {
265
+ scrollBridge.scrollStartY = pageY
266
+ }
267
+ const dy = pageY - scrollBridge.scrollStartY
268
+ if (dy <= 0) {
269
+ setScrollEnabled(true)
270
+ return
271
+ }
272
+ setScrollEnabled(false)
273
+ scrollBridge.drag(dy)
274
+ state.current.dy = dy
275
+ state.current.dys.push(dy)
276
+ // only do every so often, cut down to 10 again
277
+ if (state.current.dys.length > 100) {
278
+ state.current.dys = state.current.dys.slice(-10)
279
+ }
280
+ }
281
+ })}
282
+ onResponderReject={composeEventHandlers(props.onResponderReject, release)}
283
+ onResponderTerminate={composeEventHandlers(props.onResponderTerminate, release)}
284
+ onResponderRelease={composeEventHandlers(props.onResponderRelease, release)}
285
+ style={[
286
+ {
287
+ flex: 1,
288
+ },
289
+ props.style,
290
+ ]}
291
+ />
292
+ )
293
+ }
294
+ )
295
+
296
+ /* -------------------------------------------------------------------------------------------------
297
+ * Sheet
298
+ * -----------------------------------------------------------------------------------------------*/
299
+
190
300
  const selectionStyleSheet = isClient ? document.createElement('style') : null
191
301
  if (selectionStyleSheet) {
192
302
  document.head.appendChild(selectionStyleSheet)
@@ -232,16 +342,31 @@ export const Sheet = withStaticProperties(
232
342
  animationConfig,
233
343
  dismissOnSnapToBottom = false,
234
344
  disableDrag: disableDragProp,
235
- modal,
345
+ modal = false,
236
346
  allowPinchZoom,
237
347
  } = props
238
348
 
349
+ if (process.env.NODE_ENV === 'development') {
350
+ if (snapPointsProp.some((p) => p < 0 || p > 100)) {
351
+ console.warn(
352
+ `⚠️ Invalid snapPoint given, snapPoints must be between 0 and 100, equal to percent height of frame`
353
+ )
354
+ }
355
+ }
356
+
239
357
  // allows for sheets to be controlled by other components
240
358
  const controller = useContext(SheetControllerContext)
241
359
  const isHidden = controller?.hidden || false
242
360
  const disableDrag = disableDragProp ?? controller?.disableDrag
243
361
  const themeName = useThemeName()
244
362
  const contentRef = React.useRef<TamaguiElement>(null)
363
+ const scrollBridge = useConstant<ScrollBridge>(() => ({
364
+ enabled: false,
365
+ y: 0,
366
+ scrollStartY: -1,
367
+ drag: () => {},
368
+ release: () => {},
369
+ }))
245
370
 
246
371
  const onChangeOpenInternal = (val: boolean) => {
247
372
  controller?.onChangeOpen?.(val)
@@ -293,7 +418,7 @@ export const Sheet = withStaticProperties(
293
418
  }
294
419
 
295
420
  const [isResizing, setIsResizing] = useState(true)
296
- useLayoutEffect(() => {
421
+ useIsomorphicLayoutEffect(() => {
297
422
  if (!isResizing) {
298
423
  setIsResizing(true)
299
424
  }
@@ -355,7 +480,7 @@ export const Sheet = withStaticProperties(
355
480
  })
356
481
  })
357
482
 
358
- useLayoutEffect(() => {
483
+ useIsomorphicLayoutEffect(() => {
359
484
  animateTo(position)
360
485
  }, [isHidden, frameSize, position, animateTo])
361
486
 
@@ -370,64 +495,108 @@ export const Sheet = withStaticProperties(
370
495
  }
371
496
  }, [])
372
497
 
373
- const panResponder = useMemo(() => {
374
- if (disableDrag) return
375
- if (!frameSize) return
376
-
377
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
378
- const pos = positionValue.current!
379
- const minY = positions[0]
380
- let startY = at.current
381
-
382
- function makeUnselectable(val: boolean) {
383
- if (!selectionStyleSheet) return
384
- if (!val) {
385
- selectionStyleSheet.innerText = ``
386
- } else {
387
- selectionStyleSheet.innerText = `:root * { user-select: none !important; -webkit-user-select: none !important; }`
498
+ const panResponder = useMemo(
499
+ () => {
500
+ if (disableDrag) return
501
+ if (!frameSize) return
502
+
503
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
504
+ const pos = positionValue.current!
505
+ const minY = positions[0]
506
+ let startY = at.current
507
+
508
+ function makeUnselectable(val: boolean) {
509
+ if (!selectionStyleSheet) return
510
+ if (!val) {
511
+ selectionStyleSheet.innerText = ``
512
+ } else {
513
+ selectionStyleSheet.innerText = `:root * { user-select: none !important; -webkit-user-select: none !important; }`
514
+ }
388
515
  }
389
- }
390
516
 
391
- const finish = (_e: GestureResponderEvent, { vy, dy }: PanResponderGestureState) => {
392
- makeUnselectable(false)
393
- const at = dy + startY
394
- // seems liky vy goes up to about 4 at the very most (+ is down, - is up)
395
- // lets base our multiplier on the total layout height
396
- const end = at + frameSize * vy * 0.33
397
- let closestPoint = 0
398
- let dist = Infinity
399
- for (let i = 0; i < positions.length; i++) {
400
- const position = positions[i]
401
- const curDist = end > position ? end - position : position - end
402
- if (curDist < dist) {
403
- dist = curDist
404
- closestPoint = i
517
+ const release = ({ vy, dy }: { dy: number; vy: number }) => {
518
+ isExternalDrag = false
519
+ previouslyScrolling = false
520
+ makeUnselectable(false)
521
+ const at = dy + startY
522
+ // seems liky vy goes up to about 4 at the very most (+ is down, - is up)
523
+ // lets base our multiplier on the total layout height
524
+ const end = at + frameSize * vy * 0.33
525
+ let closestPoint = 0
526
+ let dist = Infinity
527
+ for (let i = 0; i < positions.length; i++) {
528
+ const position = positions[i]
529
+ const curDist = end > position ? end - position : position - end
530
+ if (curDist < dist) {
531
+ dist = curDist
532
+ closestPoint = i
533
+ }
405
534
  }
535
+ // have to call both because state may not change but need to snap back
536
+ setPosition(closestPoint)
537
+ animateTo(closestPoint)
538
+ }
539
+
540
+ const finish = (_e: GestureResponderEvent, state: PanResponderGestureState) => {
541
+ release(state)
406
542
  }
407
- // have to call both because state may not change but need to snap back
408
- setPosition(closestPoint)
409
- animateTo(closestPoint)
410
- }
411
543
 
412
- return PanResponder.create({
413
- onMoveShouldSetPanResponder: (_e, { dy }) => {
544
+ let previouslyScrolling = false
545
+
546
+ const onMoveShouldSet = (_e: GestureResponderEvent, { dy }: PanResponderGestureState) => {
547
+ if (scrollBridge.y !== 0) {
548
+ previouslyScrolling = true
549
+ return false
550
+ }
551
+ if (scrollBridge.y === 0 && dy < 0) {
552
+ return false
553
+ }
554
+ if (previouslyScrolling) {
555
+ previouslyScrolling = false
556
+ return true
557
+ }
414
558
  // we could do some detection of other touchables and cancel here..
415
- return Math.abs(dy) > 6
416
- },
417
- onPanResponderGrant: () => {
559
+ return Math.abs(dy) > 8
560
+ }
561
+
562
+ const grant = () => {
418
563
  makeUnselectable(true)
419
564
  stopSpring()
420
565
  startY = at.current
421
- },
422
- onPanResponderMove: (_e, { dy }) => {
566
+ }
567
+
568
+ let isExternalDrag = false
569
+
570
+ scrollBridge.drag = (dy) => {
571
+ if (!isExternalDrag) {
572
+ isExternalDrag = true
573
+ grant()
574
+ }
423
575
  const to = dy + startY
424
576
  pos.setValue(resisted(to, minY))
425
- },
426
- onPanResponderEnd: finish,
427
- onPanResponderTerminate: finish,
428
- onPanResponderRelease: finish,
429
- })
430
- }, [disableDrag, animateTo, frameSize, positions, setPosition])
577
+ }
578
+
579
+ scrollBridge.release = release
580
+
581
+ return PanResponder.create({
582
+ onMoveShouldSetPanResponder: (...args) => {
583
+ const res = onMoveShouldSet(...args)
584
+ // console.log('res', res, scrollBridge.y)
585
+ return res
586
+ },
587
+ onPanResponderGrant: grant,
588
+ onPanResponderMove: (_e, { dy }) => {
589
+ const to = dy + startY
590
+ pos.setValue(resisted(to, minY))
591
+ },
592
+ onPanResponderEnd: finish,
593
+ onPanResponderTerminate: finish,
594
+ onPanResponderRelease: finish,
595
+ })
596
+ },
597
+ // eslint-disable-next-line react-hooks/exhaustive-deps
598
+ [disableDrag, animateTo, frameSize, positions, setPosition]
599
+ )
431
600
 
432
601
  let handleComponent: React.ReactElement | null = null
433
602
  let overlayComponent: React.ReactElement | null = null
@@ -461,6 +630,7 @@ export const Sheet = withStaticProperties(
461
630
 
462
631
  const contents = (
463
632
  <SheetProvider
633
+ modal={modal}
464
634
  contentRef={contentRef}
465
635
  dismissOnOverlayPress={dismissOnOverlayPress}
466
636
  dismissOnSnapToBottom={dismissOnSnapToBottom}
@@ -472,6 +642,7 @@ export const Sheet = withStaticProperties(
472
642
  snapPoints={snapPoints}
473
643
  setPosition={setPosition}
474
644
  setOpen={setOpen}
645
+ scrollBridge={scrollBridge}
475
646
  >
476
647
  {isResizing ? null : overlayComponent}
477
648
  {/* no fancy hidden animation etc for handle for now */}
@@ -516,9 +687,12 @@ export const Sheet = withStaticProperties(
516
687
  Handle: SheetHandle,
517
688
  Frame: SheetFrame,
518
689
  Overlay: SheetOverlay,
690
+ ScrollView: SheetScrollView,
519
691
  }
520
692
  )
521
693
 
694
+ /* -------------------------------------------------------------------------------------------------*/
695
+
522
696
  function getPercentSize(point?: number, frameSize?: number) {
523
697
  if (!frameSize) return 0
524
698
  if (point === undefined) {
package/types/Sheet.d.ts CHANGED
@@ -3,7 +3,7 @@ import { ScopedProps } from '@tamagui/create-context';
3
3
  import { RemoveScroll } from '@tamagui/remove-scroll';
4
4
  import { XStackProps } from '@tamagui/stacks';
5
5
  import React, { ReactNode } from 'react';
6
- import { Animated, View } from 'react-native';
6
+ import { Animated, ScrollView, ScrollViewProps, View } from 'react-native';
7
7
  declare type RemoveScrollProps = React.ComponentProps<typeof RemoveScroll>;
8
8
  export declare type SheetProps = ScopedProps<{
9
9
  open?: boolean;
@@ -79,6 +79,7 @@ export declare const SheetOverlayFrame: import("@tamagui/core").TamaguiComponent
79
79
  }>;
80
80
  export declare type SheetOverlayProps = GetProps<typeof SheetOverlayFrame>;
81
81
  export declare const SheetOverlay: ({ __scopeSheet, ...props }: SheetScopedProps<SheetOverlayProps>) => JSX.Element;
82
+ export declare const SheetScrollView: React.ForwardRefExoticComponent<ScrollViewProps & React.RefAttributes<ScrollView>>;
82
83
  export declare const SheetFrameFrame: import("@tamagui/core").TamaguiComponent<(Omit<import("react-native").ViewProps, "children" | "display"> & import("@tamagui/core").RNWViewProps & import("@tamagui/core").TamaguiComponentPropsBase & import("@tamagui/core").WithThemeValues<import("@tamagui/core").StackStylePropsBase> & import("@tamagui/core").WithShorthands<import("@tamagui/core").WithThemeValues<import("@tamagui/core").StackStylePropsBase>> & Omit<{}, "elevation" | "fullscreen"> & {
83
84
  readonly fullscreen?: boolean | undefined;
84
85
  readonly elevation?: import("@tamagui/core").SizeTokens | undefined;
@@ -156,6 +157,7 @@ export declare const Sheet: ((props: Omit<{
156
157
  __scopeSheet?: import("@tamagui/create-context").Scope<any>;
157
158
  } & React.RefAttributes<unknown>>;
158
159
  Overlay: ({ __scopeSheet, ...props }: SheetScopedProps<SheetOverlayProps>) => JSX.Element;
160
+ ScrollView: React.ForwardRefExoticComponent<ScrollViewProps & React.RefAttributes<ScrollView>>;
159
161
  };
160
162
  declare type SheetControllerContextValue = {
161
163
  disableDrag?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"Sheet.d.ts","sourceRoot":"","sources":["../src/Sheet.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Sheet.d.ts","sourceRoot":"","sources":["../src/Sheet.tsx"],"names":[],"mappings":"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"}