When pasting from the clipboard into a text field, the value doesn't pass validation through useIMask

315 Views Asked by At

When pasting a value from the clipboard, it should go through validation using the react-imask library, just like it does when I enter a value into the field using the keyboard.

However, currently when I paste from the clipboard, once I remove focus from the input field, the placeholder overlaps the input as if there is no value, and validation doesn't trigger. The form treats it as if the field is empty.

Here is my code:

import React, { ReactElement, useCallback } from 'react';
import { useFormContext, useController } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { useIMask } from 'react-imask';

import { FormTextField } from 'components/molecules/FormTextField';
import { RoleFormState } from 'types/role';

export const PHONE_NUMBER_FIELD_NAME = 'phone';

export function PhoneNumberField(): ReactElement {
  const { t, ready } = useTranslation('roles', { keyPrefix: 'form.fields.phone-number' });
  const { control } = useFormContext<RoleFormState>();
  const { field, fieldState } = useController({
    name: PHONE_NUMBER_FIELD_NAME,
    control,
    defaultValue: '',
  });
  const { ref, unmaskedValue } = useIMask({ mask: '+7 900 000-00-00' });

  const handleChange = useCallback(() => {
    field.onChange(unmaskedValue !== '' ? `79${unmaskedValue}` : '');

    console.log(unmaskedValue);
  }, [field, unmaskedValue]);

  const handlePaste = useCallback(
    (event: React.ClipboardEvent<HTMLInputElement>) => {
      const pastedValue = event.clipboardData.getData('text');
      field.onChange(pastedValue);
    },
    [field]
  );

  if (!ready) {
    return <></>;
  }

  console.log('field.value', field.value);
  console.log('unmaskedValue', unmaskedValue);

  return (
    <FormTextField
      error={!!fieldState?.error?.message}
      helperText={fieldState?.error?.message ? t(`validation.${fieldState.error.message}`) : undefined}
      type="tel"
      label={t('label')}
      variant="outlined"
      placeholder={t<string>('placeholder')}
      fullWidth
      autoComplete="off"
      defaultValue={field.value}
      onChange={handleChange}
      onPaste={handlePaste}
      inputRef={ref}
    />
  );
}

This is how the component looks like when pasting from the clipboard:

enter image description here

If I don't use the handlePaste event handler, the value of field.value remains empty when pasting from the clipboard.

0

There are 0 best solutions below