├── .eslintignore ├── .eslintrc.js ├── .github └── workflows │ └── nodejs.yml ├── .gitignore ├── .prettierrc ├── .prettierrc.json ├── .release-it.json ├── Example ├── .gitignore ├── App.js ├── BlurToolbar.js ├── Collapsable.js ├── Imperative.js ├── Map.js ├── Sections.js ├── Test.js ├── app.json ├── assets │ ├── airport-photo.jpg │ ├── avicii-tim.jpg │ ├── fonts │ │ └── SpaceMono-Regular.ttf │ ├── icon.png │ ├── map-bg.jpg │ ├── menu.png │ └── splash.png ├── babel.config.js ├── metro.config.js ├── package.json ├── src │ └── screen │ │ └── AppleMusic.tsx ├── tsconfig.json └── yarn.lock ├── LICENSE.md ├── README.md ├── commitlint.config.js ├── gifs ├── 1.gif ├── 2.gif ├── 3.gif └── 4.gif ├── package.json ├── src └── index.tsx ├── tsconfig.json └── yarn.lock /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | lib/ 3 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es6: true, 5 | }, 6 | extends: [ 7 | 'eslint:recommended', 8 | 'plugin:react/recommended', 9 | 'eslint-config-prettier', 10 | 'eslint-config-prettier/react', 11 | ], 12 | plugins: ['react', 'prettier'], 13 | settings: { 14 | react: { 15 | pragma: 'React', 16 | version: '16.3', 17 | }, 18 | }, 19 | parserOptions: { 20 | ecmaFeatures: { 21 | jsx: true, 22 | }, 23 | ecmaVersion: 2018, 24 | sourceType: 'module', 25 | }, 26 | rules: { 27 | 'max-len': ['off', 80], 28 | 'no-undef': 'off', 29 | 'linebreak-style': ['error', 'unix'], 30 | 'prettier/prettier': 'error', 31 | 'react/prop-types': 'off', 32 | }, 33 | overrides: [ 34 | { 35 | files: ['*.js'], 36 | parser: 'babel-eslint', 37 | }, 38 | { 39 | files: ['*.ts', '*.tsx'], 40 | parser: '@typescript-eslint/parser', 41 | plugins: ['@typescript-eslint/eslint-plugin'], 42 | rules: { 43 | '@typescript-eslint/no-unused-vars': [ 44 | 'error', 45 | { argsIgnorePattern: '^_' }, 46 | ], 47 | 48 | 'no-dupe-class-members': 'off', 49 | 'no-unused-vars': 'off', 50 | }, 51 | }, 52 | ], 53 | }; 54 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: Node.js CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | strategy: 11 | matrix: 12 | node-version: [8.x, 10.x, 12.x] 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Use Node.js ${{ matrix.node-version }} 17 | uses: actions/setup-node@v1 18 | with: 19 | node-version: ${{ matrix.node-version }} 20 | - run: yarn 21 | - run: yarn lint 22 | - run: yarn typescript 23 | env: 24 | CI: true 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | 25 | # Android/IJ 26 | # 27 | *.iml 28 | .idea 29 | .gradle 30 | local.properties 31 | 32 | # node.js 33 | # 34 | node_modules/ 35 | npm-debug.log 36 | package-lock.json 37 | 38 | # vscode 39 | jsconfig.json 40 | .project 41 | .vscode 42 | 43 | # BUCK 44 | buck-out/ 45 | bin/ 46 | \.buckd/ 47 | android/app/libs 48 | android/keystores/debug.keystore 49 | 50 | # generated by bob 51 | lib/ 52 | 53 | .expo 54 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | 'singleQuote': true, 3 | 'tabWidth': 2, 4 | 'trailingComma': 'es5', 5 | 'useTabs': false, 6 | 'semi': false, 7 | } 8 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "tabWidth": 2, 4 | "trailingComma": "es5", 5 | "useTabs": false, 6 | "semi": false 7 | } 8 | -------------------------------------------------------------------------------- /.release-it.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "changelog": "conventional-changelog -p angular | tail -n +3" 4 | }, 5 | "git": { 6 | "commitMessage": "chore: release %s", 7 | "tagName": "v%s" 8 | }, 9 | "plugins": { 10 | "@release-it/conventional-changelog": { 11 | "preset": "angular" 12 | } 13 | }, 14 | "npm": { 15 | "publish": true 16 | }, 17 | "github": { 18 | "release": true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Example/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/**/* 2 | .expo/* 3 | npm-debug.* 4 | *.jks 5 | *.p12 6 | *.key 7 | *.mobileprovision 8 | web-build 9 | -------------------------------------------------------------------------------- /Example/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { 3 | Text, 4 | View, 5 | FlatList, 6 | StyleSheet, 7 | TouchableOpacity, 8 | } from 'react-native' 9 | import { createAppContainer } from 'react-navigation' 10 | import { createStackNavigator } from 'react-navigation-stack' 11 | 12 | import AppleMusic from './src/screen/AppleMusic' 13 | import Map from './Map' 14 | import BlurToolbar from './BlurToolbar' 15 | import Imperative from './Imperative' 16 | import Test from './Test' 17 | import Sections from './Sections' 18 | import Collapsable from './Collapsable' 19 | 20 | const SCREENS = { 21 | appleMusic: { 22 | screen: AppleMusic, 23 | title: 'Apple Music', 24 | }, 25 | map: { 26 | screen: Map, 27 | title: 'Apple Map', 28 | }, 29 | toolbar: { 30 | screen: BlurToolbar, 31 | title: 'Blur Toolbar', 32 | }, 33 | imperative: { 34 | screen: Imperative, 35 | title: 'Imperative managed view', 36 | }, 37 | test: { 38 | screen: Test, 39 | title: 'Test', 40 | }, 41 | sectionList: { 42 | screen: Sections, 43 | title: 'SectionList', 44 | }, 45 | collapsable: { 46 | screen: Collapsable, 47 | title: 'Collapsable Header', 48 | }, 49 | } 50 | 51 | class MainScreen extends React.Component { 52 | static navigationOptions = { 53 | title: 'Bottom Sheet Examples', 54 | } 55 | render() { 56 | const data = Object.keys(SCREENS).map(key => ({ key })) 57 | return ( 58 | ( 63 | this.props.navigation.navigate(key)} 66 | /> 67 | )} 68 | /> 69 | ) 70 | } 71 | } 72 | 73 | const ItemSeparator = () => 74 | 75 | class MainScreenItem extends React.Component { 76 | _onPress = () => this.props.onPressItem(this.props.item) 77 | render() { 78 | const { key } = this.props.item 79 | return ( 80 | 81 | {SCREENS[key].title || key} 82 | 83 | ) 84 | } 85 | } 86 | 87 | const ExampleApp = createAppContainer( 88 | createStackNavigator( 89 | { 90 | Main: { screen: MainScreen }, 91 | ...SCREENS, 92 | }, 93 | { 94 | initialRouteName: 'Main', 95 | } 96 | ) 97 | ) 98 | 99 | const styles = StyleSheet.create({ 100 | list: { 101 | backgroundColor: '#EFEFF4', 102 | }, 103 | separator: { 104 | height: 1, 105 | backgroundColor: '#DBDBE0', 106 | }, 107 | buttonText: { 108 | backgroundColor: 'transparent', 109 | }, 110 | button: { 111 | flex: 1, 112 | height: 60, 113 | padding: 10, 114 | flexDirection: 'row', 115 | alignItems: 'center', 116 | backgroundColor: '#fff', 117 | }, 118 | }) 119 | 120 | export default ExampleApp 121 | -------------------------------------------------------------------------------- /Example/BlurToolbar.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Image, StyleSheet, Text, View } from 'react-native' 3 | import BottomSheet from 'reanimated-bottom-sheet' 4 | import Animated from 'react-native-reanimated' 5 | 6 | export default class Example extends React.Component { 7 | renderInner = () => ( 8 | 9 | 10 | Copy 11 | 12 | 13 | Paste 14 | 15 | 16 | Crop 17 | 18 | 19 | Search 20 | 21 | 22 | Send 23 | 24 | 25 | ) 26 | 27 | renderHeader = () => 28 | 29 | fall = new Animated.Value(1) 30 | 31 | render() { 32 | return ( 33 | 34 | 42 | 48 | 49 | Swipe up from very bottom 50 | 51 | 52 | 53 | 54 | ) 55 | } 56 | } 57 | 58 | const IMAGE_SIZE = 200 59 | 60 | const styles = StyleSheet.create({ 61 | container: { 62 | flex: 1, 63 | backgroundColor: '#2c2c2f', 64 | }, 65 | box: { 66 | width: IMAGE_SIZE, 67 | height: IMAGE_SIZE, 68 | }, 69 | panelContainer: { 70 | position: 'absolute', 71 | top: 0, 72 | bottom: 0, 73 | left: 0, 74 | right: 0, 75 | }, 76 | panel: { 77 | height: 600, 78 | padding: 20, 79 | backgroundColor: '#2c2c2fAA', 80 | paddingTop: 20, 81 | borderTopLeftRadius: 20, 82 | borderTopRightRadius: 20, 83 | shadowColor: '#000000', 84 | shadowOffset: { width: 0, height: 0 }, 85 | shadowRadius: 5, 86 | shadowOpacity: 0.4, 87 | }, 88 | header: { 89 | width: '100%', 90 | height: 50, 91 | }, 92 | panelHeader: { 93 | alignItems: 'center', 94 | }, 95 | panelHandle: { 96 | width: 40, 97 | height: 8, 98 | borderRadius: 4, 99 | backgroundColor: '#00000040', 100 | marginBottom: 10, 101 | }, 102 | panelTitle: { 103 | fontSize: 27, 104 | height: 35, 105 | }, 106 | panelSubtitle: { 107 | fontSize: 14, 108 | color: 'gray', 109 | height: 30, 110 | marginBottom: 10, 111 | }, 112 | panelButton: { 113 | padding: 20, 114 | borderRadius: 10, 115 | backgroundColor: '#292929', 116 | alignItems: 'center', 117 | marginVertical: 10, 118 | }, 119 | panelButtonTitle: { 120 | fontSize: 17, 121 | fontWeight: 'bold', 122 | color: 'white', 123 | }, 124 | photo: { 125 | width: '100%', 126 | height: 225, 127 | marginTop: 30, 128 | }, 129 | map: { 130 | height: '100%', 131 | width: '100%', 132 | }, 133 | }) 134 | -------------------------------------------------------------------------------- /Example/Collapsable.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { StyleSheet, Text, View } from 'react-native' 3 | import BottomSheet from 'reanimated-bottom-sheet' 4 | import Animated from 'react-native-reanimated' 5 | 6 | const { block, set, greaterThan, lessThan, Value, cond, sub } = Animated 7 | 8 | const Lorem = () => ( 9 | 10 | 11 | At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis 12 | praesentium voluptatum deleniti atque corrupti quos dolores et quas 13 | molestias excepturi sint occaecati cupiditate non provident, similique 14 | sunt in culpa qui officia deserunt mollitia animi, id est laborum et 15 | dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. 16 | Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil 17 | impedit quo minus id quod maxime placeat facere possimus, omnis voluptas 18 | assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut 19 | officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates 20 | repudiandae sint et molestiae non recusandae. Itaque earum rerum hic 21 | tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias 22 | consequatur aut perferendis doloribus asperiores repellat. At vero eos et 23 | accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium 24 | voluptatum deleniti atque corrupti quos dolores et quas molestias 25 | excepturi sint occaecati cupiditate non provident, similique sunt in culpa 26 | qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et 27 | harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, 28 | cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod 29 | maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor 30 | repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum 31 | necessitatibus saepe eveniet ut et voluptates repudiandae sint et 32 | molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente 33 | delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut 34 | perferendis doloribus asperiores repellat. 35 | 36 | 37 | ) 38 | export default class Example extends React.Component { 39 | trans = new Value(0) 40 | untraversedPos = new Value(0) 41 | prevTrans = new Value(0) 42 | headerPos = block([ 43 | cond( 44 | lessThan(this.untraversedPos, sub(this.trans, 100)), 45 | set(this.untraversedPos, sub(this.trans, 100)) 46 | ), 47 | cond( 48 | greaterThan(this.untraversedPos, this.trans), 49 | set(this.untraversedPos, this.trans) 50 | ), 51 | set(this.prevTrans, this.trans), 52 | this.untraversedPos, 53 | ]) 54 | renderHeader = name => ( 55 | 63 | {name} 64 | 65 | ) 66 | 67 | renderInner = () => ( 68 | 69 | 79 | {this.renderHeader('one')} 80 | 81 | 82 | 83 | 84 | ) 85 | 86 | render() { 87 | return ( 88 | 89 | 94 | 95 | ) 96 | } 97 | } 98 | 99 | const IMAGE_SIZE = 200 100 | 101 | const styles = StyleSheet.create({ 102 | container: { 103 | flex: 1, 104 | backgroundColor: 'red', 105 | }, 106 | box: { 107 | width: IMAGE_SIZE, 108 | height: IMAGE_SIZE, 109 | }, 110 | }) 111 | -------------------------------------------------------------------------------- /Example/Imperative.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { StyleSheet, Text, TouchableOpacity, View } from 'react-native' 3 | import BottomSheet from 'reanimated-bottom-sheet' 4 | 5 | export default class Example extends React.Component { 6 | renderInner = () => ( 7 | 8 | 9 | Sample 10 | 11 | 12 | Buttons 13 | 14 | 15 | Which 16 | 17 | 18 | Could 19 | 20 | 21 | Be 22 | 23 | 24 | Clicked 25 | 26 | 27 | ) 28 | 29 | bs = React.createRef() 30 | 31 | render() { 32 | return ( 33 | 34 | 41 | 48 | this.bs.current.snapTo(0)} 51 | > 52 | 1 53 | 54 | this.bs.current.snapTo(1)} 57 | > 58 | 2 59 | 60 | this.bs.current.snapTo(2)} 63 | > 64 | 3 65 | 66 | this.bs.current.snapTo(3)} 69 | > 70 | 4 71 | 72 | 73 | 74 | ) 75 | } 76 | } 77 | 78 | const IMAGE_SIZE = 200 79 | 80 | const styles = StyleSheet.create({ 81 | container: { 82 | flex: 1, 83 | backgroundColor: '#6f6f76', 84 | }, 85 | box: { 86 | width: IMAGE_SIZE, 87 | height: IMAGE_SIZE, 88 | }, 89 | panelContainer: { 90 | position: 'absolute', 91 | top: 0, 92 | bottom: 0, 93 | left: 0, 94 | right: 0, 95 | }, 96 | commandButton: { 97 | padding: 20, 98 | borderRadius: 10, 99 | backgroundColor: '#292929', 100 | alignItems: 'center', 101 | margin: 7, 102 | }, 103 | panel: { 104 | height: 600, 105 | padding: 20, 106 | backgroundColor: '#2c2c2fAA', 107 | paddingTop: 20, 108 | borderTopLeftRadius: 20, 109 | borderTopRightRadius: 20, 110 | shadowColor: '#000000', 111 | shadowOffset: { width: 0, height: 0 }, 112 | shadowRadius: 5, 113 | shadowOpacity: 0.4, 114 | }, 115 | header: { 116 | width: '100%', 117 | height: 50, 118 | }, 119 | panelHeader: { 120 | alignItems: 'center', 121 | }, 122 | panelHandle: { 123 | width: 40, 124 | height: 8, 125 | borderRadius: 4, 126 | backgroundColor: '#00000040', 127 | marginBottom: 10, 128 | }, 129 | panelTitle: { 130 | fontSize: 27, 131 | height: 35, 132 | }, 133 | panelSubtitle: { 134 | fontSize: 14, 135 | color: 'gray', 136 | height: 30, 137 | marginBottom: 10, 138 | }, 139 | panelButton: { 140 | padding: 13, 141 | borderRadius: 10, 142 | backgroundColor: '#292929', 143 | alignItems: 'center', 144 | marginVertical: 7, 145 | }, 146 | panelButtonTitle: { 147 | fontSize: 17, 148 | fontWeight: 'bold', 149 | color: 'white', 150 | }, 151 | photo: { 152 | width: '100%', 153 | height: 225, 154 | marginTop: 30, 155 | }, 156 | map: { 157 | height: '100%', 158 | width: '100%', 159 | }, 160 | }) 161 | -------------------------------------------------------------------------------- /Example/Map.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { 3 | Image, 4 | StyleSheet, 5 | Text, 6 | TouchableWithoutFeedback, 7 | View, 8 | TextInput, 9 | } from 'react-native' 10 | import BottomSheet from 'reanimated-bottom-sheet' 11 | 12 | export default class Example extends React.Component { 13 | renderInner = () => ( 14 | 15 | { 18 | this.bs.current.snapTo(1) 19 | }} 20 | placeholder="search" 21 | /> 22 | San Francisco Airport 23 | 24 | International Airport - 40 miles away 25 | 26 | 27 | Directions 28 | 29 | 30 | Search Nearby 31 | 32 | 36 | 37 | ) 38 | 39 | renderHeader = () => ( 40 | 41 | 42 | 43 | 44 | 45 | ) 46 | 47 | bs = React.createRef() 48 | 49 | render() { 50 | return ( 51 | 52 | 59 | this.bs.current.snapTo(0)}> 60 | 61 | 62 | 63 | ) 64 | } 65 | } 66 | 67 | const IMAGE_SIZE = 200 68 | 69 | const styles = StyleSheet.create({ 70 | search: { 71 | borderColor: 'gray', 72 | borderWidth: StyleSheet.hairlineWidth, 73 | height: 40, 74 | borderRadius: 10, 75 | paddingHorizontal: 15, 76 | }, 77 | container: { 78 | flex: 1, 79 | backgroundColor: '#F5FCFF', 80 | }, 81 | box: { 82 | width: IMAGE_SIZE, 83 | height: IMAGE_SIZE, 84 | }, 85 | panelContainer: { 86 | position: 'absolute', 87 | top: 0, 88 | bottom: 0, 89 | left: 0, 90 | right: 0, 91 | }, 92 | panel: { 93 | height: 600, 94 | padding: 20, 95 | backgroundColor: '#f7f5eee8', 96 | }, 97 | header: { 98 | backgroundColor: '#f7f5eee8', 99 | shadowColor: '#000000', 100 | paddingTop: 20, 101 | borderTopLeftRadius: 20, 102 | borderTopRightRadius: 20, 103 | }, 104 | panelHeader: { 105 | alignItems: 'center', 106 | }, 107 | panelHandle: { 108 | width: 40, 109 | height: 8, 110 | borderRadius: 4, 111 | backgroundColor: '#00000040', 112 | marginBottom: 10, 113 | }, 114 | panelTitle: { 115 | fontSize: 27, 116 | height: 35, 117 | }, 118 | panelSubtitle: { 119 | fontSize: 14, 120 | color: 'gray', 121 | height: 30, 122 | marginBottom: 10, 123 | }, 124 | panelButton: { 125 | padding: 20, 126 | borderRadius: 10, 127 | backgroundColor: '#318bfb', 128 | alignItems: 'center', 129 | marginVertical: 10, 130 | }, 131 | panelButtonTitle: { 132 | fontSize: 17, 133 | fontWeight: 'bold', 134 | color: 'white', 135 | }, 136 | photo: { 137 | width: '100%', 138 | height: 225, 139 | marginTop: 30, 140 | }, 141 | map: { 142 | height: '100%', 143 | width: '100%', 144 | }, 145 | }) 146 | -------------------------------------------------------------------------------- /Example/Sections.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { StyleSheet, Text, View } from 'react-native' 3 | import BottomSheet from 'reanimated-bottom-sheet' 4 | import Animated from 'react-native-reanimated' 5 | 6 | const Lorem = () => ( 7 | 8 | 9 | At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis 10 | praesentium voluptatum deleniti atque corrupti quos dolores et quas 11 | molestias excepturi sint occaecati cupiditate non provident, similique 12 | sunt in culpa qui officia deserunt mollitia animi, id est laborum et 13 | dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. 14 | Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil 15 | impedit quo minus id quod maxime placeat facere possimus, omnis voluptas 16 | assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut 17 | officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates 18 | repudiandae sint et molestiae non recusandae. Itaque earum rerum hic 19 | tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias 20 | consequatur aut perferendis doloribus asperiores repellat. At vero eos et 21 | accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium 22 | voluptatum deleniti atque corrupti quos dolores et quas molestias 23 | excepturi sint occaecati cupiditate non provident, similique sunt in culpa 24 | qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et 25 | harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, 26 | cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod 27 | maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor 28 | repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum 29 | necessitatibus saepe eveniet ut et voluptates repudiandae sint et 30 | molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente 31 | delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut 32 | perferendis doloribus asperiores repellat. 33 | 34 | 35 | ) 36 | export default class Example extends React.Component { 37 | trans = new Animated.Value(0) 38 | renderHeader = name => ( 39 | 47 | {name} 48 | 49 | ) 50 | 51 | renderInner = () => ( 52 | 53 | 66 | {this.renderHeader('one')} 67 | 68 | 69 | 70 | 83 | {this.renderHeader('XXX')} 84 | 85 | 86 | 99 | {this.renderHeader('two')} 100 | 101 | 102 | 115 | {this.renderHeader('three')} 116 | 117 | 118 | 131 | {this.renderHeader('mmm')} 132 | 133 | 134 | 135 | ) 136 | 137 | render() { 138 | return ( 139 | 140 | 145 | 146 | ) 147 | } 148 | } 149 | 150 | const IMAGE_SIZE = 200 151 | 152 | const styles = StyleSheet.create({ 153 | container: { 154 | flex: 1, 155 | backgroundColor: 'red', 156 | }, 157 | box: { 158 | width: IMAGE_SIZE, 159 | height: IMAGE_SIZE, 160 | }, 161 | }) 162 | -------------------------------------------------------------------------------- /Example/Test.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { StyleSheet, Text, Button, View } from 'react-native' 3 | import BottomSheet from 'reanimated-bottom-sheet' 4 | 5 | export default class Example extends React.Component { 6 | renderInner = () => ( 7 | 8 | {[...Array(60)].map((e, i) => ( 9 | 13 | computed 14 | 15 | ))} 16 | 17 | ) 18 | 19 | renderHeader = () => ( 20 | 26 | 123 27 | 28 | ) 29 | 30 | bs = React.createRef() 31 | 32 | render() { 33 | return ( 34 | 35 | 41 |