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: added expand & collapse methods #8

Merged
merged 3 commits into from
Aug 12, 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
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,18 @@ Snap to one of the provided points from `snapPoints`.

> `type:` (index: number) => void

#### `expand`

Snap to the maximum provided point from `snapPoints`.

> `type:` () => void

#### `collapse`

Snap to the minimum provided point from `snapPoints`.

> `type:` () => void

#### `close`

Close the bottom sheet.
Expand All @@ -180,9 +192,9 @@ Close the bottom sheet.

#### `useBottomSheet`

The library provide `useBottomSheet` hook to provide the bottom sheet methods, anywhere inside the sheet content.
The library provide `useBottomSheet` hook to provide the bottom sheet [methods](#methods), anywhere inside the sheet content.

> `type:` { snapTo: () => void, close: () => void }
> `type:` [BottomSheetMethods](./src/types.ts#L3)

## Scrollables

Expand Down
40 changes: 20 additions & 20 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import RootScreen from './screens/Root';
import NavigatorExampleScreen from './screens/NavigatorExample';
import {
FlatListExampleScreen,
SectionListExampleScreen,
ScrollViewExampleScreen,
ViewExampleScreen,
} from './screens/BasicExamples';
import CustomHandleExampleScreen from './screens/CustomHandleExample';
import ShadowOverlayExampleScreen from './screens/ShadowOverlayExample';
import MapExampleScreen from './screens/MapExample';
import { AppStackParamsList } from './types';

const Stack = createStackNavigator<AppStackParamsList>();
Expand All @@ -21,42 +10,53 @@ function App() {
<Stack.Navigator initialRouteName="Root">
<Stack.Screen
name="Root"
component={RootScreen}
getComponent={() => require('./screens/Root').default}
options={{ headerShown: false }}
/>
{/* basic examples */}
<Stack.Screen
name="FlatListExample"
component={FlatListExampleScreen}
getComponent={() =>
require('./screens/BasicExamples').FlatListExampleScreen
}
/>
<Stack.Screen
name="SectionListExample"
component={SectionListExampleScreen}
getComponent={() =>
require('./screens/BasicExamples').SectionListExampleScreen
}
/>
<Stack.Screen
name="ScrollViewExample"
component={ScrollViewExampleScreen}
getComponent={() =>
require('./screens/BasicExamples').ScrollViewExampleScreen
}
/>
<Stack.Screen
name="ViewExample"
getComponent={() =>
require('./screens/BasicExamples').ViewExampleScreen
}
/>
<Stack.Screen name="ViewExample" component={ViewExampleScreen} />
{/* advanced examples */}
<Stack.Screen
name="NavigatorExample"
component={NavigatorExampleScreen}
getComponent={() => require('./screens/NavigatorExample').default}
/>
<Stack.Screen
name="CustomHandleExample"
component={CustomHandleExampleScreen}
getComponent={() => require('./screens/CustomHandleExample').default}
/>
<Stack.Screen
name="ShadowOverlayExample"
component={ShadowOverlayExampleScreen}
getComponent={() => require('./screens/ShadowOverlayExample').default}
/>
<Stack.Screen
name="MapExample"
options={{
headerShown: false,
}}
component={MapExampleScreen}
getComponent={() => require('./screens/MapExample').default}
/>
</Stack.Navigator>
</NavigationContainer>
Expand Down
24 changes: 20 additions & 4 deletions example/src/screens/BasicExamples.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ interface ExampleScreenProps {
const createExampleScreen = ({ type, count = 50 }: ExampleScreenProps) =>
memo(() => {
// hooks
const sheetRef = useRef<BottomSheet>(null);
const bottomSheetRef = useRef<BottomSheet>(null);
const headerHeight = useHeaderHeight();

// variables
Expand All @@ -25,10 +25,16 @@ const createExampleScreen = ({ type, count = 50 }: ExampleScreenProps) =>
console.log('handleSheetChange', index);
}, []);
const handleSnapPress = useCallback(index => {
sheetRef.current?.snapTo(index);
bottomSheetRef.current?.snapTo(index);
}, []);
const handleExpandPress = useCallback(() => {
bottomSheetRef.current?.expand();
}, []);
const handleCollapsePress = useCallback(() => {
bottomSheetRef.current?.collapse();
}, []);
const handleClosePress = useCallback(() => {
sheetRef.current?.close();
bottomSheetRef.current?.close();
}, []);

return (
Expand All @@ -48,13 +54,23 @@ const createExampleScreen = ({ type, count = 50 }: ExampleScreenProps) =>
style={styles.buttonContainer}
onPress={() => handleSnapPress(0)}
/>
<Button
label="Expand"
style={styles.buttonContainer}
onPress={() => handleExpandPress()}
/>
<Button
label="Collapse"
style={styles.buttonContainer}
onPress={() => handleCollapsePress()}
/>
<Button
label="Close"
style={styles.buttonContainer}
onPress={() => handleClosePress()}
/>
<BottomSheet
ref={sheetRef}
ref={bottomSheetRef}
snapPoints={snapPoints}
initialSnapIndex={1}
topInset={headerHeight}
Expand Down
17 changes: 16 additions & 1 deletion example/src/screens/CustomHandleExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ const CustomHandleExample = () => {
const handleSnapPress = useCallback(index => {
bottomSheetRef.current?.snapTo(index);
}, []);

const handleExpandPress = useCallback(() => {
bottomSheetRef.current?.expand();
}, []);
const handleCollapsePress = useCallback(() => {
bottomSheetRef.current?.collapse();
}, []);
const handleClosePress = useCallback(() => {
bottomSheetRef.current?.close();
}, []);
Expand Down Expand Up @@ -51,6 +56,16 @@ const CustomHandleExample = () => {
style={styles.buttonContainer}
onPress={() => handleSnapPress(0)}
/>
<Button
label="Expand"
style={styles.buttonContainer}
onPress={() => handleExpandPress()}
/>
<Button
label="Collapse"
style={styles.buttonContainer}
onPress={() => handleCollapsePress()}
/>
<Button
label="Close"
style={styles.buttonContainer}
Expand Down
2 changes: 1 addition & 1 deletion example/src/screens/MapExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const MapExample = () => {
console.log('handleSheetChanges', index);
}, []);
const handleTouchStart = useCallback(() => {
bottomSheetRef.current?.snapTo(0);
bottomSheetRef.current?.collapse();
}, []);
const handleRegionChangeComplete = useCallback(() => {
bottomSheetRef.current?.snapTo(1);
Expand Down
16 changes: 16 additions & 0 deletions example/src/screens/NavigatorExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ const NavigatorExample = () => {
const handleSnapPress = useCallback(index => {
bottomSheetRef.current?.snapTo(index);
}, []);
const handleExpandPress = useCallback(() => {
bottomSheetRef.current?.expand();
}, []);
const handleCollapsePress = useCallback(() => {
bottomSheetRef.current?.collapse();
}, []);
const handleClosePress = useCallback(() => {
bottomSheetRef.current?.close();
}, []);
Expand All @@ -106,6 +112,16 @@ const NavigatorExample = () => {
style={styles.buttonContainer}
onPress={() => handleSnapPress(0)}
/>
<Button
label="Expand"
style={styles.buttonContainer}
onPress={() => handleExpandPress()}
/>
<Button
label="Collapse"
style={styles.buttonContainer}
onPress={() => handleCollapsePress()}
/>
<Button
label="Close"
style={styles.buttonContainer}
Expand Down
17 changes: 16 additions & 1 deletion example/src/screens/ShadowOverlayExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,12 @@ const ShadowOverlayExample = () => {
const handleSnapPress = useCallback(index => {
bottomSheetRef.current?.snapTo(index);
}, []);

const handleExpandPress = useCallback(() => {
bottomSheetRef.current?.expand();
}, []);
const handleCollapsePress = useCallback(() => {
bottomSheetRef.current?.collapse();
}, []);
const handleClosePress = useCallback(() => {
bottomSheetRef.current?.close();
}, []);
Expand Down Expand Up @@ -71,6 +76,16 @@ const ShadowOverlayExample = () => {
style={styles.buttonContainer}
onPress={() => handleSnapPress(0)}
/>
<Button
label="Expand"
style={styles.buttonContainer}
onPress={() => handleExpandPress()}
/>
<Button
label="Collapse"
style={styles.buttonContainer}
onPress={() => handleCollapsePress()}
/>
<Button
label="Close"
style={styles.buttonContainer}
Expand Down
42 changes: 20 additions & 22 deletions src/components/bottomSheet/BottomSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,35 +40,21 @@ import DraggableView from '../draggableView';
import Handle from '../handle';
import ContentWrapper from '../contentWrapper';
import { useTransition } from './useTransition';
import {
normalizeSnapPoints,
useStableCallback,
useScrollable,
} from '../../utilities';
import { useStableCallback, useScrollable } from '../../hooks';
import { normalizeSnapPoints } from '../../utilities';
import {
BottomSheetInternalProvider,
BottomSheetProvider,
} from '../../context';
} from '../../contexts';
import {
DEFAULT_ANIMATION_EASING,
DEFAULT_ANIMATION_DURATION,
} from '../../constants';
import type { ScrollableRef } from '../../types';
import type { ScrollableRef, BottomSheetMethods } from '../../types';
import type { BottomSheetProps } from './types';
import { styles } from './styles';

interface BottomSheet {
/**
* Snap to one of the provided points from `snapPoints`.
* @type (index: number) => void
*/
snapTo: (index: number) => void;
/**
* Close the bottom sheet.
* @type () => void
*/
close: () => void;
}
type BottomSheet = BottomSheetMethods;

Animated.addWhitelistedUIProps({
maxDeltaY: true,
Expand Down Expand Up @@ -295,6 +281,14 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
autoSnapTo.setValue(sheetHeight);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [sheetHeight]);
const handleExpand = useCallback(() => {
autoSnapTo.setValue(snapPoints[snapPoints.length - 1]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [sheetHeight]);
const handleCollapse = useCallback(() => {
autoSnapTo.setValue(snapPoints[0]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [sheetHeight]);
//#endregion

//#region
Expand All @@ -313,18 +307,22 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
// eslint-disable-next-line react-hooks/exhaustive-deps
[]
);
const contextVariables = useMemo(
const externalContextVariables = useMemo(
() => ({
snapTo: handleSnapTo,
expand: handleExpand,
collapse: handleCollapse,
close: handleClose,
}),
[handleSnapTo, handleClose]
[handleSnapTo, handleExpand, handleCollapse, handleClose]
);
//#endregion

//#region effects
useImperativeHandle(ref, () => ({
snapTo: handleSnapTo,
expand: handleExpand,
collapse: handleCollapse,
close: handleClose,
}));

Expand Down Expand Up @@ -387,7 +385,7 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
{BackgroundComponent && (
<BackgroundComponent pointerEvents="none" />
)}
<BottomSheetProvider value={contextVariables}>
<BottomSheetProvider value={externalContextVariables}>
<PanGestureHandler
ref={handlePanGestureRef}
simultaneousHandlers={rootTapGestureRef}
Expand Down
6 changes: 3 additions & 3 deletions src/components/bottomSheet/useTransition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ import Animated, {
neq,
onChange,
or,
cond,
block,
// debug,
} from 'react-native-reanimated';
import { State } from 'react-native-gesture-handler';
import { useClock, snapPoint } from 'react-native-redash';
import { BottomSheetAnimationConfigs } from './types';

const { cond, block } = Animated;
import type { BottomSheetAnimationConfigs } from './types';

interface TransitionProps extends Required<BottomSheetAnimationConfigs> {
contentPanGestureState: Animated.Value<State>;
Expand Down
1 change: 0 additions & 1 deletion src/components/draggableView/DraggableView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import Animated, { event } from 'react-native-reanimated';
import { PanGestureHandler } from 'react-native-gesture-handler';
import { useBottomSheetInternal } from '../../hooks';
import type { BottomSheetDraggableViewProps } from './types';

import { styles } from './styles';

const BottomSheetDraggableViewComponent = ({
Expand Down
3 changes: 1 addition & 2 deletions src/components/flatList/FlatList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ import isEqual from 'lodash.isequal';
import Animated from 'react-native-reanimated';
import { NativeViewGestureHandler } from 'react-native-gesture-handler';
import DraggableView from '../draggableView';
import { useBottomSheetInternal } from '../../hooks';
import { useScrollableInternal } from '../../utilities/useScrollable';
import { useScrollableInternal, useBottomSheetInternal } from '../../hooks';
import type {
BottomSheetFlatListProps,
BottomSheetFlatListType,
Expand Down
Loading