rn: refactor BottomSheet

Avoid using a Modal since those create trouble with the view hierarchy.
This commit is contained in:
Saúl Ibarra Corretgé 2019-04-24 13:05:14 +02:00 committed by Zoltan Bettenbuk
parent 89719520e2
commit 70dc22c107
3 changed files with 29 additions and 62 deletions

View File

@ -1,10 +1,10 @@
// @flow
import React, { Component, type Node } from 'react';
import { TouchableWithoutFeedback, View } from 'react-native';
import React, { PureComponent, type Node } from 'react';
import { SafeAreaView, View } from 'react-native';
import { ColorSchemeRegistry } from '../../../color-scheme';
import { Modal } from '../../../react';
import { SlidingView } from '../../../react';
import { connect } from '../../../redux';
import { StyleType } from '../../../styles';
@ -33,19 +33,22 @@ type Props = {
};
/**
* A component emulating Android's BottomSheet. For all intents and purposes,
* this component has been designed to work and behave as a {@code Dialog}.
* A component emulating Android's BottomSheet.
*/
class BottomSheet extends Component<Props> {
class BottomSheet extends PureComponent<Props> {
/**
* Initializes a new {@code BottomSheet} instance.
* Assembles a style for the BottomSheet container.
*
* @inheritdoc
* @private
* @returns {StyleType}
*/
constructor(props: Props) {
super(props);
_getContainerStyle() {
const { _styles } = this.props;
this._onCancel = this._onCancel.bind(this);
return {
...styles.container,
backgroundColor: _styles.sheet.backgroundColor
};
}
/**
@ -57,39 +60,19 @@ class BottomSheet extends Component<Props> {
render() {
const { _styles } = this.props;
return [
<View
key = 'overlay'
style = { styles.overlay } />,
<Modal
key = 'modal'
onRequestClose = { this._onCancel }
visible = { true }>
<View style = { styles.container }>
<TouchableWithoutFeedback
onPress = { this._onCancel } >
<View style = { styles.backdrop } />
</TouchableWithoutFeedback>
return (
<SlidingView
onHide = { this.props.onCancel }
position = 'bottom'
show = { true }>
<SafeAreaView
style = { this._getContainerStyle() }>
<View style = { _styles.sheet }>
{ this.props.children }
</View>
</View>
</Modal>
];
}
_onCancel: () => void;
/**
* Cancels the dialog by calling the onCancel prop callback.
*
* @private
* @returns {void}
*/
_onCancel() {
const { onCancel } = this.props;
onCancel && onCancel();
</SafeAreaView>
</SlidingView>
);
}
}

View File

@ -28,31 +28,14 @@ export const PLACEHOLDER_COLOR = ColorPalette.lightGrey;
* {@link https://material.io/guidelines/components/bottom-sheets.html}.
*/
export const bottomSheetStyles = createStyleSheet({
/**
* Style for a backdrop which dims the view in the background. This view
* will also be clickable. The backgroundColor is applied to the overlay
* view instead, so the modal animation doesn't affect the backdrop.
*/
backdrop: {
...StyleSheet.absoluteFillObject
},
/**
* Style for the container of the sheet.
*/
container: {
alignItems: 'flex-end',
flex: 1,
flexDirection: 'row',
justifyContent: 'center'
},
/**
* Style for an overlay on top of which the sheet will be displayed.
*/
overlay: {
...StyleSheet.absoluteFillObject,
backgroundColor: 'rgba(127, 127, 127, 0.6)'
bottom: 0,
left: 0,
position: 'absolute',
right: 0
}
});

View File

@ -162,6 +162,7 @@ export default class SlidingView extends PureComponent<Props, State> {
<View style = { styles.sliderViewShadow } />
</TouchableWithoutFeedback>
<Animated.View
pointerEvents = 'box-none'
style = { this._getContentStyle() }>
{ this.props.children }
</Animated.View>