Executando verificação de segurança...
1

Esse post salvou minha task, obrigado OP. Fiz alguns ajustes, e implementei essa lógica no React Native, com mascara para CPF e CNPJ no mesmo input.

shared/utils/maskUtils.ts

export function maskCpfOrCnpj(value: string): string {
  value = value.replace(/\D/g, '') 

  if (value.length <= 11) {
    // Aplica máscara de CPF
    return value
      .replace(/(\d{3})(\d)/, '$1.$2')
      .replace(/(\d{3})(\d)/, '$1.$2')
      .replace(/(\d{3})(\d{1,2})$/, '$1-$2')
  } else {
    // Aplica máscara de CNPJ
    return value
      .replace(/^(\d{2})(\d)/, '$1.$2')
      .replace(/^(\d{2})\.(\d{3})(\d)/, '$1.$2.$3')
      .replace(/\.(\d{3})(\d)/, '.$1/$2')
      .replace(/(\d{4})(\d)/, '$1-$2')
  }
}

export function unMaskCpfOrCnpj(value: string): string {
  return value.replace(/\D/g, '') // Remove tudo que não for número, pra enviar pra api
}

Meu componente personalizado de input

import { useEffect, forwardRef } from 'react'

import { TextInput, type TextInputProps } from 'react-native'

import type { Control, FieldValues, Path } from 'react-hook-form'
import { Controller } from 'react-hook-form'

interface ControlProps<T extends FieldValues> {
  control?: Control<T>
  name?: Path<T>
}

interface MaskProps {
  mask?: (value: string) => string
}

export type FieldProps<T extends FieldValues> = TextInputProps &
  ControlProps<T> &
  MaskProps

export const Field = forwardRef(function Field<T extends FieldValues>(
  { control, name, value, mask, ...props }: FieldProps<T>,
  ref: React.LegacyRef<TextInput> | undefined,
) {

  useEffect(() => {
    if (value) {
      handleFocus(false, !!placeholder)
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  return (
        <Controller
          control={control}
          name={name}
          render={({ field: { onChange } }) => (
            <TextInput
              ref={ref}
              value={value}
              onChangeText={(text) => onChange(mask ? mask(text) : text)}
              {...props}
            />
          )}
        />
}) as <T extends FieldValues>(
  props: FieldProps<T> & { ref?: React.Ref<TextInput> },
) => JSX.Element

No arquivo da rota

const handleLogin = async () => {
  setIsLoading(true)
  const { cpfOrCnpj, password } = control._formValues

  const cpfOrCnpjUnmasked = unMaskCpfOrCnpj(cpfOrCnpj)
  const response: Response = await AuthService.login(
    cpfOrCnpjUnmasked,
    password,
  )
}

<Input error={errors.cpfOrCnpj?.message}>
  <Input.Field
    placeholder='CPF ou CNPJ'
    control={control}
    name='cpfOrCnpj'
    keyboardType='number-pad'
    inputMode='numeric'
    collapsable
    mask={maskCpfOrCnpj}
  />
</Input>
Carregando publicação patrocinada...