From 2dd0393bedb7c58a8bc01c7a32eeea5c86b56f5d Mon Sep 17 00:00:00 2001 From: galiprandi <20272796+galiprandi@users.noreply.github.com> Date: Tue, 16 Jun 2026 04:43:49 +0000 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9C=A8=20Quality:=20Bug=20Fix=20-=20Fix?= =?UTF-8?q?=20Form=20onSubmit=20prop=20overwriting=20internal=20handler?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change fixes a bug where providing an `onSubmit` prop to the `Form` component would prevent `onSubmitValues` from being called. It also improves component metadata by adding `displayName` and corrects JSDoc for `FormProps`. Changes: - Destructure `onSubmit` as `onSubmitProp` in `FormInner` to avoid it being overwritten by the `restProps` spread. - Manually call `onSubmitProp` within the internal `onSubmit` handler. - Ensure `restProps` are spread before `onSubmit` on the native `
` element. - Add `Form.displayName = 'Form'`. - Correct JSDoc for `filterEmptyValues` in `FormProps`. - Add unit test to verify that both `onSubmitValues` and `onSubmit` are called when provided. --- .axioma/quality.md | 4 ++++ lib/components/Form/index.test.tsx | 24 ++++++++++++++++++++++++ lib/components/Form/index.tsx | 15 ++++++++++----- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/.axioma/quality.md b/.axioma/quality.md index fe59e1f..f7da919 100644 --- a/.axioma/quality.md +++ b/.axioma/quality.md @@ -93,3 +93,7 @@ ## 2024-07-01 - [Achieving 100% Branch Coverage for Optional Callbacks] **Learning:** To achieve 100% branch coverage in components that utilize optional callbacks (e.g., `Input`'s `onChangeValue`, `onChangeDebounce`), unit tests must trigger relevant events (like `fireEvent.change`) while intentionally omitting these optional props to exercise the 'falsy' branches of conditional logic. **Action:** Always include a test case that omits optional callback props when testing components with event handlers to ensure all logical paths are verified. + +## 2024-07-05 - [Ensuring Internal Event Handlers Precedence] +**Learning:** When creating wrapper components that spread `restProps` onto a native element, placing internal event handlers (like `onSubmit` or `onChange`) *after* the spread ensures they are not accidentally overwritten by user-provided props. Additionally, destructuring the specific handler from props allows it to be manually invoked within the internal handler, preserving both functionalities. +**Action:** Always spread `restProps` before specifying internal event handlers in wrapper components to maintain control over the component's core logic while still supporting custom callbacks. diff --git a/lib/components/Form/index.test.tsx b/lib/components/Form/index.test.tsx index c70f9ca..930c409 100644 --- a/lib/components/Form/index.test.tsx +++ b/lib/components/Form/index.test.tsx @@ -212,4 +212,28 @@ describe('Form Component', () => { expect(ref.current).not.toBeNull() expect(ref.current?.tagName).toBe('FORM') }) + + it('should call both onSubmitValues and onSubmit when both are provided', () => { + const onSubmitValues = vi.fn() + const onSubmit = vi.fn() + const testId = 'test-both-submits' + + render( + + onSubmitValues={onSubmitValues} + onSubmit={onSubmit} + data-testid={testId} + > + + + , + ) + + fireEvent.submit(screen.getByTestId(testId)) + + expect(onSubmitValues).toHaveBeenCalledWith({ + name: 'John', + }) + expect(onSubmit).toHaveBeenCalled() + }) }) diff --git a/lib/components/Form/index.tsx b/lib/components/Form/index.tsx index 68ad873..04bbd21 100644 --- a/lib/components/Form/index.tsx +++ b/lib/components/Form/index.tsx @@ -5,7 +5,12 @@ const FormInner = ( props: FormProps, ref: ForwardedRef, ): JSX.Element => { - const { onSubmitValues, filterEmptyValues, ...restProps } = props + const { + onSubmitValues, + filterEmptyValues, + onSubmit: onSubmitProp, + ...restProps + } = props /** * Handles the form submission event. @@ -31,9 +36,9 @@ const FormInner = ( onSubmitValues(values) } - props.onSubmit && props.onSubmit(event) + onSubmitProp && onSubmitProp(event) } - return
+ return } /** @@ -73,6 +78,8 @@ export const Form = forwardRef(FormInner) as ( props: FormProps & React.RefAttributes, ) => JSX.Element +Form.displayName = 'Form' + /** * The properties for the Form component. * @@ -99,8 +106,6 @@ export interface FormProps onSubmitValues?: (values: T) => void /** * A flag to determine if empty values should be included in the form values. - * - * @param {boolean} filterEmptyValues - A flag to determine if empty values should be included in the form values. */ filterEmptyValues?: boolean } From 3c84bce7b595363dcb13fd1f57840ea26d6ab0c2 Mon Sep 17 00:00:00 2001 From: galiprandi <20272796+galiprandi@users.noreply.github.com> Date: Tue, 16 Jun 2026 04:49:22 +0000 Subject: [PATCH 2/2] =?UTF-8?q?=E2=9C=A8=20Quality:=20Bug=20Fix=20-=20Fix?= =?UTF-8?q?=20Form=20onSubmit=20prop=20and=20TypeScript=20type=20definitio?= =?UTF-8?q?n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change fixes a bug where providing an `onSubmit` prop to the `Form` component would prevent `onSubmitValues` from being called. It also fixes a TypeScript error when setting `displayName` on a generic `forwardRef` component. Changes: - Destructure `onSubmit` as `onSubmitProp` in `FormInner` to avoid it being overwritten by the `restProps` spread. - Manually call `onSubmitProp` within the internal `onSubmit` handler. - Ensure `restProps` are spread before `onSubmit` on the native `` element. - Add `Form.displayName = 'Form'` and update its type cast to include `displayName`. - Correct JSDoc for `filterEmptyValues` in `FormProps`. - Add unit test to verify that both `onSubmitValues` and `onSubmit` are called when provided. --- lib/components/Form/index.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/components/Form/index.tsx b/lib/components/Form/index.tsx index 04bbd21..879c7ee 100644 --- a/lib/components/Form/index.tsx +++ b/lib/components/Form/index.tsx @@ -74,9 +74,10 @@ const FormInner = ( * * ``` */ -export const Form = forwardRef(FormInner) as ( - props: FormProps & React.RefAttributes, -) => JSX.Element +export const Form = forwardRef(FormInner) as { + (props: FormProps & React.RefAttributes): JSX.Element + displayName?: string +} Form.displayName = 'Form'