Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Audit DataGrid public API in preparation for 0.x => 2.0 #458

Merged
merged 18 commits into from
Nov 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,22 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Bump artificially the top version
shell: python
run: |
import json
from datetime import datetime

with open("package.json") as f:
data = json.load(f)

data["version"] = datetime.now().strftime("%Y.%m.%d")
data["jupyter-releaser"]["options"]["version-cmd"] = "npm run update:versions -- --yes"

with open("package.json", "w") as f:
data = json.dump(data, f)

fcollonval marked this conversation as resolved.
Show resolved Hide resolved
- name: Check Release
uses: jupyter-server/jupyter_releaser/.github/actions/check-release@v2
with:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ docs/source/examples

.jupyter_releaser_checkout
.eslintcache
.ipynb_checkpoints
4 changes: 2 additions & 2 deletions examples/example-accordionpanel/package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"name": "@lumino/example-accordionpanel",
"version": "0.9.0-alpha.6",
"version": "2.0.0-alpha.6",
"private": true,
"scripts": {
"build": "tsc && rollup -c",
"clean": "rimraf build"
},
"dependencies": {
"@lumino/default-theme": "^1.0.0-alpha.6",
"@lumino/default-theme": "^2.0.0-alpha.6",
"@lumino/messaging": "^2.0.0-alpha.6",
"@lumino/widgets": "^2.0.0-alpha.6"
},
Expand Down
6 changes: 3 additions & 3 deletions examples/example-datagrid/package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"name": "@lumino/example-datagrid",
"version": "0.33.0-alpha.6",
"version": "2.0.0-alpha.6",
"private": true,
"scripts": {
"build": "tsc && rollup -c",
"clean": "rimraf build"
},
"dependencies": {
"@lumino/datagrid": "^1.0.0-alpha.6",
"@lumino/default-theme": "^1.0.0-alpha.6",
"@lumino/datagrid": "^2.0.0-alpha.6",
"@lumino/default-theme": "^2.0.0-alpha.6",
"@lumino/dragdrop": "^2.0.0-alpha.6",
"@lumino/widgets": "^2.0.0-alpha.6"
},
Expand Down
2 changes: 1 addition & 1 deletion examples/example-dockpanel-amd/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@lumino/example-dockpanel-amd",
"version": "0.5.0-alpha.6",
"version": "2.0.0-alpha.6",
"private": true,
"scripts": {
"test": "node ./test/runner.js"
Expand Down
2 changes: 1 addition & 1 deletion examples/example-dockpanel-iife/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@lumino/example-dockpanel-iife",
"version": "0.5.0-alpha.6",
"version": "2.0.0-alpha.6",
"private": true,
"scripts": {
"test": "node ./test/runner.js"
Expand Down
2 changes: 1 addition & 1 deletion examples/example-dockpanel/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@lumino/example-dockpanel",
"version": "0.22.0-alpha.6",
"version": "2.0.0-alpha.6",
"private": true,
"scripts": {
"build": "tsc && rollup -c",
Expand Down
3 changes: 2 additions & 1 deletion notebooks/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"name": "lumino_notebooks",
"version": "0.1",
"description": "A set of JavaScript notebooks for lumino.",
"private": true,
"description": "A set of JavaScript notebooks for Lumino.",
"keywords": [],
"author": "Project Jupyter Contributors",
"license": "Revised BSD",
Expand Down
2 changes: 1 addition & 1 deletion packages/datagrid/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@lumino/datagrid",
"version": "1.0.0-alpha.6",
"version": "2.0.0-alpha.6",
"description": "Lumino Tabular Data Grid",
"homepage": "https://github.com/jupyterlab/lumino",
"bugs": {
Expand Down
241 changes: 237 additions & 4 deletions packages/datagrid/src/celleditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
|----------------------------------------------------------------------------*/
import { IDisposable } from '@lumino/disposable';

import { Message } from '@lumino/messaging';

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

import { DataGrid } from './datagrid';

import { SelectionModel } from './selectionmodel';
Expand All @@ -20,8 +24,6 @@ import { getKeyboardLayout } from '@lumino/keyboard';

import { Signal } from '@lumino/signaling';

import { Notification } from './notification';

import { CellGroup } from './cellgroup';

/**
Expand Down Expand Up @@ -507,7 +509,7 @@ export abstract class CellEditor implements ICellEditor, IDisposable {

// show a notification popup
if (message !== '') {
this.validityNotification = new Notification({
this.validityNotification = new CellEditor.Notification({
target: this.editorContainer,
message: message,
placement: 'bottom',
Expand Down Expand Up @@ -777,7 +779,7 @@ export abstract class CellEditor implements ICellEditor, IDisposable {
/**
* Notification popup used to show validation error messages.
*/
protected validityNotification: Notification | null = null;
protected validityNotification: CellEditor.Notification | null = null;
/**
* Whether the cell editor is disposed.
*/
Expand Down Expand Up @@ -1605,6 +1607,237 @@ export namespace CellEditor {
*/
readonly column: number;
};

/**
* A widget which implements a notification popup.
*/
export class Notification extends Widget {
/**
* Construct a new notification.
*
* @param options - The options for initializing the notification.
*/
constructor(options: Notification.IOptions) {
super({ node: Notification.createNode() });
this.addClass('lm-DataGrid-notification');
this.setFlag(Widget.Flag.DisallowLayout);

this._target = options.target;
this._message = options.message || '';
this._placement = options.placement || 'bottom';

Widget.attach(this, document.body);

if (options.timeout && options.timeout > 0) {
setTimeout(() => {
this.close();
}, options.timeout);
}
}

/**
* Handle the DOM events for the notification.
*
* @param event - The DOM event sent to the notification.
*
* #### Notes
* This method implements the DOM `EventListener` interface and is
* called in response to events on the notification's DOM node.
*
* This should not be called directly by user code.
*/
handleEvent(event: Event): void {
switch (event.type) {
case 'mousedown':
this._evtMouseDown(event as MouseEvent);
break;
case 'contextmenu':
event.preventDefault();
event.stopPropagation();
break;
}
}

/**
* Get the placement of the notification.
*/
get placement(): Notification.Placement {
return this._placement;
}

/**
* Set the placement of the notification.
*/
set placement(value: Notification.Placement) {
// Do nothing if the placement does not change.
if (this._placement === value) {
return;
}

// Update the internal placement.
this._placement = value;

// Schedule an update for notification.
this.update();
}

/**
* Get the current value of the message.
*/
get message(): string {
return this._message;
}

/**
* Set the current value of the message.
*
*/
set message(value: string) {
// Do nothing if the value does not change.
if (this._message === value) {
return;
}

// Update the internal value.
this._message = value;

// Schedule an update for notification.
this.update();
}

/**
* Get the node presenting the message.
*/
get messageNode(): HTMLSpanElement {
return this.node.getElementsByClassName(
'lm-DataGrid-notificationMessage'
)[0] as HTMLSpanElement;
}

/**
* A method invoked on a 'before-attach' message.
*/
protected onBeforeAttach(msg: Message): void {
this.node.addEventListener('mousedown', this);
this.update();
}

/**
* A method invoked on an 'after-detach' message.
*/
protected onAfterDetach(msg: Message): void {
this.node.removeEventListener('mousedown', this);
}

/**
* A method invoked on an 'update-request' message.
*/
protected onUpdateRequest(msg: Message): void {
const targetRect = this._target.getBoundingClientRect();
const style = this.node.style;

switch (this._placement) {
case 'bottom':
style.left = targetRect.left + 'px';
style.top = targetRect.bottom + 'px';
break;
case 'top':
style.left = targetRect.left + 'px';
style.height = targetRect.top + 'px';
style.top = '0';
style.alignItems = 'flex-end';
style.justifyContent = 'flex-end';
break;
case 'left':
style.left = '0';
style.width = targetRect.left + 'px';
style.top = targetRect.top + 'px';
style.alignItems = 'flex-end';
style.justifyContent = 'flex-end';
break;
case 'right':
style.left = targetRect.right + 'px';
style.top = targetRect.top + 'px';
break;
}

this.messageNode.innerHTML = this._message;
}

/**
* Handle the `'mousedown'` event for the notification.
*/
private _evtMouseDown(event: MouseEvent): void {
// Do nothing if it's not a left mouse press.
if (event.button !== 0) {
return;
}

event.preventDefault();
event.stopPropagation();
this.close();
}

private _target: HTMLElement;
private _message: string = '';
private _placement: Notification.Placement;
}

/**
* The namespace for the `Notification` class statics.
*/
export namespace Notification {
/**
* A type alias for a notification placement.
*/
export type Placement = 'top' | 'bottom' | 'left' | 'right';

/**
* An options object for creating a notification.
*/
export interface IOptions {
/**
* Target element to attach notification to.
*
*/
target: HTMLElement;

/**
* The message to show on notification.
*/
message?: string;

/**
* The placement of the notification.
*
* The default is `'bottom'`.
*/
placement?: Placement;

/**
* Duration in ms after which to close notification popup.
*
* The default is undefined, and notification is kept visible
* Timeout value needs to be greater than zero
*/
timeout?: number;
}

/**
* Create the DOM node for notification.
*/
export function createNode(): HTMLElement {
const node = document.createElement('div');
const container = document.createElement('div');
container.className = 'lm-DataGrid-notificationContainer';
const message = document.createElement('span');
message.className = 'lm-DataGrid-notificationMessage';
container.appendChild(message);
node.appendChild(container);

return node;
}
}
}

/**
Expand Down
Loading