Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | 115x 115x 115x 115x 115x 115x 1809x 1809x 1809x 1809x 1809x 1809x 1809x 3222x 1809x 115x 2865x 2865x 2865x 2865x 2865x 2865x 2865x 2865x 2865x 1664x 1664x 1664x 115x 1307x 1307x 1307x 1307x 1307x 88x 115x 2865x 2865x 2865x 2865x 2865x 2855x 10x 10x 115x 115x | import { getIn, Field, FieldConfig, FieldProps } from 'formik'; import { isDate, noop } from 'lodash'; import React, { createElement, memo, useCallback, useMemo, Component, FunctionComponent } from 'react'; import shallowEqual from 'shallowequal'; import FormFieldContainer from './FormFieldContainer'; export interface BasicFormFieldProps extends FieldConfig { additionalClassName?: string; className?: string; testId?: string; onChange?(value: any): void; } const BasicFormField: FunctionComponent<BasicFormFieldProps> = ({ additionalClassName, className, component, render, testId, onChange, ...rest }) => { const renderInnerField = useCallback((props: FieldProps) => ( <InnerField { ...props } additionalClassName={ additionalClassName } className={ className } component={ component } onChange={ onChange } render={ render } testId={ testId } /> ), [ additionalClassName, className, component, render, testId, onChange, ]); return <Field { ...rest } render={ renderInnerField } />; }; type InnerFieldProps = Omit<BasicFormFieldProps, keyof FieldConfig> & InnerFieldInputProps; const InnerField: FunctionComponent<InnerFieldProps> = memo(({ additionalClassName, component, field, form, onChange, render, testId, }) => { const input = useMemo(() => <InnerFieldInput component={ component } field={ field } form={ form } onChange={ onChange } render={ render } />, [ field, form, onChange, component, render, ]); return ( <FormFieldContainer additionalClassName={ additionalClassName } hasError={ getIn(form.errors, field.name) } testId={ testId } > { input } </FormFieldContainer> ); }, ( { form: prevForm, field: prevField, ...prevProps }, { form: nextForm, field: nextField, ...nextProps } ) => ( shallowEqual(prevProps, nextProps) && shallowEqual(prevForm, nextForm) && shallowEqual(prevField, nextField) )); type InnerFieldInputProps = FieldProps & Pick<FieldConfig, 'component' | 'render'> & { onChange?(value: string): void; }; class InnerFieldInput extends Component<InnerFieldInputProps> { componentDidUpdate({ field: prevField }: InnerFieldInputProps) { const { field: { value }, onChange = noop } = this.props; const comparableValue = isDate(value) ? value.getTime() : value; const comparablePrevValue = isDate(prevField.value) ? prevField.value.getTime() : prevField.value; if (comparableValue !== comparablePrevValue) { onChange(value); } } render() { const { component = 'input', field, render, } = this.props; if (render) { // tslint:disable-next-line:no-unnecessary-type-assertion return (render as any)(this.props); } Eif (typeof component === 'string') { // tslint:disable-next-line:no-unnecessary-type-assertion return createElement(component as any, field); } // tslint:disable-next-line:no-unnecessary-type-assertion return createElement(component as any, this.props); } } export default memo(BasicFormField); |