From dafb934526ebef51786c3a144d91d6cb9d06d4a1 Mon Sep 17 00:00:00 2001 From: j264415 <128609898+j264415@users.noreply.github.com> Date: Thu, 25 Jan 2024 21:47:59 +0000 Subject: [PATCH] Enable keyboard navigation in the statusbar (#14853) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * added tabIndex, plus enter & spacebar functionality * Update Playwright Snapshots * Update Playwright Snapshots * Update Playwright Snapshots * Update Playwright Snapshots * Update Playwright Snapshots * revert back to main * WIP changes * Refactored keydown handler functionality * Changed imports * Added comment to iprops * Update keydown function to improve readability * Update keydown function to improve readability * Update packages/apputils-extension/src/statusbarplugin.ts Co-authored-by: Michał Krassowski <5832902+krassowski@users.noreply.github.com> --------- Co-authored-by: github-actions[bot] Co-authored-by: EC2 Default User Co-authored-by: EC2 Default User <141649264+m158261@users.noreply.github.com> Co-authored-by: Michał Krassowski <5832902+krassowski@users.noreply.github.com> --- .../apputils-extension/src/statusbarplugin.ts | 31 ++++++++++++++++++- packages/apputils/src/kernelstatuses.tsx | 19 +++++++++++- packages/apputils/src/runningSessions.tsx | 23 ++++++++++++-- packages/codeeditor/src/lineCol.tsx | 15 +++++++++ 4 files changed, 84 insertions(+), 4 deletions(-) diff --git a/packages/apputils-extension/src/statusbarplugin.ts b/packages/apputils-extension/src/statusbarplugin.ts index 253ccce47b6c..2ad90507a4a9 100644 --- a/packages/apputils-extension/src/statusbarplugin.ts +++ b/packages/apputils-extension/src/statusbarplugin.ts @@ -19,6 +19,7 @@ import { import { IStatusBar } from '@jupyterlab/statusbar'; import { ITranslator, nullTranslator } from '@jupyterlab/translation'; import { Title, Widget } from '@lumino/widgets'; +import { KeyboardEvent } from 'react'; /** * A plugin that provides a kernel status item to the status bar. @@ -49,8 +50,25 @@ export const kernelStatus: JupyterFrontEndPlugin = { await sessionDialogs.selectKernel(item.model.sessionContext); }; + const changeKernelOnKeyDown = async ( + event: KeyboardEvent + ) => { + if ( + event.key === 'Enter' || + event.key === 'Spacebar' || + event.key === ' ' + ) { + event.preventDefault(); + event.stopPropagation(); + return changeKernel(); + } + }; + // Create the status item. - const item = new KernelStatus({ onClick: changeKernel }, translator); + const item = new KernelStatus( + { onClick: changeKernel, onKeyDown: changeKernelOnKeyDown }, + translator + ); const providers = new Set<(w: Widget | null) => ISessionContext | null>(); @@ -128,6 +146,17 @@ export const runningSessionsStatus: JupyterFrontEndPlugin = { ) => { const item = new RunningSessions({ onClick: () => app.shell.activateById('jp-running-sessions'), + onKeyDown: (event: KeyboardEvent) => { + if ( + event.key === 'Enter' || + event.key === 'Spacebar' || + event.key === ' ' + ) { + event.preventDefault(); + event.stopPropagation(); + app.shell.activateById('jp-running-sessions'); + } + }, serviceManager: app.serviceManager, translator }); diff --git a/packages/apputils/src/kernelstatuses.tsx b/packages/apputils/src/kernelstatuses.tsx index fe8d36c9d405..3b2f6fb08307 100644 --- a/packages/apputils/src/kernelstatuses.tsx +++ b/packages/apputils/src/kernelstatuses.tsx @@ -10,7 +10,7 @@ import { } from '@jupyterlab/translation'; import { VDomModel, VDomRenderer } from '@jupyterlab/ui-components'; import { JSONArray, JSONExt } from '@lumino/coreutils'; -import React from 'react'; +import React, { KeyboardEvent } from 'react'; import { ISessionContext } from './sessioncontext'; /** @@ -58,8 +58,10 @@ function KernelStatusComponent( return ( ); } @@ -78,6 +80,12 @@ namespace KernelStatusComponent { */ handleClick: () => void; + /** + * A key down handler for the kernel status component. By default + * we have it bring up the kernel change dialog. + */ + handleKeyDown: (event: KeyboardEvent) => void; + /** * The name the kernel. */ @@ -111,6 +119,7 @@ export class KernelStatus extends VDomRenderer { super(new KernelStatus.Model(translator)); this.translator = translator || nullTranslator; this._handleClick = opts.onClick; + this._handleKeyDown = opts.onKeyDown; this.addClass('jp-mod-highlighted'); } @@ -127,6 +136,7 @@ export class KernelStatus extends VDomRenderer { kernelName={this.model.kernelName} activityName={this.model.activityName} handleClick={this._handleClick} + handleKeyDown={this._handleKeyDown} translator={this.translator} /> ); @@ -135,6 +145,7 @@ export class KernelStatus extends VDomRenderer { translator: ITranslator; private _handleClick: () => void; + private _handleKeyDown: (event: KeyboardEvent) => void; } /** @@ -271,6 +282,12 @@ export namespace KernelStatus { * we launch a kernel selection dialog. */ onClick: () => void; + + /** + * A key press handler for the item. By default + * we launch a kernel selection dialog. + */ + onKeyDown: (event: KeyboardEvent) => void; } } diff --git a/packages/apputils/src/runningSessions.tsx b/packages/apputils/src/runningSessions.tsx index d7199faec972..a39ebc36b1e9 100644 --- a/packages/apputils/src/runningSessions.tsx +++ b/packages/apputils/src/runningSessions.tsx @@ -19,7 +19,7 @@ import { VDomModel, VDomRenderer } from '@jupyterlab/ui-components'; -import React from 'react'; +import React, { KeyboardEvent } from 'react'; import { GroupItem, TextItem } from '@jupyterlab/statusbar'; /** @@ -38,7 +38,12 @@ function RunningSessionsComponent( props: RunningSessionsComponent.IProps ): React.ReactElement { return ( - + @@ -59,6 +64,11 @@ namespace RunningSessionsComponent { * The props for rendering the RunningSessionsComponent. */ export interface IProps { + /** + * A key down handler for the component. By default this is used + * to activate the running sessions side panel. + */ + handleKeyDown: (event: KeyboardEvent) => void; /** * A click handler for the component. By default this is used * to activate the running sessions side panel. @@ -88,6 +98,7 @@ export class RunningSessions extends VDomRenderer { super(new RunningSessions.Model()); this._serviceManager = opts.serviceManager; this._handleClick = opts.onClick; + this._handleKeyDown = opts.onKeyDown; this.translator = opts.translator || nullTranslator; this._trans = this.translator.load('jupyterlab'); @@ -122,6 +133,7 @@ export class RunningSessions extends VDomRenderer { sessions={this.model.sessions} terminals={this.model.terminals} handleClick={this._handleClick} + handleKeyDown={this._handleKeyDown} /> ); } @@ -165,6 +177,7 @@ export class RunningSessions extends VDomRenderer { protected translator: ITranslator; private _trans: TranslationBundle; private _handleClick: () => void; + private _handleKeyDown: (event: KeyboardEvent) => void; private _serviceManager: ServiceManager.IManager; } @@ -225,6 +238,12 @@ export namespace RunningSessions { */ onClick: () => void; + /** + * A key down handler for the item. By default this is used + * to activate the running sessions side panel. + */ + onKeyDown: (event: KeyboardEvent) => void; + /** * The application language translator. */ diff --git a/packages/codeeditor/src/lineCol.tsx b/packages/codeeditor/src/lineCol.tsx index 0ca036cf5ba6..dfeeacfd69d4 100644 --- a/packages/codeeditor/src/lineCol.tsx +++ b/packages/codeeditor/src/lineCol.tsx @@ -233,11 +233,26 @@ function LineColComponent( ): React.ReactElement { const translator = props.translator || nullTranslator; const trans = translator.load('jupyterlab'); + const keydownHandler = (event: React.KeyboardEvent) => { + if ( + event.key === 'Enter' || + event.key === 'Spacebar' || + event.key === ' ' + ) { + event.preventDefault(); + event.stopPropagation(); + props.handleClick(); + } else { + return; + } + }; return ( ); }