From 87aa6ac3be9de3cd71910a58b774943e7a2b1f9f Mon Sep 17 00:00:00 2001 From: Daniel Friesen Date: Tue, 15 Nov 2016 16:05:01 -0800 Subject: [PATCH] Allow DrawerNavigationItem props to be overwritten in subclasses using getters or methods on the class --- example/components/DrawerNavigationExample.js | 103 +++++++++++------- src/drawer/ExNavigationDrawerItem.js | 30 ++++- 2 files changed, 89 insertions(+), 44 deletions(-) diff --git a/example/components/DrawerNavigationExample.js b/example/components/DrawerNavigationExample.js index 98659d7..aa5023e 100644 --- a/example/components/DrawerNavigationExample.js +++ b/example/components/DrawerNavigationExample.js @@ -21,68 +21,89 @@ class Heading extends DrawerNavigationChild { } } -export default class DrawerNavigationExample extends Component { - - _renderHeader = () => { - return ; +class DrawerItem extends DrawerNavigationItem { + renderIcon = (isSelected: bool) => { + let extraStyle = {marginTop: 2}; + if (this.props.icon === 'md-alert') { + extraStyle = {...extraStyle, marginLeft: -3}; + } + return ( + + ); }; - _renderTitle = (text: string, isSelected: bool) => { + renderTitle = (isSelected: bool) => { return ( - {text} + {this.props.title} ); }; - _renderIcon = (name: string, isSelected: bool) => { - let extraStyle = {marginTop: 2}; - if (name === 'md-alert') { - extraStyle = {...extraStyle, marginLeft: -3}; - } + get selectedItemStyle() { + return styles.selectedItemStyle; + } + + get children() { + let { defaultRouteConfig } = this.props; + return ( - ); + } +} + +export default class DrawerNavigationExample extends Component { + renderHeader = () => { + return ; }; render() { return ( - this._renderTitle('Examples', isSelected)} - renderIcon={isSelected => this._renderIcon('md-apps', isSelected)}> - - - - + + this._renderTitle('About', isSelected)} - renderIcon={isSelected => this._renderIcon('md-alert', isSelected)}> - - + icon="md-alert" + title="About" + defaultRouteConfig={{ + navigationBar: { + backgroundColor: '#0084FF', + tintColor: '#fff', + }, + }} + stack={{ + id: 'root', + initialRoute: Router.getRoute('about'), + }} + /> ); } diff --git a/src/drawer/ExNavigationDrawerItem.js b/src/drawer/ExNavigationDrawerItem.js index 54ad118..4f0d26e 100644 --- a/src/drawer/ExNavigationDrawerItem.js +++ b/src/drawer/ExNavigationDrawerItem.js @@ -8,11 +8,34 @@ import TouchableNativeFeedbackSafe from '@exponent/react-native-touchable-native import ExNavigationDrawerChild from './ExNavigationDrawerChild'; import type { Props } from './ExNavigationDrawerChild'; +function _set(self, name, fn) { + // Stop use of `get` from interfering with `renderTitle => ...` in subclasses + Object.defineProperty(self, name, { + value: fn, + }); +} + export default class ExNavigationDrawerItem extends ExNavigationDrawerChild { props: Props; + get showsTouches() { return this.props.showsTouches; } + get renderIcon() { return this.props.renderIcon; } + get renderTitle() { return this.props.renderTitle; } + get renderRight() { return this.props.renderRight; } + get onPress() { return this.props.onPress; } + get onLongPress() { return this.props.onLongPress; } + get children() { return this.props.children; } + set showsTouches(fn) { _set(this, 'showsTouches', fn); } + set renderIcon(fn) { _set(this, 'renderIcon', fn); } + set renderTitle(fn) { _set(this, 'renderTitle', fn); } + set renderRight(fn) { _set(this, 'renderRight', fn); } + set onPress(fn) { _set(this, 'onPress', fn); } + set onLongPress(fn) { _set(this, 'onLongPress', fn); } + set children(fn) { _set(this, 'children', fn); } + renderDrawerItem() { - let { showsTouches, isSelected, renderIcon, renderTitle, renderRight, onPress, onLongPress } = this.props; + let { isSelected } = this.props; + let { showsTouches, renderIcon, renderTitle, renderRight, onPress, onLongPress } = this; const icon = renderIcon && renderIcon(isSelected); const title = renderTitle && renderTitle(isSelected); const rightElement = renderRight && renderRight(isSelected); @@ -60,8 +83,9 @@ export default class ExNavigationDrawerItem extends ExNavigationDrawerChild { } renderContent() { - if (React.Children.count(this.props.children) > 0) { - return React.Children.only(this.props.children); + const children = this.children; + if (React.Children.count(children) > 0) { + return React.Children.only(children); } return null;