diff --git a/src/components/DatePicker/index.js b/src/components/DatePicker/index.js index 8af550c9dc66..a2ca930690ac 100644 --- a/src/components/DatePicker/index.js +++ b/src/components/DatePicker/index.js @@ -1,18 +1,21 @@ import {setYear} from 'date-fns'; import _ from 'lodash'; import PropTypes from 'prop-types'; -import React, {useEffect, useState} from 'react'; +import React, {forwardRef, useState} from 'react'; import {View} from 'react-native'; -import InputWrapper from '@components/Form/InputWrapper'; import * as Expensicons from '@components/Icon/Expensicons'; +import refPropTypes from '@components/refPropTypes'; import TextInput from '@components/TextInput'; import {propTypes as baseTextInputPropTypes, defaultProps as defaultBaseTextInputPropTypes} from '@components/TextInput/BaseTextInput/baseTextInputPropTypes'; -import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; +import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import CONST from '@src/CONST'; import CalendarPicker from './CalendarPicker'; const propTypes = { + /** React ref being forwarded to the DatePicker input */ + forwardedRef: refPropTypes, + /** * The datepicker supports any value that `new Date()` can parse. * `onInputChange` would always be called with a Date (or null) @@ -33,7 +36,12 @@ const propTypes = { /** A maximum date of calendar to select */ maxDate: PropTypes.objectOf(Date), - ...withLocalizePropTypes, + /** A function that is passed by FormWrapper */ + onInputChange: PropTypes.func.isRequired, + + /** A function that is passed by FormWrapper */ + onTouched: PropTypes.func.isRequired, + ...baseTextInputPropTypes, }; @@ -44,40 +52,33 @@ const datePickerDefaultProps = { value: undefined, }; -function DatePicker({containerStyles, defaultValue, disabled, errorText, inputID, isSmallScreenWidth, label, maxDate, minDate, onInputChange, onTouched, placeholder, translate, value}) { +function DatePicker({forwardedRef, containerStyles, defaultValue, disabled, errorText, inputID, isSmallScreenWidth, label, maxDate, minDate, onInputChange, onTouched, placeholder, value}) { const styles = useThemeStyles(); + const {translate} = useLocalize(); const [selectedDate, setSelectedDate] = useState(value || defaultValue || undefined); - useEffect(() => { - if (selectedDate === value || _.isUndefined(value)) { - return; - } - setSelectedDate(value); - }, [selectedDate, value]); - - useEffect(() => { + const onSelected = (newValue) => { if (_.isFunction(onTouched)) { onTouched(); } if (_.isFunction(onInputChange)) { - onInputChange(selectedDate); + onInputChange(newValue); } - // To keep behavior from class component state update callback, we want to run effect only when the selected date is changed. - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [selectedDate]); + setSelectedDate(newValue); + }; return ( - @@ -103,4 +104,14 @@ DatePicker.propTypes = propTypes; DatePicker.defaultProps = datePickerDefaultProps; DatePicker.displayName = 'DatePicker'; -export default withLocalize(DatePicker); +const DatePickerWithRef = forwardRef((props, ref) => ( + +)); + +DatePickerWithRef.displayName = 'DatePickerWithRef'; + +export default DatePickerWithRef; diff --git a/src/pages/EditRequestCreatedPage.js b/src/pages/EditRequestCreatedPage.js index fbe1b3c782a7..6810414d7921 100644 --- a/src/pages/EditRequestCreatedPage.js +++ b/src/pages/EditRequestCreatedPage.js @@ -2,6 +2,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import DatePicker from '@components/DatePicker'; import FormProvider from '@components/Form/FormProvider'; +import InputWrapper from '@components/Form/InputWrapper'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; import useLocalize from '@hooks/useLocalize'; @@ -34,7 +35,8 @@ function EditRequestCreatedPage({defaultCreated, onSubmit}) { submitButtonText={translate('common.save')} enabledWhenOffline > - - ({value: key, label: translate(`companyStep.incorporationTypes.${key}`)}))} + items={_.map(_.keys(CONST.INCORPORATION_TYPES), (key) => ({ + value: key, + label: translate(`companyStep.incorporationTypes.${key}`), + }))} placeholder={{value: '', label: '-'}} defaultValue={getDefaultStateForField('incorporationType')} shouldSaveDraft /> - {}, }; function IdentityForm(props) { @@ -152,7 +148,6 @@ function IdentityForm(props) { role={CONST.ROLE.PRESENTATION} value={props.values.firstName} defaultValue={props.defaultValues.firstName} - onChangeText={(value) => props.onFieldChange({firstName: value})} errorText={props.errors.firstName ? props.translate('bankAccount.error.firstName') : ''} /> @@ -166,19 +161,18 @@ function IdentityForm(props) { role={CONST.ROLE.PRESENTATION} value={props.values.lastName} defaultValue={props.defaultValues.lastName} - onChangeText={(value) => props.onFieldChange({lastName: value})} errorText={props.errors.lastName ? props.translate('bankAccount.error.lastName') : ''} /> - props.onFieldChange({dob: value})} errorText={dobErrorText} minDate={minDate} maxDate={maxDate} @@ -193,7 +187,6 @@ function IdentityForm(props) { containerStyles={[styles.mt4]} inputMode={CONST.INPUT_MODE.NUMERIC} defaultValue={props.defaultValues.ssnLast4} - onChangeText={(value) => props.onFieldChange({ssnLast4: value})} errorText={props.errors.ssnLast4 ? props.translate('bankAccount.error.ssnLast4') : ''} maxLength={CONST.BANK_ACCOUNT.MAX_LENGTH.SSN} /> @@ -205,7 +198,6 @@ function IdentityForm(props) { values={_.omit(props.values, identityFormInputKeys)} defaultValues={_.omit(props.defaultValues, identityFormInputKeys)} errors={props.errors} - onFieldChange={props.onFieldChange} /> ); diff --git a/src/pages/iou/MoneyRequestDatePage.js b/src/pages/iou/MoneyRequestDatePage.js index b7d1c4002da1..f6159abd73f6 100644 --- a/src/pages/iou/MoneyRequestDatePage.js +++ b/src/pages/iou/MoneyRequestDatePage.js @@ -5,6 +5,7 @@ import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; import DatePicker from '@components/DatePicker'; import FormProvider from '@components/Form/FormProvider'; +import InputWrapper from '@components/Form/InputWrapper'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; import useLocalize from '@hooks/useLocalize'; @@ -99,7 +100,8 @@ function MoneyRequestDatePage({iou, route, selectedTab}) { submitButtonText={translate('common.save')} enabledWhenOffline > - - - -