import './index.css' import { useVisuallyHidden } from '@react-aria/visually-hidden' import { ReactNode, useCallback, useEffect, useRef, useState } from 'react' import * as React from 'react' import FieldLabel from '../FieldLabel' import { countCodePointsInString } from '../../_lib' import { useFocusWithClick } from './useFocusWithClick' import { mergeRefs, useId } from '@react-aria/utils' import { AssistiveText } from './AssistiveText' import { useClassNames } from '../../_lib/useClassNames' export type TextFieldProps = { prefix?: ReactNode suffix?: ReactNode value?: string onChange?: (value: string) => void showCount?: boolean showLabel?: boolean assistiveText?: string invalid?: boolean label?: string requiredText?: string disabled?: boolean subLabel?: React.ReactNode rdfaPrefix?: string getCount?: (value: string) => number } & Omit, 'prefix' | 'onChange'> const TextField = React.forwardRef( function SingleLineTextFieldInner( { assistiveText, className, disabled = false, label = '', maxLength, onChange, prefix = null, required, requiredText, showCount = false, showLabel = false, subLabel, suffix = null, type = 'text', invalid, value, getCount = countCodePointsInString, ...props }, forwardRef, ) { const inputRef = useRef(null) const { visuallyHiddenProps } = useVisuallyHidden() const [count, setCount] = useState(getCount(value ?? '')) const handleChange = useCallback( (e: React.ChangeEvent) => { const value = e.target.value const count = getCount(value) if (maxLength !== undefined && count > maxLength) { return } setCount(count) onChange?.(value) }, [getCount, maxLength, onChange], ) useEffect(() => { setCount(getCount(value ?? '')) }, [getCount, value]) const containerRef = useRef(null) useFocusWithClick(containerRef, inputRef) const inputId = useId(props.id) const describedbyId = useId() const labelledbyId = useId() const showAssistiveText = assistiveText != null && assistiveText.length !== 0 const classNames = useClassNames('charcoal-text-field-root', className) return (
{prefix &&
{prefix}
} {(suffix || showCount) && (
{suffix} {showCount && ( {maxLength !== undefined ? `${count}/${maxLength}` : count} )}
)}
{showAssistiveText && ( {assistiveText} )}
) }, ) export default TextField