Skip to content

Commit 53b2c39

Browse files
author
Jared Forsyth
committed
select up and down the inspector hierarchy
Summary: This allows you to select the displayed owner hierarchy, and see the styles, props, and position. @public Test Plan: Open the inspector, select something in the middle of the page. Click the breadcrumb train in the inspector, and verify that: - styles are reflected - margin/padding/box is correct - the highlight updates to show the selected item See video as well. [Video](https://www.latest.facebook.com/pxlcld/mqnl) Screenshot {F22518618}
1 parent 015b5cf commit 53b2c39

File tree

3 files changed

+92
-15
lines changed

3 files changed

+92
-15
lines changed

Libraries/ReactIOS/InspectorOverlay/ElementProperties.js

Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,38 +18,79 @@ var View = require('View');
1818
var PropTypes = require('ReactPropTypes');
1919
var BoxInspector = require('BoxInspector');
2020
var StyleInspector = require('StyleInspector');
21+
var TouchableHighlight = require('TouchableHighlight');
22+
var TouchableWithoutFeedback = require('TouchableWithoutFeedback');
2123

2224
var flattenStyle = require('flattenStyle');
25+
var mapWithSeparator = require('mapWithSeparator');
2326

2427
var ElementProperties = React.createClass({
2528
propTypes: {
2629
hierarchy: PropTypes.array.isRequired,
2730
style: PropTypes.array.isRequired,
2831
},
32+
2933
render: function() {
3034
var style = flattenStyle(this.props.style);
31-
var path = this.props.hierarchy.map((instance) => {
32-
return instance.getName ? instance.getName() : 'Unknown';
33-
}).join(' > ');
35+
var selection = this.props.selection;
36+
// Without the `TouchableWithoutFeedback`, taps on this inspector pane
37+
// would change the inspected element to whatever is under the inspector
3438
return (
35-
<View style={styles.info}>
36-
<Text style={styles.path}>
37-
{path}
38-
</Text>
39-
<View style={styles.row}>
40-
<StyleInspector style={style} />
41-
<BoxInspector style={style} frame={this.props.frame} />
39+
<TouchableWithoutFeedback>
40+
<View style={styles.info}>
41+
<View style={styles.breadcrumb}>
42+
{mapWithSeparator(
43+
this.props.hierarchy,
44+
(item, i) => (
45+
<TouchableHighlight
46+
style={[styles.breadItem, i === selection && styles.selected]}
47+
onPress={() => this.props.setSelection(i)}>
48+
<Text style={styles.breadItemText}>
49+
{item.getName ? item.getName() : 'Unknown'}
50+
</Text>
51+
</TouchableHighlight>
52+
),
53+
() => <Text style={styles.breadSep}>&#9656;</Text>
54+
)}
55+
</View>
56+
<View style={styles.row}>
57+
<StyleInspector style={style} />
58+
<BoxInspector style={style} frame={this.props.frame} />
59+
</View>
4260
</View>
43-
</View>
61+
</TouchableWithoutFeedback>
4462
);
4563
}
4664
});
4765

4866
var styles = StyleSheet.create({
67+
breadSep: {
68+
fontSize: 8,
69+
color: 'white',
70+
},
71+
breadcrumb: {
72+
flexDirection: 'row',
73+
flexWrap: 'wrap',
74+
marginBottom: 5,
75+
},
76+
selected: {
77+
borderColor: 'white',
78+
borderRadius: 5,
79+
},
80+
breadItem: {
81+
borderWidth: 1,
82+
borderColor: 'transparent',
83+
marginHorizontal: 2,
84+
},
85+
breadItemText: {
86+
fontSize: 10,
87+
color: 'white',
88+
marginHorizontal: 5,
89+
},
4990
row: {
5091
flexDirection: 'row',
5192
alignItems: 'center',
52-
justifyContent: 'space-around',
93+
justifyContent: 'space-between',
5394
},
5495
info: {
5596
backgroundColor: 'rgba(0, 0, 0, 0.7)',

Libraries/ReactIOS/InspectorOverlay/InspectorOverlay.js

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ var InspectorOverlay = React.createClass({
2424
getInitialState: function() {
2525
return {
2626
frame: null,
27+
pointerY: 0,
2728
hierarchy: [],
29+
selection: -1,
2830
};
2931
},
3032

@@ -42,13 +44,27 @@ var InspectorOverlay = React.createClass({
4244
var publicInstance = instance.getPublicInstance();
4345
this.setState({
4446
hierarchy,
47+
pointerY: locationY,
48+
selection: hierarchy.length - 1,
4549
frame: {left, top, width, height},
4650
style: publicInstance.props ? publicInstance.props.style : {},
4751
});
4852
}
4953
);
5054
},
5155

56+
setSelection(i) {
57+
var instance = this.state.hierarchy[i];
58+
var publicInstance = instance.getPublicInstance();
59+
UIManager.measure(React.findNodeHandle(instance), (x, y, width, height, left, top) => {
60+
this.setState({
61+
frame: {left, top, width, height},
62+
style: publicInstance.props ? publicInstance.props.style : {},
63+
selection: i,
64+
});
65+
});
66+
},
67+
5268
shouldSetResponser: function(e) {
5369
this.findViewForTouchEvent(e);
5470
return true;
@@ -59,9 +75,8 @@ var InspectorOverlay = React.createClass({
5975
var justifyContent = 'flex-end';
6076

6177
if (this.state.frame) {
62-
var distanceToTop = this.state.frame.top;
63-
var distanceToBottom = Dimensions.get('window').height -
64-
(this.state.frame.top + this.state.frame.height);
78+
var distanceToTop = this.state.pointerY;
79+
var distanceToBottom = Dimensions.get('window').height - distanceToTop;
6580

6681
justifyContent = distanceToTop > distanceToBottom
6782
? 'flex-start'
@@ -73,6 +88,8 @@ var InspectorOverlay = React.createClass({
7388
style={this.state.style}
7489
frame={this.state.frame}
7590
hierarchy={this.state.hierarchy}
91+
selection={this.state.selection}
92+
setSelection={this.setSelection}
7693
/>
7794
);
7895
} else {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* Copyright 2004-present Facebook. All Rights Reserved.
3+
*
4+
* @providesModule mapWithSeparator
5+
*/
6+
'use strict';
7+
8+
function mapWithSeparator(array, valueFunction, separatorFunction) {
9+
var results = [];
10+
for (var i = 0; i < array.length; i++) {
11+
results.push(valueFunction(array[i], i, array));
12+
if (i !== array.length - 1) {
13+
results.push(separatorFunction(i));
14+
}
15+
}
16+
return results;
17+
}
18+
19+
module.exports = mapWithSeparator;

0 commit comments

Comments
 (0)