Skip to content

Commit

Permalink
[Accessibility] Using arrow keys to navigate in toolbars items (jupyt…
Browse files Browse the repository at this point in the history
…erlab#15021)

* Use webcomponent for toolbar

* Tune web components styling
Support injecting the icon without wrapper

* Adds jp-select in notebook toolbar and center elements in toolbar

* fix filebrowser toolbar

* Fix select sizing and styling upstream

* Fix toolbar popup

* Set jupyter toolkit deps as singleton

* Update Playwright Snapshots

* Fix jest

* Fix CSS selector

* Fix tests in apputils and debugger packages

* Avoid setting attributes to React.Fragment in LabIcon

* Fixes ui-components tests

* updates snapshots in examples, and add some CSS rules

* Update snapshot in examples

* Fix some selectors in the notebook helper of galata

* Vertical center the cell toolbar

* Update snapshots and selectors in documentation

* Update galata and jupyterlab snapshots in ui-tests... Pfff

* Fix some more selectors in ui-tests, and style of notifications

* Remove the function to close the filebrower in favor of the existing 'sidebar.close()' helper function

* update some more snapshots

* Fix reactive toolbar and update snapshots

* lint

* Fixing debugger 'Start debug session' integration test (?)

* Improve handling of Jupyter theme

* Make helpers backward compatible

* Simplify styling for toggle button using aria-pressed

* Refactor toolbar gap item definition

* Upgrade toolkit

* Remove empty style file

* Automatic application of license header

* Remove ref to deleted file

* fix lint and ui-component test

* Update Playwright Snapshots

* update examples snapshots

* Update galata/jupyterlab snapshots

* some more snapshots

* Fix filebrowser refresh selector

* Replace buttons by divs in the debugger KernelSource panel

* Fix "Paste cell" integration test

* restore 'Running kernels and consoles' buttons' color

* Restore documentation debugger snapshot

* snapshots

* Restore the position of the refresh button in running session panel

* Fix reactive toolbar computation

* Fix the run button focus in documentation

* Stop click event on toolbar button to avoid focus leaving the editor.

* snapshots

* Documentation snapshots

* Change the sidepanel toolbar's role to 'toolbar'

* Wait for cell toolbar to be displayed in benchmark tests

* Update the selector of the cell editor in notebook helper of galata, and update snapshots

* Fix 'enterCellEditingMode()' in galata's notebook helper

* Bump package to fix typing issue

* Snapshots, after rebase

* Restore class on button label, and remove useless '.jp-mod-styled' class on buttons in running kernel sidebar

* Items in reactive toolbar are inserted back at their initial position

* Restore the HTMLSelect, since the web component select is not yet ready

* integrity

* Update documentation and examples snapshots

* Avoid rendering command toolbar buttons without registered command

* Galata snapshots

* Fix style on button with label and icon, and fix some selector in integration test

* Revert cursor position when clicking on cell editor, and fix metadataform integration test

* Add commands in debugger test to render the related button

* Fix the debugger toolbar without breaking the other ones

* Improve some CSS selectors and restore the position of kernel status indicator

* Adds jest config changes in extension migration

* Update Playwright Snapshots

* Update Playwright Snapshots

* Update Playwright Snapshots

* Update Playwright Snapshots

* Update docs/source/extension/extension_migration.rst

Co-authored-by: Michał Krassowski <[email protected]>

* Update docs/source/extension/extension_migration.rst

Co-authored-by: Michał Krassowski <[email protected]>

* Remove useless style property

* Remove debug leftover in ui-tests

Co-authored-by: Michał Krassowski <[email protected]>

* snapshots

* Try to fix readonly test

---------

Co-authored-by: Frédéric Collonval <[email protected]>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Michał Krassowski <[email protected]>
  • Loading branch information
4 people authored Nov 20, 2023
1 parent b346ac3 commit 3d525a2
Show file tree
Hide file tree
Showing 223 changed files with 819 additions and 391 deletions.
10 changes: 10 additions & 0 deletions dev_mode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
"@codemirror/language": "^6.0.0",
"@codemirror/state": "^6.2.0",
"@codemirror/view": "^6.9.6",
"@jupyter/react-components": "~0.13.3",
"@jupyter/web-components": "~0.13.3",
"@jupyter/ydoc": "~1.1.1",
"@jupyterlab/application": "~4.1.0-alpha.3",
"@jupyterlab/application-extension": "~4.1.0-alpha.3",
Expand Down Expand Up @@ -133,6 +135,9 @@
"@lumino/signaling": "^2.0.0",
"@lumino/virtualdom": "^2.0.0",
"@lumino/widgets": "^2.3.1-alpha.0",
"@microsoft/fast-components": "^2.30.6",
"@microsoft/fast-element": "^1.12.0",
"@microsoft/fast-foundation": "^2.49.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"yjs": "^13.5.40"
Expand Down Expand Up @@ -276,6 +281,8 @@
"@codemirror/language",
"@codemirror/state",
"@codemirror/view",
"@jupyter/react-components",
"@jupyter/web-components",
"@jupyter/ydoc",
"@jupyterlab/application",
"@jupyterlab/apputils",
Expand Down Expand Up @@ -332,6 +339,9 @@
"@lumino/signaling",
"@lumino/virtualdom",
"@lumino/widgets",
"@microsoft/fast-components",
"@microsoft/fast-element",
"@microsoft/fast-foundation",
"react",
"react-dom",
"yjs"
Expand Down
26 changes: 26 additions & 0 deletions docs/source/extension/extension_migration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,32 @@ If your extension previously included a custom enable/disable setting, you may b
with instructions pointing users to the Plugin Manager. However, please consider whether your extension
may be used in distributions which do not include Plugin Manager or have it disabled.

Use of UI toolkit for Toolbar and ToolbarButtonComponent
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The Toolbar and ToolbarButtonComponent (from the package *ui-components*) now relies on the external library
`jupyter-ui-toolkit <https://github.com/jupyterlab-contrib/jupyter-ui-toolkit>`.

This library uses the web component technology (https://developer.mozilla.org/en-US/docs/Web/API/Web_components),
and is based on `FAST <https://www.fast.design/>` library by Microsoft.

See https://github.com/jupyterlab/team-compass/issues/143 for more context on the change.

If you are using jest to test your extension, some new ES6 packages dependencies are added to JupyterLab.
They need to be ignored when transforming the code with Jest. You will need to update the
``transformIgnorePatterns`` to add:

.. code::
const esModules = [
'@microsoft',
'@jupyter/react-components',
'@jupyter/web-components',
'exenv-es6',
...
].join('|');
JupyterLab 3.x to 4.x
---------------------

Expand Down
Binary file modified examples/app/example.spec.ts-snapshots/example-linux.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified examples/cell/example.spec.ts-snapshots/example-linux.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions examples/cell/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"clean": "rimraf build"
},
"dependencies": {
"@jupyter/web-components": "^0.13.3",
"@jupyter/ydoc": "^1.1.1",
"@jupyterlab/application": "^4.1.0-alpha.3",
"@jupyterlab/apputils": "^4.2.0-alpha.3",
Expand Down
7 changes: 2 additions & 5 deletions examples/cell/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,8 @@ import { PageConfig, URLExt } from '@jupyterlab/coreutils';
'example/'
);

import '@jupyterlab/application/style/index.css';
import '@jupyterlab/cells/style/index.css';
import '@jupyterlab/theme-light-extension/style/theme.css';
import '@jupyterlab/completer/style/index.css';
import '../index.css';
// Import style through JS file to deduplicate them.
import './style';

import {
Toolbar as AppToolbar,
Expand Down
18 changes: 18 additions & 0 deletions examples/cell/src/style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright (c) Jupyter Development Team.
* Distributed under the terms of the Modified BSD License.
*/

import { applyJupyterTheme } from '@jupyter/web-components';

import '@jupyterlab/application/style/index.js';
import '@jupyterlab/cells/style/index.js';
import '@jupyterlab/theme-light-extension/style/theme.css';
import '@jupyterlab/completer/style/index.js';

import '../index.css';

// Apply JupyterLab theme to the Jupyter toolkit
window.addEventListener('load', () => {
applyJupyterTheme();
});
1 change: 1 addition & 0 deletions examples/console/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"clean": "rimraf build"
},
"dependencies": {
"@jupyter/web-components": "^0.13.3",
"@jupyter/ydoc": "^1.1.1",
"@jupyterlab/application": "^4.1.0-alpha.3",
"@jupyterlab/codemirror": "^4.1.0-alpha.3",
Expand Down
6 changes: 2 additions & 4 deletions examples/console/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@ import { PageConfig, URLExt } from '@jupyterlab/coreutils';
'example/'
);

import '@jupyterlab/application/style/index.css';
import '@jupyterlab/console/style/index.css';
import '@jupyterlab/theme-light-extension/style/theme.css';
import '../index.css';
// Import style through JS file to deduplicate them.
import './style';

import { CommandRegistry } from '@lumino/commands';

Expand Down
17 changes: 17 additions & 0 deletions examples/console/src/style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright (c) Jupyter Development Team.
* Distributed under the terms of the Modified BSD License.
*/

import { applyJupyterTheme } from '@jupyter/web-components';

import '@jupyterlab/application/style/index.css';
import '@jupyterlab/console/style/index.css';
import '@jupyterlab/theme-light-extension/style/theme.css';

import '../index.css';

// Apply JupyterLab theme to the Jupyter toolkit
window.addEventListener('load', () => {
applyJupyterTheme();
});
Binary file modified examples/federated/example.spec.ts-snapshots/example-linux.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions examples/filebrowser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"clean": "rimraf build"
},
"dependencies": {
"@jupyter/web-components": "^0.13.3",
"@jupyterlab/application": "^4.1.0-alpha.3",
"@jupyterlab/apputils": "^4.2.0-alpha.3",
"@jupyterlab/codemirror": "^4.1.0-alpha.3",
Expand Down
7 changes: 2 additions & 5 deletions examples/filebrowser/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,8 @@ import { PageConfig, URLExt } from '@jupyterlab/coreutils';
'example/'
);

