import React, { PropsWithChildren, ReactNode, useEffect, useState } from 'react'; import { AbstractFormComponent } from '../../models/form-component'; import { FieldValues } from 'react-hook-form/dist/types/fields'; import { get as _get } from 'lodash'; export interface AbstractFormItemProps extends PropsWithChildren> { id: string, label?: string, tooltip?: ReactNode, className?: string, disabled?: boolean, readOnly?: boolean onLabelClick?: (event: React.MouseEvent) => void, } /** * This abstract component should not be used directly. * Other forms components that are intended to be used with react-hook-form must extend this component. */ export const AbstractFormItem = ({ id, label, tooltip, className, disabled, readOnly, error, warning, rules, formState, onLabelClick, children }: AbstractFormItemProps) => { const [isDirty, setIsDirty] = useState(false); const [fieldError, setFieldError] = useState(error); useEffect(() => { setIsDirty(_get(formState?.dirtyFields, id)); setFieldError(_get(formState?.errors, id)); }, [formState]); useEffect(() => { setFieldError(error); }, [error]); // Compose classnames from props const classNames = [ 'form-item', `${className || ''}`, `${isDirty && fieldError ? 'is-incorrect' : ''}`, `${isDirty && warning ? 'is-warned' : ''}`, `${rules && rules.required ? 'is-required' : ''}`, `${readOnly ? 'is-readonly' : ''}`, `${disabled ? 'is-disabled' : ''}` ].join(' '); /** * This function is called when the label is clicked. * It is used to focus the input. */ function handleLabelClick (event: React.MouseEvent) { if (typeof onLabelClick === 'function') { onLabelClick(event); } } return ( ); };