Skip to content

Commit

Permalink
Merge pull request #1254 from rjackson/fix-safari-blanking-number-on-…
Browse files Browse the repository at this point in the history
…decimals

Fix Safari turning decimal number inputs to 0
  • Loading branch information
bofeiw authored May 15, 2023
2 parents e80e588 + a578484 commit 9999066
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 12 deletions.
14 changes: 13 additions & 1 deletion src/components/Table/TableCell/EditorCellTextField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import { spreadSx } from "@src/utils/ui";

export interface IEditorCellTextFieldProps extends IEditorCellProps<string> {
InputProps?: Partial<InputBaseProps>;
onBlur?: () => void;
}

export default function EditorCellTextField({
column,
value,
onDirty,
onChange,
onBlur,
setFocusInsideCell,
InputProps = {},
}: IEditorCellTextFieldProps) {
Expand All @@ -19,7 +21,12 @@ export default function EditorCellTextField({
return (
<InputBase
value={value}
onBlur={() => onDirty()}
onBlur={() => {
if (onBlur) {
onBlur();
}
onDirty();
}}
onChange={(e) => onChange(e.target.value)}
fullWidth
autoFocus
Expand All @@ -42,6 +49,11 @@ export default function EditorCellTextField({
setTimeout(() => setFocusInsideCell(false));
}
if (e.key === "Enter" && !e.shiftKey) {
// Trigger an onBlur in case we have any final mutations
if (onBlur) {
onBlur();
}

// Removes focus from inside cell, triggering save on unmount
setFocusInsideCell(false);
}
Expand Down
15 changes: 13 additions & 2 deletions src/components/fields/Number/EditorCell.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
import type { IEditorCellProps } from "@src/components/fields/types";
import EditorCellTextField from "@src/components/Table/TableCell/EditorCellTextField";

export default function Number_(props: IEditorCellProps<number>) {
export default function Number_(props: IEditorCellProps<number | string>) {
return (
<EditorCellTextField
{...(props as any)}
InputProps={{ type: "number" }}
onChange={(v) => props.onChange(Number(v))}
onChange={(v) => {
// Safari/Firefox gives us an empty string for invalid inputs, which includes inputs like "12." on the way to
// typing "12.34". Number would cast these to 0 and replace the user's input to 0 whilst they're mid-way through
// typing. We want to avoid that.
const parsedValue = v === "" ? v : Number(v);
props.onChange(parsedValue);
}}
onBlur={() => {
// Cast to number when the user has finished editing
props.onChange(Number(props.value));
props.onDirty();
}}
/>
);
}
17 changes: 14 additions & 3 deletions src/components/fields/Number/SideDrawerField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,25 @@ export default function Number_({
onChange,
onSubmit,
disabled,
}: ISideDrawerFieldProps) {
}: ISideDrawerFieldProps<number | string>) {
return (
<TextField
variant="filled"
fullWidth
margin="none"
onChange={(e) => onChange(Number(e.target.value))}
onBlur={onSubmit}
onChange={(e) => {
// Safari/Firefox gives us an empty string for invalid inputs, which includes inputs like "12." on the way to
// typing "12.34". Number would cast these to 0 and replace the user's input to 0 whilst they're mid-way through
// typing. We want to avoid that.
const parsedValue =
e.target.value === "" ? e.target.value : Number(e.target.value);
onChange(parsedValue);
}}
onBlur={() => {
// Cast to number when the user has finished editing
onChange(Number(value));
onSubmit();
}}
value={value}
id={getFieldId(column.key)}
label=""
Expand Down
13 changes: 11 additions & 2 deletions src/components/fields/Percentage/EditorCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { IEditorCellProps } from "@src/components/fields/types";
import EditorCellTextField from "@src/components/Table/TableCell/EditorCellTextField";
import { multiply100WithPrecision, divide100WithPrecision } from "./utils";

export default function Percentage(props: IEditorCellProps<number>) {
export default function Percentage(props: IEditorCellProps<number | string>) {
return (
<EditorCellTextField
{...(props as any)}
Expand All @@ -13,7 +13,16 @@ export default function Percentage(props: IEditorCellProps<number>) {
: props.value
}
onChange={(v) => {
props.onChange(divide100WithPrecision(Number(v)));
// Safari/Firefox gives us an empty string for invalid inputs, which includes inputs like "12." on the way to
// typing "12.34". Number would cast these to 0 and replace the user's input to 0 whilst they're mid-way through
// typing. We want to avoid that.
const parsedValue = v === "" ? v : divide100WithPrecision(Number(v));
props.onChange(parsedValue);
}}
onBlur={() => {
// Cast to number when the user has finished editing
props.onChange(Number(props.value));
props.onDirty();
}}
/>
);
Expand Down
17 changes: 14 additions & 3 deletions src/components/fields/Percentage/SideDrawerField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,27 @@ export default function Percentage({
onChange,
onSubmit,
disabled,
}: ISideDrawerFieldProps) {
}: ISideDrawerFieldProps<number | string>) {
const { colors } = (column as any).config;
const theme = useTheme();
return (
<TextField
variant="filled"
fullWidth
margin="none"
onChange={(e) => onChange(Number(e.target.value) / 100)}
onBlur={onSubmit}
onChange={(e) => {
// Safari/Firefox gives us an empty string for invalid inputs, which includes inputs like "12." on the way to
// typing "12.34". Number would cast these to 0 and replace the user's input to 0 whilst they're mid-way through
// typing. We want to avoid that.
const parsedValue =
e.target.value === "" ? e.target.value : Number(e.target.value) / 100;
onChange(parsedValue);
}}
onBlur={() => {
// Cast to number when the user has finished editing
onChange(Number(value));
onSubmit();
}}
value={
typeof value === "number" ? multiply100WithPrecision(value) : value
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/fields/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export interface ISideDrawerFieldProps<T = any> {
/** Call when the user has input but changes have not been saved */
onDirty: (dirty?: boolean) => void;
/** Update the local value. Also calls onDirty */
onChange: (T: any) => void;
onChange: (value: T) => void;
/** Call when user input is ready to be saved (e.g. onBlur) */
onSubmit: () => void;

Expand Down

0 comments on commit 9999066

Please sign in to comment.