import '@jupyterlab/application/style/index.css';
import '@jupyterlab/codemirror/style/index.css';
import '@jupyterlab/filebrowser/style/index.css';
import '@jupyterlab/theme-light-extension/style/theme.css';
import '../index.css';
// Import style through JS file to deduplicate them.
import './style';

import { CommandRegistry } from '@lumino/commands';

Expand Down
18 changes: 18 additions & 0 deletions examples/filebrowser/src/style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright (c) Jupyter Development Team.
* Distributed under the terms of the Modified BSD License.
*/

import { applyJupyterTheme } from '@jupyter/web-components';

import '@jupyterlab/application/style/index.css';
import '@jupyterlab/codemirror/style/index.css';
import '@jupyterlab/filebrowser/style/index.css';
import '@jupyterlab/theme-light-extension/style/theme.css';

import '../index.css';

// Apply JupyterLab theme to the Jupyter toolkit
window.addEventListener('load', () => {
applyJupyterTheme();
});
Binary file modified examples/notebook/example.spec.ts-snapshots/example-linux.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions examples/notebook/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"clean": "rimraf build"
},
"dependencies": {
"@jupyter/web-components": "^0.13.3",
"@jupyter/ydoc": "^1.1.1",
"@jupyterlab/application": "^4.1.0-alpha.3",
"@jupyterlab/apputils": "^4.2.0-alpha.3",
Expand Down
9 changes: 2 additions & 7 deletions examples/notebook/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,8 @@ import { PageConfig, URLExt } from '@jupyterlab/coreutils';
'example/'
);

