Skip to content

Commit

Permalink
Enable keyboard navigation in the statusbar (jupyterlab#14853)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: EC2 Default User <[email protected]>
Co-authored-by: EC2 Default User <[email protected]>
Co-authored-by: Michał Krassowski <[email protected]>
  • Loading branch information
5 people authored Jan 25, 2024
1 parent 266d009 commit dafb934
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 4 deletions.
31 changes: 30 additions & 1 deletion packages/apputils-extension/src/statusbarplugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -49,8 +50,25 @@ export const kernelStatus: JupyterFrontEndPlugin<IKernelStatusModel> = {
await sessionDialogs.selectKernel(item.model.sessionContext);
};

const changeKernelOnKeyDown = async (
event: KeyboardEvent<HTMLImageElement>
) => {
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>();

Expand Down Expand Up @@ -128,6 +146,17 @@ export const runningSessionsStatus: JupyterFrontEndPlugin<void> = {
) => {
const item = new RunningSessions({
onClick: () => app.shell.activateById('jp-running-sessions'),
onKeyDown: (event: KeyboardEvent<HTMLImageElement>) => {
if (
event.key === 'Enter' ||
event.key === 'Spacebar' ||
event.key === ' '
) {
event.preventDefault();
event.stopPropagation();
app.shell.activateById('jp-running-sessions');
}
},
serviceManager: app.serviceManager,
translator
});
Expand Down
19 changes: 18 additions & 1 deletion packages/apputils/src/kernelstatuses.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';

/**
Expand Down Expand Up @@ -58,8 +58,10 @@ function KernelStatusComponent(
return (
<TextItem
onClick={props.handleClick}
onKeyDown={props.handleKeyDown}
source={`${props.kernelName}${statusText}`}
title={trans.__('Change kernel for %1', props.activityName)}
tabIndex={0}
/>
);
}
Expand All @@ -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<HTMLImageElement>) => void;

/**
* The name the kernel.
*/
Expand Down Expand Up @@ -111,6 +119,7 @@ export class KernelStatus extends VDomRenderer<KernelStatus.Model> {
super(new KernelStatus.Model(translator));
this.translator = translator || nullTranslator;
this._handleClick = opts.onClick;
this._handleKeyDown = opts.onKeyDown;
this.addClass('jp-mod-highlighted');
}

Expand All @@ -127,6 +136,7 @@ export class KernelStatus extends VDomRenderer<KernelStatus.Model> {
kernelName={this.model.kernelName}
activityName={this.model.activityName}
handleClick={this._handleClick}
handleKeyDown={this._handleKeyDown}
translator={this.translator}
/>
);
Expand All @@ -135,6 +145,7 @@ export class KernelStatus extends VDomRenderer<KernelStatus.Model> {

translator: ITranslator;
private _handleClick: () => void;
private _handleKeyDown: (event: KeyboardEvent<HTMLImageElement>) => void;
}

/**
Expand Down Expand Up @@ -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<HTMLImageElement>) => void;
}
}

Expand Down
23 changes: 21 additions & 2 deletions packages/apputils/src/runningSessions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';

/**
Expand All @@ -38,7 +38,12 @@ function RunningSessionsComponent(
props: RunningSessionsComponent.IProps
): React.ReactElement<RunningSessionsComponent.IProps> {
return (
<GroupItem spacing={HALF_SPACING} onClick={props.handleClick}>
<GroupItem
tabIndex={0}
spacing={HALF_SPACING}
onClick={props.handleClick}
onKeyDown={props.handleKeyDown}
>
<GroupItem spacing={HALF_SPACING}>
<TextItem source={props.terminals} />
<terminalIcon.react left={'1px'} top={'3px'} stylesheet={'statusBar'} />
Expand All @@ -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<HTMLImageElement>) => void;
/**
* A click handler for the component. By default this is used
* to activate the running sessions side panel.
Expand Down Expand Up @@ -88,6 +98,7 @@ export class RunningSessions extends VDomRenderer<RunningSessions.Model> {
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');

Expand Down Expand Up @@ -122,6 +133,7 @@ export class RunningSessions extends VDomRenderer<RunningSessions.Model> {
sessions={this.model.sessions}
terminals={this.model.terminals}
handleClick={this._handleClick}
handleKeyDown={this._handleKeyDown}
/>
);
}
Expand Down Expand Up @@ -165,6 +177,7 @@ export class RunningSessions extends VDomRenderer<RunningSessions.Model> {
protected translator: ITranslator;
private _trans: TranslationBundle;
private _handleClick: () => void;
private _handleKeyDown: (event: KeyboardEvent<HTMLImageElement>) => void;
private _serviceManager: ServiceManager.IManager;
}

Expand Down Expand Up @@ -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<HTMLImageElement>) => void;

/**
* The application language translator.
*/
Expand Down
15 changes: 15 additions & 0 deletions packages/codeeditor/src/lineCol.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -233,11 +233,26 @@ function LineColComponent(
): React.ReactElement<LineColComponent.IProps> {
const translator = props.translator || nullTranslator;
const trans = translator.load('jupyterlab');
const keydownHandler = (event: React.KeyboardEvent<HTMLImageElement>) => {
if (
event.key === 'Enter' ||
event.key === 'Spacebar' ||
event.key === ' '
) {
event.preventDefault();
event.stopPropagation();
props.handleClick();
} else {
return;
}
};
return (
<TextItem
onClick={props.handleClick}
source={trans.__('Ln %1, Col %2', props.line, props.column)}
title={trans.__('Go to line number…')}
tabIndex={0}
onKeyDown={keydownHandler}
/>
);
}
Expand Down

0 comments on commit dafb934

Please sign in to comment.