Skip to content

Commit

Permalink
fix: number field interactions (microsoft#4124)
Browse files Browse the repository at this point in the history
* Fixing number field interactions

* Fix test

* Adding test
  • Loading branch information
williamw2 authored Nov 17, 2020
1 parent b814aed commit 16f677c
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,29 @@ describe("NumberFieldControl", () => {
rendered
.find("input")
.at(0)
.simulate("change", { target: { value: 1 } });
.simulate("change", { target: { value: "1" } }); // The target.value from an input text box is always a string.

expect(handleChange).toHaveBeenCalled();
expect(handleChange.mock.calls[0][0]).toEqual({ value: 1 });
});
test("should fire an `onChange` callback with undefined value if the input is an empty string", () => {
const handleChange: any = jest.fn();
const rendered: any = mount(
<NumberFieldControl
{...numberFieldProps}
onChange={handleChange}
managedClasses={managedClasses}
/>
);

rendered
.find("input")
.at(0)
.simulate("change", { target: { value: "" } });

expect(handleChange).toHaveBeenCalled();
expect(handleChange.mock.calls[0][0]).toEqual({ value: undefined });
});
test("should not fire an `onChange` callback if the input is NaN", () => {
const handleChange: any = jest.fn();
const rendered: any = mount(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class NumberFieldControl extends React.Component<
managedClasses: {},
};

private hasFocus: boolean = false;

/**
* Renders the component
*/
Expand Down Expand Up @@ -50,27 +52,47 @@ class NumberFieldControl extends React.Component<
step={this.props.step}
disabled={this.props.disabled}
ref={this.props.elementRef as React.Ref<HTMLInputElement>}
onBlur={this.props.updateValidity}
onFocus={this.props.reportValidity}
onBlur={this.handleBlur(this.props.updateValidity)}
onFocus={this.handleFocus(this.props.reportValidity)}
required={this.props.required}
/>
);
}

private handleFocus = (callback: () => void) => {
return (): void => {
this.hasFocus = true;
if (callback) callback();
};
};

private handleBlur = (callback: () => void) => {
return (): void => {
this.hasFocus = false;
if (callback) callback();
this.forceUpdate();
};
};

private handleChange = (): ((e: React.ChangeEvent<HTMLInputElement>) => void) => {
return (e: React.ChangeEvent<HTMLInputElement>): void => {
const value: number = parseInt(e.target.value, 10);
const input: string = !e.target.value
? ""
: e.target.value.replace(/\s/g, "");
const value: number = parseInt(input, 10);

if (!isNaN(value)) {
this.props.onChange({ value });
} else if (input.length === 0) {
this.props.onChange({ value: undefined });
}
};
};

private getValue(value: number | undefined): number | string {
return typeof value === "number"
? value
: typeof this.props.default !== "undefined"
: typeof this.props.default !== "undefined" && !this.hasFocus
? this.props.default
: "";
}
Expand Down

0 comments on commit 16f677c

Please sign in to comment.