您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

FormRow.native.js 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /* @flow */
  2. import React, { Component } from 'react';
  3. import {
  4. Text,
  5. View } from 'react-native';
  6. import { connect } from 'react-redux';
  7. import styles, { ANDROID_UNDERLINE_COLOR, CONTAINER_PADDING } from './styles';
  8. import { getSafetyOffset } from '../functions';
  9. import { ASPECT_RATIO_WIDE } from '../../base/aspect-ratio';
  10. import { translate } from '../../base/i18n';
  11. /**
  12. * The type of the React {@code Component} props of {@link FormRow}
  13. */
  14. type Props = {
  15. /**
  16. * The current aspect ratio of the screen.
  17. */
  18. _aspectRatio: Symbol,
  19. /**
  20. */
  21. children: Object,
  22. /**
  23. * Prop to decide if a row separator is to be rendered.
  24. */
  25. fieldSeparator: boolean,
  26. /**
  27. * The i18n key of the text label of the form field.
  28. */
  29. i18nLabel: string,
  30. /**
  31. * Invoked to obtain translated strings.
  32. */
  33. t: Function
  34. }
  35. /**
  36. * Implements a React {@code Component} which renders a standardized row
  37. * on a form. The component should have exactly one child component.
  38. */
  39. class FormRow extends Component<Props> {
  40. /**
  41. * Initializes a new {@code FormRow} instance.
  42. *
  43. * @param {Object} props - Component properties.
  44. */
  45. constructor(props) {
  46. super(props);
  47. React.Children.only(this.props.children);
  48. this._getDefaultFieldProps = this._getDefaultFieldProps.bind(this);
  49. this._getRowStyle = this._getRowStyle.bind(this);
  50. }
  51. /**
  52. * Implements React's {@link Component#render()}.
  53. *
  54. * @inheritdoc
  55. * @override
  56. * @returns {ReactElement}
  57. */
  58. render() {
  59. const { t } = this.props;
  60. // Some field types need additional props to look good and standardized
  61. // on a form.
  62. const newChild = React.cloneElement(
  63. this.props.children,
  64. this._getDefaultFieldProps(this.props.children)
  65. );
  66. return (
  67. <View
  68. style = { this._getRowStyle() } >
  69. <View style = { styles.fieldLabelContainer } >
  70. <Text style = { styles.text } >
  71. { t(this.props.i18nLabel) }
  72. </Text>
  73. </View>
  74. <View style = { styles.fieldValueContainer } >
  75. { newChild }
  76. </View>
  77. </View>
  78. );
  79. }
  80. _getDefaultFieldProps: (field: Component<*, *>) => Object;
  81. /**
  82. * Assembles the default props to the field child component of
  83. * this form row.
  84. *
  85. * Currently tested/supported field types:
  86. * - TextInput
  87. * - Switch (needs no addition props ATM).
  88. *
  89. * @private
  90. * @param {Object} field - The field (child) component.
  91. * @returns {Object}
  92. */
  93. _getDefaultFieldProps(field: Object) {
  94. if (field && field.type) {
  95. switch (field.type.displayName) {
  96. case 'TextInput':
  97. return {
  98. style: styles.textInputField,
  99. underlineColorAndroid: ANDROID_UNDERLINE_COLOR
  100. };
  101. }
  102. }
  103. return {};
  104. }
  105. _getRowStyle: () => Array<Object>;
  106. /**
  107. * Assembles the row style array based on the row's props.
  108. * For padding, see comment in functions.js.
  109. *
  110. * @private
  111. * @returns {Array<Object>}
  112. */
  113. _getRowStyle() {
  114. const rowStyle = [
  115. styles.fieldContainer
  116. ];
  117. if (this.props.fieldSeparator) {
  118. rowStyle.push(styles.fieldSeparator);
  119. }
  120. if (this.props._aspectRatio === ASPECT_RATIO_WIDE) {
  121. const safeOffset = Math.max(
  122. getSafetyOffset() - CONTAINER_PADDING, 0
  123. );
  124. rowStyle.push({
  125. marginLeft: safeOffset,
  126. marginRight: safeOffset
  127. });
  128. }
  129. return rowStyle;
  130. }
  131. }
  132. /**
  133. * Maps (parts of) the redux state to the React {@code Component} props of
  134. * {@code FormRow}.
  135. *
  136. * @param {Object} state - The redux state.
  137. * @protected
  138. * @returns {Object}
  139. */
  140. export function _mapStateToProps(state: Object) {
  141. return {
  142. _aspectRatio: state['features/base/aspect-ratio'].aspectRatio
  143. };
  144. }
  145. export default translate(connect(_mapStateToProps)(FormRow));