import { forwardRef, ReactNode, useCallback, useEffect, useImperativeHandle, useRef, useState, } from 'react'; import classnames from 'classnames'; import { Icon, TapArea, TextUI, useDefaultLabel } from 'morphe'; import styles from './VRDateInput.css'; import ErrorMessage from '../subcomponents/ErrorMessage'; import HelperText from '../subcomponents/HelperText'; type Props = { id: string; onChange: (arg1: { event: React.ChangeEvent; value: string }) => void; accessibilityControls?: string; dataTestId?: string; disabled?: boolean; errorMessage?: ReactNode; helperText?: string; label?: string; labelDisplay?: 'visible' | 'hidden'; name?: string; onBlur?: (arg1: { event: React.FocusEvent; value: string }) => void; onClick?: (arg1: { event: React.MouseEvent; value: string }) => void; onFocus?: (arg1: { event: React.FocusEvent; value: string }) => void; onKeyDown?: (arg1: { event: React.KeyboardEvent; value: string }) => void; placeholder?: string; readOnly?: boolean; value?: string; size?: 'md' | 'lg'; }; const InternalTextFieldWithForwardRef = forwardRef(function TextField( { accessibilityControls, dataTestId, disabled = false, errorMessage, helperText, id, label, labelDisplay = 'visible', name, onBlur, onChange, onClick, onFocus, onKeyDown, placeholder, readOnly, size = 'lg', value, }: Props, ref, ) { const innerRef = useRef(null); const labelRef = useRef(null); // @ts-expect-error - TS2322 - Type 'HTMLDivElement | HTMLInputElement | null' is not assignable to type 'HTMLInputElement'. useImperativeHandle(ref, () => innerRef.current); const { openCalendar } = useDefaultLabel('DatePicker'); const hasErrorMessage = Boolean(errorMessage); const isLabelVisible = labelDisplay === 'visible'; // ==== STATE ==== const [focused, setFocused] = useState(false); const [ellipsisActive, setEllipsisActive] = useState(false); // ==== A11Y ==== let ariaDescribedby; if (hasErrorMessage) { ariaDescribedby = `${id}-error`; } if (helperText) { ariaDescribedby = `${id}-helperText`; } const isEllipsisActive = (element: HTMLElement) => element.offsetHeight < element.scrollHeight || element.offsetWidth < element.scrollWidth; const checkEllipsisActive = useCallback(() => { if (labelRef.current && !ellipsisActive && isEllipsisActive(labelRef?.current)) { setEllipsisActive(true); } else if (labelRef.current && ellipsisActive && !isEllipsisActive(labelRef?.current)) { setEllipsisActive(false); } }, [ellipsisActive]); useEffect(() => { if (!label) return () => {}; checkEllipsisActive(); if (typeof window !== 'undefined') window.addEventListener('resize', checkEllipsisActive); return () => { if (typeof window !== 'undefined') window?.removeEventListener('resize', checkEllipsisActive); }; }, [label, checkEllipsisActive]); const isMD = size === 'md'; const isLG = size === 'lg'; return (
{label && ( )} { setFocused(false); onBlur?.({ event, value: event.currentTarget.value }); }} onChange={(event) => { onChange({ event, value: event.currentTarget.value }); }} onClick={(event) => onClick?.({ event, value: event.currentTarget.value })} onFocus={(event) => { setFocused(true); onFocus?.({ event, value: event.currentTarget.value }); }} onKeyDown={(event) => onKeyDown?.({ event, value: event.currentTarget.value })} placeholder={placeholder} readOnly={readOnly} value={value} /> {!disabled && (
{ innerRef.current?.focus(); }} rounding="circle" tabIndex={-1} tapStyle="none" >
)}
{helperText && !hasErrorMessage ? ( ) : null} {!disabled && hasErrorMessage ? ( ) : null}
); }); InternalTextFieldWithForwardRef.displayName = 'InternalTextField'; export default InternalTextFieldWithForwardRef;