Skip to content

Commit

Permalink
fix: pressing ESC key in a read-only input not clear
Browse files Browse the repository at this point in the history
  • Loading branch information
linyonglu committed Feb 27, 2025
1 parent 03c71ed commit f93b114
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 9 deletions.
19 changes: 19 additions & 0 deletions packages/components/input/__tests__/input.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,25 @@ describe("Input", () => {

expect(input.value).toBe("test value");
});

it("should not clear value when pressing ESC key if input is readonly", () => {
const onClear = jest.fn();
const defaultValue = "test value";

const {getByRole} = render(
<Input isClearable isReadOnly defaultValue={defaultValue} onClear={onClear} />,
);

const input = getByRole("textbox") as HTMLInputElement;

expect(input.value).toBe(defaultValue);

fireEvent.keyDown(input, {key: "Escape"});

expect(input.value).toBe(defaultValue);

expect(onClear).not.toHaveBeenCalled();
});
});

describe("Input with React Hook Form", () => {
Expand Down
9 changes: 7 additions & 2 deletions packages/components/input/src/use-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -354,12 +354,17 @@ export function useInput<T extends HTMLInputElement | HTMLTextAreaElement = HTML

const handleKeyDown = useCallback(
(e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === "Escape" && inputValue && (isClearable || onClear)) {
if (
e.key === "Escape" &&
inputValue &&
(isClearable || onClear) &&
!originalProps.isReadOnly
) {
setInputValue("");
onClear?.();
}
},
[inputValue, setInputValue, onClear, isClearable],
[inputValue, setInputValue, onClear, isClearable, originalProps.isReadOnly],
);

const getInputProps: PropGetter = useCallback(
Expand Down
26 changes: 21 additions & 5 deletions packages/components/number-input/__tests__/number-input.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ describe("NumberInput", () => {

expect(stepperButton).toBeNull();
});

it("should clear value when isClearable and pressing ESC key", async () => {
const onClear = jest.fn();
const defaultValue = 12;
Expand All @@ -257,7 +257,7 @@ describe("NumberInput", () => {
expect(input.value).toBe("");
expect(onClear).toHaveBeenCalledTimes(1);
});

it("should not clear value when pressing ESC key if input is empty", () => {
const onClear = jest.fn();

Expand All @@ -268,8 +268,8 @@ describe("NumberInput", () => {
fireEvent.keyDown(input, {key: "Escape"});
expect(onClear).not.toHaveBeenCalled();
});
it("should not clear value when pressing ESC key without isClearable", () => {

it("should not clear value when pressing ESC key without isClearable", () => {
const defaultValue = 12;

const {container} = render(<NumberInput defaultValue={defaultValue} />);
Expand All @@ -281,7 +281,23 @@ describe("NumberInput", () => {
fireEvent.keyDown(input, {key: "Escape"});
expect(input.value).toBe(defaultValue.toString());
});


it("should not clear value when pressing ESC key if input is readonly", () => {
const onClear = jest.fn();
const defaultValue = 42;

const {container} = render(<NumberInput isReadOnly defaultValue={defaultValue} />);

const input = container.querySelector("input") as HTMLInputElement;

expect(input.value).toBe(defaultValue.toString());

fireEvent.keyDown(input, {key: "Escape"});

expect(input.value).toBe(defaultValue.toString());
expect(onClear).not.toHaveBeenCalled();
});

it("should emit onChange", async () => {
const onChange = jest.fn();

Expand Down
9 changes: 7 additions & 2 deletions packages/components/number-input/src/use-number-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,12 +241,17 @@ export function useNumberInput(originalProps: UseNumberInputProps) {

const handleKeyDown = useCallback(
(e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === "Escape" && inputValue && (isClearable || onClear)) {
if (
e.key === "Escape" &&
inputValue &&
(isClearable || onClear) &&
!originalProps.isReadOnly
) {
state.setInputValue("");
onClear?.();
}
},
[inputValue, state.setInputValue, onClear, isClearable],
[inputValue, state.setInputValue, onClear, isClearable, originalProps.isReadOnly],
);

const getBaseProps: PropGetter = useCallback(
Expand Down

0 comments on commit f93b114

Please sign in to comment.