From f8ac06dbb15625acbbdd8afaf58868a660653c92 Mon Sep 17 00:00:00 2001 From: Owen Coutts Date: Mon, 26 Aug 2024 10:29:53 -0600 Subject: [PATCH] fix: Update TextInput ref forwarding (#3011) --- .../forms/TextInput/TextInput.test.tsx | 30 ++++++- src/components/forms/TextInput/TextInput.tsx | 82 ++++++++++--------- 2 files changed, 74 insertions(+), 38 deletions(-) diff --git a/src/components/forms/TextInput/TextInput.test.tsx b/src/components/forms/TextInput/TextInput.test.tsx index 0d2b9d4892..f2c5ee7ac6 100644 --- a/src/components/forms/TextInput/TextInput.test.tsx +++ b/src/components/forms/TextInput/TextInput.test.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, { MutableRefObject, useRef } from 'react' import { render } from '@testing-library/react' import { TextInput } from './TextInput' import { ValidationStatus } from '../../../types/validationStatus' @@ -59,4 +59,32 @@ describe('TextInput component', () => { } ) }) + + describe('forwarding refs', () => { + beforeEach(() => { + vi.clearAllMocks() + }) + + it('appropriateley renders a ref', () => { + let ref + const Parent = () => { + ref = useRef(null) + return ( + + ) + } + + render() + + const parentRef = ref as unknown as MutableRefObject + + expect(parentRef.current).toBeInTheDocument() + expect(parentRef.current.tagName).toBe('INPUT') + }) + }) }) diff --git a/src/components/forms/TextInput/TextInput.tsx b/src/components/forms/TextInput/TextInput.tsx index 6c33196070..77f04576f0 100644 --- a/src/components/forms/TextInput/TextInput.tsx +++ b/src/components/forms/TextInput/TextInput.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, { forwardRef } from 'react' import classnames from 'classnames' import { ValidationStatus } from '../../../types/validationStatus' @@ -28,43 +28,51 @@ export type OptionalTextInputProps = CustomTextInputProps & export type TextInputProps = RequiredTextInputProps & OptionalTextInputProps -export const TextInput = ({ - id, - name, - type, - className, - validationStatus, - inputSize, - inputRef, - ...inputProps -}: TextInputProps): React.ReactElement => { - const isError = validationStatus === 'error' - const isSuccess = validationStatus === 'success' - const isSmall = inputSize === 'small' - const isMedium = inputSize === 'medium' +export const TextInput = forwardRef( + ( + props: TextInputProps, + ref: React.ForwardedRef | undefined + ): React.ReactElement => { + const { + id, + name, + type, + className, + validationStatus, + inputSize, + inputRef, + ...inputProps + } = props - const classes = classnames( - 'usa-input', - { - 'usa-input--error': isError, - 'usa-input--success': isSuccess, - 'usa-input--small': isSmall, - 'usa-input--medium': isMedium, - }, - className - ) + const isError = validationStatus === 'error' + const isSuccess = validationStatus === 'success' + const isSmall = inputSize === 'small' + const isMedium = inputSize === 'medium' - return ( - - ) -} + const classes = classnames( + 'usa-input', + { + 'usa-input--error': isError, + 'usa-input--success': isSuccess, + 'usa-input--small': isSmall, + 'usa-input--medium': isMedium, + }, + className + ) + + return ( + + ) + } +) +TextInput.displayName = 'TextInput' export default TextInput