From 654ad186ba830992ebf0b5cd6e6d6c8f9c830ce8 Mon Sep 17 00:00:00 2001 From: Pagebakers Date: Wed, 18 Oct 2023 16:48:58 +0200 Subject: [PATCH] fix: fixed issue where Field would not infer correct change handler --- .changeset/red-needles-promise.md | 6 ++ packages/saas-ui-forms/src/create-field.tsx | 10 +++- packages/saas-ui-forms/src/default-fields.tsx | 16 ++++-- packages/saas-ui-forms/src/types.ts | 2 +- .../saas-ui-forms/tests/create-field.test.tsx | 56 +++++++++++++++++++ 5 files changed, 82 insertions(+), 8 deletions(-) create mode 100644 .changeset/red-needles-promise.md create mode 100644 packages/saas-ui-forms/tests/create-field.test.tsx diff --git a/.changeset/red-needles-promise.md b/.changeset/red-needles-promise.md new file mode 100644 index 000000000..452a8bc43 --- /dev/null +++ b/.changeset/red-needles-promise.md @@ -0,0 +1,6 @@ +--- +'@saas-ui/forms': patch +'@saas-ui/react': patch +--- + +Fixed issue where Field would not infer correct onChange handler diff --git a/packages/saas-ui-forms/src/create-field.tsx b/packages/saas-ui-forms/src/create-field.tsx index 6ee7830da..a9358bd6a 100644 --- a/packages/saas-ui-forms/src/create-field.tsx +++ b/packages/saas-ui-forms/src/create-field.tsx @@ -70,6 +70,8 @@ const withControlledInput = (InputComponent: React.FC) => { ({ name, rules, ...inputProps }, ref) => { const { control } = useFormContext() + const onChange = inputProps.onChange as (...event: any[]) => void + return ( ) => { @@ -97,11 +99,13 @@ const withUncontrolledInput = (InputComponent: React.FC) => { const { ref: _ref, ...field } = register(name, rules) + const onChange = inputProps.onChange as (...event: any[]) => void + return ( @@ -139,7 +143,7 @@ export const createField = ( displayName: `${component.displayName ?? 'Custom'}Field`, hideLabel: options?.hideLabel, BaseField: options?.BaseField || BaseField, - }) as React.FC + }) as React.FC & TProps> return Field } diff --git a/packages/saas-ui-forms/src/default-fields.tsx b/packages/saas-ui-forms/src/default-fields.tsx index 7d70fff3f..ac2d739cd 100644 --- a/packages/saas-ui-forms/src/default-fields.tsx +++ b/packages/saas-ui-forms/src/default-fields.tsx @@ -29,6 +29,8 @@ import { SelectProps, NativeSelect, NativeSelectProps, + SelectButtonProps, + SelectListProps, } from './select' import { createField } from './create-field' @@ -83,12 +85,18 @@ export const SwitchField = createField( } ) -export const SelectField = createField( +export interface SelectFieldProps extends SelectProps { + buttonProps?: SelectButtonProps + listProps?: SelectListProps +} + +export const SelectField = createField( forwardRef((props, ref) => { + const { buttonProps, listProps, ...rest } = props return ( - + + ) }), diff --git a/packages/saas-ui-forms/src/types.ts b/packages/saas-ui-forms/src/types.ts index c0f1a9907..f84cd8fa2 100644 --- a/packages/saas-ui-forms/src/types.ts +++ b/packages/saas-ui-forms/src/types.ts @@ -42,7 +42,7 @@ export type ArrayFieldPath = Name extends string export interface BaseFieldProps< TFieldValues extends FieldValues = FieldValues, TName extends FieldPath = FieldPath -> extends Omit { +> extends Omit { /** * The field name */ diff --git a/packages/saas-ui-forms/tests/create-field.test.tsx b/packages/saas-ui-forms/tests/create-field.test.tsx new file mode 100644 index 000000000..8e1a788c1 --- /dev/null +++ b/packages/saas-ui-forms/tests/create-field.test.tsx @@ -0,0 +1,56 @@ +import * as React from 'react' + +import { + DefaultFields, + Field, + FieldProps, + Select, + SelectButton, + SelectList, + SelectProps, + createField, +} from '../src' +import { forwardRef } from '@chakra-ui/react' +import { expectTypeOf } from 'vitest' + +export const CustomField = createField( + forwardRef((props, ref) => { + return ( + + ) + }), + { + isControlled: true, + } +) + +type PropTypes = React.ComponentProps + +test('should have correct event handler type', async () => { + expectTypeOf().toEqualTypeOf< + ((value: string | string[]) => void) | undefined + >() +}) + +const selectProps: FieldProps = { + name: 'test', + type: 'select', +} + +const inputProps: FieldProps = { + name: 'test', + type: 'text', +} + +test('should have correct event handler type on Field', async () => { + expectTypeOf<(typeof selectProps)['onChange']>().toEqualTypeOf< + ((value: string | string[]) => void) | undefined + >() + + expectTypeOf<(typeof inputProps)['onChange']>().toEqualTypeOf< + React.ChangeEventHandler | undefined + >() +})