diff --git a/packages/react/src/components/FileUploader/FileUploader.tsx b/packages/react/src/components/FileUploader/FileUploader.tsx index 4fbacbabff77..3d7ecd299c28 100644 --- a/packages/react/src/components/FileUploader/FileUploader.tsx +++ b/packages/react/src/components/FileUploader/FileUploader.tsx @@ -7,10 +7,10 @@ import classNames from 'classnames'; import PropTypes from 'prop-types'; -import React, { useState, ForwardedRef, ReactElement } from 'react'; +import React, { useState, ForwardedRef, useImperativeHandle } from 'react'; import Filename from './Filename'; import FileUploaderButton from './FileUploaderButton'; -import { ButtonKinds } from '../../prop-types/types'; +import { ButtonKinds } from '../Button/Button'; import { keys, matches } from '../../internal/keyboard'; import { usePrefix } from '../../internal/usePrefix'; import { ReactAttr } from '../../types/common'; @@ -107,8 +107,15 @@ export interface FileUploaderProps extends ReactAttr { size?: 'sm' | 'small' | 'md' | 'field' | 'lg'; } +export interface FileUploaderHandle { + /** + * Clear internal state + */ + clearFiles: () => void; +} + const FileUploader = React.forwardRef( - ( + ( { accept, buttonKind, @@ -127,7 +134,7 @@ const FileUploader = React.forwardRef( size, ...other }: FileUploaderProps, - ref: ForwardedRef + ref: ForwardedRef ) => { const fileUploaderInstanceId = useId('file-uploader'); const [state, updateState] = useState({ @@ -135,7 +142,6 @@ const FileUploader = React.forwardRef( }); const nodes: HTMLElement[] = []; const prefix = usePrefix(); - const handleChange = (evt) => { evt.stopPropagation(); const filenames = Array.prototype.map.call( @@ -169,10 +175,11 @@ const FileUploader = React.forwardRef( } }; - const clearFiles = () => { - // A clearFiles function that resets filenames and can be referenced using a ref by the parent. - updateState({ fileNames: [] }); - }; + useImperativeHandle(ref, () => ({ + clearFiles() { + updateState({ fileNames: [] }); + }, + })); const uploaderButton = React.createRef(); const classes = classNames({ @@ -255,12 +262,7 @@ const FileUploader = React.forwardRef( ); } -) as { - (props: FileUploaderProps): ReactElement; - propTypes?: any; - contextTypes?: any; - defaultProps?: any; -}; +); FileUploader.propTypes = { /** @@ -342,6 +344,6 @@ FileUploader.propTypes = { * sizes. */ size: PropTypes.oneOf(['sm', 'md', 'lg']), -}; +} as PropTypes.ValidationMap; export default FileUploader; diff --git a/packages/react/src/components/FileUploader/__tests__/FileUploader-test.js b/packages/react/src/components/FileUploader/__tests__/FileUploader-test.js index affd64c8aa1c..b005c9711cfc 100644 --- a/packages/react/src/components/FileUploader/__tests__/FileUploader-test.js +++ b/packages/react/src/components/FileUploader/__tests__/FileUploader-test.js @@ -50,38 +50,22 @@ describe('FileUploader', () => { it('should clear all uploaded files when `clearFiles` is called on a ref', () => { const ref = React.createRef(); - const onClick = jest.fn(); - let requiredProps1 = { - ...requiredProps, - filenameStatus: 'edit', - }; - const fileUpload = render( - - ); + const { container } = render(); // eslint-disable-next-line testing-library/no-container, testing-library/no-node-access - const input = fileUpload.container.querySelector('input'); + const input = container.querySelector('input'); const filename = 'test.png'; act(() => { uploadFiles(input, [new File(['test'], filename, { type: 'image/png' })]); }); - expect(getByText(fileUpload.container, filename)).toBeInstanceOf( - HTMLElement - ); - - const onDelete = jest.fn(); - const description = 'test-description'; - // eslint-disable-next-line testing-library/render-result-naming-convention - let removeFile = getByLabel( - fileUpload.container, - 'test description - test.png' - ); + // eslint-disable-next-line testing-library/prefer-screen-queries + expect(getByText(container, filename)).toBeInstanceOf(HTMLElement); act(() => { - Simulate.click(removeFile); + ref.current.clearFiles(); }); - - expect(onClick).toHaveBeenCalledTimes(1); + // eslint-disable-next-line testing-library/prefer-screen-queries + expect(getByText(container, filename)).not.toBeInstanceOf(HTMLElement); }); it('should synchronize the filename status state when its prop changes', () => {