diff --git a/awx/ui_next/src/components/CodeEditor/CodeEditor.jsx b/awx/ui_next/src/components/CodeEditor/CodeEditor.jsx index 7db780cb75..b60934a665 100644 --- a/awx/ui_next/src/components/CodeEditor/CodeEditor.jsx +++ b/awx/ui_next/src/components/CodeEditor/CodeEditor.jsx @@ -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 */ -
- + { + 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(); + > + { + 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} - /> -
+ ]} + ref={editor} + /> + + {isKeyboardFocused && ( +
+ {i18n._(t`Press Enter to edit. Press ESC to stop editing.`)} +
+ )} + ); } CodeEditor.propTypes = { @@ -146,4 +180,4 @@ CodeEditor.defaultProps = { className: '', }; -export default CodeEditor; +export default withI18n()(CodeEditor);