mirror of
https://github.com/ansible/awx.git
synced 2026-01-17 12:41:19 -03:30
add keyboard navigation help text to CodeEditor
This commit is contained in:
parent
070c67ffe8
commit
19f4de0d05
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useRef, useCallback } from 'react';
|
||||
import React, { useEffect, useRef, useCallback, useState } from 'react';
|
||||
import { oneOf, bool, number, string, func } from 'prop-types';
|
||||
import ReactAce from 'react-ace';
|
||||
import 'ace-builds/src-noconflict/mode-json';
|
||||
@ -6,11 +6,23 @@ import 'ace-builds/src-noconflict/mode-javascript';
|
||||
import 'ace-builds/src-noconflict/mode-yaml';
|
||||
import 'ace-builds/src-noconflict/mode-django';
|
||||
import 'ace-builds/src-noconflict/theme-github';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import styled from 'styled-components';
|
||||
|
||||
const LINE_HEIGHT = 24;
|
||||
const PADDING = 12;
|
||||
|
||||
const FocusWrapper = styled.div`
|
||||
&& + .pf-c-form__helper-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:focus-within + .pf-c-form__helper-text {
|
||||
display: block;
|
||||
}
|
||||
`;
|
||||
|
||||
const AceEditor = styled(ReactAce)`
|
||||
font-family: var(--pf-global--FontFamily--monospace);
|
||||
max-height: 90vh;
|
||||
@ -45,16 +57,21 @@ function CodeEditor({
|
||||
rows,
|
||||
fullHeight,
|
||||
className,
|
||||
i18n,
|
||||
}) {
|
||||
const [isKeyboardFocused, setIsKeyboardFocused] = useState(false);
|
||||
const wrapper = useRef(null);
|
||||
const editor = useRef(null);
|
||||
|
||||
useEffect(function removeTextareaTabIndex() {
|
||||
const editorInput = editor.current.refEditor?.querySelector('textarea');
|
||||
if (editorInput) {
|
||||
editorInput.tabIndex = -1;
|
||||
}
|
||||
}, []);
|
||||
useEffect(
|
||||
function removeTextareaTabIndex() {
|
||||
const editorInput = editor.current.refEditor?.querySelector('textarea');
|
||||
if (editorInput && !readOnly) {
|
||||
editorInput.tabIndex = -1;
|
||||
}
|
||||
},
|
||||
[readOnly]
|
||||
);
|
||||
|
||||
const listen = useCallback(event => {
|
||||
if (
|
||||
@ -88,43 +105,60 @@ function CodeEditor({
|
||||
const numRows = fullHeight ? value.split('\n').length : rows;
|
||||
|
||||
return (
|
||||
/* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */
|
||||
<div ref={wrapper} tabIndex={0}>
|
||||
<AceEditor
|
||||
mode={aceModes[mode] || 'text'}
|
||||
className={`pf-c-form-control ${className}`}
|
||||
theme="github"
|
||||
onChange={onChange}
|
||||
value={value}
|
||||
name={id || 'code-editor'}
|
||||
editorProps={{ $blockScrolling: true }}
|
||||
fontSize={16}
|
||||
width="100%"
|
||||
height={`${numRows * LINE_HEIGHT + PADDING}px`}
|
||||
hasErrors={hasErrors}
|
||||
setOptions={{
|
||||
readOnly,
|
||||
useWorker: false,
|
||||
<>
|
||||
<FocusWrapper
|
||||
ref={wrapper}
|
||||
tabIndex={readOnly ? -1 : 0}
|
||||
onFocus={e => {
|
||||
if (e.target === e.currentTarget) {
|
||||
setIsKeyboardFocused(true);
|
||||
}
|
||||
if (e.target.className.includes('ace_scrollbar')) {
|
||||
setIsKeyboardFocused(false);
|
||||
}
|
||||
}}
|
||||
commands={[
|
||||
{
|
||||
name: 'escape',
|
||||
bindKey: { win: 'Esc', mac: 'Esc' },
|
||||
exec: () => {
|
||||
wrapper.current.focus();
|
||||
>
|
||||
<AceEditor
|
||||
mode={aceModes[mode] || 'text'}
|
||||
className={`pf-c-form-control ${className}`}
|
||||
theme="github"
|
||||
onChange={onChange}
|
||||
value={value}
|
||||
name={id || 'code-editor'}
|
||||
editorProps={{ $blockScrolling: true }}
|
||||
fontSize={16}
|
||||
width="100%"
|
||||
height={`${numRows * LINE_HEIGHT + PADDING}px`}
|
||||
hasErrors={hasErrors}
|
||||
setOptions={{
|
||||
readOnly,
|
||||
useWorker: false,
|
||||
}}
|
||||
commands={[
|
||||
{
|
||||
name: 'escape',
|
||||
bindKey: { win: 'Esc', mac: 'Esc' },
|
||||
exec: () => {
|
||||
wrapper.current.focus();
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'tab escape',
|
||||
bindKey: { win: 'Shift-Tab', mac: 'Shift-Tab' },
|
||||
exec: () => {
|
||||
wrapper.current.focus();
|
||||
{
|
||||
name: 'tab escape',
|
||||
bindKey: { win: 'Shift-Tab', mac: 'Shift-Tab' },
|
||||
exec: () => {
|
||||
wrapper.current.focus();
|
||||
},
|
||||
},
|
||||
},
|
||||
]}
|
||||
ref={editor}
|
||||
/>
|
||||
</div>
|
||||
]}
|
||||
ref={editor}
|
||||
/>
|
||||
</FocusWrapper>
|
||||
{isKeyboardFocused && (
|
||||
<div className="pf-c-form__helper-text" aria-live="polite">
|
||||
{i18n._(t`Press Enter to edit. Press ESC to stop editing.`)}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
CodeEditor.propTypes = {
|
||||
@ -146,4 +180,4 @@ CodeEditor.defaultProps = {
|
||||
className: '',
|
||||
};
|
||||
|
||||
export default CodeEditor;
|
||||
export default withI18n()(CodeEditor);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user