'use client' import { forwardRef, type HTMLAttributes, type WheelEvent } from 'react' import { Text, TextField } from 'react-aria-components' import { Controller, useFormContext } from 'react-hook-form' import { useIntl, type IntlShape } from 'react-intl' import { cx } from 'class-variance-authority' import { Error } from '../ErrorMessage/Error' import { mergeRefs } from '../utils/mergeRefs' import { MaterialIcon, MaterialIconProps } from '../../Icons/MaterialIcon' import { Input } from '../../Input' import styles from './input.module.css' import type { FormInputProps } from './input' const defaultErrorFormatter = ( _intl: IntlShape, errorMessage?: string ): string => errorMessage ?? '' export const FormInput = forwardRef( function FormInput( { autoComplete, className = '', description = '', descriptionIcon = 'info' as MaterialIconProps['icon'], disabled = false, errorFormatter, hideError, inputMode, label, labelPosition = 'floating', maxLength, name, placeholder, readOnly = false, registerOptions = {}, type = 'text', validationState, ...props }, ref ) { const intl = useIntl() const { control } = useFormContext() const formatErrorMessage = errorFormatter ?? defaultErrorFormatter // Number input: prevent scroll from changing value const numberAttributes: HTMLAttributes = type === 'number' ? { onWheel: (evt: WheelEvent) => { evt.currentTarget.blur() }, } : {} return ( { const isDisabled = disabled || field.disabled const hasError = fieldState.invalid && !hideError const showDescription = description && !fieldState.error return ( // Note: No aria-label needed on TextField since the Input component // always renders a visible label that provides the accessible name {showDescription ? ( {description} ) : null} {hasError && fieldState.error ? ( {formatErrorMessage(intl, fieldState.error.message)} ) : null} ) }} /> ) } ) FormInput.displayName = 'FormInput'