Skip to content

Commit

Permalink
Create ReanimatedDrawerLayout component (#3146)
Browse files Browse the repository at this point in the history
## Description

This PR adds `ReanimatedDrawerLayout` component.

## Test plan

- use the newly added Reanimated Drawer Layout example to see how the
drawer layout functions
- use the provided sample code to test how the legacy one used to work

<details>
<summary>
Collapsed code - legacy component preview
</summary>

```js

import React, { useRef } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import {
  Gesture,
  GestureDetector,
  DrawerLayout,
} from 'react-native-gesture-handler';
import { SharedValue } from 'react-native-reanimated';

const DrawerPage = ({ progress }: { progress?: SharedValue }) => {
  progress && console.log('Drawer opening progress:', progress);
  return <View style={styles.drawerContainer} />;
};

export default function ReanimatedDrawerExample() {
  const drawerRef = useRef<any>(null);

  const tapGesture = Gesture.Tap()
    .runOnJS(true)
    .onStart(() => drawerRef.current?.openDrawer());

  return (
    <DrawerLayout ref={drawerRef} renderNavigationView={() => <DrawerPage />}>
      <GestureDetector gesture={tapGesture}>
        <View style={styles.innerContainer}>
          <Text>Open drawer</Text>
        </View>
      </GestureDetector>
    </DrawerLayout>
  );
}

const styles = StyleSheet.create({
  drawerContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'pink',
  },
  innerContainer: {
    margin: 'auto',
    padding: 35,
    paddingHorizontal: 25,
    backgroundColor: 'pink',
  },
});
```
</details>
  • Loading branch information
latekvo authored Nov 8, 2024
1 parent 56a14fb commit 18969fd
Show file tree
Hide file tree
Showing 6 changed files with 892 additions and 0 deletions.
2 changes: 2 additions & 0 deletions MacOSExample/babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ module.exports = {
'react-native-reanimated': './node_modules/react-native-reanimated',
'react-native-gesture-handler/ReanimatedSwipeable':
'../src/components/ReanimatedSwipeable',
'react-native-gesture-handler/ReanimatedDrawerLayout':
'../src/components/ReanimatedDrawerLayout',
'react-native-gesture-handler/Swipeable':
'../src/components/Swipeable',
'react-native-gesture-handler': '../src/index',
Expand Down
6 changes: 6 additions & 0 deletions ReanimatedDrawerLayout/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"main": "../lib/commonjs/components/ReanimatedDrawerLayout",
"module": "../lib/module/components/ReanimatedDrawerLayout",
"react-native": "../src/components/ReanimatedDrawerLayout",
"types": "../lib/typescript/components/ReanimatedDrawerLayout.d.ts"
}
2 changes: 2 additions & 0 deletions example/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import ForceTouch from './src/basic/forcetouch';
import Fling from './src/basic/fling';
import WebStylesResetExample from './src/release_tests/webStylesReset';
import StylusData from './src/release_tests/StylusData';
import ReanimatedDrawerLayout from './src/release_tests/reanimatedDrawerLayout';

import Camera from './src/new_api/camera';
import Transformations from './src/new_api/transformations';
Expand Down Expand Up @@ -201,6 +202,7 @@ const EXAMPLES: ExamplesSection[] = [
unsupportedPlatforms: new Set(['android', 'ios', 'macos']),
},
{ name: 'PointerType', component: PointerType },
{ name: 'Reanimated Drawer Layout', component: ReanimatedDrawerLayout },
{ name: 'Swipeable Reanimation', component: SwipeableReanimation },
{ name: 'RectButton (borders)', component: RectButtonBorders },
{ name: 'Gesturized pressable', component: GesturizedPressable },
Expand Down
2 changes: 2 additions & 0 deletions example/babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ module.exports = function (api) {
alias: {
'react-native-gesture-handler/ReanimatedSwipeable':
'../src/components/ReanimatedSwipeable',
'react-native-gesture-handler/ReanimatedDrawerLayout':
'../src/components/ReanimatedDrawerLayout',
'react-native-gesture-handler': '../src/index',
},
},
Expand Down
139 changes: 139 additions & 0 deletions example/src/release_tests/reanimatedDrawerLayout/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import React, { useRef, useState } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
import { SharedValue } from 'react-native-reanimated';

import ReanimatedDrawerLayout, {
DrawerType,
DrawerPosition,
DrawerLayoutMethods,
DrawerLockMode,
} from 'react-native-gesture-handler/ReanimatedDrawerLayout';
import { LoremIpsum } from '../../../src/common';

const DrawerPage = ({ progress }: { progress?: SharedValue }) => {
progress && console.log('Drawer opening progress:', progress);
return (
<View style={styles.drawerContainer}>
<LoremIpsum />
</View>
);
};

export default function ReanimatedDrawerExample() {
const drawerRef = useRef<DrawerLayoutMethods>(null);
const [side, setSide] = useState(DrawerPosition.LEFT);
const [type, setType] = useState(DrawerType.FRONT);
const [lock, setLock] = useState(DrawerLockMode.UNLOCKED);

const tapGesture = Gesture.Tap()
.runOnJS(true)
.onStart(() =>
drawerRef.current?.openDrawer({ animationSpeed: 1, initialVelocity: 0 })
);

const toggleSideGesture = Gesture.Tap()
.runOnJS(true)
.onStart(() =>
setSide(
side === DrawerPosition.LEFT
? DrawerPosition.RIGHT
: DrawerPosition.LEFT
)
);

const toggleTypeGesture = Gesture.Tap()
.runOnJS(true)
.onStart(() =>
setType(
type === DrawerType.FRONT
? DrawerType.BACK
: type === DrawerType.BACK
? DrawerType.SLIDE
: DrawerType.FRONT
)
);

const toggleLockGesture = Gesture.Tap()
.runOnJS(true)
.onStart(() =>
setLock(
lock === DrawerLockMode.UNLOCKED
? DrawerLockMode.LOCKED_CLOSED
: lock === DrawerLockMode.LOCKED_CLOSED
? DrawerLockMode.LOCKED_OPEN
: DrawerLockMode.UNLOCKED
)
);

return (
<ReanimatedDrawerLayout
ref={drawerRef}
renderNavigationView={() => <DrawerPage />}
drawerPosition={side}
drawerType={type}
drawerLockMode={lock}>
<View style={styles.innerContainer}>
<GestureDetector gesture={tapGesture}>
<View style={styles.box}>
<Text>Open drawer</Text>
</View>
</GestureDetector>
<GestureDetector gesture={toggleSideGesture}>
<View style={styles.box}>
<Text>
Currently opening from:{' '}
{side === DrawerPosition.LEFT ? 'left' : 'right'}
</Text>
</View>
</GestureDetector>
<GestureDetector gesture={toggleTypeGesture}>
<View style={styles.box}>
<Text>
Current background type:{' '}
{type === DrawerType.FRONT
? 'front'
: type === DrawerType.BACK
? 'back'
: 'slide'}
</Text>
</View>
</GestureDetector>
<GestureDetector gesture={toggleLockGesture}>
<View style={styles.box}>
<Text>
Current lock mode:{' '}
{lock === DrawerLockMode.UNLOCKED
? 'unlocked'
: lock === DrawerLockMode.LOCKED_OPEN
? 'locked-open'
: 'locked-closed'}
</Text>
</View>
</GestureDetector>
</View>
</ReanimatedDrawerLayout>
);
}

const styles = StyleSheet.create({
drawerContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'pink',
},
innerContainer: {
flex: 1,
backgroundColor: 'white',
alignItems: 'center',
justifyContent: 'center',
gap: 20,
},
box: {
width: 150,
padding: 10,
paddingHorizontal: 5,
backgroundColor: 'pink',
},
});
Loading

0 comments on commit 18969fd

Please sign in to comment.