Skip to content

Commit d00d1a6

Browse files
committed
feat: add one snap point change per one swipe
1 parent 7bfe7ae commit d00d1a6

File tree

5 files changed

+49
-1
lines changed

5 files changed

+49
-1
lines changed

src/components/bottomSheet/BottomSheet.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ import {
7575
DEFAULT_KEYBOARD_BEHAVIOR,
7676
DEFAULT_KEYBOARD_BLUR_BEHAVIOR,
7777
DEFAULT_KEYBOARD_INPUT_MODE,
78+
DEFAULT_ONE_SNAP_POINT_PER_SWIPE,
7879
DEFAULT_OVER_DRAG_RESISTANCE_FACTOR,
7980
INITIAL_CONTAINER_HEIGHT,
8081
INITIAL_CONTAINER_OFFSET,
@@ -108,6 +109,7 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
108109
enableOverDrag = DEFAULT_ENABLE_OVER_DRAG,
109110
enablePanDownToClose = DEFAULT_ENABLE_PAN_DOWN_TO_CLOSE,
110111
enableDynamicSizing = DEFAULT_DYNAMIC_SIZING,
112+
enableOneSnapPointPerSwipe = DEFAULT_ONE_SNAP_POINT_PER_SWIPE,
111113
overDragResistanceFactor = DEFAULT_OVER_DRAG_RESISTANCE_FACTOR,
112114
overrideReduceMotion: _providedOverrideReduceMotion,
113115

@@ -1360,6 +1362,7 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
13601362
overDragResistanceFactor,
13611363
enableOverDrag,
13621364
enablePanDownToClose,
1365+
enableOneSnapPointPerSwipe,
13631366
animatedAnimationState,
13641367
animatedSheetState,
13651368
animatedScrollableState,
@@ -1424,6 +1427,7 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
14241427
overDragResistanceFactor,
14251428
enableOverDrag,
14261429
enablePanDownToClose,
1430+
enableOneSnapPointPerSwipe,
14271431
enableDynamicSizing,
14281432
_providedSimultaneousHandlers,
14291433
_providedWaitFor,

src/components/bottomSheet/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const DEFAULT_ENABLE_OVER_DRAG = true;
1414
const DEFAULT_ENABLE_PAN_DOWN_TO_CLOSE = false;
1515
const DEFAULT_ANIMATE_ON_MOUNT = true;
1616
const DEFAULT_DYNAMIC_SIZING = true;
17+
const DEFAULT_ONE_SNAP_POINT_PER_SWIPE = false;
1718

1819
// keyboard
1920
const DEFAULT_KEYBOARD_BEHAVIOR = KEYBOARD_BEHAVIOR.interactive;
@@ -41,6 +42,7 @@ const DEFAULT_ACCESSIBILITY_ROLE = 'adjustable';
4142
export {
4243
DEFAULT_HANDLE_HEIGHT,
4344
DEFAULT_OVER_DRAG_RESISTANCE_FACTOR,
45+
DEFAULT_ONE_SNAP_POINT_PER_SWIPE,
4446
DEFAULT_ENABLE_CONTENT_PANNING_GESTURE,
4547
DEFAULT_ENABLE_HANDLE_PANNING_GESTURE,
4648
DEFAULT_ENABLE_OVER_DRAG,

src/components/bottomSheet/types.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,13 @@ export interface BottomSheetProps
8989
* @default true
9090
*/
9191
enableDynamicSizing?: boolean;
92+
/**
93+
* Enable change of one snap point per one swipe.
94+
* Works only with default Gesture Events Handlers.
95+
* @type boolean
96+
* @default false
97+
*/
98+
enableOneSnapPointPerSwipe?: boolean;
9299
/**
93100
* To start the sheet closed and snap to initial index when it's mounted.
94101
* @type boolean

src/contexts/internal.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export interface BottomSheetInternalContextType
2525
| 'enablePanDownToClose'
2626
| 'enableDynamicSizing'
2727
| 'overDragResistanceFactor'
28+
| 'enableOneSnapPointPerSwipe'
2829
>
2930
> {
3031
// animated states

src/hooks/useGestureEventsHandlersDefault.tsx

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export const useGestureEventsHandlersDefault: GestureEventsHandlersHookType =
5656
animatedScrollableContentOffsetY,
5757
enableOverDrag,
5858
enablePanDownToClose,
59+
enableOneSnapPointPerSwipe,
5960
overDragResistanceFactor,
6061
isInTemporaryPosition,
6162
isScrollableRefreshable,
@@ -125,10 +126,25 @@ export const useGestureEventsHandlersDefault: GestureEventsHandlersHookType =
125126
highestSnapPoint = context.value.initialPosition;
126127
}
127128

128-
const lowestSnapPoint = enablePanDownToClose
129+
let lowestSnapPoint = enablePanDownToClose
129130
? animatedContainerHeight.value
130131
: animatedSnapPoints.value[0];
131132

133+
if (enableOneSnapPointPerSwipe) {
134+
const currentIndex = animatedSnapPoints.value.indexOf(
135+
context.value.initialPosition
136+
);
137+
138+
const nextIndex = Math.min(
139+
currentIndex + 1,
140+
animatedSnapPoints.value.length - 1
141+
);
142+
const prevIndex = Math.max(currentIndex - 1, 0);
143+
144+
highestSnapPoint = animatedSnapPoints.value[nextIndex];
145+
lowestSnapPoint = animatedSnapPoints.value[prevIndex];
146+
}
147+
132148
/**
133149
* if scrollable is refreshable and sheet position at the highest
134150
* point, then do not interact with current gesture.
@@ -368,6 +384,24 @@ export const useGestureEventsHandlersDefault: GestureEventsHandlersHookType =
368384
return;
369385
}
370386

387+
if (enableOneSnapPointPerSwipe) {
388+
const currentIndex = snapPoints.indexOf(destinationPoint);
389+
const prevIndex = snapPoints.indexOf(context.value.initialPosition);
390+
391+
if (Math.abs(prevIndex - currentIndex) - 1) {
392+
const newIndex =
393+
prevIndex > currentIndex ? currentIndex + 1 : currentIndex - 1;
394+
395+
animateToPosition(
396+
snapPoints[newIndex],
397+
ANIMATION_SOURCE.GESTURE,
398+
velocityY / 2
399+
);
400+
401+
return;
402+
}
403+
}
404+
371405
animateToPosition(
372406
destinationPoint,
373407
ANIMATION_SOURCE.GESTURE,

0 commit comments

Comments
 (0)