diff --git a/eslint-suppressions.json b/eslint-suppressions.json index 09e46121320..708c8f9fbcc 100644 --- a/eslint-suppressions.json +++ b/eslint-suppressions.json @@ -671,11 +671,6 @@ "count": 1 } }, - "packages/grafana-ui/src/components/FileDropzone/FileDropzone.story.tsx": { - "no-restricted-syntax": { - "count": 1 - } - }, "packages/grafana-ui/src/components/FormField/FormField.tsx": { "no-restricted-syntax": { "count": 1 diff --git a/packages/grafana-ui/src/components/FileDropzone/FileDropzone.story.tsx b/packages/grafana-ui/src/components/FileDropzone/FileDropzone.story.tsx index 9ac5e775590..133022394f3 100644 --- a/packages/grafana-ui/src/components/FileDropzone/FileDropzone.story.tsx +++ b/packages/grafana-ui/src/components/FileDropzone/FileDropzone.story.tsx @@ -1,4 +1,7 @@ import { Meta, StoryFn } from '@storybook/react'; +import { useId } from 'react'; + +import { Field } from '../Forms/Field'; import { FileDropzone } from './FileDropzone'; import mdx from './FileDropzone.mdx'; @@ -10,12 +13,17 @@ const meta: Meta = { docs: { page: mdx, }, - // TODO fix a11y issue in story and remove this - a11y: { test: 'off' }, }, }; -const Template: StoryFn = (args) => ; +const Template: StoryFn = (args) => { + const inputId = useId(); + return ( + + + + ); +}; export const Basic = Template.bind({}); diff --git a/packages/grafana-ui/src/components/FileDropzone/FileDropzone.tsx b/packages/grafana-ui/src/components/FileDropzone/FileDropzone.tsx index 1d27de173a1..120c7e08a09 100644 --- a/packages/grafana-ui/src/components/FileDropzone/FileDropzone.tsx +++ b/packages/grafana-ui/src/components/FileDropzone/FileDropzone.tsx @@ -47,6 +47,11 @@ export interface FileDropzoneProps { */ fileListRenderer?: (file: DropzoneFile, removeFile: (file: DropzoneFile) => void) => ReactNode; onFileRemove?: (file: DropzoneFile) => void; + /** + * Optional id attribute for the underlying input element + * Use to link a label to the input for accessibility + */ + id?: string; } export interface DropzoneFile { @@ -58,7 +63,15 @@ export interface DropzoneFile { retryUpload?: () => void; } -export function FileDropzone({ options, children, readAs, onLoad, fileListRenderer, onFileRemove }: FileDropzoneProps) { +export function FileDropzone({ + options, + children, + readAs, + onLoad, + fileListRenderer, + onFileRemove, + id, +}: FileDropzoneProps) { const [files, setFiles] = useState([]); const [fileErrors, setErrorMessages] = useState([]); @@ -218,7 +231,7 @@ export function FileDropzone({ options, children, readAs, onLoad, fileListRender return (
- + {children ?? }
{fileErrors.length > 0 && renderErrorMessages(fileErrors)}