FileUpload: associate the label with the input (#48766)

* FileUpload: associate the label with the input

* generate a unique id and set the correct role

* add a test to prevent regressions
This commit is contained in:
Ashley Harrison 2022-05-05 17:07:27 +01:00 committed by GitHub
parent ea96c42545
commit 10db618204
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 3 deletions

View File

@ -1,4 +1,5 @@
import { render, waitFor, fireEvent, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { selectors } from '@grafana/e2e-selectors';
@ -8,10 +9,23 @@ import { FileUpload } from './FileUpload';
describe('FileUpload', () => {
it('should render upload button with default text and no file name', () => {
render(<FileUpload onFileUpload={() => {}} />);
expect(screen.getByText('Upload file')).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Upload file' })).toBeInTheDocument();
expect(screen.queryByLabelText('File name')).toBeNull();
});
it('clicking the button should trigger the input', async () => {
const mockInputOnClick = jest.fn();
const { getByTestId } = render(<FileUpload onFileUpload={() => {}} />);
const button = screen.getByRole('button', { name: 'Upload file' });
const input = getByTestId(selectors.components.FileUpload.inputField);
// attach a click listener to the input
input.onclick = mockInputOnClick;
await userEvent.click(button);
expect(mockInputOnClick).toHaveBeenCalled();
});
it('should display uploaded file name', async () => {
const testFileName = 'grafana.png';
const file = new File(['(⌐□_□)'], testFileName, { type: 'image/png' });

View File

@ -1,5 +1,6 @@
import { css, cx } from '@emotion/css';
import React, { FC, FormEvent, useCallback, useState } from 'react';
import { v4 as uuidv4 } from 'uuid';
import { GrafanaTheme2 } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
@ -31,6 +32,7 @@ export const FileUpload: FC<Props> = ({
}) => {
const style = useStyles2(getStyles(size));
const [fileName, setFileName] = useState('');
const id = uuidv4();
const onChange = useCallback(
(event: FormEvent<HTMLInputElement>) => {
@ -47,14 +49,14 @@ export const FileUpload: FC<Props> = ({
<>
<input
type="file"
id="fileUpload"
id={id}
className={style.fileUpload}
onChange={onChange}
multiple={false}
accept={accept}
data-testid={selectors.components.FileUpload.inputField}
/>
<label className={cx(style.labelWrapper, className)}>
<label role="button" htmlFor={id} className={cx(style.labelWrapper, className)}>
<Icon name="upload" className={style.icon} />
{children}
</label>