import { Field as ChakraField } from '@chakra-ui/react'; import * as React from 'react'; import getComponentDisplayName from '../utils/getComponentDisplayName'; import { space } from '../utils/htmlEntities'; import type { InputProps } from './input'; import type { InputGroupProps } from './input-group'; export interface FieldProps extends Omit { label?: React.ReactNode; helperText?: React.ReactNode; errorText?: React.ReactNode; optionalText?: React.ReactNode; children: React.ReactElement | React.ReactElement; size?: 'sm' | 'md' | 'lg' | '2xl'; } export const Field = React.forwardRef( function Field(props, ref) { const { label, children, helperText, errorText, optionalText, ...rest } = props; // A floating field cannot be without a label. if (rest.floating && label) { const injectedProps = { className: 'peer', placeholder: ' ', size: rest.size, floating: rest.floating, bgColor: rest.bgColor, disabled: rest.disabled, readOnly: rest.readOnly, }; const labelElement = ( { label } { errorText && ( -{ space }{ errorText } ) } ); const helperTextElement = helperText && ( { helperText } ); const child = React.Children.only>(children); const isInputGroup = getComponentDisplayName(child.type) === 'InputGroup'; if (isInputGroup) { const inputElement = React.cloneElement( React.Children.only>(child.props.children as React.ReactElement), injectedProps, ); const groupInputElement = React.cloneElement(child, {}, inputElement, labelElement, ); return ( { groupInputElement } { helperTextElement } ); } const inputElement = React.cloneElement(child, injectedProps); return ( { inputElement } { labelElement } { helperTextElement } ); } // Pass size value to the input component const injectedProps = { size: rest.size, }; const child = React.Children.only>(children); const clonedChild = React.cloneElement(child, injectedProps); return ( { label && ( { label } ) } { clonedChild } { helperText && ( { helperText } ) } { errorText && ( { errorText } ) } ); }, );