Fix Safari turning decimal number inputs to 0

Chrome has some slightly unique input[type="number"] handling behaviour, where it restricts the characters that can be typed to numeric characters. Under-the-hood, Chrome withholds certain invalid input states from being emitted as change events – so we only receive change events for valid numbers.

Safari behaves slightly differently. It allows any characters to be entered and emits a change event on each character press, but its internal "value" is only set if the typed input is a valid number. The change events then either come through with a numeric value represented, or as an empty string.

For example, when typing "12.34" we receive onChange events with "1", "12", "", "12.3", and "12.34".

On that third onChange event when we pass "" up to React, React happily ignores the change (I _think_ bceause the incoming value "" already matches the element's value of ""; nonetheless, React have solved this issue for us).

When we parse the input via `Number(v)` we encounter problems. `Number("")` resolves to `0`, React sets the input's value to `0`, and the user is therefore unable to type decimal values successfully.

The solution for this is not to cast to a number at all. We'll rely on default browser behaviour to manage the input for us (allowing users to enter invalid characters), but we're still safe because the element's internal state will always be numeric.

In the scenario that a customer does try enter an invalid input "abc123", the input field simply blanks itself when they leave it.
This commit is contained in:
Rob Jackson
2023-05-10 15:24:25 +01:00
parent 5708153798
commit a292667c92

View File

@@ -3,10 +3,6 @@ import EditorCellTextField from "@src/components/Table/TableCell/EditorCellTextF
export default function Number_(props: IEditorCellProps<number>) {
return (
<EditorCellTextField
{...(props as any)}
InputProps={{ type: "number" }}
onChange={(v) => props.onChange(Number(v))}
/>
<EditorCellTextField {...(props as any)} InputProps={{ type: "number" }} />
);
}