2018-01-18 21:28:25 +00:00
|
|
|
// @flow
|
2017-12-14 17:02:32 +00:00
|
|
|
|
|
|
|
import React, { Component } from 'react';
|
2018-01-18 21:28:25 +00:00
|
|
|
import { Text, View } from 'react-native';
|
2017-12-14 17:02:32 +00:00
|
|
|
|
2022-07-28 07:28:29 +00:00
|
|
|
import { translate } from '../../../base/i18n';
|
2017-12-14 17:02:32 +00:00
|
|
|
|
2019-11-13 08:57:42 +00:00
|
|
|
import styles, { ANDROID_UNDERLINE_COLOR, PLACEHOLDER_COLOR } from './styles';
|
2018-01-18 21:28:25 +00:00
|
|
|
|
2017-12-14 17:02:32 +00:00
|
|
|
/**
|
2021-11-04 21:10:43 +00:00
|
|
|
* The type of the React {@code Component} props of {@link FormRow}.
|
2018-01-18 21:28:25 +00:00
|
|
|
*/
|
2017-12-14 17:02:32 +00:00
|
|
|
type Props = {
|
|
|
|
|
|
|
|
/**
|
2018-01-18 21:28:25 +00:00
|
|
|
*
|
|
|
|
*/
|
2017-12-14 17:02:32 +00:00
|
|
|
children: Object,
|
|
|
|
|
|
|
|
/**
|
2018-01-18 21:28:25 +00:00
|
|
|
* Prop to decide if a row separator is to be rendered.
|
|
|
|
*/
|
2017-12-14 17:02:32 +00:00
|
|
|
fieldSeparator: boolean,
|
|
|
|
|
|
|
|
/**
|
2018-01-18 21:28:25 +00:00
|
|
|
* The i18n key of the text label of the form field.
|
|
|
|
*/
|
2018-05-29 12:51:55 +00:00
|
|
|
label: string,
|
2017-12-14 17:02:32 +00:00
|
|
|
|
2020-03-25 10:51:35 +00:00
|
|
|
/**
|
|
|
|
* One of 'row' (default) or 'column'.
|
|
|
|
*/
|
|
|
|
layout: string,
|
|
|
|
|
2017-12-14 17:02:32 +00:00
|
|
|
/**
|
|
|
|
* Invoked to obtain translated strings.
|
|
|
|
*/
|
|
|
|
t: Function
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-01-18 21:28:25 +00:00
|
|
|
* Implements a React {@code Component} which renders a standardized row on a
|
|
|
|
* form. The component should have exactly one child component.
|
2017-12-14 17:02:32 +00:00
|
|
|
*/
|
|
|
|
class FormRow extends Component<Props> {
|
|
|
|
/**
|
|
|
|
* Initializes a new {@code FormRow} instance.
|
|
|
|
*
|
|
|
|
* @param {Object} props - Component properties.
|
|
|
|
*/
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
|
|
|
|
React.Children.only(this.props.children);
|
2018-02-26 16:14:46 +00:00
|
|
|
|
2017-12-14 17:02:32 +00:00
|
|
|
this._getDefaultFieldProps = this._getDefaultFieldProps.bind(this);
|
|
|
|
this._getRowStyle = this._getRowStyle.bind(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Implements React's {@link Component#render()}.
|
|
|
|
*
|
|
|
|
* @inheritdoc
|
|
|
|
* @override
|
|
|
|
* @returns {ReactElement}
|
|
|
|
*/
|
|
|
|
render() {
|
2020-03-25 10:51:35 +00:00
|
|
|
const { layout, t } = this.props;
|
2017-12-14 17:02:32 +00:00
|
|
|
|
|
|
|
// Some field types need additional props to look good and standardized
|
|
|
|
// on a form.
|
2018-02-26 16:14:46 +00:00
|
|
|
const newChild
|
|
|
|
= React.cloneElement(
|
|
|
|
this.props.children,
|
|
|
|
this._getDefaultFieldProps(this.props.children));
|
2017-12-14 17:02:32 +00:00
|
|
|
|
|
|
|
return (
|
|
|
|
<View
|
|
|
|
style = { this._getRowStyle() } >
|
|
|
|
<View style = { styles.fieldLabelContainer } >
|
2018-02-02 14:48:43 +00:00
|
|
|
<Text
|
|
|
|
style = { [
|
2018-02-26 16:14:46 +00:00
|
|
|
styles.text,
|
2020-03-25 10:51:35 +00:00
|
|
|
styles.fieldLabelText,
|
|
|
|
layout === 'column' ? styles.fieldLabelTextColumn : undefined
|
2018-02-02 14:48:43 +00:00
|
|
|
] } >
|
2018-05-29 12:51:55 +00:00
|
|
|
{ t(this.props.label) }
|
2017-12-14 17:02:32 +00:00
|
|
|
</Text>
|
|
|
|
</View>
|
|
|
|
<View style = { styles.fieldValueContainer } >
|
|
|
|
{ newChild }
|
|
|
|
</View>
|
|
|
|
</View>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
_getDefaultFieldProps: (field: Component<*, *>) => Object;
|
|
|
|
|
|
|
|
/**
|
2018-01-18 21:28:25 +00:00
|
|
|
* Assembles the default props to the field child component of this form
|
|
|
|
* row.
|
|
|
|
*
|
|
|
|
* Currently tested/supported field types:
|
|
|
|
* - TextInput
|
|
|
|
* - Switch (needs no addition props ATM).
|
|
|
|
*
|
|
|
|
* @param {Object} field - The field (child) component.
|
2018-02-26 16:14:46 +00:00
|
|
|
* @private
|
2018-01-18 21:28:25 +00:00
|
|
|
* @returns {Object}
|
|
|
|
*/
|
2017-12-14 17:02:32 +00:00
|
|
|
_getDefaultFieldProps(field: Object) {
|
|
|
|
if (field && field.type) {
|
|
|
|
switch (field.type.displayName) {
|
|
|
|
case 'TextInput':
|
|
|
|
return {
|
2019-11-13 08:57:42 +00:00
|
|
|
placeholderTextColor: PLACEHOLDER_COLOR,
|
2020-03-25 10:51:35 +00:00
|
|
|
style: [
|
|
|
|
styles.textInputField,
|
|
|
|
this.props.layout === 'column' ? styles.textInputFieldColumn : undefined
|
|
|
|
],
|
2017-12-14 17:02:32 +00:00
|
|
|
underlineColorAndroid: ANDROID_UNDERLINE_COLOR
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
_getRowStyle: () => Array<Object>;
|
|
|
|
|
|
|
|
/**
|
2018-02-02 14:48:43 +00:00
|
|
|
* Assembles the row style array based on the row's props.
|
2018-01-18 21:28:25 +00:00
|
|
|
*
|
|
|
|
* @private
|
|
|
|
* @returns {Array<Object>}
|
|
|
|
*/
|
2017-12-14 17:02:32 +00:00
|
|
|
_getRowStyle() {
|
2020-03-25 10:51:35 +00:00
|
|
|
const { fieldSeparator, layout } = this.props;
|
2017-12-14 17:02:32 +00:00
|
|
|
const rowStyle = [
|
|
|
|
styles.fieldContainer
|
|
|
|
];
|
|
|
|
|
2020-03-25 10:51:35 +00:00
|
|
|
if (fieldSeparator) {
|
2017-12-14 17:02:32 +00:00
|
|
|
rowStyle.push(styles.fieldSeparator);
|
|
|
|
}
|
|
|
|
|
2020-03-25 10:51:35 +00:00
|
|
|
if (layout === 'column') {
|
|
|
|
rowStyle.push(
|
|
|
|
styles.fieldContainerColumn
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2017-12-14 17:02:32 +00:00
|
|
|
return rowStyle;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-02 14:48:43 +00:00
|
|
|
export default translate(FormRow);
|