, isDisabled: false, isExpanded: false, type: TextInputTypes.text, isLeftTruncated: false, isStartTruncated: false, onChange: (): any => undefined, ouiaSafe: true }; inputRef = React.createRef(); observer: any = () => {}; constructor(props: TextInputProps) { super(props); if (!props.id && !props['aria-label'] && !props['aria-labelledby']) { // eslint-disable-next-line no-console console.error('Text input:', 'Text input requires either an id or aria-label to be specified'); } this.state = { ouiaStateId: getDefaultOUIAId(TextInputBase.displayName) }; } handleChange = (event: React.FormEvent) => { if (this.props.onChange) { this.props.onChange(event, event.currentTarget.value); } }; componentDidMount() { if (this.props.isLeftTruncated || this.props.isStartTruncated) { const inputRef = this.props.innerRef || this.inputRef; this.observer = getResizeObserver(inputRef.current, this.handleResize, true); this.handleResize(); } } componentWillUnmount() { if (this.props.isLeftTruncated || this.props.isStartTruncated) { this.observer(); } } handleResize = () => { const inputRef = this.props.innerRef || this.inputRef; if (inputRef && inputRef.current) { trimLeft(inputRef.current, String(this.props.value)); } }; restoreText = () => { const inputRef = this.props.innerRef || this.inputRef; // restore the value (inputRef.current as HTMLInputElement).value = String(this.props.value); // make sure we still see the rightmost value to preserve cursor click position inputRef.current.scrollLeft = inputRef.current.scrollWidth; }; onFocus = (event?: any) => { const { isLeftTruncated, isStartTruncated, onFocus } = this.props; if (isLeftTruncated || isStartTruncated) { this.restoreText(); } onFocus && onFocus(event); }; onBlur = (event?: any) => { const { isLeftTruncated, isStartTruncated, onBlur } = this.props; if (isLeftTruncated || isStartTruncated) { this.handleResize(); } onBlur && onBlur(event); }; render() { const { innerRef, className, type, value, placeholder, validated, /* eslint-disable @typescript-eslint/no-unused-vars */ onChange, onFocus, onBlur, isLeftTruncated, isStartTruncated, isExpanded, expandedProps, readOnly, readOnlyVariant, isRequired, isDisabled, customIcon, ouiaId, ouiaSafe, ...props } = this.props; const hasStatusIcon = ['success', 'error', 'warning'].includes(validated); const ariaExpandedProps = expandedProps ? { 'aria-expanded': expandedProps?.isExpanded, 'aria-controls': expandedProps?.ariaControls, role: 'combobox' } : {}; return ( {(customIcon || hasStatusIcon) && ( {customIcon && } {hasStatusIcon && } )} ); } private sanitizeInputValue = (value: string | number) => typeof value === 'string' ? value.replace(/\n/g, ' ') : value; } export const TextInput = React.forwardRef((props: TextInputProps, ref: React.Ref) => ( } /> )); TextInput.displayName = 'TextInput';