diff --git a/css/_font.scss b/css/_font.scss
index 41e5ed1c4..5641b64cf 100644
--- a/css/_font.scss
+++ b/css/_font.scss
@@ -24,7 +24,12 @@
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
-
+.icon-arrow_back:before {
+ content: "\e5c4";
+}
+.icon-navigate_before:before {
+ content: "\e408";
+}
.icon-event_note:before {
content: "\e616";
}
diff --git a/fonts/jitsi.eot b/fonts/jitsi.eot
index 7621636a8..475d60124 100755
Binary files a/fonts/jitsi.eot and b/fonts/jitsi.eot differ
diff --git a/fonts/jitsi.svg b/fonts/jitsi.svg
index 15552e68d..d8891378c 100755
--- a/fonts/jitsi.svg
+++ b/fonts/jitsi.svg
@@ -11,7 +11,9 @@
+
+
diff --git a/fonts/jitsi.ttf b/fonts/jitsi.ttf
index e67633eab..f0e20c48e 100755
Binary files a/fonts/jitsi.ttf and b/fonts/jitsi.ttf differ
diff --git a/fonts/jitsi.woff b/fonts/jitsi.woff
index f110bbb59..217d7fb19 100755
Binary files a/fonts/jitsi.woff and b/fonts/jitsi.woff differ
diff --git a/fonts/selection.json b/fonts/selection.json
index ce40a7d5b..350abea45 100755
--- a/fonts/selection.json
+++ b/fonts/selection.json
@@ -1,6 +1,60 @@
{
"IcoMoonType": "selection",
"icons": [
+ {
+ "icon": {
+ "paths": [
+ "M854 470v84h-520l238 240-60 60-342-342 342-342 60 60-238 240h520z"
+ ],
+ "attrs": [],
+ "isMulticolor": false,
+ "isMulticolor2": false,
+ "tags": [
+ "arrow_back"
+ ],
+ "defaultCode": 58820,
+ "grid": 24
+ },
+ "attrs": [],
+ "properties": {
+ "ligatures": "arrow_back",
+ "id": 45,
+ "order": 924,
+ "prevSize": 24,
+ "code": 58820,
+ "name": "arrow_back"
+ },
+ "setIdx": 0,
+ "setId": 2,
+ "iconIdx": 45
+ },
+ {
+ "icon": {
+ "paths": [
+ "M658 316l-196 196 196 196-60 60-256-256 256-256z"
+ ],
+ "attrs": [],
+ "isMulticolor": false,
+ "isMulticolor2": false,
+ "tags": [
+ "navigate_before"
+ ],
+ "defaultCode": 58376,
+ "grid": 24
+ },
+ "attrs": [],
+ "properties": {
+ "ligatures": "chevron_left, navigate_before",
+ "id": 152,
+ "order": 923,
+ "prevSize": 24,
+ "code": 58376,
+ "name": "navigate_before"
+ },
+ "setIdx": 0,
+ "setId": 2,
+ "iconIdx": 152
+ },
{
"icon": {
"paths": [
@@ -24,9 +78,9 @@
"code": 59403,
"name": "public"
},
- "setIdx": 0,
- "setId": 2,
- "iconIdx": 605
+ "setIdx": 1,
+ "setId": 1,
+ "iconIdx": 0
},
{
"icon": {
@@ -53,7 +107,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 0
+ "iconIdx": 1
},
{
"icon": {
@@ -80,7 +134,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 1
+ "iconIdx": 2
},
{
"icon": {
@@ -107,7 +161,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 2
+ "iconIdx": 3
},
{
"icon": {
@@ -134,7 +188,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 3
+ "iconIdx": 4
},
{
"icon": {
@@ -161,7 +215,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 4
+ "iconIdx": 5
},
{
"icon": {
@@ -188,7 +242,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 5
+ "iconIdx": 6
},
{
"icon": {
@@ -217,7 +271,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 6
+ "iconIdx": 7
},
{
"icon": {
@@ -244,7 +298,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 7
+ "iconIdx": 8
},
{
"icon": {
@@ -271,7 +325,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 8
+ "iconIdx": 9
},
{
"icon": {
@@ -300,7 +354,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 9
+ "iconIdx": 10
},
{
"icon": {
@@ -329,7 +383,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 10
+ "iconIdx": 11
},
{
"icon": {
@@ -358,7 +412,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 11
+ "iconIdx": 12
},
{
"icon": {
@@ -387,7 +441,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 12
+ "iconIdx": 13
},
{
"icon": {
@@ -416,7 +470,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 13
+ "iconIdx": 14
},
{
"icon": {
@@ -442,7 +496,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 14
+ "iconIdx": 15
},
{
"icon": {
@@ -468,7 +522,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 15
+ "iconIdx": 16
},
{
"icon": {
@@ -494,7 +548,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 16
+ "iconIdx": 17
},
{
"icon": {
@@ -520,7 +574,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 17
+ "iconIdx": 18
},
{
"icon": {
@@ -546,7 +600,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 18
+ "iconIdx": 19
},
{
"icon": {
@@ -572,7 +626,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 19
+ "iconIdx": 20
},
{
"icon": {
@@ -598,7 +652,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 20
+ "iconIdx": 21
},
{
"icon": {
@@ -616,7 +670,7 @@
"attrs": [],
"properties": {
"id": 10,
- "order": 900,
+ "order": 922,
"ligatures": "expand_less",
"prevSize": 32,
"code": 59679,
@@ -624,7 +678,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 21
+ "iconIdx": 22
},
{
"icon": {
@@ -650,7 +704,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 22
+ "iconIdx": 23
},
{
"icon": {
@@ -676,7 +730,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 23
+ "iconIdx": 24
},
{
"icon": {
@@ -702,7 +756,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 24
+ "iconIdx": 25
},
{
"icon": {
@@ -728,7 +782,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 25
+ "iconIdx": 26
},
{
"icon": {
@@ -754,7 +808,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 26
+ "iconIdx": 27
},
{
"icon": {
@@ -780,7 +834,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 27
+ "iconIdx": 28
},
{
"icon": {
@@ -806,7 +860,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 28
+ "iconIdx": 29
},
{
"icon": {
@@ -832,7 +886,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 29
+ "iconIdx": 30
},
{
"icon": {
@@ -858,7 +912,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 30
+ "iconIdx": 31
},
{
"icon": {
@@ -884,7 +938,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 31
+ "iconIdx": 32
},
{
"icon": {
@@ -910,7 +964,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 32
+ "iconIdx": 33
},
{
"icon": {
@@ -936,7 +990,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 33
+ "iconIdx": 34
},
{
"icon": {
@@ -962,7 +1016,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 34
+ "iconIdx": 35
},
{
"icon": {
@@ -988,7 +1042,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 35
+ "iconIdx": 36
},
{
"icon": {
@@ -1014,7 +1068,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 36
+ "iconIdx": 37
},
{
"icon": {
@@ -1040,7 +1094,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 37
+ "iconIdx": 38
},
{
"icon": {
@@ -1066,7 +1120,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 38
+ "iconIdx": 39
},
{
"icon": {
@@ -1092,7 +1146,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 39
+ "iconIdx": 40
},
{
"icon": {
@@ -1118,7 +1172,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 40
+ "iconIdx": 41
},
{
"icon": {
@@ -1144,7 +1198,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 41
+ "iconIdx": 42
},
{
"icon": {
@@ -1170,7 +1224,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 42
+ "iconIdx": 43
},
{
"icon": {
@@ -1199,7 +1253,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 43
+ "iconIdx": 44
},
{
"icon": {
@@ -1229,7 +1283,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 44
+ "iconIdx": 45
},
{
"icon": {
@@ -1259,7 +1313,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 45
+ "iconIdx": 46
},
{
"icon": {
@@ -1285,7 +1339,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 46
+ "iconIdx": 47
},
{
"icon": {
@@ -1311,7 +1365,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 47
+ "iconIdx": 48
},
{
"icon": {
@@ -1337,7 +1391,7 @@
},
"setIdx": 1,
"setId": 1,
- "iconIdx": 48
+ "iconIdx": 49
}
],
"height": 1024,
diff --git a/lang/main.json b/lang/main.json
index b7002dcc3..a3c0bda4d 100644
--- a/lang/main.json
+++ b/lang/main.json
@@ -539,9 +539,11 @@
"tooltip": "Get access info about the meeting"
},
"profileModal": {
+ "conferenceSection": "Conference",
"displayName": "Display name",
"email": "Email",
"header": "Settings",
+ "profileSection": "Profile",
"serverURL": "Server URL",
"startWithAudioMuted": "Start with audio muted",
"startWithVideoMuted": "Start with video muted"
diff --git a/react/features/app-settings/actions.js b/react/features/app-settings/actions.js
index 359b96cf1..6b92cd21f 100644
--- a/react/features/app-settings/actions.js
+++ b/react/features/app-settings/actions.js
@@ -1,9 +1,6 @@
/* @flow */
-import {
- HIDE_APP_SETTINGS,
- SHOW_APP_SETTINGS
-} from './actionTypes';
+import { HIDE_APP_SETTINGS, SHOW_APP_SETTINGS } from './actionTypes';
/**
* Redux-signals the request to open the app settings modal.
diff --git a/react/features/app-settings/components/AbstractAppSettings.js b/react/features/app-settings/components/AbstractAppSettings.js
index 934c404ba..0827656bf 100644
--- a/react/features/app-settings/components/AbstractAppSettings.js
+++ b/react/features/app-settings/components/AbstractAppSettings.js
@@ -10,6 +10,16 @@ import { getProfile, updateProfile } from '../../base/profile';
*/
type Props = {
+ /**
+ * The current aspect ratio of the screen.
+ */
+ _aspectRatio: Symbol,
+
+ /**
+ * The default URL for when there is no custom URL set in the profile.
+ */
+ _serverURL: string,
+
/**
* The current profile object.
*/
@@ -26,45 +36,13 @@ type Props = {
dispatch: Dispatch<*>
};
-/**
- * The type of the React {@code Component} state of {@link AbstractAppSettings}.
- */
-type State = {
-
- /**
- * The display name field value on the settings screen.
- */
- displayName: string,
-
- /**
- * The email field value on the settings screen.
- */
- email: string,
-
- /**
- * The server url field value on the settings screen.
- */
- serverURL: string,
-
- /**
- * The start audio muted switch value on the settings screen.
- */
- startWithAudioMuted: boolean,
-
- /**
- * The start video muted switch value on the settings screen.
- */
- startWithVideoMuted: boolean
-}
-
/**
* Base (abstract) class for container component rendering
* the app settings page.
*
* @abstract
*/
-export class AbstractAppSettings extends Component {
-
+export class AbstractAppSettings extends Component {
/**
* Initializes a new {@code AbstractAppSettings} instance.
*
@@ -76,38 +54,14 @@ export class AbstractAppSettings extends Component {
this._onChangeDisplayName = this._onChangeDisplayName.bind(this);
this._onChangeEmail = this._onChangeEmail.bind(this);
- this._onChangeServerName = this._onChangeServerName.bind(this);
+ this._onChangeServerURL = this._onChangeServerURL.bind(this);
this._onRequestClose = this._onRequestClose.bind(this);
- this._onSaveDisplayName = this._onSaveDisplayName.bind(this);
- this._onSaveEmail = this._onSaveEmail.bind(this);
- this._onSaveServerName = this._onSaveServerName.bind(this);
this._onStartAudioMutedChange
= this._onStartAudioMutedChange.bind(this);
this._onStartVideoMutedChange
= this._onStartVideoMutedChange.bind(this);
}
- /**
- * Invokes React's {@link Component#componentWillReceiveProps()} to make
- * sure we have the state Initialized on component mount.
- *
- * @inheritdoc
- */
- componentWillMount() {
- this._updateStateFromProps(this.props);
- }
-
- /**
- * Implements React's {@link Component#componentWillReceiveProps()}. Invoked
- * before this mounted component receives new props.
- *
- * @inheritdoc
- * @param {Props} nextProps - New props component will receive.
- */
- componentWillReceiveProps(nextProps: Props) {
- this._updateStateFromProps(nextProps);
- }
-
_onChangeDisplayName: (string) => void;
/**
@@ -118,7 +72,7 @@ export class AbstractAppSettings extends Component {
* @returns {void}
*/
_onChangeDisplayName(text) {
- this.setState({
+ this._updateProfile({
displayName: text
});
}
@@ -133,12 +87,12 @@ export class AbstractAppSettings extends Component {
* @returns {void}
*/
_onChangeEmail(text) {
- this.setState({
+ this._updateProfile({
email: text
});
}
- _onChangeServerName: (string) => void;
+ _onChangeServerURL: (string) => void;
/**
* Handles the server name field value change.
@@ -147,8 +101,8 @@ export class AbstractAppSettings extends Component {
* @param {string} text - The server URL typed in the server field.
* @returns {void}
*/
- _onChangeServerName(text) {
- this.setState({
+ _onChangeServerURL(text) {
+ this._updateProfile({
serverURL: text
});
}
@@ -156,7 +110,7 @@ export class AbstractAppSettings extends Component {
_onRequestClose: () => void;
/**
- * Handles the hardware back button.
+ * Handles the back button.
*
* @returns {void}
*/
@@ -164,61 +118,6 @@ export class AbstractAppSettings extends Component {
this.props.dispatch(hideAppSettings());
}
- _onSaveDisplayName: () => void;
-
- /**
- * Handles the display name field onEndEditing.
- *
- * @protected
- * @returns {void}
- */
- _onSaveDisplayName() {
- this._updateProfile({
- displayName: this.state.displayName
- });
- }
-
- _onSaveEmail: () => void;
-
- /**
- * Handles the email field onEndEditing.
- *
- * @protected
- * @returns {void}
- */
- _onSaveEmail() {
- this._updateProfile({
- email: this.state.email
- });
- }
-
- _onSaveServerName: () => void;
-
- /**
- * Handles the server name field onEndEditing.
- *
- * @protected
- * @returns {void}
- */
- _onSaveServerName() {
- let serverURL;
-
- if (this.state.serverURL.endsWith('/')) {
- serverURL = this.state.serverURL.substr(
- 0, this.state.serverURL.length - 1
- );
- } else {
- serverURL = this.state.serverURL;
- }
-
- this._updateProfile({
- defaultURL: serverURL
- });
- this.setState({
- serverURL
- });
- }
-
_onStartAudioMutedChange: (boolean) => void;
/**
@@ -230,10 +129,6 @@ export class AbstractAppSettings extends Component {
* @returns {void}
*/
_onStartAudioMutedChange(newValue) {
- this.setState({
- startWithAudioMuted: newValue
- });
-
this._updateProfile({
startWithAudioMuted: newValue
});
@@ -250,10 +145,6 @@ export class AbstractAppSettings extends Component {
* @returns {void}
*/
_onStartVideoMutedChange(newValue) {
- this.setState({
- startWithVideoMuted: newValue
- });
-
this._updateProfile({
startWithVideoMuted: newValue
});
@@ -274,25 +165,6 @@ export class AbstractAppSettings extends Component {
...updateObject
}));
}
-
- _updateStateFromProps: (Object) => void;
-
- /**
- * Updates the component state when (new) props are received.
- *
- * @private
- * @param {Object} props - The component's props.
- * @returns {void}
- */
- _updateStateFromProps(props) {
- this.setState({
- displayName: props._profile.displayName,
- email: props._profile.email,
- serverURL: props._profile.defaultURL,
- startWithAudioMuted: props._profile.startWithAudioMuted,
- startWithVideoMuted: props._profile.startWithVideoMuted
- });
- }
}
/**
@@ -304,8 +176,13 @@ export class AbstractAppSettings extends Component {
* @returns {Object}
*/
export function _mapStateToProps(state: Object) {
+ const _serverURL = state['features/app'].app._getDefaultURL();
+ const _profile = getProfile(state);
+
return {
- _profile: getProfile(state),
+ _aspectRatio: state['features/base/aspect-ratio'].aspectRatio,
+ _serverURL,
+ _profile,
_visible: state['features/app-settings'].visible
};
}
diff --git a/react/features/app-settings/components/AppSettings.native.js b/react/features/app-settings/components/AppSettings.native.js
index afd5c0118..206330a89 100644
--- a/react/features/app-settings/components/AppSettings.native.js
+++ b/react/features/app-settings/components/AppSettings.native.js
@@ -1,6 +1,7 @@
import React from 'react';
import {
Modal,
+ ScrollView,
Switch,
Text,
TextInput,
@@ -11,10 +12,16 @@ import {
_mapStateToProps,
AbstractAppSettings
} from './AbstractAppSettings';
+import BackButton from './BackButton';
import FormRow from './FormRow';
-import styles from './styles';
+import FormSectionHeader from './FormSectionHeader';
+import styles, { HEADER_PADDING } from './styles';
+import { getSafetyOffset } from '../functions.native';
+
+import { ASPECT_RATIO_NARROW } from '../../base/aspect-ratio';
import { translate } from '../../base/i18n';
+import { isIPad } from '../../base/react';
/**
* The native container rendering the app settings page.
@@ -22,6 +29,16 @@ import { translate } from '../../base/i18n';
* @extends AbstractAppSettings
*/
class AppSettings extends AbstractAppSettings {
+ /**
+ * Instantiates a new {@code AppSettings} instance.
+ *
+ * @inheritdoc
+ */
+ constructor(props) {
+ super(props);
+
+ this._getSafetyPadding = this._getSafetyPadding.bind(this);
+ }
/**
* Implements React's {@link Component#render()}, renders the settings page.
@@ -30,49 +47,62 @@ class AppSettings extends AbstractAppSettings {
* @returns {ReactElement}
*/
render() {
- const { t } = this.props;
+ const { _profile, t } = this.props;
+
+ // FIXME: presentationStyle is added to workaround
+ // orientation issue on iOS
return (
-
+
+
{ t('profileModal.header') }
-
-
-
-
+
+
+ value = { _profile.displayName } />
+ value = { _profile.email } />
+
+
+
+
+ value = {
+ _profile.startWithAudioMuted
+ } />
@@ -89,12 +121,33 @@ class AppSettings extends AbstractAppSettings {
onValueChange = {
this._onStartVideoMutedChange
}
- value = { this.state.startWithVideoMuted } />
+ value = {
+ _profile.startWithVideoMuted
+ } />
-
+
);
}
+
+ /**
+ * Calculates header safety padding for mobile devices.
+ * See comment in functions.js.
+ *
+ * @private
+ * @returns {Object}
+ */
+ _getSafetyPadding() {
+ if (isIPad() || this.props._aspectRatio === ASPECT_RATIO_NARROW) {
+ const safeOffset = Math.max(getSafetyOffset(), HEADER_PADDING);
+
+ return {
+ paddingTop: safeOffset
+ };
+ }
+
+ return undefined;
+ }
}
export default translate(connect(_mapStateToProps)(AppSettings));
diff --git a/react/features/app-settings/components/BackButton.native.js b/react/features/app-settings/components/BackButton.native.js
new file mode 100644
index 000000000..98673b8f5
--- /dev/null
+++ b/react/features/app-settings/components/BackButton.native.js
@@ -0,0 +1,56 @@
+// @flow
+
+import React, { Component } from 'react';
+import { TouchableOpacity } from 'react-native';
+
+import styles from './styles';
+
+import { Icon } from '../../base/font-icons';
+import { Platform } from '../../base/react';
+
+/**
+* The icon glyph to be used on a specific platform.
+*/
+const BACK_ICON = Platform.OS === 'android' ? 'arrow_back' : 'navigate_before';
+
+/**
+* The type of the React {@code Component} props of {@link BackButton}
+*/
+type Props = {
+
+ /**
+ * The action to be performed when the button is pressed.
+ */
+ onPress: Function,
+
+ /**
+ * An external style object passed to the component.
+ */
+ style: Object
+};
+
+/**
+ * A component rendering a back button that looks native on both platforms.
+ */
+export default class BackButton extends Component {
+ /**
+ * Implements React's {@link Component#render()}, renders the button.
+ *
+ * @inheritdoc
+ * @returns {ReactElement}
+ */
+ render() {
+ return (
+
+
+
+ );
+ }
+}
diff --git a/react/features/app-settings/components/FormRow.native.js b/react/features/app-settings/components/FormRow.native.js
index 0c4150792..46f0b50a3 100644
--- a/react/features/app-settings/components/FormRow.native.js
+++ b/react/features/app-settings/components/FormRow.native.js
@@ -6,8 +6,11 @@ import {
View } from 'react-native';
import { connect } from 'react-redux';
-import styles, { ANDROID_UNDERLINE_COLOR } from './styles';
+import styles, { ANDROID_UNDERLINE_COLOR, CONTAINER_PADDING } from './styles';
+import { getSafetyOffset } from '../functions';
+
+import { ASPECT_RATIO_WIDE } from '../../base/aspect-ratio';
import { translate } from '../../base/i18n';
/**
@@ -15,6 +18,11 @@ import { translate } from '../../base/i18n';
*/
type Props = {
+ /**
+ * The current aspect ratio of the screen.
+ */
+ _aspectRatio: Symbol,
+
/**
*/
children: Object,
@@ -40,7 +48,6 @@ type Props = {
* on a form. The component should have exactly one child component.
*/
class FormRow extends Component {
-
/**
* Initializes a new {@code FormRow} instance.
*
@@ -118,6 +125,7 @@ class FormRow extends Component {
/**
* Assembles the row style array based on the row's props.
+ * For padding, see comment in functions.js.
*
* @private
* @returns {Array