react-native/RNTester/js/ViewExample.js

383 lines
10 KiB
JavaScript
Raw Normal View History

2015-01-30 01:10:49 +00:00
/**
* Copyright (c) Facebook, Inc. and its affiliates.
Implement CSS z-index for iOS Summary: This diff implement the CSS z-index for React Native iOS views. We've had numerous pull request for this feature, but they've all attempted to use the `layer.zPosition` property, which is problematic for two reasons: 1. zPosition only affects rendering order, not event processing order. Views with a higher zPosition will appear in front of others in the hierarchy, but won't be the first to receive touch events, and may be blocked by views that are visually behind them. 2. when using a perspective transform matrix, views with a nonzero zPosition will be rendered in a different position due to parallax, which probably isn't desirable. See https://github.com/facebook/react-native/pull/7825 for further discussion of this problem. So instead of using `layer.zPosition`, I've implemented this by actually adjusting the order of the subviews within their parent based on the zIndex. This can't be done on the JS side because it would affect layout, which is order-dependent, so I'm doing it inside the view itself. It works as follows: 1. The `reactSubviews` array is set, whose order matches the order of the JS components and shadowView components, as specified by the UIManager. 2. `didUpdateReactSubviews` is called, which in turn calls `sortedSubviews` (which lazily generates a sorted array of `reactSubviews` by zIndex) and inserts the result into the view. 3. If a subview is added or removed, or the zIndex of any subview is changed, the previous `sortedSubviews` array is cleared and `didUpdateReactSubviews` is called again. To demonstrate it working, I've modified the UIExplorer example from https://github.com/facebook/react-native/pull/7825 Reviewed By: javache Differential Revision: D3365717 fbshipit-source-id: b34aa8bfad577bce023f8af5414f9b974aafd8aa
2016-06-07 14:40:25 +00:00
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
Implement CSS z-index for iOS Summary: This diff implement the CSS z-index for React Native iOS views. We've had numerous pull request for this feature, but they've all attempted to use the `layer.zPosition` property, which is problematic for two reasons: 1. zPosition only affects rendering order, not event processing order. Views with a higher zPosition will appear in front of others in the hierarchy, but won't be the first to receive touch events, and may be blocked by views that are visually behind them. 2. when using a perspective transform matrix, views with a nonzero zPosition will be rendered in a different position due to parallax, which probably isn't desirable. See https://github.com/facebook/react-native/pull/7825 for further discussion of this problem. So instead of using `layer.zPosition`, I've implemented this by actually adjusting the order of the subviews within their parent based on the zIndex. This can't be done on the JS side because it would affect layout, which is order-dependent, so I'm doing it inside the view itself. It works as follows: 1. The `reactSubviews` array is set, whose order matches the order of the JS components and shadowView components, as specified by the UIManager. 2. `didUpdateReactSubviews` is called, which in turn calls `sortedSubviews` (which lazily generates a sorted array of `reactSubviews` by zIndex) and inserts the result into the view. 3. If a subview is added or removed, or the zIndex of any subview is changed, the previous `sortedSubviews` array is cleared and `didUpdateReactSubviews` is called again. To demonstrate it working, I've modified the UIExplorer example from https://github.com/facebook/react-native/pull/7825 Reviewed By: javache Differential Revision: D3365717 fbshipit-source-id: b34aa8bfad577bce023f8af5414f9b974aafd8aa
2016-06-07 14:40:25 +00:00
*
* @format
* @flow strict-local
2015-01-30 01:10:49 +00:00
*/
2015-01-30 01:10:49 +00:00
'use strict';
/* eslint-disable react-native/no-inline-styles */
2015-01-30 01:10:49 +00:00
const React = require('react');
const {StyleSheet, Text, View} = require('react-native');
const TouchableWithoutFeedback = require('TouchableWithoutFeedback');
Implement CSS z-index for iOS Summary: This diff implement the CSS z-index for React Native iOS views. We've had numerous pull request for this feature, but they've all attempted to use the `layer.zPosition` property, which is problematic for two reasons: 1. zPosition only affects rendering order, not event processing order. Views with a higher zPosition will appear in front of others in the hierarchy, but won't be the first to receive touch events, and may be blocked by views that are visually behind them. 2. when using a perspective transform matrix, views with a nonzero zPosition will be rendered in a different position due to parallax, which probably isn't desirable. See https://github.com/facebook/react-native/pull/7825 for further discussion of this problem. So instead of using `layer.zPosition`, I've implemented this by actually adjusting the order of the subviews within their parent based on the zIndex. This can't be done on the JS side because it would affect layout, which is order-dependent, so I'm doing it inside the view itself. It works as follows: 1. The `reactSubviews` array is set, whose order matches the order of the JS components and shadowView components, as specified by the UIManager. 2. `didUpdateReactSubviews` is called, which in turn calls `sortedSubviews` (which lazily generates a sorted array of `reactSubviews` by zIndex) and inserts the result into the view. 3. If a subview is added or removed, or the zIndex of any subview is changed, the previous `sortedSubviews` array is cleared and `didUpdateReactSubviews` is called again. To demonstrate it working, I've modified the UIExplorer example from https://github.com/facebook/react-native/pull/7825 Reviewed By: javache Differential Revision: D3365717 fbshipit-source-id: b34aa8bfad577bce023f8af5414f9b974aafd8aa
2016-06-07 14:40:25 +00:00
exports.title = '<View>';
exports.description =
'Basic building block of all UI, examples that ' +
'demonstrate some of the many styles available.';
exports.displayName = 'ViewExample';
exports.examples = [
{
title: 'Background Color',
render() {
return (
<View style={{backgroundColor: '#527FE4', padding: 5}}>
<Text style={{fontSize: 11}}>Blue background</Text>
</View>
);
},
},
{
title: 'Border',
render() {
return (
<View style={{borderColor: '#527FE4', borderWidth: 5, padding: 10}}>
<Text style={{fontSize: 11}}>5px blue border</Text>
</View>
);
},
},
{
title: 'Padding/Margin',
render() {
const styles = StyleSheet.create({
box: {
backgroundColor: '#527FE4',
borderColor: '#000033',
borderWidth: 1,
},
});
return (
<View style={{borderColor: '#bb0000', borderWidth: 0.5}}>
<View style={[styles.box, {padding: 5}]}>
<Text style={{fontSize: 11}}>5px padding</Text>
2015-01-30 01:10:49 +00:00
</View>
<View style={[styles.box, {margin: 5}]}>
<Text style={{fontSize: 11}}>5px margin</Text>
2015-01-30 01:10:49 +00:00
</View>
<View
style={[
styles.box,
{margin: 5, padding: 5, alignSelf: 'flex-start'},
]}>
<Text style={{fontSize: 11}}>5px margin and padding,</Text>
<Text style={{fontSize: 11}}>widthAutonomous=true</Text>
2015-01-30 01:10:49 +00:00
</View>
</View>
);
},
},
{
title: 'Border Radius',
render() {
return (
<View style={{borderWidth: 0.5, borderRadius: 5, padding: 5}}>
<Text style={{fontSize: 11}}>
Too much use of `borderRadius` (especially large radii) on anything
which is scrolling may result in dropped frames. Use sparingly.
</Text>
</View>
);
},
},
{
2015-07-03 02:16:29 +00:00
title: 'Border Style',
render() {
type Props = $ReadOnly<{||}>;
type State = {|
showBorder: boolean,
|};
class ViewBorderStyleExample extends React.Component<Props, State> {
state = {
showBorder: true,
};
render() {
return (
<TouchableWithoutFeedback onPress={this._handlePress}>
<View>
<View
style={[
{
borderWidth: 1,
padding: 5,
},
this.state.showBorder
? {
borderStyle: 'dashed',
}
: null,
]}>
<Text style={{fontSize: 11}}>Dashed border style</Text>
</View>
<View
style={[
{
marginTop: 5,
borderWidth: 1,
borderRadius: 5,
padding: 5,
},
this.state.showBorder
? {
borderStyle: 'dotted',
}
: null,
]}>
<Text style={{fontSize: 11}}>Dotted border style</Text>
</View>
</View>
</TouchableWithoutFeedback>
);
}
_handlePress = () => {
this.setState({showBorder: !this.state.showBorder});
};
}
2015-07-03 02:16:29 +00:00
return <ViewBorderStyleExample />;
},
},
{
title: 'Circle with Border Radius',
render() {
return (
<View
style={{borderRadius: 10, borderWidth: 1, width: 20, height: 20}}
/>
);
},
},
{
title: 'Overflow',
render() {
const styles = StyleSheet.create({
container: {
borderWidth: StyleSheet.hairlineWidth,
height: 12,
marginBottom: 8,
marginEnd: 16,
width: 95,
},
content: {
height: 20,
width: 200,
},
});
// NOTE: The <View> that sets `overflow` should only have other layout
// styles so that we can accurately test view flattening optimizations.
return (
<View style={{flexDirection: 'row'}}>
<View style={styles.container}>
<View style={[StyleSheet.absoluteFill]}>
<Text style={styles.content}>undefined</Text>
2015-01-30 01:10:49 +00:00
</View>
</View>
<View style={styles.container}>
<View style={[StyleSheet.absoluteFill, {overflow: 'hidden'}]}>
<Text style={styles.content}>hidden</Text>
</View>
</View>
<View style={styles.container}>
<View style={[StyleSheet.absoluteFill, {overflow: 'visible'}]}>
<Text style={styles.content}>visible</Text>
2015-01-30 01:10:49 +00:00
</View>
</View>
</View>
);
},
},
{
title: 'Opacity',
render() {
return (
<View>
<View style={{opacity: 0}}>
<Text>Opacity 0</Text>
</View>
<View style={{opacity: 0.1}}>
<Text>Opacity 0.1</Text>
</View>
<View style={{opacity: 0.3}}>
<Text>Opacity 0.3</Text>
</View>
<View style={{opacity: 0.5}}>
<Text>Opacity 0.5</Text>
</View>
<View style={{opacity: 0.7}}>
<Text>Opacity 0.7</Text>
</View>
<View style={{opacity: 0.9}}>
<Text>Opacity 0.9</Text>
</View>
<View style={{opacity: 1}}>
<Text>Opacity 1</Text>
</View>
</View>
);
},
},
{
Implement CSS z-index for iOS Summary: This diff implement the CSS z-index for React Native iOS views. We've had numerous pull request for this feature, but they've all attempted to use the `layer.zPosition` property, which is problematic for two reasons: 1. zPosition only affects rendering order, not event processing order. Views with a higher zPosition will appear in front of others in the hierarchy, but won't be the first to receive touch events, and may be blocked by views that are visually behind them. 2. when using a perspective transform matrix, views with a nonzero zPosition will be rendered in a different position due to parallax, which probably isn't desirable. See https://github.com/facebook/react-native/pull/7825 for further discussion of this problem. So instead of using `layer.zPosition`, I've implemented this by actually adjusting the order of the subviews within their parent based on the zIndex. This can't be done on the JS side because it would affect layout, which is order-dependent, so I'm doing it inside the view itself. It works as follows: 1. The `reactSubviews` array is set, whose order matches the order of the JS components and shadowView components, as specified by the UIManager. 2. `didUpdateReactSubviews` is called, which in turn calls `sortedSubviews` (which lazily generates a sorted array of `reactSubviews` by zIndex) and inserts the result into the view. 3. If a subview is added or removed, or the zIndex of any subview is changed, the previous `sortedSubviews` array is cleared and `didUpdateReactSubviews` is called again. To demonstrate it working, I've modified the UIExplorer example from https://github.com/facebook/react-native/pull/7825 Reviewed By: javache Differential Revision: D3365717 fbshipit-source-id: b34aa8bfad577bce023f8af5414f9b974aafd8aa
2016-06-07 14:40:25 +00:00
title: 'ZIndex',
render() {
type Props = $ReadOnly<{||}>;
type State = {|
flipped: boolean,
|};
const styles = StyleSheet.create({
zIndex: {
justifyContent: 'space-around',
width: 100,
height: 50,
marginTop: -10,
},
});
class ZIndexExample extends React.Component<Props, State> {
state = {
flipped: false,
};
render() {
const indices = this.state.flipped ? [-1, 0, 1, 2] : [2, 1, 0, -1];
return (
<TouchableWithoutFeedback onPress={this._handlePress}>
<View>
<Text style={{paddingBottom: 10}}>
Tap to flip sorting order
</Text>
<View
style={[
styles.zIndex,
{
marginTop: 0,
backgroundColor: '#E57373',
zIndex: indices[0],
},
]}>
<Text>ZIndex {indices[0]}</Text>
</View>
<View
style={[
styles.zIndex,
{
marginLeft: 50,
backgroundColor: '#FFF176',
zIndex: indices[1],
},
]}>
<Text>ZIndex {indices[1]}</Text>
</View>
<View
style={[
styles.zIndex,
{
marginLeft: 100,
backgroundColor: '#81C784',
zIndex: indices[2],
},
]}>
<Text>ZIndex {indices[2]}</Text>
</View>
<View
style={[
styles.zIndex,
{
marginLeft: 150,
backgroundColor: '#64B5F6',
zIndex: indices[3],
},
]}>
<Text>ZIndex {indices[3]}</Text>
</View>
</View>
</TouchableWithoutFeedback>
);
}
_handlePress = () => {
this.setState({flipped: !this.state.flipped});
};
}
Implement CSS z-index for iOS Summary: This diff implement the CSS z-index for React Native iOS views. We've had numerous pull request for this feature, but they've all attempted to use the `layer.zPosition` property, which is problematic for two reasons: 1. zPosition only affects rendering order, not event processing order. Views with a higher zPosition will appear in front of others in the hierarchy, but won't be the first to receive touch events, and may be blocked by views that are visually behind them. 2. when using a perspective transform matrix, views with a nonzero zPosition will be rendered in a different position due to parallax, which probably isn't desirable. See https://github.com/facebook/react-native/pull/7825 for further discussion of this problem. So instead of using `layer.zPosition`, I've implemented this by actually adjusting the order of the subviews within their parent based on the zIndex. This can't be done on the JS side because it would affect layout, which is order-dependent, so I'm doing it inside the view itself. It works as follows: 1. The `reactSubviews` array is set, whose order matches the order of the JS components and shadowView components, as specified by the UIManager. 2. `didUpdateReactSubviews` is called, which in turn calls `sortedSubviews` (which lazily generates a sorted array of `reactSubviews` by zIndex) and inserts the result into the view. 3. If a subview is added or removed, or the zIndex of any subview is changed, the previous `sortedSubviews` array is cleared and `didUpdateReactSubviews` is called again. To demonstrate it working, I've modified the UIExplorer example from https://github.com/facebook/react-native/pull/7825 Reviewed By: javache Differential Revision: D3365717 fbshipit-source-id: b34aa8bfad577bce023f8af5414f9b974aafd8aa
2016-06-07 14:40:25 +00:00
return <ZIndexExample />;
},
2015-01-30 01:10:49 +00:00
},
{
title: 'BackfaceVisibility',
render: function() {
return (
<>
<Text style={{paddingBottom: 10}}>
View #1, front is visible, back is hidden.
</Text>
<View style={{justifyContent: 'center', alignItems: 'center'}}>
<View
style={{
height: 200,
width: 200,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'blue',
backfaceVisibility: 'hidden',
}}>
<Text>Front</Text>
</View>
<View
style={{
height: 200,
width: 200,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'red',
backfaceVisibility: 'hidden',
transform: [{rotateY: '180deg'}],
position: 'absolute',
top: 0,
}}>
<Text>Back (You should not see this)</Text>
</View>
</View>
<Text style={{paddingVertical: 10}}>
View #2, front is hidden, back is visible.
</Text>
<View style={{justifyContent: 'center', alignItems: 'center'}}>
<View
style={{
height: 200,
width: 200,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'blue',
backfaceVisibility: 'hidden',
}}>
<Text>Front (You should not see this)</Text>
</View>
<View
style={{
height: 200,
width: 200,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'red',
backfaceVisibility: 'hidden',
position: 'absolute',
top: 0,
}}>
<Text>Back</Text>
</View>
</View>
</>
);
},
},
];