| 186 | * @param ref - Ref to the HTML input or textarea element. |
| 187 | */ |
| 188 | export function useTextField<T extends TextFieldIntrinsicElements = DefaultElementType>( |
| 189 | props: AriaTextFieldOptions<T>, |
| 190 | ref: TextFieldRefObject<T> |
| 191 | ): TextFieldAria<T> { |
| 192 | let { |
| 193 | inputElementType = 'input', |
| 194 | isDisabled = false, |
| 195 | isRequired = false, |
| 196 | isReadOnly = false, |
| 197 | type = 'text', |
| 198 | validationBehavior = 'aria' |
| 199 | } = props; |
| 200 | let [value, setValue] = useControlledState<string>( |
| 201 | props.value, |
| 202 | props.defaultValue || '', |
| 203 | props.onChange |
| 204 | ); |
| 205 | let {focusableProps} = useFocusable<TextFieldHTMLElementType[T]>(props, ref); |
| 206 | let validationState = useFormValidationState({ |
| 207 | ...props, |
| 208 | value |
| 209 | }); |
| 210 | let {isInvalid, validationErrors, validationDetails} = validationState.displayValidation; |
| 211 | let {labelProps, fieldProps, descriptionProps, errorMessageProps} = useField({ |
| 212 | ...props, |
| 213 | isInvalid, |
| 214 | errorMessage: props.errorMessage || validationErrors |
| 215 | }); |
| 216 | let domProps = filterDOMProps(props, {labelable: true}); |
| 217 | |
| 218 | const inputOnlyProps = { |
| 219 | type, |
| 220 | pattern: props.pattern |
| 221 | }; |
| 222 | |
| 223 | let [initialValue] = useState(value); |
| 224 | useFormReset(ref, props.defaultValue ?? initialValue, setValue); |
| 225 | useFormValidation(props, validationState, ref); |
| 226 | |
| 227 | return { |
| 228 | labelProps, |
| 229 | inputProps: mergeProps(domProps, inputElementType === 'input' ? inputOnlyProps : undefined, { |
| 230 | disabled: isDisabled, |
| 231 | readOnly: isReadOnly, |
| 232 | required: isRequired && validationBehavior === 'native', |
| 233 | 'aria-required': (isRequired && validationBehavior === 'aria') || undefined, |
| 234 | 'aria-invalid': isInvalid || undefined, |
| 235 | 'aria-errormessage': props['aria-errormessage'], |
| 236 | 'aria-activedescendant': props['aria-activedescendant'], |
| 237 | 'aria-autocomplete': props['aria-autocomplete'], |
| 238 | 'aria-haspopup': props['aria-haspopup'], |
| 239 | 'aria-controls': props['aria-controls'], |
| 240 | value, |
| 241 | onChange: (e: ChangeEvent<HTMLInputElement>) => setValue(getEventTarget(e).value), |
| 242 | autoComplete: props.autoComplete, |
| 243 | autoCapitalize: props.autoCapitalize, |
| 244 | maxLength: props.maxLength, |
| 245 | minLength: props.minLength, |