mirror of
https://github.com/ansible/awx.git
synced 2026-03-09 13:39:27 -02:30
add code editor focus/blur keyboard controls
This commit is contained in:
committed by
Keith J. Grant
parent
1afdd7ac1d
commit
4e9c6a956d
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect, useRef, useCallback } from 'react';
|
||||||
import { oneOf, bool, number, string, func } from 'prop-types';
|
import { oneOf, bool, number, string, func } from 'prop-types';
|
||||||
import AceEditor from 'react-ace';
|
import AceEditor from 'react-ace';
|
||||||
// import * as ace from 'ace-builds';
|
// import * as ace from 'ace-builds';
|
||||||
@@ -79,6 +79,7 @@ const CodeMirror = styled(ReactCodeMirror)`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
function CodeMirrorInput({
|
function CodeMirrorInput({
|
||||||
|
id,
|
||||||
value,
|
value,
|
||||||
onChange,
|
onChange,
|
||||||
mode,
|
mode,
|
||||||
@@ -89,19 +90,33 @@ function CodeMirrorInput({
|
|||||||
className,
|
className,
|
||||||
placeholder,
|
placeholder,
|
||||||
}) {
|
}) {
|
||||||
// Workaround for CodeMirror bug: If CodeMirror renders in a modal on the
|
const wrapper = useRef(null);
|
||||||
// modal's initial render, it appears as an empty box due to mis-calculated
|
const editor = useRef(null);
|
||||||
// element height. Forcing an initial render before mounting <CodeMirror>
|
|
||||||
// fixes this.
|
useEffect(function removeTextareaTabIndex() {
|
||||||
const [isInitialized, setIsInitialized] = useState(false);
|
const editorInput = editor.current.refEditor?.querySelector('textarea');
|
||||||
useEffect(() => {
|
if (editorInput) {
|
||||||
if (!isInitialized) {
|
editorInput.tabIndex = -1;
|
||||||
setIsInitialized(true);
|
|
||||||
}
|
}
|
||||||
}, [isInitialized]);
|
}, []);
|
||||||
if (!isInitialized) {
|
|
||||||
return <div />;
|
const listen = useCallback(event => {
|
||||||
}
|
if (wrapper.current === document.activeElement && event.key === 'Enter') {
|
||||||
|
const editorInput = editor.current.refEditor?.querySelector('textarea');
|
||||||
|
if (editorInput) {
|
||||||
|
editorInput.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(function addKeyEventListeners() {
|
||||||
|
const wrapperEl = wrapper.current;
|
||||||
|
wrapperEl.addEventListener('keydown', listen);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
wrapperEl.removeEventListener('keydown', listen);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -121,19 +136,38 @@ function CodeMirrorInput({
|
|||||||
fullHeight={fullHeight}
|
fullHeight={fullHeight}
|
||||||
rows={rows}
|
rows={rows}
|
||||||
/> */}
|
/> */}
|
||||||
<AceEditor
|
<div ref={wrapper} tabIndex={0}>
|
||||||
mode={mode === 'javascript' ? 'json' : mode}
|
<AceEditor
|
||||||
theme="github"
|
mode={mode === 'javascript' ? 'json' : mode}
|
||||||
onChange={onChange}
|
theme="github"
|
||||||
value={value}
|
onChange={onChange}
|
||||||
name="UNIQUE_ID_OF_DIV"
|
value={value}
|
||||||
editorProps={{ $blockScrolling: true }}
|
name={id || 'code-editor'}
|
||||||
width="100%"
|
editorProps={{ $blockScrolling: true }}
|
||||||
setOptions={{
|
width="100%"
|
||||||
readOnly,
|
setOptions={{
|
||||||
useWorker: false,
|
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();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
ref={editor}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user