From 92fb6872f037e11f8fb52c00b7a20aeddfc4d52f Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Tue, 28 Oct 2025 09:22:09 +0000 Subject: [PATCH] FileDropzone: expose `id` to underlying input, fix story a11y violations (#113042) * expose inputId to underlying input, add field to story * just use id instead of inputId --- eslint-suppressions.json | 5 ----- .../FileDropzone/FileDropzone.story.tsx | 14 +++++++++++--- .../components/FileDropzone/FileDropzone.tsx | 17 +++++++++++++++-- 3 files changed, 26 insertions(+), 10 deletions(-) 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)}