@lodev09/react-native-true-sheet 3.11.3 → 3.11.5

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 (71) hide show
  1. package/RNTrueSheet.podspec +6 -2
  2. package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerView.kt +69 -1
  3. package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentView.kt +62 -4
  4. package/android/src/main/java/com/lodev09/truesheet/TrueSheetPackage.kt +2 -1
  5. package/android/src/main/java/com/lodev09/truesheet/TrueSheetPeekView.kt +72 -0
  6. package/android/src/main/java/com/lodev09/truesheet/TrueSheetPeekViewManager.kt +33 -0
  7. package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +7 -1
  8. package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +10 -0
  9. package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDetentCalculator.kt +24 -1
  10. package/ios/TrueSheetContainerView.h +18 -0
  11. package/ios/TrueSheetContainerView.mm +78 -1
  12. package/ios/TrueSheetContentView.mm +82 -4
  13. package/ios/TrueSheetPeekView.h +32 -0
  14. package/ios/TrueSheetPeekView.mm +99 -0
  15. package/ios/TrueSheetView.mm +19 -0
  16. package/ios/TrueSheetViewController.h +2 -0
  17. package/ios/TrueSheetViewController.mm +10 -0
  18. package/ios/core/TrueSheetDetentCalculator.h +10 -0
  19. package/ios/core/TrueSheetDetentCalculator.mm +9 -0
  20. package/ios/tvos/TrueSheetStubs.mm +152 -0
  21. package/lib/module/TrueSheet.js +2 -1
  22. package/lib/module/TrueSheet.js.map +1 -1
  23. package/lib/module/TrueSheet.web.js +104 -69
  24. package/lib/module/TrueSheet.web.js.map +1 -1
  25. package/lib/module/TrueSheetPeek.js +15 -0
  26. package/lib/module/TrueSheetPeek.js.map +1 -0
  27. package/lib/module/TrueSheetPeek.web.js +46 -0
  28. package/lib/module/TrueSheetPeek.web.js.map +1 -0
  29. package/lib/module/fabric/TrueSheetPeekViewNativeComponent.ts +8 -0
  30. package/lib/module/index.js +1 -0
  31. package/lib/module/index.js.map +1 -1
  32. package/lib/module/mocks/index.js +10 -0
  33. package/lib/module/mocks/index.js.map +1 -1
  34. package/lib/module/web/vaul/constants.js +1 -0
  35. package/lib/module/web/vaul/constants.js.map +1 -1
  36. package/lib/module/web/vaul/index.js +2 -0
  37. package/lib/module/web/vaul/index.js.map +1 -1
  38. package/lib/module/web/vaul/use-snap-points.js +6 -4
  39. package/lib/module/web/vaul/use-snap-points.js.map +1 -1
  40. package/lib/typescript/src/TrueSheet.d.ts.map +1 -1
  41. package/lib/typescript/src/TrueSheet.types.d.ts +10 -0
  42. package/lib/typescript/src/TrueSheet.types.d.ts.map +1 -1
  43. package/lib/typescript/src/TrueSheet.web.d.ts.map +1 -1
  44. package/lib/typescript/src/TrueSheetPeek.d.ts +9 -0
  45. package/lib/typescript/src/TrueSheetPeek.d.ts.map +1 -0
  46. package/lib/typescript/src/TrueSheetPeek.web.d.ts +19 -0
  47. package/lib/typescript/src/TrueSheetPeek.web.d.ts.map +1 -0
  48. package/lib/typescript/src/fabric/TrueSheetPeekViewNativeComponent.d.ts +6 -0
  49. package/lib/typescript/src/fabric/TrueSheetPeekViewNativeComponent.d.ts.map +1 -0
  50. package/lib/typescript/src/index.d.ts +1 -0
  51. package/lib/typescript/src/index.d.ts.map +1 -1
  52. package/lib/typescript/src/mocks/index.d.ts +6 -2
  53. package/lib/typescript/src/mocks/index.d.ts.map +1 -1
  54. package/lib/typescript/src/web/vaul/constants.d.ts +1 -0
  55. package/lib/typescript/src/web/vaul/constants.d.ts.map +1 -1
  56. package/lib/typescript/src/web/vaul/index.d.ts +6 -1
  57. package/lib/typescript/src/web/vaul/index.d.ts.map +1 -1
  58. package/lib/typescript/src/web/vaul/use-snap-points.d.ts +2 -1
  59. package/lib/typescript/src/web/vaul/use-snap-points.d.ts.map +1 -1
  60. package/package.json +4 -1
  61. package/src/TrueSheet.tsx +2 -1
  62. package/src/TrueSheet.types.ts +11 -0
  63. package/src/TrueSheet.web.tsx +110 -71
  64. package/src/TrueSheetPeek.tsx +11 -0
  65. package/src/TrueSheetPeek.web.tsx +48 -0
  66. package/src/fabric/TrueSheetPeekViewNativeComponent.ts +8 -0
  67. package/src/index.ts +1 -0
  68. package/src/mocks/index.ts +8 -1
  69. package/src/web/vaul/constants.ts +2 -0
  70. package/src/web/vaul/index.tsx +7 -0
  71. package/src/web/vaul/use-snap-points.ts +17 -4
