[RN] Refactor SideBar layout and animation (coding style)
This commit is contained in:
parent
c700261852
commit
c6d553738f
|
@ -1,11 +1,7 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import React, { Component, type Node } from 'react';
|
import React, { Component, type Node } from 'react';
|
||||||
import {
|
import { Animated, TouchableWithoutFeedback, View } from 'react-native';
|
||||||
Animated,
|
|
||||||
TouchableWithoutFeedback,
|
|
||||||
View
|
|
||||||
} from 'react-native';
|
|
||||||
|
|
||||||
import styles, { SIDEBAR_WIDTH } from './styles';
|
import styles, { SIDEBAR_WIDTH } from './styles';
|
||||||
|
|
||||||
|
@ -15,21 +11,21 @@ import styles, { SIDEBAR_WIDTH } from './styles';
|
||||||
type Props = {
|
type Props = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The children of the Component
|
* The children of {@code SideBar}.
|
||||||
*/
|
*/
|
||||||
children: Node,
|
children: Node,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback to notify the containing Component that the sidebar is
|
* Callback to notify the containing {@code Component} that the sidebar is
|
||||||
* closing.
|
* closing.
|
||||||
*/
|
*/
|
||||||
onHide: Function,
|
onHide: Function,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the menu displayed or hidden.
|
* Whether the menu (of the {@code SideBar}?) is displayed/rendered/shown.
|
||||||
*/
|
*/
|
||||||
show: boolean
|
show: boolean
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of the React {@code Component} state of {@link SideBar}.
|
* The type of the React {@code Component} state of {@link SideBar}.
|
||||||
|
@ -37,18 +33,18 @@ type Props = {
|
||||||
type State = {
|
type State = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether the side overlay should be rendered or not.
|
* Whether the side overlay should be displayed/rendered/shown.
|
||||||
*/
|
*/
|
||||||
showOverlay: boolean,
|
showOverlay: boolean,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The native animation object.
|
* The native animation object.
|
||||||
*/
|
*/
|
||||||
sliderAnimation: Object
|
sliderAnimation: Animated.Value
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A generic animated side bar to be used for left side menus
|
* A generic animated side bar to be used for left-side, hamburger-style menus.
|
||||||
*/
|
*/
|
||||||
export default class SideBar extends Component<Props, State> {
|
export default class SideBar extends Component<Props, State> {
|
||||||
/**
|
/**
|
||||||
|
@ -64,11 +60,12 @@ export default class SideBar extends Component<Props, State> {
|
||||||
sliderAnimation: new Animated.Value(0)
|
sliderAnimation: new Animated.Value(0)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Bind event handlers so they are only bound once per instance.
|
||||||
this._onHideMenu = this._onHideMenu.bind(this);
|
this._onHideMenu = this._onHideMenu.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements the Component's componentDidMount method.
|
* Implements React's {@link Component#componentDidMount()}.
|
||||||
*
|
*
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
|
@ -77,14 +74,12 @@ export default class SideBar extends Component<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements the Component's componentWillReceiveProps method.
|
* Implements React's {@link Component#componentWillReceiveProps()}.
|
||||||
*
|
*
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
componentWillReceiveProps(newProps: Props) {
|
componentWillReceiveProps({ show }: Props) {
|
||||||
if (newProps.show !== this.props.show) {
|
(show === this.props.show) || this._setShow(show);
|
||||||
this._setShow(newProps.show);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -120,17 +115,16 @@ export default class SideBar extends Component<Props, State> {
|
||||||
* @returns {Array<Object>}
|
* @returns {Array<Object>}
|
||||||
*/
|
*/
|
||||||
_getContentStyle() {
|
_getContentStyle() {
|
||||||
const { sliderAnimation } = this.state;
|
return [
|
||||||
const transformStyle
|
styles.sideMenuContent,
|
||||||
= { transform: [ { translateX: sliderAnimation } ] };
|
{ transform: [ { translateX: this.state.sliderAnimation } ] }
|
||||||
|
];
|
||||||
return [ styles.sideMenuContent, transformStyle ];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_onHideMenu: () => void;
|
_onHideMenu: () => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hides the menu.
|
* Hides the side menu.
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
|
@ -146,28 +140,30 @@ export default class SideBar extends Component<Props, State> {
|
||||||
_setShow: (boolean) => void;
|
_setShow: (boolean) => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the side menu visible or hidden.
|
* Shows/hides the side menu.
|
||||||
*
|
*
|
||||||
* @param {boolean} show - The new expected visibility value.
|
* @param {boolean} show - If the side menu is to be made visible,
|
||||||
|
* {@code true}; otherwise, {@code false}.
|
||||||
* @private
|
* @private
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
_setShow(show) {
|
_setShow(show) {
|
||||||
if (show) {
|
show && this.setState({ showOverlay: true });
|
||||||
this.setState({ showOverlay: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
Animated
|
Animated
|
||||||
.timing(
|
.timing(
|
||||||
this.state.sliderAnimation,
|
/* value */ this.state.sliderAnimation,
|
||||||
{
|
/* config */ {
|
||||||
toValue: show ? SIDEBAR_WIDTH : 0,
|
toValue: show ? SIDEBAR_WIDTH : 0,
|
||||||
useNativeDriver: true
|
useNativeDriver: true
|
||||||
})
|
})
|
||||||
.start(animationState => {
|
.start(({ finished }) => {
|
||||||
if (animationState.finished && !show) {
|
finished && !show && this.setState({ showOverlay: false });
|
||||||
this.setState({ showOverlay: false });
|
|
||||||
}
|
// XXX Technically, the arrow function can further be simplified
|
||||||
|
// by removing the {} and returning the boolean expression
|
||||||
|
// above. Practically and unfortunately though, Flow freaks out
|
||||||
|
// and states that Animated.timing doesn't exist!?
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
import { StyleSheet } from 'react-native';
|
import { StyleSheet } from 'react-native';
|
||||||
|
|
||||||
import {
|
import { BoxModel, ColorPalette, createStyleSheet } from '../../../styles';
|
||||||
BoxModel,
|
|
||||||
ColorPalette,
|
|
||||||
createStyleSheet
|
|
||||||
} from '../../../styles';
|
|
||||||
|
|
||||||
const AVATAR_OPACITY = 0.4;
|
const AVATAR_OPACITY = 0.4;
|
||||||
const AVATAR_SIZE = 65;
|
const AVATAR_SIZE = 65;
|
||||||
|
@ -21,7 +19,7 @@ export const UNDERLAY_COLOR = 'rgba(255, 255, 255, 0.2)';
|
||||||
|
|
||||||
const HEADER_STYLES = {
|
const HEADER_STYLES = {
|
||||||
/**
|
/**
|
||||||
* Platform specific header button (e.g. back, menu...etc).
|
* Platform specific header button (e.g. back, menu, etc).
|
||||||
*/
|
*/
|
||||||
headerButton: {
|
headerButton: {
|
||||||
alignSelf: 'center',
|
alignSelf: 'center',
|
||||||
|
@ -57,7 +55,7 @@ const HEADER_STYLES = {
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base style of Header
|
* Base style of Header.
|
||||||
*/
|
*/
|
||||||
screenHeader: {
|
screenHeader: {
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
|
@ -293,8 +291,8 @@ const SIDEBAR_STYLES = {
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The opaque area that covers the rest of the screen, when
|
* The opaque area that covers the rest of the screen, when the side bar is
|
||||||
* the side bar is open.
|
* open.
|
||||||
*/
|
*/
|
||||||
sideMenuShadow: {
|
sideMenuShadow: {
|
||||||
...StyleSheet.absoluteFillObject,
|
...StyleSheet.absoluteFillObject,
|
||||||
|
@ -303,8 +301,8 @@ const SIDEBAR_STYLES = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The styles of the React {@code Components} of the generic components
|
* The styles of the generic React {@code Component}s implemented by the feature
|
||||||
* in the app.
|
* base/react.
|
||||||
*/
|
*/
|
||||||
export default createStyleSheet({
|
export default createStyleSheet({
|
||||||
...HEADER_STYLES,
|
...HEADER_STYLES,
|
||||||
|
|
Loading…
Reference in New Issue