mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
Fixing console a11y failures (#57520)
This commit is contained in:
parent
76d475a64c
commit
0160aa4211
5 changed files with 74 additions and 54 deletions
|
@ -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" />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
flex: 1 1 1px;
|
||||
}
|
||||
|
||||
.conApp__textAreaLabelHack,
|
||||
.conApp__editorContent,
|
||||
.conApp__outputContent {
|
||||
height: 100%;
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue