From 41720c2f69407e41c27b325923bce63436b07f45 Mon Sep 17 00:00:00 2001 From: Yazalde Filimone Date: Fri, 11 Aug 2023 03:17:51 +0200 Subject: [PATCH] Feat/support custom field component, (#3858) (#3862) --- .vscode/settings.json | 6 +++++- packages/formik/src/Field.tsx | 31 ++++++++++++++++------------- packages/formik/test/Field.test.tsx | 20 ++++++++++++++++++- 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 25fa6215f..e56b4cfc8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,7 @@ { - "typescript.tsdk": "node_modules/typescript/lib" + "typescript.tsdk": "node_modules/typescript/lib", + "editor.formatOnSave": false, + "editor.codeActionsOnSave": { + "source.fixAll.eslint": true + }, } diff --git a/packages/formik/src/Field.tsx b/packages/formik/src/Field.tsx index 9eb851b25..5e33d8331 100644 --- a/packages/formik/src/Field.tsx +++ b/packages/formik/src/Field.tsx @@ -22,19 +22,19 @@ export interface FieldConfig { * Field component to render. Can either be a string like 'select' or a component. */ component?: - | string - | React.ComponentType> - | React.ComponentType - | React.ForwardRefExoticComponent; + | string + | React.ComponentType> + | React.ComponentType + | React.ForwardRefExoticComponent; /** * Component to render. Can either be a string e.g. 'select', 'input', or 'textarea', or a component. */ as?: - | React.ComponentType['field']> - | string - | React.ComponentType - | React.ForwardRefExoticComponent; + | React.ComponentType['field']> + | string + | React.ComponentType + | React.ForwardRefExoticComponent; /** * Render prop (works like React router's } />) @@ -72,9 +72,11 @@ export interface FieldConfig { innerRef?: (instance: any) => void; } -export type FieldAttributes = GenericFieldHTMLAttributes & +export type FieldAttributes = { className?: string; } & GenericFieldHTMLAttributes & FieldConfig & - T & { name: string }; + T & { + name: string, + }; export type FieldHookConfig = GenericFieldHTMLAttributes & FieldConfig; @@ -139,6 +141,7 @@ export function Field({ children, as: is, // `as` is reserved in typescript lol component, + className, ...props }: FieldAttributes) { const { @@ -202,14 +205,14 @@ export function Field({ const { innerRef, ...rest } = props; return React.createElement( component, - { ref: innerRef, ...field, ...rest }, + { ref: innerRef, ...field, ...rest, className }, children ); } // We don't pass `meta` for backwards compat return React.createElement( component, - { field, form: formik, ...props }, + { field, form: formik, ...props, className }, children ); } @@ -221,10 +224,10 @@ export function Field({ const { innerRef, ...rest } = props; return React.createElement( asElement, - { ref: innerRef, ...field, ...rest }, + { ref: innerRef, ...field, ...rest, className }, children ); } - return React.createElement(asElement, { ...field, ...props }, children); + return React.createElement(asElement, { ...field, ...props, className }, children); } diff --git a/packages/formik/test/Field.test.tsx b/packages/formik/test/Field.test.tsx index 03b03eb7b..9103f982e 100644 --- a/packages/formik/test/Field.test.tsx +++ b/packages/formik/test/Field.test.tsx @@ -100,8 +100,10 @@ describe('Field / FastField', () => { describe('renders an by default', () => { it('', () => { - const { container } = renderForm(); + const className = 'field-custom' + const { container } = renderForm(); expect(container.querySelectorAll('input')).toHaveLength(1); + expect(container.querySelector(`.${className}`)?.getAttribute('value')).toEqual('jared') }); it('', () => { @@ -110,6 +112,22 @@ describe('Field / FastField', () => { }); }); + describe('renders an with className', () => { + it('', () => { + const className = 'field-custom' + const { container } = renderForm(); + expect(container.querySelectorAll(`.${className}`)).toHaveLength(1) + expect(container.querySelector(`.${className}`)?.getAttribute('value')).toEqual('jared') + }); + + it('', () => { + const className = 'field-custom' + const { container } = renderForm(); + expect(container.querySelectorAll(`.${className}`)).toHaveLength(1) + expect(container.querySelector(`.${className}`)?.getAttribute('value')).toEqual('jared') + }); + }); + describe('receives { field, form, meta } props and renders element', () => { it('', () => { let injected: FieldProps[] = [];