ElementProperties.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /**
  2. * Copyright (c) Facebook, Inc. and its affiliates.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. *
  7. * @format
  8. * @flow
  9. */
  10. 'use strict';
  11. const BoxInspector = require('./BoxInspector');
  12. const React = require('react');
  13. const StyleInspector = require('./StyleInspector');
  14. const StyleSheet = require('../StyleSheet/StyleSheet');
  15. const Text = require('../Text/Text');
  16. const TouchableHighlight = require('../Components/Touchable/TouchableHighlight');
  17. const TouchableWithoutFeedback = require('../Components/Touchable/TouchableWithoutFeedback');
  18. const View = require('../Components/View/View');
  19. const flattenStyle = require('../StyleSheet/flattenStyle');
  20. const mapWithSeparator = require('../Utilities/mapWithSeparator');
  21. const openFileInEditor = require('../Core/Devtools/openFileInEditor');
  22. import type {ViewStyleProp} from '../StyleSheet/StyleSheet';
  23. type Props = $ReadOnly<{|
  24. hierarchy: Array<{|name: string|}>,
  25. style?: ?ViewStyleProp,
  26. source?: ?{
  27. fileName?: string,
  28. lineNumber?: number,
  29. ...
  30. },
  31. frame?: ?Object,
  32. selection?: ?number,
  33. setSelection?: number => mixed,
  34. |}>;
  35. class ElementProperties extends React.Component<Props> {
  36. render(): React.Node {
  37. const style = flattenStyle(this.props.style);
  38. const selection = this.props.selection;
  39. let openFileButton;
  40. const source = this.props.source;
  41. const {fileName, lineNumber} = source || {};
  42. if (fileName && lineNumber) {
  43. const parts = fileName.split('/');
  44. const fileNameShort = parts[parts.length - 1];
  45. openFileButton = (
  46. <TouchableHighlight
  47. style={styles.openButton}
  48. onPress={openFileInEditor.bind(null, fileName, lineNumber)}>
  49. <Text style={styles.openButtonTitle} numberOfLines={1}>
  50. {fileNameShort}:{lineNumber}
  51. </Text>
  52. </TouchableHighlight>
  53. );
  54. }
  55. // Without the `TouchableWithoutFeedback`, taps on this inspector pane
  56. // would change the inspected element to whatever is under the inspector
  57. return (
  58. <TouchableWithoutFeedback>
  59. <View style={styles.info}>
  60. <View style={styles.breadcrumb}>
  61. {mapWithSeparator(
  62. this.props.hierarchy,
  63. (hierarchyItem, i) => (
  64. <TouchableHighlight
  65. key={'item-' + i}
  66. style={[styles.breadItem, i === selection && styles.selected]}
  67. // $FlowFixMe found when converting React.createClass to ES6
  68. onPress={() => this.props.setSelection(i)}>
  69. <Text style={styles.breadItemText}>{hierarchyItem.name}</Text>
  70. </TouchableHighlight>
  71. ),
  72. i => (
  73. <Text key={'sep-' + i} style={styles.breadSep}>
  74. &#9656;
  75. </Text>
  76. ),
  77. )}
  78. </View>
  79. <View style={styles.row}>
  80. <View style={styles.col}>
  81. <StyleInspector style={style} />
  82. {openFileButton}
  83. </View>
  84. {<BoxInspector style={style} frame={this.props.frame} />}
  85. </View>
  86. </View>
  87. </TouchableWithoutFeedback>
  88. );
  89. }
  90. }
  91. const styles = StyleSheet.create({
  92. breadSep: {
  93. fontSize: 8,
  94. color: 'white',
  95. },
  96. breadcrumb: {
  97. flexDirection: 'row',
  98. flexWrap: 'wrap',
  99. alignItems: 'flex-start',
  100. marginBottom: 5,
  101. },
  102. selected: {
  103. borderColor: 'white',
  104. borderRadius: 5,
  105. },
  106. breadItem: {
  107. borderWidth: 1,
  108. borderColor: 'transparent',
  109. marginHorizontal: 2,
  110. },
  111. breadItemText: {
  112. fontSize: 10,
  113. color: 'white',
  114. marginHorizontal: 5,
  115. },
  116. row: {
  117. flexDirection: 'row',
  118. alignItems: 'center',
  119. justifyContent: 'space-between',
  120. },
  121. col: {
  122. flex: 1,
  123. },
  124. info: {
  125. padding: 10,
  126. },
  127. openButton: {
  128. padding: 10,
  129. backgroundColor: '#000',
  130. marginVertical: 5,
  131. marginRight: 5,
  132. borderRadius: 2,
  133. },
  134. openButtonTitle: {
  135. color: 'white',
  136. fontSize: 8,
  137. },
  138. });
  139. module.exports = ElementProperties;