Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow control panning gestures #123

Merged
merged 2 commits into from
Dec 20, 2020
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
54 changes: 50 additions & 4 deletions example/src/screens/BasicExamples.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback, memo, useRef, useMemo } from 'react';
import React, { useCallback, memo, useRef, useMemo, useState } from 'react';
import { StyleSheet, View } from 'react-native';
import BottomSheet from '@gorhom/bottom-sheet';
import ContactList from '../components/contactList';
Expand All @@ -12,13 +12,40 @@ interface ExampleScreenProps {

const createExampleScreen = ({ type, count = 25 }: ExampleScreenProps) =>
memo(() => {
// hooks
//#region state
const [
enableContentPanningGesture,
setEnableContentPanningGesture,
] = useState(true);
const [
enableHandlePanningGesture,
setEnableHandlePanningGesture,
] = useState(true);
//#endregion

//#region refs
const bottomSheetRef = useRef<BottomSheet>(null);
//#endregion

// variables
//#region variables
const snapPoints = useMemo(() => ['25%', '50%', '90%'], []);
const enableContentPanningGestureButtonText = useMemo(
() =>
enableContentPanningGesture
? 'Disable Content Panning Gesture'
: 'Enable Content Panning Gesture',
[enableContentPanningGesture]
);
const enableHandlePanningGestureButtonText = useMemo(
() =>
enableHandlePanningGesture
? 'Disable Handle Panning Gesture'
: 'Enable Handle Panning Gesture',
[enableHandlePanningGesture]
);
//#endregion

// callbacks
//#region callbacks
const handleSheetChange = useCallback(index => {
console.log('handleSheetChange', index);
}, []);
Expand All @@ -34,6 +61,13 @@ const createExampleScreen = ({ type, count = 25 }: ExampleScreenProps) =>
const handleClosePress = useCallback(() => {
bottomSheetRef.current?.close();
}, []);
const handleEnableContentPanningGesturePress = useCallback(() => {
setEnableContentPanningGesture(state => !state);
}, []);
const handleEnableHandlePanningGesturePress = useCallback(() => {
setEnableHandlePanningGesture(state => !state);
}, []);
//#endregion

return (
<View style={styles.container}>
Expand Down Expand Up @@ -67,11 +101,23 @@ const createExampleScreen = ({ type, count = 25 }: ExampleScreenProps) =>
style={styles.buttonContainer}
onPress={() => handleClosePress()}
/>
<Button
label={enableContentPanningGestureButtonText}
style={styles.buttonContainer}
onPress={handleEnableContentPanningGesturePress}
/>
<Button
label={enableHandlePanningGestureButtonText}
style={styles.buttonContainer}
onPress={handleEnableHandlePanningGesturePress}
/>
<BottomSheet
ref={bottomSheetRef}
index={1}
snapPoints={snapPoints}
animateOnMount={true}
enableContentPanningGesture={enableContentPanningGesture}
enableHandlePanningGesture={enableHandlePanningGesture}
onChange={handleSheetChange}
>
<ContactList key={`${type}.list`} type={type} count={count} />
Expand Down
7 changes: 7 additions & 0 deletions src/components/bottomSheet/BottomSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ import {
DEFAULT_HANDLE_HEIGHT,
DEFAULT_ANIMATE_ON_MOUNT,
DECELERATION_RATE,
DEFAULT_ENABLE_CONTENT_PANNING_GESTURE,
DEFAULT_ENABLE_HANDLE_PANNING_GESTURE,
} from './constants';
import type { ScrollableRef, BottomSheetMethods } from '../../types';
import type { BottomSheetProps } from './types';
Expand All @@ -74,6 +76,8 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
index: _providedIndex = 0,
snapPoints: _providedSnapPoints,
animateOnMount = DEFAULT_ANIMATE_ON_MOUNT,
enableContentPanningGesture = DEFAULT_ENABLE_CONTENT_PANNING_GESTURE,
enableHandlePanningGesture = DEFAULT_ENABLE_HANDLE_PANNING_GESTURE,
// layout
handleHeight: _providedHandleHeight,
containerHeight: _providedContainerHeight,
Expand Down Expand Up @@ -341,6 +345,7 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
//#region contexts variables
const internalContextVariables = useMemo(
() => ({
enableContentPanningGesture,
snapPointsCount: snapPoints.length,
animatedIndex,
animatedPosition,
Expand All @@ -362,6 +367,7 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
removeScrollableRef,
scrollableContentOffsetY,
scrollableDecelerationRate,
enableContentPanningGesture,
]
);
const externalContextVariables = useMemo(
Expand Down Expand Up @@ -504,6 +510,7 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
simultaneousHandlers={contentWrapperGestureRef}
shouldMeasureHeight={shouldMeasureHandleHeight}
snapPoints={snapPoints}
enableHandlePanningGesture={enableHandlePanningGesture}
animateToPoint={animateToPoint}
handleComponent={handleComponent}
onMeasureHeight={handleOnHandleMeasureHeight}
Expand Down
4 changes: 4 additions & 0 deletions src/components/bottomSheet/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ const DEFAULT_ANIMATION_EASING: Animated.EasingFunction = Easing.out(
);
const DEFAULT_ANIMATION_DURATION = 500;
const DEFAULT_HANDLE_HEIGHT = 24;
const DEFAULT_ENABLE_CONTENT_PANNING_GESTURE = true;
const DEFAULT_ENABLE_HANDLE_PANNING_GESTURE = true;
const DEFAULT_ANIMATE_ON_MOUNT = false;

const DECELERATION_RATE = Platform.select({
Expand All @@ -19,5 +21,7 @@ export {
DEFAULT_ANIMATION_DURATION,
DEFAULT_HANDLE_HEIGHT,
DEFAULT_ANIMATE_ON_MOUNT,
DEFAULT_ENABLE_CONTENT_PANNING_GESTURE,
DEFAULT_ENABLE_HANDLE_PANNING_GESTURE,
DECELERATION_RATE,
};
19 changes: 16 additions & 3 deletions src/components/bottomSheet/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,32 @@ export interface BottomSheetProps extends BottomSheetAnimationConfigs {
containerHeight?: number;
/**
* Top inset value helps to calculate percentage snap points values,
* usually comes from `@react-navigation/stack` hook `useHeaderHeight` or from `react-native-safe-area-context` hook `useSafeArea`.
* usually comes from `@react-navigation/stack` hook `useHeaderHeight` or
* from `react-native-safe-area-context` hook `useSafeArea`.
* @type number
* @default 0
*/
topInset?: number;

// animated nodes
/**
* Enable content panning gesture interaction.
* @type boolean
* @default true
*/
enableContentPanningGesture?: boolean;
/**
* Enable handle panning gesture interaction.
* @type boolean
* @default true
*/
enableHandlePanningGesture?: boolean;
/**
* To start the sheet closed and snap to initial index when it's mounted.
* @type boolean
* @default false
*/
animateOnMount?: boolean;

// animated nodes
/**
* Animated value to be used as a callback of the position node internally.
* @type Animated.Value<number>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const BottomSheetDraggableViewComponent = ({

// hooks
const {
enableContentPanningGesture,
contentWrapperGestureRef,
contentPanGestureHandler,
} = useBottomSheetInternal();
Expand All @@ -39,6 +40,7 @@ const BottomSheetDraggableViewComponent = ({
return (
<PanGestureHandler
ref={panGestureRef}
enabled={enableContentPanningGesture}
simultaneousHandlers={simultaneousHandlers}
shouldCancelWhenOutside={false}
onGestureEvent={contentPanGestureHandler}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const BottomSheetHandleContainerComponent = ({
animatedIndex,
animatedPosition,
simultaneousHandlers,
enableHandlePanningGesture,
shouldMeasureHeight,
snapPoints,
animateToPoint,
Expand Down Expand Up @@ -71,6 +72,7 @@ const BottomSheetHandleContainerComponent = ({
// );
return shouldRenderHandle ? (
<PanGestureHandler
enabled={enableHandlePanningGesture}
simultaneousHandlers={simultaneousHandlers}
shouldCancelWhenOutside={false}
onGestureEvent={handlePanGestureHandler}
Expand Down
2 changes: 1 addition & 1 deletion src/components/bottomSheetHandleContainer/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { BottomSheetHandleProps } from '../bottomSheetHandle';

export interface BottomSheetHandleContainerProps
extends Pick<PanGestureHandlerProperties, 'simultaneousHandlers'>,
Pick<BottomSheetProps, 'handleComponent'>,
Pick<BottomSheetProps, 'handleComponent' | 'enableHandlePanningGesture'>,
BottomSheetHandleProps {
shouldMeasureHeight: boolean;
snapPoints: Array<number>;
Expand Down
6 changes: 5 additions & 1 deletion src/components/flatList/FlatList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ const BottomSheetFlatListComponent = forwardRef(
handleScrollEvent,
handleSettingScrollable,
} = useScrollableInternal(BottomSheetFlatListName);
const { contentWrapperGestureRef } = useBottomSheetInternal();
const {
contentWrapperGestureRef,
enableContentPanningGesture,
} = useBottomSheetInternal();

// effects
// @ts-ignore
Expand All @@ -61,6 +64,7 @@ const BottomSheetFlatListComponent = forwardRef(
>
<NativeViewGestureHandler
ref={nativeGestureRef}
enabled={enableContentPanningGesture}
waitFor={contentWrapperGestureRef}
>
<AnimatedFlatList
Expand Down
6 changes: 5 additions & 1 deletion src/components/scrollView/ScrollView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ const BottomSheetScrollViewComponent = forwardRef(
handleScrollEvent,
handleSettingScrollable,
} = useScrollableInternal(BottomSheetScrollViewName);
const { contentWrapperGestureRef } = useBottomSheetInternal();
const {
contentWrapperGestureRef,
enableContentPanningGesture,
} = useBottomSheetInternal();

// effects
// @ts-ignore
Expand All @@ -60,6 +63,7 @@ const BottomSheetScrollViewComponent = forwardRef(
>
<NativeViewGestureHandler
ref={nativeGestureRef}
enabled={enableContentPanningGesture}
waitFor={contentWrapperGestureRef}
>
<AnimatedScrollView
Expand Down
6 changes: 5 additions & 1 deletion src/components/sectionList/SectionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ const BottomSheetSectionListComponent = forwardRef(
handleScrollEvent,
handleSettingScrollable,
} = useScrollableInternal(BottomSheetSectionListName);
const { contentWrapperGestureRef } = useBottomSheetInternal();
const {
contentWrapperGestureRef,
enableContentPanningGesture,
} = useBottomSheetInternal();

// effects
// @ts-ignore
Expand All @@ -61,6 +64,7 @@ const BottomSheetSectionListComponent = forwardRef(
>
<NativeViewGestureHandler
ref={nativeGestureRef}
enabled={enableContentPanningGesture}
waitFor={contentWrapperGestureRef}
>
<AnimatedSectionList
Expand Down
1 change: 1 addition & 0 deletions src/contexts/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ANIMATION_STATE } from '../constants';
import type { Scrollable, ScrollableRef } from '../types';

export type BottomSheetInternalContextType = {
enableContentPanningGesture: boolean;
snapPointsCount: number;
animatedPosition: Animated.SharedValue<number>;
animatedIndex: Animated.SharedValue<number>;
Expand Down