@@ -224,6 +224,17 @@ export type SheetDetent =
224
224
  */
225
225
  | 'auto'
226
226
 
227
+ /**
228
+ * Collapsed height based on the combined `header` and `footer` heights.
229
+ * Render a `TrueSheetPeek` component within the content to also include
230
+ * the content up to its bottom edge.
231
+ * Falls back to a fixed height of `150` when none is provided.
232
+ *
233
+ * @platform android
234
+ * @platform ios 16+
235
+ */
236
+ | 'peek'
237
+
227
238
  /**
228
239
  * Relative height as a fraction (0-1) of the available height.
229
240
  * For example, 0.5 represents 50% of the available height.
@@ -11,9 +11,11 @@ import {
11
11
  useState,
12
12
  } from 'react';
13
13
  import { View, useColorScheme, useWindowDimensions } from 'react-native';
14
+ import type { LayoutChangeEvent } from 'react-native';
14
15
 
15
16
  import { Drawer } from './web/vaul';
16
- import { TRANSITIONS } from './web/vaul/constants';
17
+ import { DEFAULT_PEEK_HEIGHT, TRANSITIONS } from './web/vaul/constants';
18
+ import { TrueSheetPeekContext } from './TrueSheetPeek.web';
17
19
  import type {
18
20
  DetentChangeEvent,
19
21
  DetentInfoEventPayload,
@@ -99,7 +101,10 @@ const TrueSheetComponent = forwardRef<TrueSheetMethods, TrueSheetProps>((props,
99
101
  } = props;
100
102
 
101
103
  const validDetents = useMemo(
102
- () => detents.filter((d): d is SheetDetent => typeof d === 'number' || d === 'auto'),
104
+ () =>
105
+ detents.filter(
106
+ (d): d is SheetDetent => typeof d === 'number' || d === 'auto' || d === 'peek'
107
+ ),
103
108
  [detents]
104
109
  );
105
110
 
@@ -149,7 +154,7 @@ const TrueSheetComponent = forwardRef<TrueSheetMethods, TrueSheetProps>((props,
149
154
  setActiveSnapPoint(
150
155
  snapPoint == null
151
156
  ? null
152
- : typeof snapPoint === 'number' || snapPoint === 'auto'
157
+ : typeof snapPoint === 'number' || snapPoint === 'auto' || snapPoint === 'peek'
153
158
  ? (snapPoint as SheetDetent)
154
159
  : null
155
160
  );
@@ -227,6 +232,29 @@ const TrueSheetComponent = forwardRef<TrueSheetMethods, TrueSheetProps>((props,
227
232
 
228
233
  const drawerContentRef = useRef<HTMLDivElement | null>(null);
229
234
 
235
+ // Measured header/footer heights drive the 'peek' snap point — mirrors
236
+ // native, where the controller tracks headerHeight/footerHeight.
237
+ const [headerHeight, setHeaderHeight] = useState(0);
238
+ const [footerHeight, setFooterHeight] = useState(0);
239
+
240
+ const handleHeaderLayout = useCallback((e: LayoutChangeEvent) => {
241
+ setHeaderHeight(e.nativeEvent.layout.height);
242
+ }, []);
243
+
244
+ const handleFooterLayout = useCallback((e: LayoutChangeEvent) => {
245
+ setFooterHeight(e.nativeEvent.layout.height);
246
+ }, []);
247
+
248
+ // Distance from the content top to the bottom of a `TrueSheetPeek` rendered
249
+ // within the content — measured by the peek against `contentRef`.
250
+ const [peekContentHeight, setPeekContentHeight] = useState(0);
251
+ const contentRef = useRef<View>(null);
252
+ const peekContext = useMemo(() => ({ contentRef, setPeekContentHeight }), []);
253
+
254
+ const peekHeight =
255
+ (header ? headerHeight : 0) + (footer ? footerHeight : 0) + peekContentHeight ||
256
+ DEFAULT_PEEK_HEIGHT;
257
+
230
258
  // Present/dismiss events. The sheet settles via a CSS `transform` transition
231
259
  // on either the drawer (snap-points on autopresent) or the wrapper (whole-
232
260
  // card slide on reopen/dismiss). `Animation.finished` from the Web Animations
@@ -295,6 +323,10 @@ const TrueSheetComponent = forwardRef<TrueSheetMethods, TrueSheetProps>((props,
295
323
  const h = Math.min(d * effectiveH, ceiling);
296
324
  positions.push(effectiveH - h);
297
325
  values.push(effectiveH > 0 ? h / effectiveH : 0);
326
+ } else if (d === 'peek') {
327
+ const h = Math.min(peekHeight, ceiling);
328
+ positions.push(effectiveH - h);
329
+ values.push(effectiveH > 0 ? h / effectiveH : 0);
298
330
  } else {
299
331
  positions.push(effectiveH - autoHeight);
300
332
  values.push(effectiveH > 0 ? autoHeight / effectiveH : 0);
@@ -346,7 +378,7 @@ const TrueSheetComponent = forwardRef<TrueSheetMethods, TrueSheetProps>((props,
346
378
 
347
379
  return { index: count - 1, detent: values[count - 1]! };
348
380
  },
349
- [effectiveDetached, detachedOffset, maxContentHeight]
381
+ [effectiveDetached, detachedOffset, maxContentHeight, peekHeight]
350
382
  );
351
383
 
352
384
  const handlePositionChange = useCallback(
@@ -844,75 +876,82 @@ const TrueSheetComponent = forwardRef<TrueSheetMethods, TrueSheetProps>((props,
844
876
  );
845
877
 
846
878
  return (
847
- <Drawer.Root
848
- open={isOpen}
849
- onOpenChange={handleOpenChange}
850
- onPositionChange={handlePositionChange}
851
- onDrag={handleDrag}
852
- onRelease={handleRelease}
853
- dismissible={dismissible}
854
- draggable={draggable}
855
- repositionInputs={false}
856
- modal={dimmed}
857
- nested={isNested}
858
- detached={effectiveDetached}
859
- detachedOffset={effectiveDetachedOffset}
860
- detachedRadius={effectiveCornerRadius}
861
- maxContentHeight={effectiveMaxContentHeight}
862
- initialAnimated={initialDetentAnimated}
863
- detachedWrapperStyle={wrapperStyle}
864
- onContentHeightChange={setMeasuredContentHeight}
865
- activeSnapPoint={activeSnapPoint}
866
- setActiveSnapPoint={handleSetActiveSnapPoint}
867
- {...snapPointsProps}
868
- >
869
- <Drawer.Portal container={portalContainer ?? undefined}>
870
- <Drawer.Overlay style={overlayStyle} />
871
- <Drawer.Content
872
- ref={drawerContentRef}
873
- style={mergedContentStyle}
874
- onPointerDownOutside={handlePointerDownOutside}
875
- detachedSiblings={
876
- footer ? (
877
- <div style={footerFloatStyle}>
878
- <View style={footerStyle}>
879
- {isValidElement(footer) ? footer : createElement(footer)}
880
- </View>
881
- </div>
882
- ) : undefined
883
- }
884
- >
885
- <Drawer.Title style={visuallyHiddenStyle}>Sheet</Drawer.Title>
886
- {grabber && <Drawer.Handle style={handleStyle} />}
887
- {scrollable ? (
888
- // vaul wraps children in `[data-vaul-auto-size-wrapper]` (display:
889
- // flow-root) which doesn't honor descendant flex layout. Use an
890
- // absolute fill sized to the visible portion (via vaul's
891
- // `--snap-point-height` var) so the inner flex column has a
892
- // definite height for the scroll container's flex:1 to fill.
893
- <div style={scrollableLayoutStyle}>
894
- {header && (
895
- <View style={headerStyle}>
896
- {isValidElement(header) ? header : createElement(header)}
897
- </View>
898
- )}
899
- <div style={scrollableContainerStyle}>
900
- <View style={style}>{children}</View>
879
+ <TrueSheetPeekContext.Provider value={peekContext}>
880
+ <Drawer.Root
881
+ open={isOpen}
882
+ onOpenChange={handleOpenChange}
883
+ onPositionChange={handlePositionChange}
884
+ onDrag={handleDrag}
885
+ onRelease={handleRelease}
886
+ dismissible={dismissible}
887
+ draggable={draggable}
888
+ repositionInputs={false}
889
+ modal={dimmed}
890
+ nested={isNested}
891
+ detached={effectiveDetached}
892
+ detachedOffset={effectiveDetachedOffset}
893
+ detachedRadius={effectiveCornerRadius}
894
+ maxContentHeight={effectiveMaxContentHeight}
895
+ peekHeight={peekHeight}
896
+ initialAnimated={initialDetentAnimated}
897
+ detachedWrapperStyle={wrapperStyle}
898
+ onContentHeightChange={setMeasuredContentHeight}
899
+ activeSnapPoint={activeSnapPoint}
900
+ setActiveSnapPoint={handleSetActiveSnapPoint}
901
+ {...snapPointsProps}
902
+ >
903
+ <Drawer.Portal container={portalContainer ?? undefined}>
904
+ <Drawer.Overlay style={overlayStyle} />
905
+ <Drawer.Content
906
+ ref={drawerContentRef}
907
+ style={mergedContentStyle}
908
+ onPointerDownOutside={handlePointerDownOutside}
909
+ detachedSiblings={
910
+ footer ? (
911
+ <div style={footerFloatStyle}>
912
+ <View style={footerStyle} onLayout={handleFooterLayout}>
913
+ {isValidElement(footer) ? footer : createElement(footer)}
914
+ </View>
915
+ </div>
916
+ ) : undefined
917
+ }
918
+ >
919
+ <Drawer.Title style={visuallyHiddenStyle}>Sheet</Drawer.Title>
920
+ {grabber && <Drawer.Handle style={handleStyle} />}
921
+ {scrollable ? (
922
+ // vaul wraps children in `[data-vaul-auto-size-wrapper]` (display:
923
+ // flow-root) which doesn't honor descendant flex layout. Use an
924
+ // absolute fill sized to the visible portion (via vaul's
925
+ // `--snap-point-height` var) so the inner flex column has a
926
+ // definite height for the scroll container's flex:1 to fill.
927
+ <div style={scrollableLayoutStyle}>
928
+ {header && (
929
+ <View style={headerStyle} onLayout={handleHeaderLayout}>
930
+ {isValidElement(header) ? header : createElement(header)}
931
+ </View>
932
+ )}
933
+ <div style={scrollableContainerStyle}>
934
+ <View ref={contentRef} style={style}>
935
+ {children}
936
+ </View>
937
+ </div>
901
938
  </div>
902
- </div>
903
- ) : (
904
- <>
905
- {header && (
906
- <View style={headerStyle}>
907
- {isValidElement(header) ? header : createElement(header)}
939
+ ) : (
940
+ <>
941
+ {header && (
942
+ <View style={headerStyle} onLayout={handleHeaderLayout}>
943
+ {isValidElement(header) ? header : createElement(header)}
944
+ </View>
945
+ )}
946
+ <View ref={contentRef} style={style}>
947
+ {children}
908
948
  </View>
909
- )}
910
- <View style={style}>{children}</View>
911
- </>
912
- )}
913
- </Drawer.Content>
914
- </Drawer.Portal>
915
- </Drawer.Root>
949
+ </>
950
+ )}
951
+ </Drawer.Content>
952
+ </Drawer.Portal>
953
+ </Drawer.Root>
954
+ </TrueSheetPeekContext.Provider>
916
955
  );
917
956
  });
918
957
 
@@ -0,0 +1,11 @@
1
+ import type { ViewProps } from 'react-native';
2
+
3
+ import TrueSheetPeekViewNativeComponent from './fabric/TrueSheetPeekViewNativeComponent';
4
+
5
+ /**
6
+ * Wrapper component that marks its children as the sheet's peek content.
7
+ * When rendered within a `TrueSheet`, the `"peek"` detent reveals everything
8
+ * from the top of the sheet through the bottom of this component — content
9
+ * below it stays hidden until the sheet is expanded.
10
+ */
11
+ export const TrueSheetPeek = (props: ViewProps) => <TrueSheetPeekViewNativeComponent {...props} />;
@@ -0,0 +1,48 @@
1
+ import { createContext, useContext, useEffect, useRef, type RefObject } from 'react';
2
+ import { View, type LayoutChangeEvent, type ViewProps } from 'react-native';
3
+
4
+ /**
5
+ * Reports the measured peek content height to the owning TrueSheet.
6
+ * @internal
7
+ */
8
+ export interface TrueSheetPeekContextValue {
9
+ contentRef: RefObject<View | null>;
10
+ setPeekContentHeight: (height: number) => void;
11
+ }
12
+
13
+ export const TrueSheetPeekContext = createContext<TrueSheetPeekContextValue | null>(null);
14
+
15
+ /**
16
+ * Wrapper component that marks its children as the sheet's peek content.
17
+ * When rendered within a `TrueSheet`, the `"peek"` detent reveals everything
18
+ * from the top of the sheet through the bottom of this component — content
19
+ * below it stays hidden until the sheet is expanded.
20
+ */
21
+ export const TrueSheetPeek = ({ onLayout, ...rest }: ViewProps) => {
22
+ const context = useContext(TrueSheetPeekContext);
23
+ const viewRef = useRef<View>(null);
24
+
25
+ useEffect(() => () => context?.setPeekContentHeight(0), [context]);
26
+
27
+ const handleLayout = (event: LayoutChangeEvent) => {
28
+ if (context) {
29
+ // On web, View refs resolve to the underlying DOM elements.
30
+ const peekElement = viewRef.current as unknown as HTMLElement | null;
31
+ const contentElement = context.contentRef.current as unknown as HTMLElement | null;
32
+
33
+ // Distance from the top of the content view to the bottom of the peek view,
34
+ // so the peek view's offset within the content (padding, views above it)
35
+ // counts toward the peek detent.
36
+ const bottom =
37
+ peekElement && contentElement
38
+ ? peekElement.getBoundingClientRect().bottom - contentElement.getBoundingClientRect().top
39
+ : event.nativeEvent.layout.height;
40
+
41
+ context.setPeekContentHeight(bottom);
42
+ }
43
+
44
+ onLayout?.(event);
45
+ };
46
+
47
+ return <View {...rest} ref={viewRef} onLayout={handleLayout} />;
48
+ };
@@ -0,0 +1,8 @@
1
+ import type { ViewProps } from 'react-native';
2
+ import { codegenNativeComponent } from 'react-native';
3
+
4
+ export interface NativeProps extends ViewProps {
5
+ // Peek-specific props can be added here if needed
6
+ }
7
+
8
+ export default codegenNativeComponent<NativeProps>('TrueSheetPeekView', {});
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './TrueSheet';
2
2
  export * from './TrueSheet.types';
