mirror of
https://github.com/nextui-org/nextui.git
synced 2025-12-08 19:26:11 +00:00
fix(number-input): ignore name prop in getNumberInputProps (#5762)
* fix(number-input): ignore name prop in getNumberInputProps * fix(number-input): react-hook-form test case * chore(number-input): assert no duplicate name attribute
This commit is contained in:
parent
0d95d7faa0
commit
f13c6875db
5
.changeset/short-ravens-stare.md
Normal file
5
.changeset/short-ravens-stare.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@heroui/number-input": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
ignore name prop in getNumberInputProps (#5594)
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import type {UserEvent} from "@testing-library/user-event";
|
import type {UserEvent} from "@testing-library/user-event";
|
||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import {render, renderHook, fireEvent, act} from "@testing-library/react";
|
import {render, fireEvent, act} from "@testing-library/react";
|
||||||
import userEvent from "@testing-library/user-event";
|
import userEvent from "@testing-library/user-event";
|
||||||
import {useForm} from "react-hook-form";
|
import {useForm} from "react-hook-form";
|
||||||
import {Form} from "@heroui/form";
|
import {Form} from "@heroui/form";
|
||||||
@ -330,59 +330,85 @@ describe("NumberInput", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("NumberInput with React Hook Form", () => {
|
describe("NumberInput with React Hook Form", () => {
|
||||||
let input1: HTMLInputElement;
|
let hiddenInput1: HTMLInputElement;
|
||||||
let input2: HTMLInputElement;
|
let hiddenInput2: HTMLInputElement;
|
||||||
let input3: HTMLInputElement;
|
let hiddenInput3: HTMLInputElement;
|
||||||
|
let visibleInput3: HTMLInputElement;
|
||||||
let submitButton: HTMLButtonElement;
|
let submitButton: HTMLButtonElement;
|
||||||
let onSubmit: () => void;
|
let onSubmit: () => void;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const {result} = renderHook(() =>
|
|
||||||
useForm({
|
|
||||||
defaultValues: {
|
|
||||||
withDefaultValue: 1234,
|
|
||||||
withoutDefaultValue: undefined,
|
|
||||||
requiredField: undefined,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
const {
|
|
||||||
handleSubmit,
|
|
||||||
register,
|
|
||||||
formState: {errors},
|
|
||||||
} = result.current;
|
|
||||||
|
|
||||||
onSubmit = jest.fn();
|
onSubmit = jest.fn();
|
||||||
|
|
||||||
render(
|
function TestForm() {
|
||||||
|
const {
|
||||||
|
handleSubmit,
|
||||||
|
setValue,
|
||||||
|
watch,
|
||||||
|
register,
|
||||||
|
formState: {errors},
|
||||||
|
} = useForm<{
|
||||||
|
withDefaultValue: number;
|
||||||
|
withoutDefaultValue?: number;
|
||||||
|
requiredField?: number;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
register("withDefaultValue");
|
||||||
|
register("withoutDefaultValue");
|
||||||
|
register("requiredField", {required: true});
|
||||||
|
}, [register]);
|
||||||
|
|
||||||
|
const requiredFieldValue = watch("requiredField");
|
||||||
|
|
||||||
|
return (
|
||||||
<form className="flex flex-col gap-4" onSubmit={handleSubmit(onSubmit)}>
|
<form className="flex flex-col gap-4" onSubmit={handleSubmit(onSubmit)}>
|
||||||
<NumberInput isClearable label="With default value" {...register("withDefaultValue")} />
|
<NumberInput
|
||||||
|
isClearable
|
||||||
|
data-testid="input-1"
|
||||||
|
defaultValue={1234}
|
||||||
|
label="With default value"
|
||||||
|
name="withDefaultValue"
|
||||||
|
onValueChange={(value) => setValue("withDefaultValue", value)}
|
||||||
|
/>
|
||||||
<NumberInput
|
<NumberInput
|
||||||
data-testid="input-2"
|
data-testid="input-2"
|
||||||
label="Without default value"
|
label="Without default value"
|
||||||
{...register("withoutDefaultValue")}
|
name="withoutDefaultValue"
|
||||||
|
onValueChange={(value) => setValue("withoutDefaultValue", value)}
|
||||||
/>
|
/>
|
||||||
<NumberInput
|
<NumberInput
|
||||||
data-testid="input-3"
|
data-testid="input-3"
|
||||||
label="Required"
|
label="Required"
|
||||||
{...register("requiredField", {required: true})}
|
name="requiredField"
|
||||||
|
value={requiredFieldValue}
|
||||||
|
onValueChange={(value) =>
|
||||||
|
setValue("requiredField", value, {shouldValidate: true, shouldDirty: true})
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
{errors.requiredField && <span className="text-danger">This field is required</span>}
|
{errors.requiredField && <span className="text-danger">This field is required</span>}
|
||||||
<button type="submit">Submit</button>
|
<button type="submit">Submit</button>
|
||||||
</form>,
|
</form>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
input1 = document.querySelector("input[name=withDefaultValue]")!;
|
const {getByTestId} = render(<TestForm />);
|
||||||
input2 = document.querySelector("input[name=withoutDefaultValue]")!;
|
|
||||||
input3 = document.querySelector("input[name=requiredField]")!;
|
hiddenInput1 = document.querySelector("input[name=withDefaultValue][type=hidden]")!;
|
||||||
|
hiddenInput2 = document.querySelector("input[name=withoutDefaultValue][type=hidden]")!;
|
||||||
|
hiddenInput3 = document.querySelector("input[name=requiredField][type=hidden]")!;
|
||||||
|
visibleInput3 = getByTestId("input-3") as HTMLInputElement;
|
||||||
submitButton = document.querySelector('button[type="submit"]')!;
|
submitButton = document.querySelector('button[type="submit"]')!;
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should work with defaultValues", () => {
|
it("should work with defaultValues", () => {
|
||||||
expect(input1).toHaveValue("1234");
|
expect(hiddenInput1).toHaveValue("1234");
|
||||||
expect(input2).not.toHaveValue();
|
expect(hiddenInput2).not.toHaveValue();
|
||||||
expect(input3).not.toHaveValue();
|
expect(hiddenInput3).not.toHaveValue();
|
||||||
|
|
||||||
|
expect(document.querySelectorAll('input[name="requiredField"]')).toHaveLength(1);
|
||||||
|
expect(visibleInput3).not.toHaveAttribute("name");
|
||||||
|
expect(hiddenInput3).toHaveAttribute("name", "requiredField");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not submit form when required field is empty", async () => {
|
it("should not submit form when required field is empty", async () => {
|
||||||
@ -394,10 +420,13 @@ describe("NumberInput with React Hook Form", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should submit form when required field is not empty", async () => {
|
it("should submit form when required field is not empty", async () => {
|
||||||
fireEvent.change(input3, {target: {value: 123}});
|
|
||||||
|
|
||||||
const user = userEvent.setup();
|
const user = userEvent.setup();
|
||||||
|
|
||||||
|
await user.click(visibleInput3);
|
||||||
|
await user.keyboard("123");
|
||||||
|
|
||||||
|
expect(hiddenInput3).toHaveValue("123");
|
||||||
|
|
||||||
await user.click(submitButton);
|
await user.click(submitButton);
|
||||||
|
|
||||||
expect(onSubmit).toHaveBeenCalledTimes(1);
|
expect(onSubmit).toHaveBeenCalledTimes(1);
|
||||||
|
|||||||
@ -334,7 +334,7 @@ export function useNumberInput(originalProps: UseNumberInputProps) {
|
|||||||
enabled: true,
|
enabled: true,
|
||||||
labelable: true,
|
labelable: true,
|
||||||
omitEventNames: new Set(Object.keys(inputProps)),
|
omitEventNames: new Set(Object.keys(inputProps)),
|
||||||
omitPropNames: new Set(["value"]),
|
omitPropNames: new Set(["value", "name"]),
|
||||||
}),
|
}),
|
||||||
props,
|
props,
|
||||||
),
|
),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user