feat(client): add hotkey 'r' to focus on instructions panel (#42503)
This commit is contained in:
@ -119,6 +119,7 @@ class ShowClassic extends Component<ShowClassicProps, ShowClassicState> {
|
|||||||
static displayName: string;
|
static displayName: string;
|
||||||
containerRef: React.RefObject<unknown>;
|
containerRef: React.RefObject<unknown>;
|
||||||
editorRef: React.RefObject<unknown>;
|
editorRef: React.RefObject<unknown>;
|
||||||
|
instructionsPanelRef: React.RefObject<HTMLElement>;
|
||||||
resizeProps: ResizePropsType;
|
resizeProps: ResizePropsType;
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
layoutState: any;
|
layoutState: any;
|
||||||
@ -137,6 +138,7 @@ class ShowClassic extends Component<ShowClassicProps, ShowClassicState> {
|
|||||||
|
|
||||||
this.containerRef = React.createRef();
|
this.containerRef = React.createRef();
|
||||||
this.editorRef = React.createRef();
|
this.editorRef = React.createRef();
|
||||||
|
this.instructionsPanelRef = React.createRef();
|
||||||
// Holds the information of the panes sizes for desktop view
|
// Holds the information of the panes sizes for desktop view
|
||||||
this.layoutState = this.getLayoutState();
|
this.layoutState = this.getLayoutState();
|
||||||
}
|
}
|
||||||
@ -278,6 +280,7 @@ class ShowClassic extends Component<ShowClassicProps, ShowClassicState> {
|
|||||||
description={description}
|
description={description}
|
||||||
guideUrl={getGuideUrl({ forumTopicId, title })}
|
guideUrl={getGuideUrl({ forumTopicId, title })}
|
||||||
instructions={instructions}
|
instructions={instructions}
|
||||||
|
instructionsPanelRef={this.instructionsPanelRef}
|
||||||
showToolPanel={showToolPanel}
|
showToolPanel={showToolPanel}
|
||||||
superBlock={superBlock}
|
superBlock={superBlock}
|
||||||
title={title}
|
title={title}
|
||||||
@ -356,6 +359,7 @@ class ShowClassic extends Component<ShowClassicProps, ShowClassicState> {
|
|||||||
editorRef={this.editorRef}
|
editorRef={this.editorRef}
|
||||||
executeChallenge={executeChallenge}
|
executeChallenge={executeChallenge}
|
||||||
innerRef={this.containerRef}
|
innerRef={this.containerRef}
|
||||||
|
instructionsPanelRef={this.instructionsPanelRef}
|
||||||
nextChallengePath={nextChallengePath}
|
nextChallengePath={nextChallengePath}
|
||||||
prevChallengePath={prevChallengePath}
|
prevChallengePath={prevChallengePath}
|
||||||
>
|
>
|
||||||
|
@ -22,6 +22,7 @@ const keyMap = {
|
|||||||
NAVIGATION_MODE: 'escape',
|
NAVIGATION_MODE: 'escape',
|
||||||
EXECUTE_CHALLENGE: ['ctrl+enter', 'command+enter'],
|
EXECUTE_CHALLENGE: ['ctrl+enter', 'command+enter'],
|
||||||
FOCUS_EDITOR: 'e',
|
FOCUS_EDITOR: 'e',
|
||||||
|
FOCUS_INSTRUCTIONS_PANEL: 'r',
|
||||||
NAVIGATE_PREV: ['p'],
|
NAVIGATE_PREV: ['p'],
|
||||||
NAVIGATE_NEXT: ['n']
|
NAVIGATE_NEXT: ['n']
|
||||||
};
|
};
|
||||||
@ -33,6 +34,7 @@ interface HotkeysProps {
|
|||||||
editorRef?: React.Ref<HTMLElement> | any;
|
editorRef?: React.Ref<HTMLElement> | any;
|
||||||
executeChallenge?: () => void;
|
executeChallenge?: () => void;
|
||||||
innerRef: React.Ref<HTMLElement> | unknown;
|
innerRef: React.Ref<HTMLElement> | unknown;
|
||||||
|
instructionsPanelRef?: React.RefObject<HTMLElement>;
|
||||||
nextChallengePath: string;
|
nextChallengePath: string;
|
||||||
prevChallengePath: string;
|
prevChallengePath: string;
|
||||||
setEditorFocusability: (arg0: boolean) => void;
|
setEditorFocusability: (arg0: boolean) => void;
|
||||||
@ -41,6 +43,7 @@ interface HotkeysProps {
|
|||||||
function Hotkeys({
|
function Hotkeys({
|
||||||
canFocusEditor,
|
canFocusEditor,
|
||||||
children,
|
children,
|
||||||
|
instructionsPanelRef,
|
||||||
editorRef,
|
editorRef,
|
||||||
executeChallenge,
|
executeChallenge,
|
||||||
innerRef,
|
innerRef,
|
||||||
@ -63,6 +66,11 @@ function Hotkeys({
|
|||||||
editorRef.current.getWrappedInstance().editor.focus();
|
editorRef.current.getWrappedInstance().editor.focus();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
FOCUS_INSTRUCTIONS_PANEL: () => {
|
||||||
|
if (instructionsPanelRef && instructionsPanelRef.current) {
|
||||||
|
instructionsPanelRef.current.focus();
|
||||||
|
}
|
||||||
|
},
|
||||||
NAVIGATION_MODE: () => setEditorFocusability(false),
|
NAVIGATION_MODE: () => setEditorFocusability(false),
|
||||||
NAVIGATE_PREV: () => {
|
NAVIGATE_PREV: () => {
|
||||||
if (!canFocusEditor) void navigate(prevChallengePath);
|
if (!canFocusEditor) void navigate(prevChallengePath);
|
||||||
|
@ -26,6 +26,7 @@ const propTypes = {
|
|||||||
description: PropTypes.string,
|
description: PropTypes.string,
|
||||||
guideUrl: PropTypes.string,
|
guideUrl: PropTypes.string,
|
||||||
instructions: PropTypes.string,
|
instructions: PropTypes.string,
|
||||||
|
instructionsPanelRef: PropTypes.any.isRequired,
|
||||||
isChallengeCompleted: PropTypes.bool,
|
isChallengeCompleted: PropTypes.bool,
|
||||||
showToolPanel: PropTypes.bool,
|
showToolPanel: PropTypes.bool,
|
||||||
superBlock: PropTypes.string,
|
superBlock: PropTypes.string,
|
||||||
@ -72,6 +73,7 @@ export class SidePanel extends Component {
|
|||||||
title,
|
title,
|
||||||
description,
|
description,
|
||||||
instructions,
|
instructions,
|
||||||
|
instructionsPanelRef,
|
||||||
isChallengeCompleted,
|
isChallengeCompleted,
|
||||||
guideUrl,
|
guideUrl,
|
||||||
tests,
|
tests,
|
||||||
@ -81,7 +83,12 @@ export class SidePanel extends Component {
|
|||||||
videoUrl
|
videoUrl
|
||||||
} = this.props;
|
} = this.props;
|
||||||
return (
|
return (
|
||||||
<div className='instructions-panel' role='complementary' tabIndex='-1'>
|
<div
|
||||||
|
className='instructions-panel'
|
||||||
|
ref={instructionsPanelRef}
|
||||||
|
role='complementary'
|
||||||
|
tabIndex='-1'
|
||||||
|
>
|
||||||
<div>
|
<div>
|
||||||
<ChallengeTitle
|
<ChallengeTitle
|
||||||
block={block}
|
block={block}
|
||||||
|
Reference in New Issue
Block a user