import { forwardRef, ReactNode, useCallback, useEffect, useImperativeHandle, useRef, useState, } from 'react'; import classnames from 'classnames'; import IconEnd from './IconEnd'; import styles from './VRSelectList.css'; import boxStyles from '../Box.css'; import FormErrorMessage from '../sharedSubcomponents/FormErrorMessage'; import FormHelperText from '../sharedSubcomponents/FormHelperText'; import TextUI from '../TextUI'; import typographyStyle from '../Typography.css'; type SizeType = 'md' | 'lg'; type Props = { dataTestId?: string; children: ReactNode; disabled?: boolean; errorMessage?: string; helperText?: string; id: string; label?: string; labelDisplay?: 'visible' | 'hidden'; name?: string; onBlur?: (arg1: { event: React.FocusEvent; value: string }) => void; onChange: (arg1: { event: React.ChangeEvent; value: string }) => void; onFocus?: (arg1: { event: React.FocusEvent; value: string }) => void; placeholder?: string; size?: SizeType; value?: string | null | undefined; }; const SelectListWithForwardRef = forwardRef(function InternalSelectList( { dataTestId, children, disabled = false, errorMessage, helperText, id, label, labelDisplay = 'visible', name, onBlur, onChange, onFocus, placeholder, size = 'md', 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 hasErrorMessage = Boolean(errorMessage); const isLabelVisible = labelDisplay === 'visible'; const showPlaceholder = placeholder && !value; const isMD = size === 'md'; const isLG = size === 'lg'; // ==== 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]); return (
{label && ( )} {!disabled && }
{helperText && !hasErrorMessage ? ( ) : null} {!disabled && hasErrorMessage ? ( ) : null}
); }); SelectListWithForwardRef.displayName = 'InternalSelectList'; export default SelectListWithForwardRef;