marmelab / react-admin

A frontend Framework for single-page applications on top of REST/GraphQL APIs, using TypeScript, React and Material Design
http://marmelab.com/react-admin
MIT License
24.74k stars 5.21k forks source link

NumberInput fails to parse not a number input value and which causes input label overlaying non existing value #10069

Open vlzuiev opened 1 month ago

vlzuiev commented 1 month ago

What you were expecting: When parsing on an input field fails, the value in the shadow element of an input is also removed.

What happened instead: When parsing on an input field fails, the value in the shadow element exists and is shown on the UI. The input value doesn't have any value and the input label overlays the shadow element of the input.

Steps to reproduce: Navigate to any number input component and try to add a nonexisting value like "5." in Chome and any letters in Firefox like "asd". You can navigate to demo react-admin page like this one: https://marmelab.com/react-admin-demo/#/products/124/details and change any number input field.

The workaround we've implemented is to reset the input reference value when the event value is empty.

const inputRef = useRef(null);

const ReactAdminNumberInput = () => {
  return (
    <NumberInput
      inputRef={inputRef}
      label="Label text"
      source="anysource"
      InputProps={{
        onBlur: (e) => {
          if (!e.currentTarget.value && inputRef.current) {
            inputRef.current.value = '';
          }
        }
      }}
    />
  );
};

Environment

https://github.com/user-attachments/assets/0223905d-3159-4cbb-a58e-db8d1719f8c5

adguernier commented 1 month ago

Reproduced, thanks. Feel free to open a PR, any contribution is welcome :+1:

neehhaa06 commented 2 weeks ago

Hello!! @vlzuiev :)

To fix the issue where invalid input values cause the label to overlay incorrectly, you can reset the input value in the onBlur event.

import React, { useRef } from 'react';
import { NumberInput } from 'react-admin';

const ReactAdminNumberInput = () => {
  const inputRef = useRef(null);

  const handleBlur = (e) => {
    const value = e.currentTarget.value;
    if (!value || isNaN(value)) {
      if (inputRef.current) {
        inputRef.current.value = '';
      }
    }
  };

  return (
    <NumberInput
      inputRef={inputRef}
      label="Label text"
      source="anysource"
      InputProps={{
        onBlur: handleBlur,
      }}
    />
  );
};

export default ReactAdminNumberInput;

handleBlur Function: Clears the input field if the value is empty or not a number.

inputRef: Used to directly manipulate the input value.