3
+ export { TrueSheetPeek } from './TrueSheetPeek';
3
4
  export { TrueSheetProvider, useTrueSheet } from './TrueSheetProvider';
@@ -1,5 +1,5 @@
1
1
  import React, { createElement, isValidElement, type ReactNode } from 'react';
2
- import { View } from 'react-native';
2
+ import { View, type ViewProps } from 'react-native';
3
3
 
4
4
  import type { TrueSheetProps, TrueSheetStaticMethods } from '../TrueSheet.types';
5
5
 
@@ -59,6 +59,13 @@ export class TrueSheet extends React.Component<TrueSheetProps, TrueSheetState> {
59
59
  }
60
60
  }
61
61
 
62
+ /**
63
+ * Mock TrueSheetPeek component for testing.
64
+ */
65
+ export function TrueSheetPeek({ children, ...rest }: ViewProps) {
66
+ return React.createElement(View, rest, children);
67
+ }
68
+
62
69
  /**
63
70
  * Mock TrueSheetProvider for testing.
64
71
  */
@@ -5,6 +5,8 @@ export const TRANSITIONS = {
5
5
 
6
6
  export const VELOCITY_THRESHOLD = 0.4;
7
7
 
8
+ export const DEFAULT_PEEK_HEIGHT = 150;
9
+
8
10
  export const CLOSE_THRESHOLD = 0.25;
9
11
 
10
12
  export const SCROLL_LOCK_TIMEOUT = 100;
@@ -181,6 +181,11 @@ export type DialogProps = {
181
181
  * respect a user-specified ceiling.
182
182
  */
183
183
  maxContentHeight?: number;
184
+ /**
185
+ * Resolved height (in px) for the 'peek' snap point — the caller measures
186
+ * its header/footer and passes the combined height.
187
+ */
188
+ peekHeight?: number;
184
189
  /**
185
190
  * When `false` the first snap on mount is applied without a transition so
186
191
  * the sheet appears at its target detent instantly. Defaults to `true`.
@@ -231,6 +236,7 @@ export function Root({
231
236
  detachedRadius = 0,
232
237
  detachedWrapperStyle,
233
238
  maxContentHeight,
239
+ peekHeight,
234
240
  initialAnimated = true,
235
241
  onContentHeightChange,
236
242
  }: DialogProps) {
@@ -307,6 +313,7 @@ export function Root({
307
313
  contentHeight,
308
314
  detachedOffset: detached ? detachedOffset : 0,
309
315
  maxContentHeight,
316
+ peekHeight,
310
317
  initialAnimated,
311
318
  });
312
319
 
@@ -1,7 +1,7 @@
1
1
  // @ts-nocheck — vendored upstream, incompatible with noUncheckedIndexedAccess
2
2
  import React from 'react';
3
3
  import { set, isVertical } from './helpers';
4
- import { TRANSITIONS, VELOCITY_THRESHOLD } from './constants';
4
+ import { DEFAULT_PEEK_HEIGHT, TRANSITIONS, VELOCITY_THRESHOLD } from './constants';
5
5
  import { useControllableState } from './use-controllable-state';
6
6
  import type { DrawerDirection } from './types';
7
7
 
@@ -20,6 +20,7 @@ export function useSnapPoints({
20
20
  contentHeight,
21
21
  detachedOffset = 0,
22
22
  maxContentHeight,
23
+ peekHeight,
23
24
  initialAnimated = true,
24
25
  }: {
25
26
  activeSnapPointProp?: number | string | null;
@@ -36,6 +37,7 @@ export function useSnapPoints({
36
37
  contentHeight?: number;
37
38
  detachedOffset?: number;
38
39
  maxContentHeight?: number;
40
+ peekHeight?: number;
39
41
  initialAnimated?: boolean;
40
42
  }) {
41
43
  const [activeSnapPoint, setActiveSnapPoint] = useControllableState<string | number | null>({
@@ -102,11 +104,14 @@ export function useSnapPoints({
102
104
  snapPoints?.map((snapPoint) => {
103
105
  // 'auto' resolves to measured content height. Falls back to half the
104
106
  // container so the initial snap is close to final before ResizeObserver
105
- // reports a real measurement.
107
+ // reports a real measurement. 'peek' resolves to the caller-measured
108
+ // header + footer height.
106
109
  const resolved =
107
110
  snapPoint === 'auto'
108
111
  ? `${contentHeight && contentHeight > 0 ? contentHeight : effectiveHeight / 2}px`
109
- : snapPoint;
112
+ : snapPoint === 'peek'
113
+ ? `${peekHeight && peekHeight > 0 ? peekHeight : DEFAULT_PEEK_HEIGHT}px`
114
+ : snapPoint;
110
115
  const isPx = typeof resolved === 'string';
111
116
  let snapPointAsNumber = 0;
112
117
 
@@ -151,7 +156,15 @@ export function useSnapPoints({
151
156
  return width;
152
157
  }) ?? []
153
158
  );
154
- }, [snapPoints, windowDimensions, container, contentHeight, detachedOffset, maxContentHeight]);
159
+ }, [
160
+ snapPoints,
161
+ windowDimensions,
162
+ container,
163
+ contentHeight,
164
+ detachedOffset,
165
+ maxContentHeight,
166
+ peekHeight,
167
+ ]);
155
168
 
156
169
  const activeSnapPointOffset = React.useMemo(
157
170
  () => (activeSnapPointIndex !== null ? snapPointsOffset?.[activeSnapPointIndex] : null),