diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/components/forms/DateField/index.android.tsx | 26 | ||||
-rw-r--r-- | src/components/forms/DateField/index.tsx | 19 | ||||
-rw-r--r-- | src/components/forms/DateField/index.web.tsx | 3 | ||||
-rw-r--r-- | src/components/forms/DateField/types.ts | 5 | ||||
-rw-r--r-- | src/screens/Signup/StepInfo/index.tsx | 27 |
5 files changed, 70 insertions, 10 deletions
diff --git a/src/components/forms/DateField/index.android.tsx b/src/components/forms/DateField/index.android.tsx index a6b6993dc..3be555238 100644 --- a/src/components/forms/DateField/index.android.tsx +++ b/src/components/forms/DateField/index.android.tsx @@ -1,4 +1,5 @@ -import React from 'react' +import {useCallback, useImperativeHandle, useState} from 'react' +import {Keyboard} from 'react-native' import DatePicker from 'react-native-date-picker' import {useTheme} from '#/alf' @@ -12,6 +13,7 @@ export const LabelText = TextField.LabelText export function DateField({ value, + inputRef, onChangeDate, label, isInvalid, @@ -20,9 +22,9 @@ export function DateField({ maximumDate, }: DateFieldProps) { const t = useTheme() - const [open, setOpen] = React.useState(false) + const [open, setOpen] = useState(false) - const onChangeInternal = React.useCallback( + const onChangeInternal = useCallback( (date: Date) => { setOpen(false) @@ -32,11 +34,25 @@ export function DateField({ [onChangeDate, setOpen], ) - const onPress = React.useCallback(() => { + useImperativeHandle( + inputRef, + () => ({ + focus: () => { + Keyboard.dismiss() + setOpen(true) + }, + blur: () => { + setOpen(false) + }, + }), + [], + ) + + const onPress = useCallback(() => { setOpen(true) }, []) - const onCancel = React.useCallback(() => { + const onCancel = useCallback(() => { setOpen(false) }, []) diff --git a/src/components/forms/DateField/index.tsx b/src/components/forms/DateField/index.tsx index eca4d5cbd..b8ecf2e6f 100644 --- a/src/components/forms/DateField/index.tsx +++ b/src/components/forms/DateField/index.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {useCallback, useImperativeHandle} from 'react' import {Keyboard, View} from 'react-native' import DatePicker from 'react-native-date-picker' import {msg, Trans} from '@lingui/macro' @@ -25,6 +25,7 @@ export const LabelText = TextField.LabelText */ export function DateField({ value, + inputRef, onChangeDate, testID, label, @@ -36,7 +37,7 @@ export function DateField({ const t = useTheme() const control = Dialog.useDialogControl() - const onChangeInternal = React.useCallback( + const onChangeInternal = useCallback( (date: Date | undefined) => { if (date) { const formatted = toSimpleDateString(date) @@ -46,6 +47,20 @@ export function DateField({ [onChangeDate], ) + useImperativeHandle( + inputRef, + () => ({ + focus: () => { + Keyboard.dismiss() + control.open() + }, + blur: () => { + control.close() + }, + }), + [control], + ) + return ( <> <DateFieldButton diff --git a/src/components/forms/DateField/index.web.tsx b/src/components/forms/DateField/index.web.tsx index 057ea1673..00f58202a 100644 --- a/src/components/forms/DateField/index.web.tsx +++ b/src/components/forms/DateField/index.web.tsx @@ -34,6 +34,7 @@ const Input = TextField.createInput(InputBase as unknown as typeof TextInput) export function DateField({ value, + inputRef, onChangeDate, label, isInvalid, @@ -58,9 +59,9 @@ export function DateField({ <TextField.Icon icon={CalendarDays} /> <Input value={toSimpleDateString(value)} + inputRef={inputRef as React.Ref<TextInput>} label={label} onChange={handleOnChange} - onChangeText={() => {}} testID={testID} accessibilityHint={accessibilityHint} // @ts-expect-error not typed as <input type="date"> even though it is one diff --git a/src/components/forms/DateField/types.ts b/src/components/forms/DateField/types.ts index 1784b884f..560d780b4 100644 --- a/src/components/forms/DateField/types.ts +++ b/src/components/forms/DateField/types.ts @@ -1,7 +1,12 @@ +export type DateFieldRef = { + focus: () => void + blur: () => void +} export type DateFieldProps = { value: string | Date onChangeDate: (date: string) => void label: string + inputRef?: React.Ref<DateFieldRef> isInvalid?: boolean testID?: string accessibilityHint?: string diff --git a/src/screens/Signup/StepInfo/index.tsx b/src/screens/Signup/StepInfo/index.tsx index 4ad899864..18ba38528 100644 --- a/src/screens/Signup/StepInfo/index.tsx +++ b/src/screens/Signup/StepInfo/index.tsx @@ -1,5 +1,5 @@ import React, {useRef} from 'react' -import {View} from 'react-native' +import {TextInput, View} from 'react-native' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import * as EmailValidator from 'email-validator' @@ -11,8 +11,9 @@ import {logger} from '#/logger' import {ScreenTransition} from '#/screens/Login/ScreenTransition' import {is13, is18, useSignupContext} from '#/screens/Signup/state' import {Policies} from '#/screens/Signup/StepInfo/Policies' -import {atoms as a} from '#/alf' +import {atoms as a, native} from '#/alf' import * as DateField from '#/components/forms/DateField' +import {DateFieldRef} from '#/components/forms/DateField/types' import {FormError} from '#/components/forms/FormError' import {HostingProvider} from '#/components/forms/HostingProvider' import * as TextField from '#/components/forms/TextField' @@ -51,6 +52,10 @@ export function StepInfo({ const prevEmailValueRef = useRef<string>(state.email) const passwordValueRef = useRef<string>(state.password) + const emailInputRef = useRef<TextInput>(null) + const passwordInputRef = useRef<TextInput>(null) + const birthdateInputRef = useRef<DateFieldRef>(null) + const [hasWarnedEmail, setHasWarnedEmail] = React.useState<boolean>(false) const tldtsRef = React.useRef<typeof tldts>() @@ -155,6 +160,11 @@ export function StepInfo({ autoCapitalize="none" autoComplete="email" keyboardType="email-address" + returnKeyType="next" + submitBehavior={native('submit')} + onSubmitEditing={native(() => + emailInputRef.current?.focus(), + )} /> </TextField.Root> </View> @@ -167,6 +177,7 @@ export function StepInfo({ <TextField.Icon icon={Envelope} /> <TextField.Input testID="emailInput" + inputRef={emailInputRef} onChangeText={value => { emailValueRef.current = value.trim() if (hasWarnedEmail) { @@ -178,6 +189,11 @@ export function StepInfo({ autoCapitalize="none" autoComplete="email" keyboardType="email-address" + returnKeyType="next" + submitBehavior={native('submit')} + onSubmitEditing={native(() => + passwordInputRef.current?.focus(), + )} /> </TextField.Root> </View> @@ -189,6 +205,7 @@ export function StepInfo({ <TextField.Icon icon={Lock} /> <TextField.Input testID="passwordInput" + inputRef={passwordInputRef} onChangeText={value => { passwordValueRef.current = value }} @@ -197,6 +214,11 @@ export function StepInfo({ secureTextEntry autoComplete="new-password" autoCapitalize="none" + returnKeyType="next" + submitBehavior={native('blurAndSubmit')} + onSubmitEditing={native(() => + birthdateInputRef.current?.focus(), + )} /> </TextField.Root> </View> @@ -206,6 +228,7 @@ export function StepInfo({ </DateField.LabelText> <DateField.DateField testID="date" + inputRef={birthdateInputRef} value={state.dateOfBirth} onChangeDate={date => { dispatch({ |