diff --git a/README.md b/README.md
index 35b4046..2e81ba6 100755
--- a/README.md
+++ b/README.md
@@ -86,8 +86,8 @@ The document is being written, please refer to the example source code.
## Overlay
![](https://github.com/rilyu/teaset/blob/master/screenshots/15-Overlay1.png?raw=true) ![](https://github.com/rilyu/teaset/blob/master/screenshots/15-Overlay2.png?raw=true)
-![](https://github.com/rilyu/teaset/blob/master/screenshots/15-Overlay3.png?raw=true) ![](https://github.com/rilyu/teaset/blob/master/screenshots/15-Overlay4.png?raw=true)
-![](https://github.com/rilyu/teaset/blob/master/screenshots/15-Overlay5.png?raw=true)
+![](https://github.com/rilyu/teaset/blob/master/screenshots/15-Overlay3.png?raw=true) ![](https://github.com/rilyu/teaset/blob/master/screenshots/15-Overlay6.png?raw=true)
+![](https://github.com/rilyu/teaset/blob/master/screenshots/15-Overlay4.png?raw=true) ![](https://github.com/rilyu/teaset/blob/master/screenshots/15-Overlay5.png?raw=true)
## Toast
![](https://github.com/rilyu/teaset/blob/master/screenshots/16-Toast1.png?raw=true) ![](https://github.com/rilyu/teaset/blob/master/screenshots/16-Toast2.png?raw=true)
diff --git a/components/NavigationBar/NavigationBar.js b/components/NavigationBar/NavigationBar.js
index e049bed..0ff2f22 100644
--- a/components/NavigationBar/NavigationBar.js
+++ b/components/NavigationBar/NavigationBar.js
@@ -3,7 +3,7 @@
'use strict';
import React, {Component, PropTypes} from 'react';
-import {StyleSheet, Platform, StatusBar, View, Text} from 'react-native';
+import {StyleSheet, Platform, StatusBar, View, Text, Animated} from 'react-native';
import Theme from 'teaset/themes/Theme';
import NavigationTitle from './NavigationTitle';
@@ -22,6 +22,8 @@ export default class NavigationBar extends Component {
leftView: PropTypes.element,
rightView: PropTypes.element,
tintColor: PropTypes.string, //bar tint color, default tint color leftView and rightView
+ hidden: PropTypes.bool, //bar hidden
+ animated: PropTypes.bool, //hide or show bar with animation
statusBarStyle: PropTypes.oneOf(['default', 'light-content']), //status bar style (iOS only)
statusBarColor: PropTypes.string, //status bar color, default: style.backgroundColor
statusBarHidden: PropTypes.bool, //status bar hidden
@@ -31,6 +33,8 @@ export default class NavigationBar extends Component {
static defaultProps = {
...View.defaultProps,
type: 'ios',
+ hidden: false,
+ animated: true,
statusBarInsets: true,
};
@@ -49,15 +53,23 @@ export default class NavigationBar extends Component {
this.state = {
leftViewWidth: 0,
rightViewWidth: 0,
+ barTop: new Animated.Value(props.hidden ? -64 : 0),
+ barOpacity: new Animated.Value(props.hidden ? 0 : 1),
};
}
+ componentWillReceiveProps(nextProps) {
+ if (nextProps.hidden != this.props.hidden) {
+ this.checkBarHidden(nextProps.hidden, nextProps.animated);
+ }
+ }
+
getChildContext() {
return {tintColor: this.props.tintColor};
}
buildProps() {
- let {style, type, title, titleStyle, tintColor, statusBarColor, statusBarStyle, statusBarInsets, ...others} = this.props;
+ let {style, type, title, titleStyle, tintColor, hidden, animated, statusBarColor, statusBarStyle, statusBarInsets, ...others} = this.props;
//build style
let justifyContent, titleTextAlign;
@@ -74,7 +86,6 @@ export default class NavigationBar extends Component {
style = [{
backgroundColor: Theme.navColor,
position: 'absolute',
- top: 0,
left: 0,
right: 0,
height: statusBarInsets && Platform.OS === 'ios' ? 64 : 44,
@@ -86,7 +97,9 @@ export default class NavigationBar extends Component {
flexDirection: 'row',
alignItems: 'center',
justifyContent: justifyContent,
- }].concat(style);
+ }].concat(style).concat({
+ top: this.state.barTop, //hidden or shown
+ });
let fs = StyleSheet.flatten(style);
@@ -121,17 +134,46 @@ export default class NavigationBar extends Component {
height: 44,
paddingLeft: paddingLeft,
paddingRight: paddingRight,
+ opacity: this.state.barOpacity,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
- }
+ };
+
+ //build leftView and rightView style
+ let leftRightViewStyle = {opacity: this.state.barOpacity};
//convert string title to NavigationBar.Title
if (typeof title === 'string') {
title = ;
}
- this.props = {style, type, title, titleStyle, tintColor, titleViewStyle, statusBarColor, statusBarStyle, statusBarInsets, ...others};
+ this.props = {style, type, title, titleStyle, tintColor, titleViewStyle, leftRightViewStyle, hidden, animated, statusBarColor, statusBarStyle, statusBarInsets, ...others};
+ }
+
+ checkBarHidden(hidden, animated) {
+ let {barTop, barOpacity} = this.state;
+ let barTopValue = hidden ? -this.barHeight : 0;
+ let barOpacityValue = hidden ? 0 : 1;
+ if (barTop._value != barTopValue || barOpacity._value != barOpacityValue) {
+ if (animated) {
+ Animated.parallel([
+ Animated.spring(barTop, {toValue: barTopValue, friction: 9}),
+ Animated.spring(barOpacity, {toValue: barOpacityValue, friction: 9}),
+ ]).start();
+ } else {
+ barTop.setValue(barTopValue);
+ barOpacity.setValue(barOpacityValue);
+ }
+ }
+ }
+
+ onLayout(e) {
+ if (e.nativeEvent.layout.height != this.barHeight) {
+ this.barHeight = e.nativeEvent.layout.height;
+ this.checkBarHidden(this.props.hidden, this.props.animated);
+ }
+ this.props.onLayout && this.props.onLayout(e);
}
onLeftViewLayout(e) {
@@ -149,17 +191,14 @@ export default class NavigationBar extends Component {
render() {
this.buildProps();
- let {style, statusBarStyle, statusBarColor, statusBarHidden, title, titleViewStyle, leftView, rightView, ...others} = this.props;
- if (statusBarHidden) return (
-
- );
+ let {style, animated, statusBarStyle, statusBarColor, statusBarHidden, title, titleViewStyle, leftRightViewStyle, leftView, rightView, ...others} = this.props;
return (
-
-
- {title}
- this.onLeftViewLayout(e)}>{leftView}
- this.onRightViewLayout(e)}>{rightView}
-
+ this.onLayout(e)}>
+
+ {title}
+ this.onLeftViewLayout(e)}>{leftView}
+ this.onRightViewLayout(e)}>{rightView}
+
);
}
}
diff --git a/components/NavigationPage/NavigationPage.js b/components/NavigationPage/NavigationPage.js
index 5d659cc..c18a44d 100644
--- a/components/NavigationPage/NavigationPage.js
+++ b/components/NavigationPage/NavigationPage.js
@@ -16,6 +16,7 @@ export default class NavigationPage extends BasePage {
...BasePage.propTypes,
title: PropTypes.string,
showBackButton: PropTypes.bool,
+ navigationBarInsets: PropTypes.bool,
};
static defaultProps = {
@@ -23,18 +24,19 @@ export default class NavigationPage extends BasePage {
scene: Navigator.SceneConfigs.PushFromRight,
title: null,
showBackButton: false,
+ navigationBarInsets: true,
};
buildProps() {
super.buildProps();
- let {...others} = this.props;
+ let {navigationBarInsets, ...others} = this.props;
let pageContainerStyle = [{
flex: 1,
padding: 0,
- marginTop: Platform.OS === 'ios' ? 64 : 44,
+ marginTop: navigationBarInsets ? (Platform.OS === 'ios' ? 64 : 44) : 0,
}];
- this.props = {pageContainerStyle, ...others};
+ this.props = {navigationBarInsets, pageContainerStyle, ...others};
}
renderNavigationTitle() {
diff --git a/components/Overlay/OverlayPullView.js b/components/Overlay/OverlayPullView.js
index 27acb48..9126cd5 100644
--- a/components/Overlay/OverlayPullView.js
+++ b/components/Overlay/OverlayPullView.js
@@ -15,7 +15,7 @@ export default class OverlayPullView extends OverlayView {
...OverlayView.propTypes,
side: PropTypes.oneOf(['top', 'bottom', 'left', 'right']),
containerStyle: View.propTypes.style,
- rootTransform: PropTypes.oneOfType(
+ rootTransform: PropTypes.oneOfType([
PropTypes.oneOf(['none', 'translate', 'scale']),
PropTypes.arrayOf(PropTypes.shape({
translateX: PropTypes.number,
@@ -23,7 +23,7 @@ export default class OverlayPullView extends OverlayView {
scaleX: PropTypes.number,
scaleY: PropTypes.number,
})),
- ),
+ ]),
};
static defaultProps = {
diff --git a/docs/cn/NavigationBar.md b/docs/cn/NavigationBar.md
index 888badc..5ca4c86 100644
--- a/docs/cn/NavigationBar.md
+++ b/docs/cn/NavigationBar.md
@@ -11,6 +11,8 @@ NavigationBar 组件定义一个页面导航条, 用于页面顶部显示页面
| leftView | element | | 导航条左视图。
| rightView | element | | 导航条右视图。
| tintColor | string | | 导航条左、右视图文字与图像颜色, 默认值在 Theme 中设置。
+| hidden | bool | false | 是否隐藏导航条
+| animated | bool | true | 显示/隐藏导航条和状态栏时是否有动画效果
| statusBarStyle | string | 'default' | 系统状态栏样式(iOS only)。
- default: 默认, 黑色文字或图标。
- light-content: 亮色调, 白色文字或图标。
| statusBarColor | string | | 导航条背景颜色, 默认值在 Theme 中设置。
| statusBarHidden | bool | false | 是否隐藏系统状态栏, 为 true 时系统状态栏与导航条均不显示。
diff --git a/docs/cn/NavigationPage.md b/docs/cn/NavigationPage.md
index 8d5840c..6e89b33 100644
--- a/docs/cn/NavigationPage.md
+++ b/docs/cn/NavigationPage.md
@@ -7,6 +7,7 @@ NavigationPage 定义一个导航页面组件, 继承自 [BasePage](./BasePage.m
| [BasePage props...](./BasePage.md) | | | NavigationPage 组件继承 BasePage 组件的全部属性。
| title | string | null | 导航条标题。
| showBackButton | bool | false | 是否显示返回按钮。
+| navigationBarInsets | bool | true | 是否为内容区域增加导航条占用空间。
此属性默认为 true, 使得内容不被导航条遮挡, 如果页面内容实用 ScrollView 且需要自行控制 NavigationBar 导航条的显示/隐藏, 那么你需要将此属性设置为 false 并自行在 ScrollView 容器里增加导航条的占用空间, 这样可以在导航条隐藏后把顶部空间利用起来。
| scene | object | Navigator.SceneConfigs.PushFromRight | 继承自 BasePage 并修改默认值。
## Methods
diff --git a/example/views/NavigationBarExample.js b/example/views/NavigationBarExample.js
index 5e0fd56..2bcd4c0 100644
--- a/example/views/NavigationBarExample.js
+++ b/example/views/NavigationBarExample.js
@@ -3,99 +3,260 @@
'use strict';
import React, {Component, PropTypes} from 'react';
-import {View, ScrollView} from 'react-native';
+import {Platform, View, ScrollView, Switch} from 'react-native';
-import {NavigationPage, ListRow, NavigationBar, Label} from 'teaset';
+import {Theme, NavigationPage, ListRow, NavigationBar, Label, Select} from 'teaset';
export default class NavigationBarExample extends NavigationPage {
static defaultProps = {
...NavigationPage.defaultProps,
title: 'NavigationBar',
- showBackButton: true,
+ navigationBarInsets: false,
};
- renderHeader(text) {
- return (
-
-
-
- );
+ constructor(props) {
+ super(props);
+
+ this.typeItems = ['Auto', 'iOS', 'Android'];
+ this.titleItems = ['String', 'Custom'];
+ this.leftViewItems = ['None', 'Back button', 'Link button', 'Icon button', 'Two icon button'];
+ this.rightViewItems = ['None', 'Link button', 'Icon button', 'Two icon button'];
+ this.bgColorItems = ['Default', 'Custom'];
+ this.tintColorItems = ['Default', 'Custom'];
+ this.statusBarStyleItems = ['Default', 'Light Content'];
+
+ Object.assign(this.state, {
+ type: 'iOS',
+ title: 'String',
+ leftView: 'Back button',
+ rightView: 'None',
+ bgColor: 'Default',
+ tintColor: 'Default',
+ hidden: false,
+ animated: true,
+ statusBarStyle: 'Light Content',
+ statusBarHidden: false,
+ });
+ }
+
+ get type() {
+ switch (this.state.type) {
+ case 'Auto': return Platform.OS;
+ default: return this.state.type.toLowerCase();
+ }
}
- renderDetail(type, example) {
- let title = example, leftView, rightView;
- let style = {
- //only for this example, do not use in your code
- flex: 1,
- position: 'relative',
- };
- let tintColor;
- switch (example) {
- case 'Default':
- rightView = (
+ get style() {
+ switch (this.state.bgColor) {
+ case 'Default': return null;
+ case 'Custom': return {backgroundColor: '#e75f35'};
+ }
+ }
+
+ get tintColor() {
+ switch(this.state.tintColor) {
+ case 'Default': return null;
+ case 'Custom': return '#3af455';
+ }
+ }
+
+ get statusBarStyle() {
+ switch(this.state.statusBarStyle) {
+ case 'Default': return 'default';
+ case 'Light Content': return 'light-content';
+ }
+ }
+
+ renderLeftRightView(item) {
+ switch (item) {
+ case 'None':
+ return null;
+ case 'Back button':
+ return (
+ this.navigator.pop()}
+ />
+ );
+ case 'Link button':
+ return (
+
+ );
+ case 'Icon button':
+ return (
);
- break;
+ case 'Two icon button':
+ return (
+
+
+
+
+ );
+ }
+ }
+
+ renderNavigationTitle() {
+ let {title} = this.state;
+ switch (title) {
+ case 'String':
+ return this.props.title;
case 'Custom':
let titleStyle = {
flex: 1,
paddingLeft: 4,
paddingRight: 4,
- alignItems: type === 'ios' ? 'center' : 'flex-start',
+ alignItems: this.type === 'ios' ? 'center' : 'flex-start',
};
- style.backgroundColor = '#eff';
- tintColor = '#333';
- title = (
+ return (
-
-
+
+
);
- leftView = (
-
- );
- rightView = (
-
-
-
-
- );
- break;
- case 'Back Button':
- leftView = ;
- break;
- case 'Link Button':
- leftView = ;
- rightView = ;
- break;
}
+ }
+
+ renderNavigationLeftView() {
+ return this.renderLeftRightView(this.state.leftView);
+ }
+
+ renderNavigationRightView() {
+ return this.renderLeftRightView(this.state.rightView);
+ }
+
+ renderNavigationBar() {
+ let {hidden, animated, statusBarHidden} = this.state;
return (
);
}
renderPage() {
+ let {type, title, leftView, rightView, bgColor, tintColor, hidden, animated, statusBarStyle, statusBarHidden} = this.state;
return (
- {this.renderHeader('Android')}
-
-
- {this.renderHeader('iOS')}
-
-
-
- {this.renderHeader('Auto')}
-
+
+
+
+
+ this.setState({type: item})}
+ topSeparator='full'
+ />
+ this.setState({title: item})}
+ />
+ this.setState({leftView: item})}
+ />
+ this.setState({rightView: item})}
+ />
+ this.setState({bgColor: item})}
+ />
+ this.setState({tintColor: item})}
+ />
+ this.setState({hidden: value})} />}
+ />
+ this.setState({animated: value})} />}
+ bottomSeparator='full'
+ />
+
+ this.setState({statusBarStyle: item})}
+ topSeparator='full'
+ />
+ this.setState({statusBarHidden: value})} />}
+ bottomSeparator='full'
+ />
);
}
}
+
+class SelectRow extends ListRow {
+
+ static propTypes = {
+ ...ListRow.propTypes,
+ value: PropTypes.any,
+ items: PropTypes.array,
+ getItemValue: PropTypes.func,
+ getItemText: PropTypes.func,
+ emptyText: PropTypes.string,
+ emptyTextColor: PropTypes.string,
+ onSelected: PropTypes.func.isRequired,
+ };
+
+ static defaultProps = {
+ ...ListRow.defaultProps,
+ emptyText: 'Select item',
+ emptyTextColor: '#ff8f99',
+ };
+
+ buildProps() {
+ let {title, detail, value, items, getItemValue, getItemText, emptyText, emptyTextColor, onSelected, ...others} = this.props;
+ detail = (
+