Fixing console a11y failures (#57520)

This commit is contained in:
Michail Yasonik 2020-02-18 17:44:25 -05:00 committed by GitHub
parent 76d475a64c
commit 0160aa4211
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 74 additions and 54 deletions

View file

@ -16,10 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
import React, { useEffect } from 'react';
import { EuiScreenReaderOnly } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
// @ts-ignore
import exampleText from 'raw-loader!../constants/help_example.txt';
import React, { useEffect } from 'react';
import { createReadOnlyAceEditor } from '../models/legacy_core_editor';
interface EditorExampleProps {
@ -28,16 +29,31 @@ interface EditorExampleProps {
export function EditorExample(props: EditorExampleProps) {
const elemId = `help-example-${props.panel}`;
const inputId = `help-example-${props.panel}-input`;
useEffect(() => {
const el = document.querySelector<HTMLElement>(`#${elemId}`)!;
const el = document.getElementById(elemId)!;
el.textContent = exampleText.trim();
const editor = createReadOnlyAceEditor(el);
const textarea = el.querySelector('textarea')!;
textarea.setAttribute('id', inputId);
textarea.setAttribute('readonly', 'true');
return () => {
editor.destroy();
};
}, [elemId]);
}, [elemId, inputId]);
return <div id={elemId} className="conHelp__example" />;
return (
<>
<EuiScreenReaderOnly>
<label htmlFor={inputId}>
{i18n.translate('console.exampleOutputTextarea', {
defaultMessage: 'Dev Tools Console editor example',
})}
</label>
</EuiScreenReaderOnly>
<div id={elemId} className="conHelp__example" />
</>
);
}

View file

@ -17,31 +17,26 @@
* under the License.
*/
import React, { CSSProperties, useCallback, useEffect, useRef, useState } from 'react';
import { EuiToolTip } from '@elastic/eui';
import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiScreenReaderOnly, EuiToolTip } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { debounce } from 'lodash';
import { parse } from 'query-string';
import { EuiIcon, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { useServicesContext, useEditorReadContext } from '../../../../contexts';
import { useUIAceKeyboardMode } from '../use_ui_ace_keyboard_mode';
import { ConsoleMenu } from '../../../../components';
import { autoIndent, getDocumentation } from '../console_menu_actions';
import { registerCommands } from './keyboard_shortcuts';
import { applyCurrentSettings } from './apply_editor_settings';
import {
useSendCurrentRequestToES,
useSetInputEditor,
useSaveCurrentTextObject,
} from '../../../../hooks';
import * as senseEditor from '../../../../models/sense_editor';
import React, { CSSProperties, useCallback, useEffect, useRef, useState } from 'react';
// @ts-ignore
import mappings from '../../../../../lib/mappings/mappings';
import { ConsoleMenu } from '../../../../components';
import { useEditorReadContext, useServicesContext } from '../../../../contexts';
import {
useSaveCurrentTextObject,
useSendCurrentRequestToES,
useSetInputEditor,
} from '../../../../hooks';
import * as senseEditor from '../../../../models/sense_editor';
import { autoIndent, getDocumentation } from '../console_menu_actions';
import { subscribeResizeChecker } from '../subscribe_console_resize_checker';
import { useUIAceKeyboardMode } from '../use_ui_ace_keyboard_mode';
import { applyCurrentSettings } from './apply_editor_settings';
import { registerCommands } from './keyboard_shortcuts';
export interface EditorProps {
initialTextValue: string;
@ -66,6 +61,8 @@ const DEFAULT_INPUT_VALUE = `GET _search
}
}`;
const inputId = 'ConAppInputTextarea';
function EditorUI({ initialTextValue }: EditorProps) {
const {
services: { history, notifications },
@ -95,6 +92,11 @@ function EditorUI({ initialTextValue }: EditorProps) {
useEffect(() => {
editorInstanceRef.current = senseEditor.create(editorRef.current!);
const editor = editorInstanceRef.current;
const textareaElement = editorRef.current!.querySelector('textarea');
if (textareaElement) {
textareaElement.setAttribute('id', inputId);
}
const readQueryParams = () => {
const [, queryString] = (window.location.hash || '').split('?');
@ -244,19 +246,19 @@ function EditorUI({ initialTextValue }: EditorProps) {
</EuiFlexItem>
</EuiFlexGroup>
{/* Axe complains about Ace's textarea element missing a label, which interferes with our
automated a11y tests per #52136. This wrapper does nothing to address a11y but it does
satisfy Axe. */}
{/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
<label className="conApp__textAreaLabelHack">
<div
ref={editorRef}
id="ConAppEditor"
className="conApp__editorContent"
data-test-subj="request-editor"
/>
</label>
<EuiScreenReaderOnly>
<label htmlFor={inputId}>
{i18n.translate('console.inputTextarea', {
defaultMessage: 'Dev Tools Console',
})}
</label>
</EuiScreenReaderOnly>
<div
ref={editorRef}
id="ConAppEditor"
className="conApp__editorContent"
data-test-subj="request-editor"
/>
</div>
</div>
);

View file

@ -17,17 +17,16 @@
* under the License.
*/
import { EuiScreenReaderOnly } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { useEffect, useRef } from 'react';
import { createReadOnlyAceEditor, CustomAceEditor } from '../../../../models/legacy_core_editor';
import { expandLiteralStrings } from '../../../../../../../es_ui_shared/console_lang/lib';
import {
useServicesContext,
useEditorReadContext,
useRequestReadContext,
useServicesContext,
} from '../../../../contexts';
import { expandLiteralStrings } from '../../../../../../../es_ui_shared/console_lang/lib';
import { createReadOnlyAceEditor, CustomAceEditor } from '../../../../models/legacy_core_editor';
import { subscribeResizeChecker } from '../subscribe_console_resize_checker';
import { applyCurrentSettings } from './apply_editor_settings';
@ -44,18 +43,22 @@ function EditorOutputUI() {
const editorRef = useRef<null | HTMLDivElement>(null);
const editorInstanceRef = useRef<null | CustomAceEditor>(null);
const { services } = useServicesContext();
const { settings: readOnlySettings } = useEditorReadContext();
const {
lastResult: { data, error },
} = useRequestReadContext();
const inputId = 'ConAppOutputTextarea';
useEffect(() => {
editorInstanceRef.current = createReadOnlyAceEditor(editorRef.current!);
const unsubscribe = subscribeResizeChecker(editorRef.current!, editorInstanceRef.current);
const textarea = editorRef.current!.querySelector('textarea')!;
textarea.setAttribute('id', inputId);
textarea.setAttribute('readonly', 'true');
return () => {
unsubscribe();
editorInstanceRef.current!.destroy();
};
}, [services.settings]);
@ -84,15 +87,15 @@ function EditorOutputUI() {
return (
<>
<div ref={editorRef} className="conApp__output" data-test-subj="response-editor">
{/* Axe complains about Ace's textarea element missing a label, which interferes with our
automated a11y tests per #52136. This wrapper does nothing to address a11y but it does
satisfy Axe. */}
{/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
<label className="conApp__textAreaLabelHack">
<div className="conApp__outputContent" id="ConAppOutput" />
<EuiScreenReaderOnly>
<label htmlFor={inputId}>
{i18n.translate('console.outputTextarea', {
defaultMessage: 'Dev Tools Console output',
})}
</label>
</EuiScreenReaderOnly>
<div ref={editorRef} className="conApp__output" data-test-subj="response-editor">
<div className="conApp__outputContent" id="ConAppOutput" />
</div>
</>
);

View file

@ -37,7 +37,6 @@
flex: 1 1 1px;
}
.conApp__textAreaLabelHack,
.conApp__editorContent,
.conApp__outputContent {
height: 100%;

View file

@ -32,7 +32,7 @@ export default async function({ readConfigFile }: FtrConfigProviderContext) {
require.resolve('./apps/dashboard'),
require.resolve('./apps/visualize'),
require.resolve('./apps/management'),
// require.resolve('./apps/console'),
require.resolve('./apps/console'),
require.resolve('./apps/home'),
],
pageObjects,