osdnk / react-native-reanimated-bottom-sheet Goto Github PK
View Code? Open in Web Editor NEWHighly configurable bottom sheet component made with react-native-reanimated and react-native-gesture-handler
License: MIT License
Highly configurable bottom sheet component made with react-native-reanimated and react-native-gesture-handler
License: MIT License
How to 'scrollToTop' for the scrollable content inside the bottom-sheet? Is it possible to add a scrollTo({}) method for the component?
I've tried couple times but failed. It's too complicated since the 'scrollView' inside the bottom-sheet is controlled by all these math... I don't know where to start.
So, is it basically add another animated.value to signal a manuallySetScroll, inject something inside the this.Y(), if manuallySetScroll is on then, stop the clock, reset manuallySetScroll, and return position 0 for the this.Y().
Thanks a lot
I want to use this library https://www.npmjs.com/package/react-native-scrollable-tab-view inside the BottomSheet but it only works if enabledGestureInteraction is false, but I need keep the drag feature to move the BottomSheet, what can I do ?
First of all, awesome library 👏
I've come across what I think is a bug where the bottomSheet content is leaking into the SafeArea
from the bottom (on notch phones like iPhone X). SafeArea
is a component from react-navigation
that ensures content is not overlapping outside of viewable area in notch phones.
You can see the bottom sheet content is overflowing at the bottom when it should not be.
Here's my configuration:
<BottomSheet
snapPoints={[290, 75]}
initialSnap={1}
renderContent={renderInner}
renderHeader={renderHeader}
/>
react-native info
React Native Environment Info:
System:
OS: macOS 10.14.2
CPU: x64 Intel(R) Core(TM) i7-7820HQ CPU @ 2.90GHz
Memory: 27.74 MB / 16.00 GB
Shell: 5.3 - /bin/zsh
Binaries:
Node: 8.12.0 - ~/.nvm/versions/node/v8.12.0/bin/node
Yarn: 1.6.0 - /usr/local/bin/yarn
npm: 6.4.1 - ~/.nvm/versions/node/v8.12.0/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 12.1, macOS 10.14, tvOS 12.1, watchOS 5.1
Android SDK:
Build Tools: 26.0.3, 27.0.3, 28.0.2, 28.0.3
API Levels: 21, 22, 23, 24, 25, 26, 27
IDEs:
Android Studio: 3.1 AI-173.4907809
Xcode: 10.1/10B61 - /usr/bin/xcodebuild
npmPackages:
react: 16.6.3 => 16.6.3
react-native: 0.57.8 => 0.57.8
npmGlobalPackages:
react-native-log-ios: 1.0.1
I tried setting zIndex on the SafeArea
view to a high value like 9 but still, the bottom sheet is showing on top.
Any other ideas I can try to work around this?
Thanks 👋
If you're setting up react-native-gesture-handler
for the first time you must override the root view in your MainActivity.java
file, for anyone using this library without already having setup react-native-gesture-handler
this library appears incorrectly to be broken on android.
We should add in a caveat to follow the gesture handler getting started guide instead of simply saying "install and link" when installing the peer dependencies.
As you can see, the touch event is going to the map in the background and not the bottom sheet content. I have to use two-finger gesture in order to interact with the bottom sheet content on Android.
enabled={true}
and disallowInterruption={true}
onScroll={event => {
console.log(event.nativeEvent);
}}
and confirmed that trying to scroll with a single finger doesn't even call this function but two-finger touch calls it sometimes.
<View>
<MapView ... />
<BottomSheet
enabledInnerScrolling={true}
enabledGestureInteraction={true}
overdragResistanceFactor={0}
snapPoints={[
Dimensions.get('window').height / 2.275,
Dimensions.get('window').height / 3,
83,
]}
initialSnap={1}
renderContent={() =>
return <View>... (doesn't matter what I put here)</View>
}
renderHeader={() => <View>... (doesn't matter what I put here)</View>}
/>
</View>
React Native Environment Info:
System:
OS: macOS 10.14.2
CPU: x64 Intel(R) Core(TM) i7-7820HQ CPU @ 2.90GHz
Memory: 604.60 MB / 16.00 GB
Shell: 5.3 - /bin/zsh
Binaries:
Node: 8.12.0 - ~/.nvm/versions/node/v8.12.0/bin/node
Yarn: 1.6.0 - /usr/local/bin/yarn
npm: 6.4.1 - ~/.nvm/versions/node/v8.12.0/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 12.1, macOS 10.14, tvOS 12.1, watchOS 5.1
Android SDK:
Build Tools: 26.0.3, 27.0.3, 28.0.2, 28.0.3
API Levels: 21, 22, 23, 24, 25, 26, 27
IDEs:
Android Studio: 3.1 AI-173.4907809
Xcode: 10.1/10B61 - /usr/bin/xcodebuild
npmPackages:
react: 16.6.3 => 16.6.3
react-native: 0.57.8 => 0.57.8
npmGlobalPackages:
react-native-log-ios: 1.0.1
Tested it on multiple Android phones/versions: Android 8.1 and Android 5.1
"react-native-gesture-handler": "^1.1.0",
"react-native-reanimated": "^1.0.0-alpha.12",
"reanimated-bottom-sheet": "^1.0.0-alpha.1",
@osdnk Any workarounds/ideas I can try?
Thanks
This error is located at BottomSheetBehavior at Map.js:16
Steps to reproduce:
I have a simple app that has a bottom tab bar navigation. From just trying to get this going, it doesn't show up at all if I remove everything except the snap points, which are listed as required to render. If I include the initialSnap prop in any way, it throws the error in the title. A Map.js
file is one of the screens:
import React from 'react';
import { View, StyleSheet } from 'react-native';
import MapView, { PROVIDER_GOOGLE } from 'react-native-maps';
import BottomSheet from 'reanimated-bottom-sheet';
import renderMarker from './Marker';
const Map = () => {
return (
<View style={{ ...StyleSheet.absoluteFillObject }}>
<BottomSheet
snapPoints={[500, 250]}
renderContent={() => <View />}
initialSnap={250} //this line gives the error described
/>
<MapView
provider={PROVIDER_GOOGLE}
showsUserLocation
showsMyLocationButton
followUserLocation
showsCompass
style={{ ...StyleSheet.absoluteFillObject }}
initialRegion={initialRegion}
>
{renderMarker()}
</MapView>
</View >
);
};
export default Map;
Is it a default behaviour that the bottom sheet will limit the scrollable content we see within the bottom sheet or am I doing something wrong. I have a reasonable amount of content within the renderContent but I am unable to scroll below a certain point. Any advise?
Please have a look at the following gist and advise if I am doing something wrong here.
https://gist.github.com/cedricavigo/7388438f70a6ac077ed2c0440f75d71d
On reach a specific index of the Bottom Sheet snapPoints
, I need to fire an event in my application, how can I do it? Looks like that currently there is no way to control events or the bottom sheet position with the library.
I am trying to achieve some interaction when the bottom sheet is hidden and visible. I am able to follow the example and I have added the animated value to a view within the same component(add opacity & remove).
Now, I would like to animate a component which is not part of this based on the callbackNode value. This could be a basic approach, but I am new to RN and any advise to achieve this experience will be great.
More details:
App.js
<SafeAreaView style={styles.container} forceInset={{ bottom: 0 }}>
<View style={styles.notifHolder}>
<NotifPanel /> <----- A notification panel(based on react-native-reanimated example) is always visible(25%). FYI, this is an Interactable.View.
</View>
<Nav /> <----- Bottom sheet code is inside a stack navigation page
</SafeAreaView>
Expected output/effect:
I would like to,
a) Slowly hide the notifications panel based on the callbackNode snap position to 1
b) Same way, I would like to bring the notifications panel back when the callbackNode snap position is 0
Thanks for your help!
Hello,
The panel sometimes gets stuck in the middle of the screen on first app load. And it's invisible. It prevents me from clicking on the map. Android only. iOS is ok.
I noticed that this happens when initialSnap reference to not maximal value.
In my example: initialSnap = 0 works normally. And the panel is in it's max size.
Map and panel components is on one level and wrapped in one flex container with no other params.
Bug occurs more often on slow Android devices, or in debug mode.
const content = ({ children, height }) => (
<View style={[styles.panel, { height }]}>
{children}
</View>
);
const renderHeader = () => (
<View style={styles.header}>
<View style={styles.panelHeader}>
<View style={styles.panelHandle} />
</View>
</View>
);
const MapPanel = ({ panelRef, children, height }) => (
<BottomSheet
ref={panelRef}
snapPoints={[600, 300, 0]}
renderContent={() => content({ children, height })}
renderHeader={renderHeader}
initialSnap={2}
/>
);
https://expo.io/@osdnk/reanimated-bottomsheet-expample
When I try to open this on my phone, the Expo app gives me the error:
There was a problem loading the requested app.
Experience "@osdnk/reanimated-bottomsheet-expample" for platform "ios" is not viewable by you. You will need to authenticate or ask the author to grant you access.
Hi, i want to implement with tabview like this video: https://drive.google.com/open?id=1ZXd1_Ak9gKc6FztfGPUebGVF-gjB-3NB
anyone has any idea?
@osdnk Keep it visible in small height. It hides. I need make it always visible width min height. Is that possible?
Hi, I was trying to have QRCode scanner in the bottomsheet. I tried using RNCamera (using react-native-qrcode-scanner), also tried BarcodeScanner from expo. But I am having some issues on android.
Here's what happens when used with camera (randomly):
I have tried to reproduce the issue. Here is the link to the github repo for the example:
I found a weird behavior when I put text input in the bottom sheet. My snap point is only 0 and device's width but when text input focused and keyboard appears, bottom sheet slide to the top of screen. The problem is; I have a header which floats above all components. So I can not see text input when I type something.
Hey!
I want to get a callback when the user closes the bottom sheet, something like onClosed.
I don't know how to use callbackNode, could you please explain this to me?
Thank you
I was trying to perform snapTo to hide bottomsheet when header is tapped. I wasn't able to do so Android. However, it works on iOS.
It can be reproduced in this snack. (Took one of the snack from earlier issues)
Long press the "Profile" tab to show the bottom sheet.
https://snack.expo.io/@roshangm1/bottom-sheet
I would like to dig in more on this (doing it too). If you have any clue on what could be the possible reason for this behavior, please do let me know.
Touchable Opacity inside renderContent has no actions when tapped on Android. iOS is working fine.
It can be reproduced in this snack. (Took one of the snack from earlier issues)
Long press the "Profile" tab to show the bottom sheet.
Inside bottom sheet, press click me text.
https://snack.expo.io/@roshangm1/bottom-sheet
I want to implement a close callback that listens to the bottom-sheet. How do I implement this?
How would you implement this library in the following use case ?
I have a bottom tab navigator with 4 tabs. I have to show bottom sheet with different content in different tabs (even 1 tab can have different content).
One approach would be to have the bottom sheet in the root file and calling it from other tab. (Problem here would be rendering dynamic height and dynamic content for bottom sheet for each tab (as height and content are not consistent).
Other approach would be to have bottom sheet for each tab. With this approach, in snapPoints=[0, 400]
, snapPoints[0]
is not going to be true 0 from the bottom of app screen. It's going to be the bottom: 0
from tab navigator instead.
I am not thinking of calculating height of the tab navigator and making snapPoints=[-heightOfTabNavigator, 400]
or similar. Suggest me if this is a good idea.
I am using https://www.npmjs.com/package/react-native-tab-navigator [This is a pretty old project 🗡 ] for tab navigator. But I am willing to use react-navigation's bottom navigator if required.
Any kind of suggestions would be helpful. :)
cc @brentvatne @osdnk @Eyesonly88 @satya164 (Sorry to mention you guys here ) 🥂
When tapping touchable inside the content of bottomsheet (to close bottomsheet) doesn't close the bottomsheet when enabledInnerScrolling
is set false
. However, tapping header closes the bottomsheet (with the latest fix in react-native-gesture-handler
.
Also, this is android only.
Hey!
Awesome component, thanks for sharing!
Is it possible to make only the header draggable?
In my particular use case i would like to render a few ScrollView in the content, so I've turned off enabledGestureInteraction
. It works so far, but it would be cool to make the header draggable, to allow the user to close the sheet via dragging.
Any suggestion?
Thanks!
Thanks a lot for this library. I am trying to work on a pull to refresh UI ( I already have flat list rendered in the bottom sheet content). I know there are three gesture handlers that get passed through the instance, but I am not sure how to go about it.
I am thinking of getting the initial position of the header ref and check if the drag went below a certain level ( say maybe -50) and then trigger it. What I am not able to find is how do I get the initial position of the header ref and how to keep a check on where the header ref current is.
P.S. I couldn't find a StackOverflow tag for this so had to ask here. Let me know if there is anything you aren't clear about. I would try my best to come up with an example.
Edit
After going through the examples I figured out that you need to get the contentPosition from the prop and based on the value you can define a custom callback. What I am not quite sure about is where do I implement the callback. I saw the callbackNode prop but it only accepts an animatedValue which gets updated based on the content position.
callbackNode: reanimated node which holds position of bottom sheet, where 1 it the highest snap point and 0 is the lowest.
Currently when using callbackNode
, it is set to 0 at the highest point and 1 at the lowest. See https://snack.expo.io/@notbrent/bottom-sheet - long press on the "Profile" tab to make sheet appear.
Right now, the calculation simply looks at which snap point is nearest to the release point. It would be nice to be able to bias certain snap points so that the user can move only a short distance away from one snap point and be considered closer to the next snap point.
Use cases for this is when you have a near-fullscreen snap point and don't want your user to have to pull the sheet half a screen height just to get to the next snap point.
I can show up that bottom sheet with touchable highlight's on press even at my first page but not at my second page even i just save as my first page.
this is my first page code:
import React, { Component } from 'react';
import { ScrollView, View, Text, Image, TextInput, TouchableHighlight, StatusBar, Dimensions, FlatList } from 'react-native';
import { StackActions, NavigationActions } from 'react-navigation';
import { Container, Content } from 'native-base';
import { BarPasswordStrengthDisplay } from 'react-native-password-strength-meter';
import BottomSheet from 'reanimated-bottom-sheet';
import Icon from 'react-native-vector-icons/FontAwesome';
import { LOGO } from '../../../assets/img';
import { placeholder, buttonSuccess, mainBlue, mainBackground } from '../../../assets/ColorIndex';
const {width, height} = Dimensions.get('screen')
export default class FirstScreen extends Component {
constructor(props) {
super(props);
this.bottomSheetRegisterCompany = React.createRef();
this.goRegister = this._goRegister.bind(this);
this.goLogin = this._goLogin.bind(this);
this.showBottomSheet = this._showBottomSheet.bind(this);
this.headerBottomSheet = this._renderHeader.bind(this);
this.contentBottomSheet = this._renderContent.bind(this);
this.renderItem = this._renderItem.bind(this);
}
_goRegister() {
this.props.navigation.dispatch(StackActions.reset({ index: 0, actions: [ NavigationActions.navigate({ routeName: 'Register' }) ] }));
}
_goLogin() {
this.props.navigation.dispatch(StackActions.reset({ index: 0, actions: [ NavigationActions.navigate({ routeName: 'Login' }) ] }));
}
_renderHeader() {
const { bottomSheetActive } = this.props.registerCompany;
switch(bottomSheetActive){
case 'bussiness_entity':
return (
<View style={{ justifyContent: 'space-around', alignItems: 'center', backgroundColor: mainBackground }}>
<View style={{ height: 5, width: width*0.2, borderRadius: 20, backgroundColor: placeholder, marginVertical: 10 }} />
<Text style={{ fontWeight: 'bold', fontSize: 18, marginBottom: 5 }}>Pilih Badan Usaha</Text>
</View>
);
case 'province':
return (
<View style={{ justifyContent: 'space-around', alignItems: 'center', backgroundColor: mainBackground }}>
<View style={{ height: 5, width: width*0.2, borderRadius: 20, backgroundColor: placeholder, marginVertical: 10 }} />
<Text style={{ fontWeight: 'bold', fontSize: 18, marginBottom: 5 }}>Pilih Provinsi</Text>
</View>
);
case 'city':
return (
<View style={{ justifyContent: 'space-around', alignItems: 'center', backgroundColor: mainBackground }}>
<View style={{ height: 5, width: width*0.2, borderRadius: 20, backgroundColor: placeholder, marginVertical: 10 }} />
<Text style={{ fontWeight: 'bold', fontSize: 18, marginBottom: 5 }}>Pilih Kota</Text>
</View>
);
case 'district':
return (
<View style={{ justifyContent: 'space-around', alignItems: 'center', backgroundColor: mainBackground }}>
<View style={{ height: 5, width: width*0.2, borderRadius: 20, backgroundColor: placeholder, marginVertical: 10 }} />
<Text style={{ fontWeight: 'bold', fontSize: 18, marginBottom: 5 }}>Pilih Kecamatan</Text>
</View>
);
case 'bussiness_industry':
return (
<View style={{ justifyContent: 'space-around', alignItems: 'center', backgroundColor: mainBackground }}>
<View style={{ height: 5, width: width*0.2, borderRadius: 20, backgroundColor: placeholder, marginVertical: 10 }} />
<Text style={{ fontWeight: 'bold', fontSize: 18, marginBottom: 5 }}>Pilih Bisnis Industri</Text>
</View>
);
case 'jenis_kelamin':
return (
<View style={{ justifyContent: 'space-around', alignItems: 'center', backgroundColor: mainBackground }}>
<View style={{ height: 5, width: width*0.2, borderRadius: 20, backgroundColor: placeholder, marginVertical: 10 }} />
<Text style={{ fontWeight: 'bold', fontSize: 18, marginBottom: 5 }}>Pilih Jenis Kelamin</Text>
</View>
);
case 'job_position':
return (
<View style={{ justifyContent: 'space-around', alignItems: 'center', backgroundColor: mainBackground }}>
<View style={{ height: 5, width: width*0.2, borderRadius: 20, backgroundColor: placeholder, marginVertical: 10 }} />
<Text style={{ fontWeight: 'bold', fontSize: 18, marginBottom: 5 }}>Pilih Jabatan</Text>
</View>
);
}
}
_renderContent(){
const { bottomSheetActive } = this.props.registerCompany;
const { bussinessEntities, bussinessIndustries, provinces, cities, districts, jenisKelamin, jobPositions } = this.props.masterData;
switch(bottomSheetActive){
case 'bussiness_entity':
return (
<View style={{ backgroundColor: mainBackground, height: Math.max(bussinessEntities.length*45+15, 40), minHeight: height*0.9 }}>
<FlatList
keyExtractor={item => `bussinessEntities-${item.id}`}
renderItem={({item}) => this.renderItem(item)}
data={bussinessEntities}
scrollEnabled={false}
/>
</View>
);
case 'bussiness_industry':
return (
<View style={{ backgroundColor: mainBackground, height: Math.max(bussinessIndustries.length*45+15, 40), minHeight: height*0.9 }}>
<FlatList
keyExtractor={item => `bussinessIndustries-${item.id}`}
renderItem={({item}) => this.renderItem(item)}
data={bussinessIndustries}
scrollEnabled={false}
/>
</View>
);
case 'province':
return (
<View style={{ backgroundColor: mainBackground, height: Math.max(provinces.length*45+15, 40), minHeight: height*0.9 }}>
<FlatList
keyExtractor={item => `provinces-${item.id}`}
renderItem={({item}) => this.renderItem(item)}
data={provinces}
scrollEnabled={false}
/>
</View>
);
case 'city':
return (
<View style={{ backgroundColor: mainBackground, height: Math.max(cities.length*45+15, 40), minHeight: height*0.9 }}>
<FlatList
keyExtractor={item => `cities-${item.id}`}
renderItem={({item}) => this.renderItem(item)}
data={cities}
scrollEnabled={false}
/>
</View>
);
case 'district':
return (
<View style={{ backgroundColor: mainBackground, height: Math.max(districts.length*45+15, 40), minHeight: height*0.9 }}>
<FlatList
keyExtractor={item => `districts-${item.id}`}
renderItem={({item}) => this.renderItem(item)}
data={districts}
scrollEnabled={false}
/>
</View>
);
case 'jenis_kelamin':
return (
<View style={{ backgroundColor: mainBackground, height: Math.max(jenisKelamin.length*45+15, 40), minHeight: height*0.9 }}>
<FlatList
keyExtractor={item => `jenisKelamin-${item.id}`}
renderItem={({item}) => this.renderItem(item)}
data={jenisKelamin}
scrollEnabled={false}
/>
</View>
);
case 'job_position':
return (
<View style={{ backgroundColor: mainBackground, height: Math.max(jobPositions.length*45+15, 40), minHeight: height*0.9 }}>
<FlatList
keyExtractor={item => `jobPositions-${item.id}`}
renderItem={({item}) => this.renderItem(item)}
data={jobPositions}
scrollEnabled={false}
/>
</View>
);
}
}
_renderItem(item) {
return (
<TouchableHighlight style={{ padding: 10 }}>
<View style={{ justifyContent: 'space-between', alignItems: 'center', flexDirection: 'row' }}>
<View style={{ justifyContent: 'flex-start', alignItems: 'flex-start', paddingHorizontal: 10 }}>
<Text style={{ fontWeight: 'bold', fontSize: 18 }}>{item.name}</Text>
</View>
<Icon name='circle-o' size={20} color={mainBlue} />
</View>
</TouchableHighlight>
);
}
async _showBottomSheet(type, withContent = true) {
const _type = type.toLowerCase();
const {provinceValue, cityValue} = this.props.registerCompany
switch(_type){
case 'bussiness_entity':
if(withContent){
await this.props.getBussinessEntities();
}
break;
case 'bussiness_industry':
if(withContent){
await this.props.getBussinessIndustries();
}
break;
case 'province':
if(withContent){
await this.props.getProvinces();
}
break;
case 'city':
if(withContent){
await this.props.getCitiesByProvince(provinceValue.id);
}
break;
case 'district':
if(withContent){
await this.props.getDistrictsByCity(cityValue.id);
}
break;
case 'position':
if(withContent){
await this.props.getJobPositions();
}
break;
}
this.props.setBottomSheetLoading(_type, true);
this.bottomSheetRegisterCompany.current.snapTo(1);
}
componentDidMount() {
this.props.clearProps();
}
render() {
return (
<Container style={{ backgroundColor: mainBackground, justifyContent: 'center' }}>
<StatusBar backgroundColor={mainBlue} barStyle={'light-content'} />
<Content>
<View style={{ alignItems: 'center', justifyContent: 'center', height: 100 }}>
<Image source={LOGO} resizeMode='contain' style={{ width: '20%' }} />
</View>
<View
style={{
alignItems: 'center',
alignSelf: 'center',
justifyContent: 'space-around',
backgroundColor: '#fff',
padding: 10,
width: '90%'
}}
>
<View style={{ alignItems: 'center', width: '100%', marginBottom: 20 }}>
<Text style={{ fontSize: 20, fontWeight: 'bold', alignSelf: 'center', marginVertical: 15, color: '#000' }}>Daftar Sebagai Perusahaan</Text>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TouchableHighlight onPress={() => this.showBottomSheet('bussiness_entity') }>
<View style={{ alignItems: 'center', justifyContent: 'space-between', flexDirection: 'row', paddingVertical: 10 }}>
<Text style={{ color: placeholder, fontSize: 15, maxWidth: '94%', minWidth: '94%' }}>Pilih Badan Usaha</Text>
<Icon name='sort' size={20} color={'#000'} />
</View>
</TouchableHighlight>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TextInput
style={{ width: '100%' }}
placeholderColor={placeholder}
placeholder='Nama Perusahaan'
onChangeText={() => {}}
/>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TextInput
style={{ width: '100%' }}
placeholderColor={placeholder}
placeholder='NPWP Perusahaan'
onChangeText={() => {}}
/>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TextInput
style={{ width: '100%' }}
placeholderColor={placeholder}
placeholder='Nomor Telepon Perusahaan'
onChangeText={() => {}}
/>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TextInput
style={{ width: '100%' }}
placeholderColor={placeholder}
placeholder='Nomor Fax Perusahaan'
onChangeText={() => {}}
/>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TextInput
style={{ width: '100%' }}
placeholderColor={placeholder}
placeholder='Alamat Perusahaan'
onChangeText={() => {}}
/>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TouchableHighlight onPress={() => this.showBottomSheet('province')}>
<View style={{ alignItems: 'center', justifyContent: 'space-between', flexDirection: 'row', paddingVertical: 10 }}>
<Text style={{ color: placeholder, fontSize: 15, maxWidth: '94%', minWidth: '94%' }}>Pilih Provinsi</Text>
<Icon name='sort' size={20} color={'#000'} />
</View>
</TouchableHighlight>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TouchableHighlight onPress={() => this.showBottomSheet('city')} disabled={true}>
<View style={{ alignItems: 'center', justifyContent: 'space-between', flexDirection: 'row', paddingVertical: 10 }}>
<Text style={{ color: placeholder, fontSize: 15, maxWidth: '94%', minWidth: '94%' }}>Pilih Kota</Text>
<Icon name='sort' size={20} color={'#000'} />
</View>
</TouchableHighlight>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TouchableHighlight onPress={() => this.showBottomSheet('district')} disabled={true}>
<View style={{ alignItems: 'center', justifyContent: 'space-between', flexDirection: 'row', paddingVertical: 10 }}>
<Text style={{ color: placeholder, fontSize: 15, maxWidth: '94%', minWidth: '94%' }}>Pilih Kecamatan</Text>
<Icon name='sort' size={20} color={'#000'} />
</View>
</TouchableHighlight>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TouchableHighlight onPress={() => this.showBottomSheet('bussiness_industry')}>
<View style={{ alignItems: 'center', justifyContent: 'space-between', flexDirection: 'row', paddingVertical: 10 }}>
<Text style={{ color: placeholder, fontSize: 15, maxWidth: '94%', minWidth: '94%' }}>Pilih Bisnis Industri</Text>
<Icon name='sort' size={20} color={'#000'} />
</View>
</TouchableHighlight>
</View>
<View style={{ width: '100%', height: 50, marginVertical: 10, flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }}>
<View style={{ borderBottomWidth: 2, borderBottomColor: mainBackground, flexGrow: 1 }} />
<Text style={{ fontSize: 20, fontWeight: 'bold', paddingHorizontal: 10 }}>Data Akun</Text>
<View style={{ borderBottomWidth: 2, borderBottomColor: mainBackground, flexGrow: 1 }} />
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TextInput
style={{ width: '100%' }}
placeholderColor={placeholder}
placeholder='Email'
onChangeText={() => {}}
/>
</View>
<View style={{ alignItems: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1, flexDirection: 'row' }}>
<TextInput
style={{ width: '90%' }}
placeholderColor={placeholder}
placeholder='Kata Sandi'
secureTextEntry={!this.props.registerCompany.showPassword}
onChangeText={() => {}}
/>
<TouchableHighlight onPress={ () => this.props.showPassword() } underlayColor={'#fff'} activeOpacity={0.5}>
{
this.props.registerCompany.showPassword ?
<Icon name='eye-slash' size={20} color={mainBlue} />
:
<Icon name='eye' size={20} color={mainBlue} />
}
</TouchableHighlight>
</View>
<BarPasswordStrengthDisplay password={this.props.registerCompany.password} width={width - 65} wrapperStyle={{ marginBottom: 10 }} />
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TextInput
style={{ width: '100%' }}
placeholderColor={placeholder}
placeholder='Konfirmasi Kata Sandi'
secureTextEntry={!this.props.registerCompany.showPassword}
onChangeText={() => {}}
/>
</View>
<View style={{ width: '100%', height: 50, marginVertical: 10, flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }}>
<View style={{ borderBottomWidth: 2, borderBottomColor: mainBackground, flexGrow: 1 }} />
<Text style={{ fontSize: 20, fontWeight: 'bold', paddingHorizontal: 10 }}>Penanggung Jawab</Text>
<View style={{ borderBottomWidth: 2, borderBottomColor: mainBackground, flexGrow: 1 }} />
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TouchableHighlight onPress={() => this.showBottomSheet('jenis_kelamin')}>
<View style={{ alignItems: 'center', justifyContent: 'space-between', flexDirection: 'row', paddingVertical: 10 }}>
<Text style={{ color: placeholder, fontSize: 15, maxWidth: '94%', minWidth: '94%' }}>Pilih Jenis Kelamin</Text>
<Icon name='sort' size={20} color={'#000'} />
</View>
</TouchableHighlight>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TextInput
style={{ width: '100%' }}
placeholderColor={placeholder}
placeholder='Nama Lengkap'
onChangeText={() => {}}
/>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TouchableHighlight onPress={() => this.showBottomSheet('job_position')}>
<View style={{ alignItems: 'center', justifyContent: 'space-between', flexDirection: 'row', paddingVertical: 10 }}>
<Text style={{ color: placeholder, fontSize: 15, maxWidth: '94%', minWidth: '94%' }}>Pilih Jabatan</Text>
<Icon name='sort' size={20} color={'#000'} />
</View>
</TouchableHighlight>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TextInput
style={{ width: '100%' }}
placeholderColor={placeholder}
placeholder='Nomor Handphone'
onChangeText={() => {}}
/>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', marginVertical: 10 }}>
<TouchableHighlight onPress={ () => {} } underlayColor={'#fff'} activeOpacity={0.5} style={{ width: '100%', justifyContent: 'space-around', alignItems: 'center' }}>
<View style={{ width: '100%', flexDirection: 'row' }}>
<View style={{ justifyContent: 'flex-start', alignItems: 'center', marginHorizontal: 5 }}>
<Icon name='square-o' size={20} color={placeholder} />
</View>
<View style={{ justifyContent: 'flex-start', alignItems: 'center', marginHorizontal: 5 }}>
<Text>Daftar Sebagai EMKL</Text>
</View>
</View>
</TouchableHighlight>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', marginVertical: 10 }}>
<TouchableHighlight onPress={ () => {} } underlayColor={'#fff'} activeOpacity={0.5} style={{ width: '100%' }}>
<View style={{ width: '100%', flexDirection: 'row', paddingHorizontal: 10, justifyContent: 'space-between' }}>
<View style={{ justifyContent: 'flex-start', alignItems: 'center', marginHorizontal: 5, marginTop: 5 }}>
<Icon name='square-o' size={20} color={placeholder} />
</View>
<View style={{ justifyContent: 'flex-start', alignItems: 'center', marginHorizontal: 5 }}>
<Text>Saya telah membaca dan menyetujui Syarat dan Ketentuan, Kebijakan Privasi, dan Persetujuan Pengguna</Text>
</View>
</View>
</TouchableHighlight>
</View>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%' }}>
<TouchableHighlight style={{ width: '90%', backgroundColor: buttonSuccess, alignItems: 'center', justifyContent: 'center', marginBottom: 20 }}>
<Text style={{ fontSize: 15, color: '#fff', fontWeight: 'bold', padding: 10 }}>Daftar</Text>
</TouchableHighlight>
</View>
</View>
<View style={{ position: 'relative', bottom: 0 }}>
<Text style={{ color: '#000', fontSize: 15, marginVertical: 20, alignSelf: 'center' }}>Sudah Punya Akun? <Text style={{ color: mainBlue, fontSize: 15, fontWeight: 'bold' }} onPress={ () => this.goLogin() }>Masuk disini</Text></Text>
</View>
</Content>
<BottomSheet
ref={this.bottomSheetRegisterCompany}
snapPoints={[-1000, width, height*0.9 ]}
initialSnap={0}
renderHeader={() => this.headerBottomSheet()}
renderContent={() => this.contentBottomSheet()}
/>
</Container>
);
}
}
and here is my secon page:
import React, { Component } from 'react';
import { ScrollView, View, Text, Image, TextInput, TouchableHighlight, StatusBar, Dimensions, FlatList } from 'react-native';
import { StackActions, NavigationActions } from 'react-navigation';
import { Container, Content } from 'native-base';
import { BarPasswordStrengthDisplay } from 'react-native-password-strength-meter';
import BottomSheet from 'reanimated-bottom-sheet';
import Icon from 'react-native-vector-icons/FontAwesome';
import { LOGO } from '../../../assets/img';
import { placeholder, buttonSuccess, mainBlue, mainBackground } from '../../../assets/ColorIndex';
const {width, height} = Dimensions.get('screen');
export default class RegisterSupplierScreen extends Component {
constructor(props) {
super(props);
this.bottomSheetRegisterSupplier = React.createRef();
this.goRegister = this._goRegister.bind(this);
this.goLogin = this._goLogin.bind(this);
this.showBottomSheet = this._showBottomSheets.bind(this);
this.headerBottomSheet = this._renderHeader.bind(this);
this.contentBottomSheet = this._renderContent.bind(this);
this.renderItem = this._renderItem.bind(this);
}
_goRegister() {
this.props.navigation.dispatch(StackActions.reset({ index: 0, actions: [ NavigationActions.navigate({ routeName: 'Register' }) ] }));
}
_goLogin() {
this.props.navigation.dispatch(StackActions.reset({ index: 0, actions: [ NavigationActions.navigate({ routeName: 'Login' }) ] }));
}
_renderHeader() {
const { bottomSheetActive } = this.props.registerSupplier;
switch(bottomSheetActive){
case 'bussiness_entity':
return (
<View style={{ justifyContent: 'space-around', alignItems: 'center', backgroundColor: mainBackground }}>
<View style={{ height: 5, width: width*0.2, borderRadius: 20, backgroundColor: placeholder, marginVertical: 10 }} />
<Text style={{ fontWeight: 'bold', fontSize: 18, marginBottom: 5 }}>Pilih Badan Usaha</Text>
</View>
);
case 'province':
return (
<View style={{ justifyContent: 'space-around', alignItems: 'center', backgroundColor: mainBackground }}>
<View style={{ height: 5, width: width*0.2, borderRadius: 20, backgroundColor: placeholder, marginVertical: 10 }} />
<Text style={{ fontWeight: 'bold', fontSize: 18, marginBottom: 5 }}>Pilih Provinsi</Text>
</View>
);
case 'city':
return (
<View style={{ justifyContent: 'space-around', alignItems: 'center', backgroundColor: mainBackground }}>
<View style={{ height: 5, width: width*0.2, borderRadius: 20, backgroundColor: placeholder, marginVertical: 10 }} />
<Text style={{ fontWeight: 'bold', fontSize: 18, marginBottom: 5 }}>Pilih Kota</Text>
</View>
);
case 'district':
return (
<View style={{ justifyContent: 'space-around', alignItems: 'center', backgroundColor: mainBackground }}>
<View style={{ height: 5, width: width*0.2, borderRadius: 20, backgroundColor: placeholder, marginVertical: 10 }} />
<Text style={{ fontWeight: 'bold', fontSize: 18, marginBottom: 5 }}>Pilih Kecamatan</Text>
</View>
);
case 'bussiness_industry':
return (
<View style={{ justifyContent: 'space-around', alignItems: 'center', backgroundColor: mainBackground }}>
<View style={{ height: 5, width: width*0.2, borderRadius: 20, backgroundColor: placeholder, marginVertical: 10 }} />
<Text style={{ fontWeight: 'bold', fontSize: 18, marginBottom: 5 }}>Pilih Bisnis Industri</Text>
</View>
);
case 'jenis_kelamin':
return (
<View style={{ justifyContent: 'space-around', alignItems: 'center', backgroundColor: mainBackground }}>
<View style={{ height: 5, width: width*0.2, borderRadius: 20, backgroundColor: placeholder, marginVertical: 10 }} />
<Text style={{ fontWeight: 'bold', fontSize: 18, marginBottom: 5 }}>Pilih Jenis Kelamin</Text>
</View>
);
case 'job_position':
return (
<View style={{ justifyContent: 'space-around', alignItems: 'center', backgroundColor: mainBackground }}>
<View style={{ height: 5, width: width*0.2, borderRadius: 20, backgroundColor: placeholder, marginVertical: 10 }} />
<Text style={{ fontWeight: 'bold', fontSize: 18, marginBottom: 5 }}>Pilih Jabatan</Text>
</View>
);
}
}
_renderContent(){
const { bottomSheetActive } = this.props.registerSupplier;
const { bussinessEntities, bussinessIndustries, provinces, cities, districts, jenisKelamin, jobPositions } = this.props.masterData;
switch(bottomSheetActive){
case 'bussiness_entity':
return (
<View style={{ backgroundColor: mainBackground, height: Math.max(bussinessEntities.length*45+15, 40), minHeight: height*0.9 }}>
<FlatList
keyExtractor={item => `bussinessEntities-${item.id}`}
renderItem={({item}) => this.renderItem(item)}
data={bussinessEntities}
scrollEnabled={false}
/>
</View>
);
case 'bussiness_industry':
return (
<View style={{ backgroundColor: mainBackground, height: Math.max(bussinessIndustries.length*45+15, 40), minHeight: height*0.9 }}>
<FlatList
keyExtractor={item => `bussinessIndustries-${item.id}`}
renderItem={({item}) => this.renderItem(item)}
data={bussinessIndustries}
scrollEnabled={false}
/>
</View>
);
case 'province':
return (
<View style={{ backgroundColor: mainBackground, height: Math.max(provinces.length*45+15, 40), minHeight: height*0.9 }}>
<FlatList
keyExtractor={item => `provinces-${item.id}`}
renderItem={({item}) => this.renderItem(item)}
data={provinces}
scrollEnabled={false}
/>
</View>
);
case 'city':
return (
<View style={{ backgroundColor: mainBackground, height: Math.max(cities.length*45+15, 40), minHeight: height*0.9 }}>
<FlatList
keyExtractor={item => `cities-${item.id}`}
renderItem={({item}) => this.renderItem(item)}
data={cities}
scrollEnabled={false}
/>
</View>
);
case 'district':
return (
<View style={{ backgroundColor: mainBackground, height: Math.max(districts.length*45+15, 40), minHeight: height*0.9 }}>
<FlatList
keyExtractor={item => `districts-${item.id}`}
renderItem={({item}) => this.renderItem(item)}
data={districts}
scrollEnabled={false}
/>
</View>
);
case 'jenis_kelamin':
return (
<View style={{ backgroundColor: mainBackground, height: Math.max(jenisKelamin.length*45+15, 40), minHeight: height*0.9 }}>
<FlatList
keyExtractor={item => `jenisKelamin-${item.id}`}
renderItem={({item}) => this.renderItem(item)}
data={jenisKelamin}
scrollEnabled={false}
/>
</View>
);
case 'job_position':
return (
<View style={{ backgroundColor: mainBackground, height: Math.max(jobPositions.length*45+15, 40), minHeight: height*0.9 }}>
<FlatList
keyExtractor={item => `jobPositions-${item.id}`}
renderItem={({item}) => this.renderItem(item)}
data={jobPositions}
scrollEnabled={false}
/>
</View>
);
}
}
_renderItem(item) {
return (
<TouchableHighlight style={{ padding: 10 }}>
<View style={{ justifyContent: 'space-between', alignItems: 'center', flexDirection: 'row' }}>
<View style={{ justifyContent: 'flex-start', alignItems: 'flex-start', paddingHorizontal: 10 }}>
<Text style={{ fontWeight: 'bold', fontSize: 18 }}>{item.name}</Text>
</View>
<Icon name='circle-o' size={20} color={mainBlue} />
</View>
</TouchableHighlight>
);
}
async _showBottomSheets(type, withContent = true) {
const _type = type.toLowerCase();
// const {provinceValue, cityValue} = this.props.registerSupplier
switch(_type){
case 'bussiness_entity':
if(withContent){
await this.props.getBussinessEntities();
}
break;
case 'bussiness_industry':
if(withContent){
await this.props.getBussinessIndustries();
}
break;
case 'province':
if(withContent){
await this.props.getProvinces();
}
break;
case 'city':
if(withContent){
// await this.props.getCitiesByProvince(provinceValue.id);
}
break;
case 'district':
if(withContent){
// await this.props.getDistrictsByCity(cityValue.id);
}
break;
case 'position':
if(withContent){
await this.props.getJobPositions();
}
break;
}
await this.props.setBottomSheetLoading(_type, true);
this.bottomSheetRegisterSupplier.current.snapTo(1);
console.warn('after '+this.props.registerSupplier.bottomSheetActive);
}
componentDidMount() {
this.props.clearProps();
}
render() {
return (
<Container style={{ backgroundColor: mainBackground, justifyContent: 'center' }}>
<StatusBar backgroundColor={mainBlue} barStyle={'light-content'} />
<Content>
<View style={{ alignItems: 'center', justifyContent: 'center', height: 100 }}>
<Image source={LOGO} resizeMode='contain' style={{ width: '20%' }} />
</View>
<View
style={{
alignItems: 'center',
alignSelf: 'center',
justifyContent: 'space-around',
backgroundColor: '#fff',
padding: 10,
width: '90%'
}}
>
<View style={{ alignItems: 'center', width: '100%', marginBottom: 20 }}>
<Text style={{ fontSize: 20, fontWeight: 'bold', alignSelf: 'center', marginVertical: 15, color: '#000' }}>Daftar Sebagai Supplier</Text>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TouchableHighlight onPress={() => this.showBottomSheet('bussiness_entity') }>
<View style={{ alignItems: 'center', justifyContent: 'space-between', flexDirection: 'row', paddingVertical: 10 }}>
<Text style={{ color: placeholder, fontSize: 15, maxWidth: '94%', minWidth: '94%' }}>Pilih Badan Usaha</Text>
<Icon name='sort' size={20} color={'#000'} />
</View>
</TouchableHighlight>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TextInput
style={{ width: '100%' }}
placeholderColor={placeholder}
placeholder='Nama Perusahaan'
onChangeText={() => {}}
/>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TextInput
style={{ width: '100%' }}
placeholderColor={placeholder}
placeholder='NPWP Perusahaan'
onChangeText={() => {}}
/>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TextInput
style={{ width: '100%' }}
placeholderColor={placeholder}
placeholder='Alamat Perusahaan'
onChangeText={() => {}}
/>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TouchableHighlight onPress={() => this.showBottomSheet('province')}>
<View style={{ alignItems: 'center', justifyContent: 'space-between', flexDirection: 'row', paddingVertical: 10 }}>
<Text style={{ color: placeholder, fontSize: 15, maxWidth: '94%', minWidth: '94%' }}>Pilih Provinsi</Text>
<Icon name='sort' size={20} color={'#000'} />
</View>
</TouchableHighlight>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TouchableHighlight onPress={() => this.showBottomSheet('city')} disabled={true}>
<View style={{ alignItems: 'center', justifyContent: 'space-between', flexDirection: 'row', paddingVertical: 10 }}>
<Text style={{ color: placeholder, fontSize: 15, maxWidth: '94%', minWidth: '94%' }}>Pilih Kota</Text>
<Icon name='sort' size={20} color={'#000'} />
</View>
</TouchableHighlight>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TouchableHighlight onPress={() => this.showBottomSheet('district')} disabled={true}>
<View style={{ alignItems: 'center', justifyContent: 'space-between', flexDirection: 'row', paddingVertical: 10 }}>
<Text style={{ color: placeholder, fontSize: 15, maxWidth: '94%', minWidth: '94%' }}>Pilih Kecamatan</Text>
<Icon name='sort' size={20} color={'#000'} />
</View>
</TouchableHighlight>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TouchableHighlight onPress={() => this.showBottomSheet('bussiness_industry')}>
<View style={{ alignItems: 'center', justifyContent: 'space-between', flexDirection: 'row', paddingVertical: 10 }}>
<Text style={{ color: placeholder, fontSize: 15, maxWidth: '94%', minWidth: '94%' }}>Pilih Bisnis Industri</Text>
<Icon name='sort' size={20} color={'#000'} />
</View>
</TouchableHighlight>
</View>
<View style={{ width: '100%', height: 50, marginVertical: 10, flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }}>
<View style={{ borderBottomWidth: 2, borderBottomColor: mainBackground, flexGrow: 1 }} />
<Text style={{ fontSize: 20, fontWeight: 'bold', paddingHorizontal: 10 }}>Data Akun</Text>
<View style={{ borderBottomWidth: 2, borderBottomColor: mainBackground, flexGrow: 1 }} />
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TextInput
style={{ width: '100%' }}
placeholderColor={placeholder}
placeholder='Email'
onChangeText={() => {}}
/>
</View>
<View style={{ alignItems: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<View style={{ alignItems: 'center', flexDirection: 'row', width: '100%' }}>
<TextInput
style={{ width: '90%' }}
placeholderColor={placeholder}
placeholder='Kata Sandi'
secureTextEntry={!this.props.registerSupplier.showPassword}
onChangeText={() => {}}
/>
<TouchableHighlight onPress={ () => {} } underlayColor={'#fff'} activeOpacity={0.5}>
{
this.props.registerSupplier.showPassword ?
<Icon name='eye-slash' size={20} color={mainBlue} />
:
<Icon name='eye' size={20} color={mainBlue} />
}
</TouchableHighlight>
</View>
<BarPasswordStrengthDisplay password={this.props.registerSupplier.password} width={width - 65} wrapperStyle={{ marginVertical: 10 }} />
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TextInput
style={{ width: '100%' }}
placeholderColor={placeholder}
placeholder='Konfirmasi Kata Sandi'
secureTextEntry={!this.props.registerSupplier.showPassword}
onChangeText={() => {}}
/>
</View>
<View style={{ width: '100%', height: 50, marginVertical: 10, flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }}>
<View style={{ borderBottomWidth: 2, borderBottomColor: mainBackground, flexGrow: 1 }} />
<Text style={{ fontSize: 20, fontWeight: 'bold', paddingHorizontal: 10 }}>Penanggung Jawab</Text>
<View style={{ borderBottomWidth: 2, borderBottomColor: mainBackground, flexGrow: 1 }} />
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TouchableHighlight onPress={() => this.showBottomSheet('jenis_kelamin')}>
<View style={{ alignItems: 'center', justifyContent: 'space-between', flexDirection: 'row', paddingVertical: 10 }}>
<Text style={{ color: placeholder, fontSize: 15, maxWidth: '94%', minWidth: '94%' }}>Pilih Jenis Kelamin</Text>
<Icon name='sort' size={20} color={'#000'} />
</View>
</TouchableHighlight>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TextInput
style={{ width: '100%' }}
placeholderColor={placeholder}
placeholder='Nama Lengkap'
onChangeText={() => {}}
/>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TouchableHighlight onPress={() => this.showBottomSheet('job_position')}>
<View style={{ alignItems: 'center', justifyContent: 'space-between', flexDirection: 'row', paddingVertical: 10 }}>
<Text style={{ color: placeholder, fontSize: 15, maxWidth: '94%', minWidth: '94%' }}>Pilih Jabatan</Text>
<Icon name='sort' size={20} color={'#000'} />
</View>
</TouchableHighlight>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TextInput
style={{ width: '100%' }}
placeholderColor={placeholder}
placeholder='Nomor Handphone'
onChangeText={() => {}}
/>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TextInput
style={{ width: '100%' }}
placeholderColor={placeholder}
placeholder='Nomor Telepon'
onChangeText={() => {}}
/>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', borderBottomColor: mainBackground, borderBottomWidth: 1 }}>
<TextInput
style={{ width: '100%' }}
placeholderColor={placeholder}
placeholder='Nomor Fax'
onChangeText={() => {}}
/>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', marginVertical: 10 }}>
<TouchableHighlight onPress={ () => {} } underlayColor={'#fff'} activeOpacity={0.5} style={{ width: '100%', justifyContent: 'space-around', alignItems: 'center' }}>
<View style={{ width: '100%', flexDirection: 'row' }}>
<View style={{ justifyContent: 'flex-start', alignItems: 'center', marginHorizontal: 5 }}>
<Icon name='square-o' size={20} color={placeholder} />
</View>
<View style={{ justifyContent: 'flex-start', alignItems: 'center', marginHorizontal: 5 }}>
<Text>PKP ( Perusahaan Kena Pajak )</Text>
</View>
</View>
</TouchableHighlight>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%', marginVertical: 10 }}>
<TouchableHighlight onPress={ () => {} } underlayColor={'#fff'} activeOpacity={0.5} style={{ width: '100%', justifyContent: 'space-around', alignItems: 'center' }}>
<View style={{ width: '100%', flexDirection: 'row' }}>
<View style={{ justifyContent: 'flex-start', alignItems: 'center', marginHorizontal: 5 }}>
<Icon name='square-o' size={20} color={placeholder} />
</View>
<View style={{ justifyContent: 'flex-start', alignItems: 'center', marginHorizontal: 5 }}>
<Text>Saya telah membaca dan menyetujui Syarat dan Ketentuan, Kebijakan Privasi, dan Persetujuan Pengguna </Text>
</View>
</View>
</TouchableHighlight>
</View>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center', width: '100%' }}>
<TouchableHighlight style={{ width: '90%', backgroundColor: buttonSuccess, alignItems: 'center', justifyContent: 'center', marginBottom: 20 }}>
<Text style={{ fontSize: 15, color: '#fff', fontWeight: 'bold', padding: 10 }}>Daftar</Text>
</TouchableHighlight>
</View>
</View>
<View style={{ position: 'relative', bottom: 0 }}>
<Text style={{ color: '#000', fontSize: 15, marginVertical: 20, alignSelf: 'center' }}>Sudah Punya Akun? <Text style={{ color: mainBlue, fontSize: 15, fontWeight: 'bold' }} onPress={ () => this.goLogin() }>Masuk disini</Text></Text>
</View>
<BottomSheet
ref={this.bottomSheetRegisterSupplier}
snapPoints={[0, width, height*0.9 ]}
renderHeader={() => this.headerBottomSheet()}
renderContent={() => this.contentBottomSheet()}
/>
</Content>
</Container>
);
}
}
I hope it can solved/closed ASAP.
cheers
Hi there,
I'm thinking of setting up some unit tests for this package. I decided to create an issue because I wasn't sure if someone is already working on this or not.
If you would like me to do it, then please upvote.
Otherwise, close it if it's in progress by someone else or not needed.
It started jumping sometimes and sth is wrong with sorting snap points
Created a snack: https://snack.expo.io/SkCT567t4
On android, the content elements of bottom sheet don't execute "onPress" when clicked. For some reason it still launches the ripple effect. It's all okay on iOS. Another thing is it works on long press.
Versions: alpha 3-8
Any ideas?
Hi dear,
I am using it in 0.60. i put enabledGestureInteraction true. but i am not able sliding up/donw. any help. thanks,
I would like the closed sheet to have height of 124. However, I need to fetch data to see how high the content will be, and once I update the state to update the snapPoints, the sheet no longer snaps to 124.
Could you support updating snapPoints by ref?
Inside render:
` var snapPoints = [];
var closedIndex = 0;
if (this.state.height != "60%" && this.state.height < 124) {
snapPoints = [124, this.state.height];
} else {
snapPoints = [this.state.height, 124];
closedIndex = 1;
}
return (
<Container style={{ flex: 1 }}>
<BottomSheet
renderContent={this.renderSheetContent.bind(this)}
renderHeader={this.renderSheetHeader.bind(this)}
snapPoints={snapPoints}
initialSnap={closedIndex}
ref={this._bottomSheet}
/>
</Container>`
Hey! Great lib!
Is it possible to add a FlatList to content and use that scroll position when the bottom sheet should expand or not?
Like the apple map, when the list is in the top and you move upwards, the sheat goes up. but when you scroll down the sheet stays until the user scroll to the top of the list within.
Is it possible to hook up using this or should I go custom with reanimates and gesture handler?
When I use Bottomsheet
in a screen, In a very random manner, I am unable to type any thing in a TextInput
and also sometimes unable to tap the touchables in that particular screen. This is only happening on Android.
I have to re-open the app to make it work fine again and also sometimes I have to clear the data and open again.
When not using BottomSheet, this error doesn't occur.
I am not sure if this is issue with the bottomsheet, but if you have faced this before with anything, please do let me know.
It doesn't appear that the position of the sheet changes if the snapPoints
props are changed. Is there any way to make this work? Or is that not supported?
It would be nice to have the positions be dynamic based on content heights, where the snapPoints
are defined from state values set in onLayout
callbacks of the sheet elements.
This project is great and shows a lot of promise, but currently, there is no way to read the current index of the sheet and wanted to propose a feature to read this state
Perhaps we can add a function prop onIndexChange(prev, current)
that the user would pass in that would get called anytime the current index changes.
It'd be nice to have an option to allow you to drag past the highest snap point, but gesture translation past that snap point shouldn't result in 1:1 translation of the sheet, so it feels like there is some resistance. On release it should then bounce back to the highest snap point.
If you over-drag and the content is scrollable for as far as you can over-drag, you should see more of the scrollable content appear. (nevermind, it actually should just continue into scroll at the snap point)
If the content is not scrollable, we will need to have some way to style the area that is visible below 'content'. I'm bad at explaining so let's just look at a video. Notice that it's not scrollable, and the sheet style continues when we over-drag.
Here is my problem:
snapTo
snapTo
no longer worksI debugged the issue shallowly, and I think the problem is that when the screen gets pushed above bottom sheet, panMasterState
is set to CANCELLED
and never comes back to END
(unless dragged manually).
I was able to hack my way around this by overriding panMasterState
. It seems to work, but I need to test it more. I think proper handling of CANCELLED
state is required, because it's as valid outcome of gesture handling flow as END
this.translateMaster = block([
// TODO: this is a HACK
cond(
eq(this.panMasterState, GestureState.CANCELLED),
set(this.panMasterState, GestureState.END),
),
// END OF HACK
cond(
eq(this.panMasterState, GestureState.END),
Setting snapPoints={['50%', '10%']}
causes the component to throw the following exception:
Exception thrown while executing UI block: -[NSNull doubleValue]: unrecognized selector sent to instance 0x10ca14f28
__44-[RCTUIManager flushUIBlocksWithCompletion:]_block_invoke
RCTUIManager.m:1114
__44-[RCTUIManager flushUIBlocksWithCompletion:]_block_invoke.544
__RCTExecuteOnMainQueue_block_invoke
_dispatch_call_block_and_release
_dispatch_client_callout
_dispatch_main_queue_callback_4CF
__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
__CFRunLoopRun
CFRunLoopRunSpecific
GSEventRunModal
UIApplicationMain
main
start
React Native Environment Info:
System:
OS: macOS 10.14.2
CPU: x64 Intel(R) Core(TM) i7-7820HQ CPU @ 2.90GHz
Memory: 27.74 MB / 16.00 GB
Shell: 5.3 - /bin/zsh
Binaries:
Node: 8.12.0 - ~/.nvm/versions/node/v8.12.0/bin/node
Yarn: 1.6.0 - /usr/local/bin/yarn
npm: 6.4.1 - ~/.nvm/versions/node/v8.12.0/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 12.1, macOS 10.14, tvOS 12.1, watchOS 5.1
Android SDK:
Build Tools: 26.0.3, 27.0.3, 28.0.2, 28.0.3
API Levels: 21, 22, 23, 24, 25, 26, 27
IDEs:
Android Studio: 3.1 AI-173.4907809
Xcode: 10.1/10B61 - /usr/bin/xcodebuild
npmPackages:
react: 16.6.3 => 16.6.3
react-native: 0.57.8 => 0.57.8
npmGlobalPackages:
react-native-log-ios: 1.0.1
Workaround: use numbers for now.
First of all, ty for this library ;)
I have issue probably related to #15 . When i try to render TextInput in header (renderHeader) it is means that snapTo() broken
renderBottomSheetHeader = () => (
<View style={styles.sheetHeaderContainer}>
<Marker />
<Search
onChangeText={() => {}}
/>
</View>
);
const Search = () => {
return (
<View style={style || styles.searchContainer}>
<TextInput
{...inputProps}
style={styles.searchInput}
placeholder={l10n.searchPlaceholder}
placeholderTextColor={constants.defaultIconColor}
underlineColorAndroid={'transparent'}
onChangeText={(text) => {
this.setState({ message: text });
this.onChangeTextDelayed(text);
}}
value={this.state.message}
multiline={false}
/>
</View>
);
It is also reproduce with TextInput from react-native-gesture-handler
trying to slide up but not working.
<View style={{flex:1,backgroundColor:'#fff',height:'100%'}}>
<BottomSheet
snapPoints = {[450,200]}
renderContent = {this.renderInner}
renderHeader = {this.renderHeader}
initialSnap={1}
/>
<Animated.View style={{ alignItems: 'center', opacity: Animated.add(0.1, Animated.multiply(this.fall, 0.9)) }}>
{this.map()}
</Animated.View>
</View>
I'm using the latest version as of today alpha.8
and react-native 59.5
and the exact same code I had before the upgrade now does not render anything anymore on both iOS and Android 😢 😭
I get no errors or warnings 😮
I've tried all released alpha versions 3,4,5,6,7,8.
Has anyone got this library working with the latest react-native 59.5?
I've changed the BottomSheet to just use defaults for everything and still can't get it to render anything. I'm using it just like this:
<BottomSheet
snapPoints={[
100,
200,
]}
initialSnap={1}
renderContent={() =>
<View><Text>Hello Header!</Text></View>
}
renderHeader={() => <View><Text>Hello Content!</Text></View>}
/>
I can't provide a link because expo doesn't use latest RN 59.5 atm.
React Native Environment Info:
System:
OS: macOS 10.14.4
CPU: x64 Intel(R) Core(TM) i7-7820HQ CPU @ 2.90GHz
Memory: 1018.41 MB / 16.00 GB
Shell: 5.3 - /bin/zsh
Binaries:
Node: 8.12.0 - ~/.nvm/versions/node/v8.12.0/bin/node
Yarn: 1.6.0 - /usr/local/bin/yarn
npm: 6.4.1 - ~/.nvm/versions/node/v8.12.0/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 12.2, macOS 10.14, tvOS 12.2, watchOS 5.2
Android SDK:
Build Tools: 26.0.3, 27.0.3, 28.0.2, 28.0.3
API Levels: 21, 22, 23, 24, 25, 26, 27, 28
IDEs:
Android Studio: 3.1 AI-173.4907809
Xcode: 10.2.1/10E1001 - /usr/bin/xcodebuild
npmPackages:
react: 16.8.3 => 16.8.3
react-native: 0.59.5 => 0.59.5
npmGlobalPackages:
react-native-log-ios: 1.0.1
Send help plz 👍 🙏
I want to render components in bottomsheet dynamically. For example, I have a list of vendors which I can follow or unfollow. A user can follow the vendor by clicking Follow button inside bottomsheet. The button will change to Unfollow now when the user opens bottomsheet.
I know, we can use states to manage the content inside bottomsheet.
How would you perform this behavior also minimizing the number of renders ?
Hi. Great component! This is working fantastic so far. One thing I haven't figure out is a way to easily dismiss it when tapping outside of the sheet. I can easily dismiss it programmatically by using snapTo(index)
however when the sheet is raised I am not sure how to intercept these taps to prevent it from tapping on content underneath.
Thank you!
I spent all morning debugging - please add to docs that snapPoints array must be descending. If ascending nothing works and you lose hours of your life staring in to the darkness that is despair because 'nothing makes sense.' Ty.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.