import {useCallback, useImperativeHandle, useState} from 'react' import {Keyboard, View} from 'react-native' import DatePicker from 'react-native-date-picker' import {msg} from '@lingui/core/macro' import {useLingui} from '@lingui/react' import {Trans} from '@lingui/react/macro' import {atoms as a, useTheme} from '#/alf' import {Button, ButtonText} from '#/components/Button' import * as Dialog from '#/components/Dialog' import {type DateFieldProps} from '#/components/forms/DateField/types' import {toSimpleDateString} from '#/components/forms/DateField/utils' import * as TextField from '#/components/forms/TextField' import {DateFieldButton} from './index.shared' export * as utils from '#/components/forms/DateField/utils' export const LabelText = TextField.LabelText /** * Date-only input. Accepts a string in the format YYYY-MM-DD, or a Date object. * Date objects are converted to strings in the format YYYY-MM-DD. * Returns a string in the format YYYY-MM-DD. * * To generate a string in the format YYYY-MM-DD from a Date object, use the * `utils.toSimpleDateString(Date)` export of this file. */ export function DateField({ value, inputRef, onChangeDate, onConfirm, placeholder, testID, label, isInvalid, accessibilityHint, maximumDate, }: DateFieldProps) { const {_, i18n} = useLingui() const t = useTheme() const control = Dialog.useDialogControl() /* * The picker requires a valid date, so when value is empty we fall back to * maximumDate (if set) or today. Draft state lets the picker scroll even when * the parent does not echo value back (e.g. a clearable field). */ const fallbackDate = maximumDate ? toSimpleDateString(maximumDate) : toSimpleDateString(new Date()) const [draft, setDraft] = useState(() => value === '' ? fallbackDate : toSimpleDateString(value), ) const onChangeInternal = useCallback( (date: Date | undefined) => { if (date) { const formatted = toSimpleDateString(date) setDraft(formatted) onChangeDate(formatted) } }, [onChangeDate], ) useImperativeHandle( inputRef, () => ({ focus: () => { Keyboard.dismiss() setDraft(value === '' ? fallbackDate : toSimpleDateString(value)) control.open() }, blur: () => { control.close() }, }), [control, value, fallbackDate], ) return ( <> { Keyboard.dismiss() setDraft(value === '' ? fallbackDate : toSimpleDateString(value)) control.open() }} isInvalid={isInvalid} accessibilityHint={accessibilityHint} /> ) }