diff --git a/.changeset/cold-geese-visit.md b/.changeset/cold-geese-visit.md
new file mode 100644
index 0000000000..2f82a20f8e
--- /dev/null
+++ b/.changeset/cold-geese-visit.md
@@ -0,0 +1,5 @@
+---
+"@heroui/number-input": patch
+---
+
+handle onChange event in number input (#4874)
diff --git a/packages/components/number-input/__tests__/number-input.test.tsx b/packages/components/number-input/__tests__/number-input.test.tsx
index 99e2d1c6b2..a042f79576 100644
--- a/packages/components/number-input/__tests__/number-input.test.tsx
+++ b/packages/components/number-input/__tests__/number-input.test.tsx
@@ -240,6 +240,34 @@ describe("NumberInput", () => {
expect(stepperButton).toBeNull();
});
+
+ it("should emit onChange", async () => {
+ const onChange = jest.fn();
+
+ const {container} = render();
+
+ const input = container.querySelector("input") as HTMLInputElement;
+
+ await user.click(input);
+ await user.keyboard("1024");
+
+ expect(onChange).toHaveBeenCalledTimes(4);
+ });
+
+ it("should emit onChange with keyboard up & down key", async () => {
+ const onChange = jest.fn();
+
+ const {container} = render();
+
+ const input = container.querySelector("input") as HTMLInputElement;
+
+ await user.click(input);
+ await user.keyboard("[ArrowUp]");
+ await user.keyboard("[ArrowUp]");
+ expect(onChange).toHaveBeenCalledTimes(2);
+ await user.keyboard("[ArrowDown]");
+ expect(onChange).toHaveBeenCalledTimes(3);
+ });
});
describe("NumberInput with React Hook Form", () => {
@@ -503,7 +531,6 @@ describe("NumberInput with React Hook Form", () => {
await user.tab();
await user.keyboard("1234");
- await user.tab();
});
});
});
diff --git a/packages/components/number-input/src/use-number-input.ts b/packages/components/number-input/src/use-number-input.ts
index 1de8811ed7..8543a07370 100644
--- a/packages/components/number-input/src/use-number-input.ts
+++ b/packages/components/number-input/src/use-number-input.ts
@@ -136,7 +136,7 @@ export function useNumberInput(originalProps: UseNumberInputProps) {
...originalProps,
validationBehavior,
locale,
- onChange: onValueChange,
+ onChange: chain(onValueChange, onChange),
});
const {