import '@jupyterlab/application/style/index.css';
import '@jupyterlab/codemirror/style/index.css';
import '@jupyterlab/completer/style/index.css';
import '@jupyterlab/documentsearch/style/index.css';
import '@jupyterlab/notebook/style/index.css';
import '@jupyterlab/theme-light-extension/style/theme.css';
import '../index.css';
// Import style through JS file to deduplicate them.
import './style';

import { IYText } from '@jupyter/ydoc';
import {
Expand Down
20 changes: 20 additions & 0 deletions examples/notebook/src/style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright (c) Jupyter Development Team.
* Distributed under the terms of the Modified BSD License.
*/

import { applyJupyterTheme } from '@jupyter/web-components';

import '@jupyterlab/application/style/index.css';
import '@jupyterlab/codemirror/style/index.css';
import '@jupyterlab/completer/style/index.css';
import '@jupyterlab/documentsearch/style/index.css';
import '@jupyterlab/notebook/style/index.css';
import '@jupyterlab/theme-light-extension/style/theme.css';

import '../index.css';

// Apply JupyterLab theme to the Jupyter toolkit
window.addEventListener('load', () => {
applyJupyterTheme();
});
1 change: 1 addition & 0 deletions examples/terminal/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"clean": "rimraf build"
},
"dependencies": {
"@jupyter/web-components": "^0.13.3",
"@jupyterlab/application": "^4.1.0-alpha.3",
"@jupyterlab/coreutils": "^6.1.0-alpha.3",
"@jupyterlab/services": "^7.1.0-alpha.3",
Expand Down
6 changes: 2 additions & 4 deletions examples/terminal/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@ import { PageConfig, URLExt } from '@jupyterlab/coreutils';
'example/'
);

