fix: #[Rules > Detection rules][AXE-CORE]: Form elements must have anaccessible label (#177205)

Closes: https://github.com/elastic/security-team/issues/8568

## Summary

The Import Rules modal in the Axe browser plugin is being flagged by the
tool for lacking an accessible label on a form element. This pull
request addresses this issue by introducing the `aria-labelledby`
attribute to the `input[type="file"]`.

### Screen

![image](6130c0ef-5c5d-4c08-b602-f997efe248d9)

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Alexey Antonov 2024-03-05 12:17:05 +02:00 committed by GitHub
parent 872b25096a
commit 82f25ce154
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 28 additions and 8 deletions

View file

@ -48,7 +48,9 @@ Object {
<div <div
class="euiText emotion-euiText-s" class="euiText emotion-euiText-s"
> >
<h4> <h4
id="generated-id"
>
description description
</h4> </h4>
</div> </div>
@ -64,6 +66,7 @@ Object {
<input <input
accept=".ndjson" accept=".ndjson"
aria-describedby="rule-file-picker-filePicker__prompt" aria-describedby="rule-file-picker-filePicker__prompt"
aria-labelledby="generated-id"
class="euiFilePicker__input" class="euiFilePicker__input"
data-test-subj="rule-file-picker" data-test-subj="rule-file-picker"
id="rule-file-picker" id="rule-file-picker"
@ -255,7 +258,9 @@ Object {
<div <div
class="euiText emotion-euiText-s" class="euiText emotion-euiText-s"
> >
<h4> <h4
id="generated-id"
>
description description
</h4> </h4>
</div> </div>
@ -271,6 +276,7 @@ Object {
<input <input
accept=".ndjson" accept=".ndjson"
aria-describedby="rule-file-picker-filePicker__prompt" aria-describedby="rule-file-picker-filePicker__prompt"
aria-labelledby="generated-id"
class="euiFilePicker__input" class="euiFilePicker__input"
data-test-subj="rule-file-picker" data-test-subj="rule-file-picker"
id="rule-file-picker" id="rule-file-picker"
@ -541,7 +547,9 @@ Object {
<div <div
class="euiText emotion-euiText-s" class="euiText emotion-euiText-s"
> >
<h4> <h4
id="generated-id"
>
description description
</h4> </h4>
</div> </div>
@ -557,6 +565,7 @@ Object {
<input <input
accept=".ndjson" accept=".ndjson"
aria-describedby="rule-file-picker-filePicker__prompt" aria-describedby="rule-file-picker-filePicker__prompt"
aria-labelledby="generated-id"
class="euiFilePicker__input" class="euiFilePicker__input"
data-test-subj="rule-file-picker" data-test-subj="rule-file-picker"
id="rule-file-picker" id="rule-file-picker"

View file

@ -5,7 +5,8 @@
* 2.0. * 2.0.
*/ */
import React, { useCallback, useState } from 'react'; import React, { useCallback, useMemo, useState } from 'react';
import type { EuiFilePickerProps } from '@elastic/eui';
import { import {
EuiButton, EuiButton,
EuiButtonEmpty, EuiButtonEmpty,
@ -18,6 +19,7 @@ import {
EuiModalHeaderTitle, EuiModalHeaderTitle,
EuiSpacer, EuiSpacer,
EuiText, EuiText,
htmlIdGenerator,
} from '@elastic/eui'; } from '@elastic/eui';
import type { WarningSchema } from '../../../../common/api/detection_engine'; import type { WarningSchema } from '../../../../common/api/detection_engine';
@ -78,6 +80,8 @@ export const ImportDataModalComponent = ({
const [actionConnectorsWarnings, setActionConnectorsWarnings] = useState<WarningSchema[] | []>( const [actionConnectorsWarnings, setActionConnectorsWarnings] = useState<WarningSchema[] | []>(
[] []
); );
const descriptionElementId = useMemo(() => htmlIdGenerator()(), []);
const [importedActionConnectorsCount, setImportedActionConnectorsCount] = useState< const [importedActionConnectorsCount, setImportedActionConnectorsCount] = useState<
number | undefined number | undefined
>(0); >(0);
@ -168,6 +172,14 @@ export const ImportDataModalComponent = ({
const handleActionConnectorsCheckboxClick = useCallback(() => { const handleActionConnectorsCheckboxClick = useCallback(() => {
setOverwriteActionConnectors((shouldOverwrite) => !shouldOverwrite); setOverwriteActionConnectors((shouldOverwrite) => !shouldOverwrite);
}, []); }, []);
const handleFilePickerChange: EuiFilePickerProps['onChange'] = useCallback(
(files: FileList | null) => {
setSelectedFiles(files && files.length > 0 ? files : null);
},
[]
);
return ( return (
<> <>
{showModal && ( {showModal && (
@ -178,7 +190,7 @@ export const ImportDataModalComponent = ({
<EuiModalBody> <EuiModalBody>
<EuiText size="s"> <EuiText size="s">
<h4>{description}</h4> <h4 id={descriptionElementId}>{description}</h4>
</EuiText> </EuiText>
<EuiSpacer size="s" /> <EuiSpacer size="s" />
@ -187,12 +199,11 @@ export const ImportDataModalComponent = ({
accept=".ndjson" accept=".ndjson"
id="rule-file-picker" id="rule-file-picker"
initialPromptText={subtitle} initialPromptText={subtitle}
onChange={(files: FileList | null) => { onChange={handleFilePickerChange}
setSelectedFiles(files && files.length > 0 ? files : null);
}}
display={'large'} display={'large'}
fullWidth={true} fullWidth={true}
isLoading={isImporting} isLoading={isImporting}
aria-labelledby={descriptionElementId}
/> />
<EuiSpacer size="s" /> <EuiSpacer size="s" />