Add imperative API to StatusBar
Reviewed By: svcscm Differential Revision: D2938743 fb-gh-sync-id: 30af304efd5b089854d9a8defc1b77fd8e817d13 shipit-source-id: 30af304efd5b089854d9a8defc1b77fd8e817d13
This commit is contained in:
parent
9a918ef48f
commit
edbe6a2b24
|
@ -57,12 +57,16 @@ const showHideTransitions = [
|
||||||
'slide',
|
'slide',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
function getValue(values: Array<any>, index: number): any {
|
||||||
|
return values[index % values.length];
|
||||||
|
}
|
||||||
|
|
||||||
const StatusBarExample = React.createClass({
|
const StatusBarExample = React.createClass({
|
||||||
getInitialState(): State {
|
getInitialState(): State {
|
||||||
return {
|
return {
|
||||||
animated: true,
|
animated: true,
|
||||||
backgroundColor: this._getValue(colors, 0),
|
backgroundColor: getValue(colors, 0),
|
||||||
showHideTransition: this._getValue(showHideTransitions, 0),
|
showHideTransition: getValue(showHideTransitions, 0),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -70,10 +74,6 @@ const StatusBarExample = React.createClass({
|
||||||
_barStyleIndex: 0,
|
_barStyleIndex: 0,
|
||||||
_showHideTransitionIndex: 0,
|
_showHideTransitionIndex: 0,
|
||||||
|
|
||||||
_getValue(values: Array<any>, index: number): any {
|
|
||||||
return values[index % values.length];
|
|
||||||
},
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
|
@ -110,10 +110,10 @@ const StatusBarExample = React.createClass({
|
||||||
style={styles.wrapper}
|
style={styles.wrapper}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
this._barStyleIndex++;
|
this._barStyleIndex++;
|
||||||
this.setState({barStyle: this._getValue(barStyles, this._barStyleIndex)});
|
this.setState({barStyle: getValue(barStyles, this._barStyleIndex)});
|
||||||
}}>
|
}}>
|
||||||
<View style={styles.button}>
|
<View style={styles.button}>
|
||||||
<Text>style: '{this._getValue(barStyles, this._barStyleIndex)}'</Text>
|
<Text>style: '{getValue(barStyles, this._barStyleIndex)}'</Text>
|
||||||
</View>
|
</View>
|
||||||
</TouchableHighlight>
|
</TouchableHighlight>
|
||||||
</View>
|
</View>
|
||||||
|
@ -138,13 +138,13 @@ const StatusBarExample = React.createClass({
|
||||||
this._showHideTransitionIndex++;
|
this._showHideTransitionIndex++;
|
||||||
this.setState({
|
this.setState({
|
||||||
showHideTransition:
|
showHideTransition:
|
||||||
this._getValue(showHideTransitions, this._showHideTransitionIndex),
|
getValue(showHideTransitions, this._showHideTransitionIndex),
|
||||||
});
|
});
|
||||||
}}>
|
}}>
|
||||||
<View style={styles.button}>
|
<View style={styles.button}>
|
||||||
<Text>
|
<Text>
|
||||||
showHideTransition:
|
showHideTransition:
|
||||||
'{this._getValue(showHideTransitions, this._showHideTransitionIndex)}'
|
'{getValue(showHideTransitions, this._showHideTransitionIndex)}'
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
</TouchableHighlight>
|
</TouchableHighlight>
|
||||||
|
@ -155,10 +155,10 @@ const StatusBarExample = React.createClass({
|
||||||
style={styles.wrapper}
|
style={styles.wrapper}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
this._colorIndex++;
|
this._colorIndex++;
|
||||||
this.setState({backgroundColor: this._getValue(colors, this._colorIndex)});
|
this.setState({backgroundColor: getValue(colors, this._colorIndex)});
|
||||||
}}>
|
}}>
|
||||||
<View style={styles.button}>
|
<View style={styles.button}>
|
||||||
<Text>backgroundColor: '{this._getValue(colors, this._colorIndex)}'</Text>
|
<Text>backgroundColor: '{getValue(colors, this._colorIndex)}'</Text>
|
||||||
</View>
|
</View>
|
||||||
</TouchableHighlight>
|
</TouchableHighlight>
|
||||||
</View>
|
</View>
|
||||||
|
@ -181,11 +181,116 @@ const StatusBarExample = React.createClass({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const StatusBarStaticExample = React.createClass({
|
||||||
|
_colorIndex: 0,
|
||||||
|
_barStyleIndex: 0,
|
||||||
|
_showHideTransitionIndex: 0,
|
||||||
|
|
||||||
|
getInitialState() {
|
||||||
|
return {
|
||||||
|
backgroundColor: getValue(colors, 0),
|
||||||
|
barStyle: getValue(barStyles, 0),
|
||||||
|
hidden: false,
|
||||||
|
networkActivityIndicatorVisible: false,
|
||||||
|
translucent: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<View>
|
||||||
|
<TouchableHighlight
|
||||||
|
style={styles.wrapper}
|
||||||
|
onPress={() => {
|
||||||
|
const hidden = !this.state.hidden;
|
||||||
|
StatusBar.setHidden(hidden, 'slide');
|
||||||
|
this.setState({hidden});
|
||||||
|
}}>
|
||||||
|
<View style={styles.button}>
|
||||||
|
<Text>hidden: {this.state.hidden ? 'true' : 'false'}</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableHighlight>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.title}>iOS</Text>
|
||||||
|
<View>
|
||||||
|
<TouchableHighlight
|
||||||
|
style={styles.wrapper}
|
||||||
|
onPress={() => {
|
||||||
|
this._barStyleIndex++;
|
||||||
|
const barStyle = getValue(barStyles, this._barStyleIndex);
|
||||||
|
StatusBar.setBarStyle(barStyle, true);
|
||||||
|
this.setState({barStyle});
|
||||||
|
}}>
|
||||||
|
<View style={styles.button}>
|
||||||
|
<Text>style: '{getValue(barStyles, this._barStyleIndex)}'</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableHighlight>
|
||||||
|
</View>
|
||||||
|
<View>
|
||||||
|
<TouchableHighlight
|
||||||
|
style={styles.wrapper}
|
||||||
|
onPress={() => {
|
||||||
|
const networkActivityIndicatorVisible = !this.state.networkActivityIndicatorVisible;
|
||||||
|
StatusBar.setNetworkActivityIndicatorVisible(networkActivityIndicatorVisible);
|
||||||
|
this.setState({networkActivityIndicatorVisible});
|
||||||
|
}}>
|
||||||
|
<View style={styles.button}>
|
||||||
|
<Text>
|
||||||
|
networkActivityIndicatorVisible:
|
||||||
|
{this.state.networkActivityIndicatorVisible ? 'true' : 'false'}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableHighlight>
|
||||||
|
</View>
|
||||||
|
<Text style={styles.title}>Android</Text>
|
||||||
|
<View>
|
||||||
|
<TouchableHighlight
|
||||||
|
style={styles.wrapper}
|
||||||
|
onPress={() => {
|
||||||
|
this._colorIndex++;
|
||||||
|
const backgroundColor = getValue(colors, this._colorIndex);
|
||||||
|
StatusBar.setBackgroundColor(backgroundColor, true);
|
||||||
|
this.setState({backgroundColor});
|
||||||
|
}}>
|
||||||
|
<View style={styles.button}>
|
||||||
|
<Text>backgroundColor: '{getValue(colors, this._colorIndex)}'</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableHighlight>
|
||||||
|
</View>
|
||||||
|
<View>
|
||||||
|
<TouchableHighlight
|
||||||
|
style={styles.wrapper}
|
||||||
|
onPress={() => {
|
||||||
|
const translucent = !this.state.translucent;
|
||||||
|
const backgroundColor = !this.state.translucent ? 'rgba(0, 0, 0, 0.4)' : 'black';
|
||||||
|
StatusBar.setTranslucent(translucent);
|
||||||
|
StatusBar.setBackgroundColor(backgroundColor, true);
|
||||||
|
this.setState({
|
||||||
|
translucent,
|
||||||
|
backgroundColor,
|
||||||
|
});
|
||||||
|
}}>
|
||||||
|
<View style={styles.button}>
|
||||||
|
<Text>translucent: {this.state.translucent ? 'true' : 'false'}</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableHighlight>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
exports.examples = [{
|
exports.examples = [{
|
||||||
title: 'Status Bar',
|
title: 'StatusBar',
|
||||||
render() {
|
render() {
|
||||||
return <StatusBarExample />;
|
return <StatusBarExample />;
|
||||||
},
|
},
|
||||||
|
}, {
|
||||||
|
title: 'StatusBar static API',
|
||||||
|
render() {
|
||||||
|
return <StatusBarStaticExample />;
|
||||||
|
},
|
||||||
}];
|
}];
|
||||||
|
|
||||||
var styles = StyleSheet.create({
|
var styles = StyleSheet.create({
|
||||||
|
|
|
@ -19,6 +19,17 @@ const processColor = require('processColor');
|
||||||
|
|
||||||
const StatusBarManager = require('NativeModules').StatusBarManager;
|
const StatusBarManager = require('NativeModules').StatusBarManager;
|
||||||
|
|
||||||
|
export type StatusBarStyle = $Enum<{
|
||||||
|
'default': string,
|
||||||
|
'light-content': string,
|
||||||
|
}>;
|
||||||
|
|
||||||
|
export type StatusBarAnimation = $Enum<{
|
||||||
|
'none': string,
|
||||||
|
'fade': string,
|
||||||
|
'slide': string,
|
||||||
|
}>;
|
||||||
|
|
||||||
type DefaultProps = {
|
type DefaultProps = {
|
||||||
animated: boolean;
|
animated: boolean;
|
||||||
};
|
};
|
||||||
|
@ -26,16 +37,10 @@ type DefaultProps = {
|
||||||
/**
|
/**
|
||||||
* Merges the prop stack with the default values.
|
* Merges the prop stack with the default values.
|
||||||
*/
|
*/
|
||||||
function mergePropsStack(propsStack: Array<Object>): Object {
|
function mergePropsStack(propsStack: Array<Object>, defaultValues: Object): Object {
|
||||||
return propsStack.reduce((prev, cur) => {
|
return propsStack.reduce((prev, cur) => {
|
||||||
return Object.assign(prev, cur);
|
return Object.assign(prev, cur);
|
||||||
}, {
|
}, defaultValues);
|
||||||
backgroundColor: 'black',
|
|
||||||
barStyle: 'default',
|
|
||||||
translucent: false,
|
|
||||||
hidden: false,
|
|
||||||
networkActivityIndicatorVisible: false,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -64,10 +69,75 @@ function mergePropsStack(propsStack: Array<Object>): Object {
|
||||||
* />
|
* />
|
||||||
* </View>
|
* </View>
|
||||||
* ```
|
* ```
|
||||||
|
*
|
||||||
|
* ### Imperative API
|
||||||
|
*
|
||||||
|
* For cases where using a component is not ideal, there is also an imperative
|
||||||
|
* API exposed as static functions on the component. It is however not recommended
|
||||||
|
* to use the static API and the compoment for the same prop because any value
|
||||||
|
* set by the static API will get overriden by the one set by the component in
|
||||||
|
* the next render.
|
||||||
*/
|
*/
|
||||||
const StatusBar = React.createClass({
|
const StatusBar = React.createClass({
|
||||||
statics: {
|
statics: {
|
||||||
_propsStack: [],
|
_propsStack: [],
|
||||||
|
_defaultProps: {
|
||||||
|
backgroundColor: 'black',
|
||||||
|
barStyle: 'default',
|
||||||
|
translucent: false,
|
||||||
|
hidden: false,
|
||||||
|
networkActivityIndicatorVisible: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Provide an imperative API as static functions of the component.
|
||||||
|
// See the corresponding prop for more detail.
|
||||||
|
setHidden(hidden: boolean, animation?: StatusBarAnimation) {
|
||||||
|
animation = animation || 'none';
|
||||||
|
StatusBar._defaultProps.hidden = hidden;
|
||||||
|
if (Platform.OS === 'ios') {
|
||||||
|
StatusBarManager.setHidden(hidden, animation);
|
||||||
|
} else if (Platform.OS === 'android') {
|
||||||
|
StatusBarManager.setHidden(hidden);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setBarStyle(style: StatusBarStyle, animated?: boolean) {
|
||||||
|
if (Platform.OS !== 'ios') {
|
||||||
|
console.warn('`setBarStyle` is only available on iOS');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
animated = animated || false;
|
||||||
|
StatusBar._defaultProps.barStyle = style;
|
||||||
|
StatusBarManager.setStyle(style, animated);
|
||||||
|
},
|
||||||
|
|
||||||
|
setNetworkActivityIndicatorVisible(visible: boolean) {
|
||||||
|
if (Platform.OS !== 'ios') {
|
||||||
|
console.warn('`setNetworkActivityIndicatorVisible` is only available on iOS');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
StatusBar._defaultProps.networkActivityIndicatorVisible = visible;
|
||||||
|
StatusBarManager.setNetworkActivityIndicatorVisible(visible);
|
||||||
|
},
|
||||||
|
|
||||||
|
setBackgroundColor(color, animated?: boolean) {
|
||||||
|
if (Platform.OS !== 'android') {
|
||||||
|
console.warn('`setBackgroundColor` is only available on Android');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
animated = animated || false;
|
||||||
|
StatusBar._defaultProps.backgroundColor = color;
|
||||||
|
StatusBarManager.setColor(processColor(color), animated);
|
||||||
|
},
|
||||||
|
|
||||||
|
setTranslucent(translucent: boolean) {
|
||||||
|
if (Platform.OS !== 'android') {
|
||||||
|
console.warn('`setTranslucent` is only available on Android');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
StatusBar._defaultProps.translucent = translucent;
|
||||||
|
StatusBarManager.setTranslucent(translucent);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
|
@ -156,7 +226,7 @@ const StatusBar = React.createClass({
|
||||||
* Updates the native status bar with the props from the stack.
|
* Updates the native status bar with the props from the stack.
|
||||||
*/
|
*/
|
||||||
_updatePropsStack() {
|
_updatePropsStack() {
|
||||||
const mergedProps = mergePropsStack(StatusBar._propsStack);
|
const mergedProps = mergePropsStack(StatusBar._propsStack, StatusBar._defaultProps);
|
||||||
|
|
||||||
if (Platform.OS === 'ios') {
|
if (Platform.OS === 'ios') {
|
||||||
if (mergedProps.barStyle !== undefined) {
|
if (mergedProps.barStyle !== undefined) {
|
||||||
|
|
|
@ -11,33 +11,31 @@
|
||||||
*/
|
*/
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var RCTStatusBarManager = require('NativeModules').StatusBarManager;
|
const StatusBar = require('StatusBar');
|
||||||
|
|
||||||
type StatusBarStyle = $Enum<{
|
import type {StatusBarStyle, StatusBarAnimation} from 'StatusBar';
|
||||||
'default': string,
|
|
||||||
'light-content': string,
|
|
||||||
}>;
|
|
||||||
|
|
||||||
type StatusBarAnimation = $Enum<{
|
/**
|
||||||
'none': string,
|
* Deprecated. Use `StatusBar` instead.
|
||||||
'fade': string,
|
*/
|
||||||
'slide': string,
|
const StatusBarIOS = {
|
||||||
}>;
|
|
||||||
|
|
||||||
var StatusBarIOS = {
|
|
||||||
|
|
||||||
setStyle(style: StatusBarStyle, animated?: boolean) {
|
setStyle(style: StatusBarStyle, animated?: boolean) {
|
||||||
animated = animated || false;
|
console.warn('`StatusBarIOS.setStyle` is deprecated. Use `StatusBar.setBarStyle` instead.');
|
||||||
RCTStatusBarManager.setStyle(style, animated);
|
StatusBar.setBarStyle(style, animated);
|
||||||
},
|
},
|
||||||
|
|
||||||
setHidden(hidden: boolean, animation?: StatusBarAnimation) {
|
setHidden(hidden: boolean, animation?: StatusBarAnimation) {
|
||||||
animation = animation || 'none';
|
console.warn('`StatusBarIOS.setHidden` is deprecated. Use `StatusBar.setHidden` instead.');
|
||||||
RCTStatusBarManager.setHidden(hidden, animation);
|
StatusBar.setHidden(hidden, animation);
|
||||||
},
|
},
|
||||||
|
|
||||||
setNetworkActivityIndicatorVisible(visible: boolean) {
|
setNetworkActivityIndicatorVisible(visible: boolean) {
|
||||||
RCTStatusBarManager.setNetworkActivityIndicatorVisible(visible);
|
console.warn(
|
||||||
|
'`StatusBarIOS.setNetworkActivityIndicatorVisible` is deprecated. ' +
|
||||||
|
'Use `StatusBar.setNetworkActivityIndicatorVisible` instead.'
|
||||||
|
);
|
||||||
|
StatusBar.setNetworkActivityIndicatorVisible(visible);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue