mirror of
https://github.com/zhigang1992/wallet.git
synced 2026-01-12 22:53:27 +08:00
refactor: improve form validation
This commit is contained in:
14
src/app/common/form-utils.ts
Normal file
14
src/app/common/form-utils.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { useField, useFormikContext } from 'formik';
|
||||
|
||||
function useIsFieldDirty(name: string) {
|
||||
const [field, meta] = useField(name);
|
||||
return field.value !== meta.initialValue;
|
||||
}
|
||||
|
||||
export function useShowFieldError(name: string) {
|
||||
const form = useFormikContext();
|
||||
const [_, meta] = useField(name);
|
||||
const isDirty = useIsFieldDirty(name);
|
||||
|
||||
return (form.submitCount > 0 && meta.error) || (meta.touched && isDirty && meta.error);
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import { useField } from 'formik';
|
||||
import { STX_DECIMALS } from '@shared/constants';
|
||||
import { Money } from '@shared/models/money.model';
|
||||
|
||||
import { useShowFieldError } from '@app/common/form-utils';
|
||||
import { figmaTheme } from '@app/common/utils/figma-theme';
|
||||
import { ErrorLabel } from '@app/components/error-label';
|
||||
|
||||
@@ -51,6 +52,7 @@ export function AmountField({
|
||||
tokenSymbol,
|
||||
}: AmountFieldProps) {
|
||||
const [field, meta, helpers] = useField('amount');
|
||||
const showError = useShowFieldError('amount');
|
||||
const [fontSize, setFontSize] = useState(maxFontSize);
|
||||
const [previousTextLength, setPreviousTextLength] = useState(1);
|
||||
|
||||
@@ -106,7 +108,7 @@ export function AmountField({
|
||||
<Stack
|
||||
alignItems="center"
|
||||
px="extra-loose"
|
||||
spacing={['base', meta.error && meta.touched ? 'base' : '48px']}
|
||||
spacing={['base', showError ? 'base' : '48px']}
|
||||
width="100%"
|
||||
>
|
||||
<Flex alignItems="center" flexDirection="column" onClick={onClickFocusInput}>
|
||||
@@ -137,13 +139,6 @@ export function AmountField({
|
||||
fontWeight={500}
|
||||
autoComplete={autoComplete}
|
||||
{...field}
|
||||
// Custom `onBlur` logic. If value is empty, let's not validate to
|
||||
// avoid unwanted blur interactions such as when interacting with
|
||||
// send max button
|
||||
onBlur={e => {
|
||||
if (!field.value || field.value === '0') return;
|
||||
return field.onBlur(e);
|
||||
}}
|
||||
/>
|
||||
<Text fontSize={fontSize + 'px'} pl="tight">
|
||||
{symbol.toUpperCase()}
|
||||
@@ -151,7 +146,7 @@ export function AmountField({
|
||||
</Flex>
|
||||
<Box mt="12px">{switchableAmount && switchableAmount}</Box>
|
||||
</Flex>
|
||||
{meta.error && meta.touched && (
|
||||
{showError && (
|
||||
<ErrorLabel data-testid={SendCryptoAssetSelectors.AmountFieldInputErrorLabel}>
|
||||
{meta.error}
|
||||
</ErrorLabel>
|
||||
|
||||
@@ -5,17 +5,17 @@ import { Box, Flex } from '@stacks/ui';
|
||||
import { SendCryptoAssetSelectors } from '@tests/selectors/send.selectors';
|
||||
import { useField } from 'formik';
|
||||
|
||||
import { useShowFieldError } from '@app/common/form-utils';
|
||||
import { ErrorLabel } from '@app/components/error-label';
|
||||
|
||||
const closedHeight = 0;
|
||||
const openHeight = 24;
|
||||
|
||||
export function FieldError(props: { name: string }) {
|
||||
export function TextInputFieldError(props: { name: string }) {
|
||||
const { name } = props;
|
||||
const [, meta] = useField(name);
|
||||
const [showHide, setShowHide] = useState(closedHeight);
|
||||
|
||||
const showError = meta.touched && meta.error;
|
||||
const showError = useShowFieldError(name);
|
||||
|
||||
useEffect(() => {
|
||||
if (meta.touched && meta.error) {
|
||||
|
||||
@@ -3,10 +3,11 @@ import { Box, Flex, FlexProps, Input, Text, color } from '@stacks/ui';
|
||||
import { SendCryptoAssetSelectors } from '@tests/selectors/send.selectors';
|
||||
import { useField } from 'formik';
|
||||
|
||||
import { useShowFieldError } from '@app/common/form-utils';
|
||||
import { capitalize } from '@app/common/utils';
|
||||
import { SpaceBetween } from '@app/components/layout/space-between';
|
||||
|
||||
import { FieldError } from './field-error';
|
||||
import { TextInputFieldError } from './field-error';
|
||||
|
||||
interface TextInputFieldProps extends FlexProps {
|
||||
dataTestId?: string;
|
||||
@@ -31,9 +32,9 @@ export function TextInputField({
|
||||
topInputOverlay,
|
||||
...props
|
||||
}: TextInputFieldProps) {
|
||||
const [field, meta] = useField(name);
|
||||
const [field] = useField(name);
|
||||
|
||||
const showError = meta.error && meta.touched;
|
||||
const showError = useShowFieldError(name);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -120,7 +121,7 @@ export function TextInputField({
|
||||
}}
|
||||
/>
|
||||
</Flex>
|
||||
<FieldError name={name} />
|
||||
<TextInputFieldError name={name} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -70,7 +70,8 @@ export function useBtcSendForm() {
|
||||
.string()
|
||||
.concat(btcAddressValidator())
|
||||
.concat(btcAddressNetworkValidator(currentNetwork.chain.bitcoin.network))
|
||||
.concat(notCurrentAddressValidator(currentAccountBtcAddress || '')),
|
||||
.concat(notCurrentAddressValidator(currentAccountBtcAddress || ''))
|
||||
.required('Enter a bitcoin address'),
|
||||
}),
|
||||
|
||||
async chooseTransactionFee(
|
||||
|
||||
Reference in New Issue
Block a user