You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

FormRow.native.js 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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 } from './styles';
  8. import { translate } from '../../base/i18n';
  9. /**
  10. * The type of the React {@code Component} props of {@link FormRow}
  11. */
  12. type Props = {
  13. /**
  14. */
  15. children: Object,
  16. /**
  17. * Prop to decide if a row separator is to be rendered.
  18. */
  19. fieldSeparator: boolean,
  20. /**
  21. * The i18n key of the text label of the form field.
  22. */
  23. i18nLabel: string,
  24. /**
  25. * Invoked to obtain translated strings.
  26. */
  27. t: Function
  28. }
  29. /**
  30. * Implements a React {@code Component} which renders a standardized row
  31. * on a form. The component should have exactly one child component.
  32. */
  33. class FormRow extends Component<Props> {
  34. /**
  35. * Initializes a new {@code FormRow} instance.
  36. *
  37. * @param {Object} props - Component properties.
  38. */
  39. constructor(props) {
  40. super(props);
  41. React.Children.only(this.props.children);
  42. this._getDefaultFieldProps = this._getDefaultFieldProps.bind(this);
  43. this._getRowStyle = this._getRowStyle.bind(this);
  44. }
  45. /**
  46. * Implements React's {@link Component#render()}.
  47. *
  48. * @inheritdoc
  49. * @override
  50. * @returns {ReactElement}
  51. */
  52. render() {
  53. const { t } = this.props;
  54. // Some field types need additional props to look good and standardized
  55. // on a form.
  56. const newChild = React.cloneElement(
  57. this.props.children,
  58. this._getDefaultFieldProps(this.props.children)
  59. );
  60. return (
  61. <View
  62. style = { this._getRowStyle() } >
  63. <View style = { styles.fieldLabelContainer } >
  64. <Text style = { styles.text } >
  65. { t(this.props.i18nLabel) }
  66. </Text>
  67. </View>
  68. <View style = { styles.fieldValueContainer } >
  69. { newChild }
  70. </View>
  71. </View>
  72. );
  73. }
  74. _getDefaultFieldProps: (field: Component<*, *>) => Object;
  75. /**
  76. * Assembles the default props to the field child component of
  77. * this form row.
  78. *
  79. * Currently tested/supported field types:
  80. * - TextInput
  81. * - Switch (needs no addition props ATM).
  82. *
  83. * @private
  84. * @param {Object} field - The field (child) component.
  85. * @returns {Object}
  86. */
  87. _getDefaultFieldProps(field: Object) {
  88. if (field && field.type) {
  89. switch (field.type.displayName) {
  90. case 'TextInput':
  91. return {
  92. style: styles.textInputField,
  93. underlineColorAndroid: ANDROID_UNDERLINE_COLOR
  94. };
  95. }
  96. }
  97. return {};
  98. }
  99. _getRowStyle: () => Array<Object>;
  100. /**
  101. * Assembles the row style array based on the row's props.
  102. *
  103. * @private
  104. * @returns {Array<Object>}
  105. */
  106. _getRowStyle() {
  107. const rowStyle = [
  108. styles.fieldContainer
  109. ];
  110. if (this.props.fieldSeparator) {
  111. rowStyle.push(styles.fieldSeparator);
  112. }
  113. return rowStyle;
  114. }
  115. }
  116. export default translate(connect()(FormRow));