import '@jupyterlab/application/style/index.css';
import '@jupyterlab/terminal/style/index.css';
import '@jupyterlab/theme-light-extension/style/theme.css';
import '../index.css';
// Import style through JS file to deduplicate them.
import './style';

import { DockPanel, Widget } from '@lumino/widgets';

Expand Down
17 changes: 17 additions & 0 deletions examples/terminal/src/style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright (c) Jupyter Development Team.
* Distributed under the terms of the Modified BSD License.
*/

import { applyJupyterTheme } from '@jupyter/web-components';

import '@jupyterlab/application/style/index.css';
import '@jupyterlab/terminal/style/index.css';
import '@jupyterlab/theme-light-extension/style/theme.css';

import '../index.css';

// Apply JupyterLab theme to the Jupyter toolkit
window.addEventListener('load', () => {
applyJupyterTheme();
});
10 changes: 7 additions & 3 deletions galata/src/contents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -348,15 +348,19 @@ export class ContentsHelper {
* @param trigger Action to trigger while waiting
*/
async waitForAPIResponse(
trigger?: () => Promise<void> | void
trigger?: () => Promise<void> | void,
options?: {
timeout?: number;
}
): Promise<void> {
if (!this.page) {
return Promise.reject('No page available.');
}

await Promise.all([
this.page.waitForResponse(response =>
response.url().includes('api/contents')
this.page.waitForResponse(
response => response.url().includes('api/contents'),
options
),
Promise.resolve(trigger?.call(this))
]);
Expand Down
32 changes: 14 additions & 18 deletions galata/src/helpers/filebrowser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,25 +210,21 @@ export class FileBrowserHelper {
*/
async refresh(): Promise<void> {
const page = this.page;
const item = await page.$(
`xpath=//div[@id='filebrowser']//button[${Utils.xpContainsClass(
'jp-ToolbarButtonComponent'
)} and .//*[@data-icon='ui-components:refresh']]`
);
const item = page
.locator('#filebrowser')
.locator(
'.jp-ToolbarButtonComponent[data-command="filebrowser:refresh"]'
);

if (item) {
// wait for network response or timeout
await Promise.race([
page.waitForTimeout(2000),
this.contents.waitForAPIResponse(async () => {
await item.click();
})
]);
// wait for DOM rerender
await page.waitForTimeout(200);
} else {
throw new Error('Could not find refresh toolbar item');
}
// wait for network response or timeout
await this.contents.waitForAPIResponse(
async () => {
await item.click();
},
{ timeout: 2000 }
);
// wait for DOM rerender
await page.waitForTimeout(200);
}

protected async _openDirectory(dirName: string): Promise<boolean> {
Expand Down
25 changes: 18 additions & 7 deletions galata/src/helpers/notebook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -823,8 +823,8 @@ export class NotebookHelper {
return false;
}

const cellEditor = await cell.$('.jp-Cell-inputArea');
if (cellEditor) {
const cellInput = await cell.$('.jp-Cell-inputArea');
if (cellInput) {
let isMarkdown = false;
const cellType = await this.getCellType(cellIndex);
if (cellType === 'markdown') {
Expand All @@ -835,7 +835,12 @@ export class NotebookHelper {
}

if (isMarkdown) {
await cellEditor.dblclick();
await cellInput.dblclick();
}

const cellEditor = await cellInput.$('.jp-InputArea-editor');
if (!cellEditor) {
return false;
}

await cellEditor.click();
Expand Down Expand Up @@ -1121,14 +1126,20 @@ export class NotebookHelper {
}

await this.clickToolbarItem('cellType');
const selectInput = await nbPanel.$(
'div.jp-Notebook-toolbarCellTypeDropdown select'
);
const selectInput = await nbPanel.$('.jp-Notebook-toolbarCellTypeDropdown');
if (!selectInput) {
return false;
}

await selectInput.selectOption(cellType);
// Legay select
const select = await selectInput.$('select');
if (select) {
await select.selectOption(cellType);
} else {
await selectInput.evaluate((el, cellType) => {
(el as any).value = cellType;
}, cellType);
}

// Wait for the new cell to be rendered
let cell: ElementHandle | null;
Expand Down
Loading

0 comments on commit 3d525a2

Please sign in to comment.