jupyterlab / lumino Goto Github PK
View Code? Open in Web Editor NEWLumino is a library for building interactive web applications
Home Page: https://lumino.readthedocs.io/
License: Other
Lumino is a library for building interactive web applications
Home Page: https://lumino.readthedocs.io/
License: Other
I'm trying to update this code to use jupyterlab 2.1. It had previously been using phosphor/datagrid 0.1.6.
I have two failing tests that rely on resizeRow
and resizeColumn
, and stepping through them, it looks to me like the resizeRow
doesn't actually do anything. I thought maybe it was just async and there was a race condition, but it doesn't seem like it. It passes a message along but the row section size never changes afaict. If I call the private method, it works as expected. What am I missing?
Am I not using them correctly? Here's an example that I updated from resizeSection
.
The current behavior skews new ids to the end of the range for large inserts.
Context:
For creating a single triplex ID, a random path is generated within the start of the available range (uniformly in the first Math.sqrt(max - min)
part of the range). Currently, when inserting a range, this ID generation is called sequentially, each time using the previous random ID as the start of the range.
Behavior:
With this logic, any sequence insert will have an ID distribution that is heavy towards the end of the insertion range (the density increases as more of the range is consumed). This effect is also further pronounced if the range is already small, i.e. for insertions within a previous insertion.
Proposed solution:
For range inserts:
Hi, my name is Logan McNichols. I am an intern for Jupyter Cal Poly. I am working on a tabular data editor powered by the DataGrid
along with @kgoo124 and @ryuntalan.
We are relying on the Datastore
to store some data for us. In particular we have two ListField<number>
objects tracking the position of row and columns respectively. I encountered some unexpected behavior when trying to work with a ListField<number>
object who's length was greater than 100000.
I think I traced the problem to the function in listfield.ts
called spliceArray
. I copied this function to my workspace and ran the following test.
function spliceArray(arr, start, deleteCount, items) {
if (!items) {
return arr.splice(start, deleteCount);
}
let size = 100000;
if (items.length < size) {
return arr.splice(start, deleteCount || 0, ...items);
}
let deleted = arr.splice(start, deleteCount);
let n = Math.floor(items.length / size);
let idx = 0;
for (let i = 0; i < n; i++, idx += size) {
arr.splice(idx, 0, ...items.slice(idx, size));
}
arr.splice(idx, 0, ...items.slice(idx));
return deleted;
}
const arr = new Array(500).fill(0);
const items = new Array(10**6).fill(0);
const start = 500;
const deleteCount = 0;
spliceArray(arr, start, deleteCount, items);
console.log("expected output", 1000500, "actual output", arr.length);
// expected output 1000500 actual output 100500
CC @mbektasbbg
When editing a cell following a change to the data model, the state used by the cell editing class is referring to the old data model before it was changed. This results in null references to cells which may no longer exist (if the row of column has been eliminated from the data model).
Consider the following situation:
My parent Menu and your sub-Menu will then have different renderers/styles. While in some circumstances this is a feature, in terms of enforcing a unified style across an application this is a bug. A similar situation exists with MenuBar and Menu.
The real issue is that there seems to be no clear way to extend the existing Lumino codebase in order to resolve the above. Here's some things I tried:
Menu.insertItem
Ideally if I'm the owner of the parent Menu I would have some way of inspecting any sub-Menu that gets added so that I could ensure it's Renderer/style. However, even if you try to subclass Menu.insertItem
there's no easy way to alter an incoming sub-Menu:
Menu.Renderer
is readonly, so you can't replace an existing sub-Menu's Renderer without a castMenu.defaultRenderer
This works, but has some down sides:
Menu.defaultRenderer
is readonly, so you need a castMenu.defaultRenderer
runs before any of your code that constructs a new MenuNot quite sure how to untie this knot.
A little while ago in the Jupyterlab core code I tried to set up some Menu widgets with a custom Renderer, but kept running into weird problems. My goal was to add my own custom renderering for the check mark and submenu icons that are common to all Menu widgets. I was able to get the menus supplied by Jupyterlab core code to render correctly, but I had a whole bunch of trouble getting my icons to show up in any sub-Menu and any Menu supplied by an external extension.
Ultimately I came up with a bunch of ugly hacks to work around this. Said hacks work well enough, but this seems like a legit problem that deserves a built-in solution. I'm just not sure what.
I have a grid based on DataGrid
, and I am trying to make it so that certain columns are not editable.
DataGrid
already has a method for selecting cells based on metadata, and this might be the best way to identify data that should not be editable.
I tried doing something like:
const columnIdentifier = {'type': 'date'};
grid.editorController!.setEditor(columnIdentifier, (config: CellEditor.CellConfig): ICellEditor => {
return null;
});
(which is a bit verbose) but could let you pick which types of cells can be edited.
However, that approached doesn't work because (I think) this code in CellEditorController
:
private _getMetadataBasedEditor(cell: CellEditor.CellConfig): ICellEditor | undefined {
let editorMatched: ICellEditor | undefined;
const metadata = cell.grid.dataModel!.metadata('body', cell.row, cell.column);
if (metadata) {
this._metadataBasedOverrides.forEach((value) => {
if (!editorMatched) {
let [identifier, editor] = value;
if (this._metadataMatchesIdentifier(metadata, identifier)) {
editorMatched = resolveOption(editor, cell);
}
}
});
}
return editorMatched;
}
Because editorMatched
is not true when it is null
, it continues searching. If this logic was changed to allow null
to be returned, then it could provide a null Editor which would prevent the editor from editing this cell.
Does that sound correct and a viable solution for the problem?
Team,
I am opening this issue to discuss a potential enhancement to the lumino DataGrid. Specifically, I am interested in hearing your opinions on adding some mechanism where the DataGrid can have "context aware" cells.
We are big fans of the DataGrid and rely on it quite extensively in some of our internal projects. Some of the frequent use cases we have involve the notion of cell merging so we can represent hierarchies of nested columns and rows. Other ones involve setting the formatting of one cell based on the value of another cell, for example.
Custom data models are not enough for this type of functionality as there is no clear notion of a cell object. Cells are painted based on a calculated region, but they are not aware of their neighbors. This means that conditional formatting in one column based on the values in another column cannot be done. The same idea applies to cell hierarchies when rendering nested column and row headers. The existing data model, actually, can accommodate multiple header rows/columns:
lumino/packages/datagrid/src/jsonmodel.ts
Line 49 in 925377c
But that model assumes all cells are distinct, and does not allow for a visual representation of any merged regions.
To get around that, at the moment, we are maintaining a fork which has a quick and dirty hack to allow the for visual representation of nested columns. However the current implementation is not something we think is sustainable to maintain, and ideally we could have a better, well thought-of, model to address all these use cases, and that's why I am opening this PR!
I would appreciate any feedback you have on this idea.
Many thanks
Hi, my name is Logan McNichols. I am an intern for Jupyter Cal Poly. I am working on a tabular data editor powered by the DataGrid
along with @kgoo124 and @ryuntalan.
We are working on a design that involves painting LabIcons
onto the DataGrid
's canvas to correspond the the type of field in a given column. To achieve this, we would like to be able to extend the DataGrid
class to add custom drawing functions. To do this, our class would need to be able to access some properties & methods of the DataGrid
that are currently set to private
.
The methods we would need access to are
_paintContent
_repaintContent
& _repaintOverlay
The properties we would need getters for are
_canvasGC
_rowSections
_columnSections
_columnHeaderSections
_rowHeaderSections
.Given the following layout (adapted from the DockPanel example), where dock2
is a second DockPanel
added to the first one with:
let dock2 = new DockPanel();
dock2.addWidget(g2);
dock2.addWidget(y2, { mode: 'split-right', ref: g2 });
dock2.id = 'dock2';
dock2.title.label = 'Dock 2';
dock.addWidget(dock2, { mode: 'split-bottom', ref: r1});
Is is possible to have control on where the widgets of an inner DockPanel can be docked? For example to disallow dropping them outside of "Dock 2":
We should still make the accessibility enhancements proposed at the Web4All Hackathon in 2019:
phosphorjs/phosphor#404
phosphorjs/phosphor#405
phosphorjs/phosphor#406
If I try to build the latest master of jupyter-fs:
git clone [email protected]:jpmorganchase/jupyter-fs.git
cd jupyter-fs
make js
I get the following error on the tsc
(ie typescript compilation) step:
$ tsc
../node_modules/@jupyterlab/observables/lib/modeldb.d.ts:227:9 - error TS2416: Property 'changed' in type 'ObservableValue' is not assignable to the same property in base type 'IObservableValue'.
Type 'ISignal<this, IChangedArgs>' is not assignable to type 'ISignal<IObservableValue, IChangedArgs>'.
Type 'this' is not assignable to type 'IObservableValue'.
Type 'ObservableValue' is not assignable to type 'IObservableValue'.
The types returned by 'get()' are incompatible between these types.
Type 'JSONValue' is not assignable to type 'PartialJSONValue'.
Type 'JSONObject' is not assignable to type 'PartialJSONValue'.
Type 'JSONObject' is not assignable to type 'string'.
227 get changed(): ISignal<this, ObservableValue.IChangedArgs>;
~~~~~~~
../node_modules/@jupyterlab/observables/lib/modeldb.d.ts:231:5 - error TS2416: Property 'get' in type 'ObservableValue' is not assignable to the same property in base type 'IObservableValue'.
Type '() => JSONValue' is not assignable to type '() => PartialJSONValue'.
231 get(): JSONValue;
~~~
Found 2 errors.
This is definitely being caused by the latest release of @lumino/coreutils
, since if I add a resolution to the previous coreutils
to my package.json
:
"resolutions": {
"@lumino/coreutils": "1.5.0"
}
the build error is fixed.
I beleive the underlying cause is the redefintion of JSONObject
that was part of the 1.5.1 release.
@lumino/[email protected]:
lumino/packages/coreutils/src/json.ts
Lines 26 to 30 in 00ae441
@lumino/[email protected]:
lumino/packages/coreutils/src/json.ts
Lines 26 to 30 in 36debf6
Because this was a patch release of coretuils (1.5.0 => 1.5.1), you'll likely only see the bug if you delete your yarn.lock
(or if start from a fresh build that never had one).
Hi, my name is Logan McNichols. I am an intern for Jupyter Cal Poly, working with @kgoo124 and @ryuntalan to develop a tabular data editor powered by the DataGrid
. On of the editing functions we are including is the ability to move rows and columns.
We have already enabled adding and removing rows and columns. The pattern to do this has been (1) create the desired change to the DataModel
and (2) emit a DataModel.ChangedArgs
signal to the DataGrid
with the appropriate type (e.g. if we were adding a row we would submit a signal with a type
attribute 'rows-added'
).
We attempted this same pattern for moving columns and rows. But, submitting a 'rows-moved'
or 'columns-moved'
signal to the DataGrid
does not seem to update it visually. Interestingly, the grid will update if we move to another panel in JupyterLab and then come back to it.
Early in Phosphor/Lumino's development, we decided to use .keyCode
instead of .key
for the basis of the keyboard shortcut system. This came about in part because (among other things) we realized that browsers were inconsistent with the .key
attribute when modifiers were used. For example (and I just checked this is still the case with Firefox 76), in Firefox we saw that on a mac, pressing the numbers on a en-us keyboard layout while holding shift, control, alt, and command, led to the following sequence of event.key
attributes:
1@345^7890
On Chrome, we get:
1€345fl7890
I suppose once browsers can be consistent about .key
, we can look again at a keyboard shortcut system that depends on it. A nice thing about using .key
is that presumably it would transparently support different keyboard maps, instead of relying on manually creating and selecting keyboard maps.
Another option, as @vidartf points out below, is moving to the .code
attribute, especially since .keyCode
is both deprecated and a bit convoluted across different browsers.
Hi, my name is Logan McNichols. I am an intern for Jupyter Cal Poly. I am working on a tabular data editor powered by the DataGrid along with @kgoo124 and @ryuntalan.
Our editor paints LabIcons
onto the column-header
of the grid. During a horizontal scroll, these icons can get partially painted onto the corner header. Sometimes, these kind of issues can be solved by bounding the dirty rect very precisely. However, in this case, our canvas is painting on complex svg paths. It would be challenging to bound this object to a given x-coordinate. Alternatively, we could be conservative and say that if any of the svg stands outside of the dirty rect, then don't paint it at all. But this means that our icons will not appear and disappear gradually on a scroll, but will abruptly appear and disappear.
I think the preferable solution is to redraw the corner header as the final draw operation. This is in fact how the DataGrid
already does it. Can we allow extending classes access to _drawCornerHeader
so that they can do this as well?
After @jupyterlab/buildutils
2.0 is published, the dependency in the root package.json
in Lumino needs to be updated so that its dependency on @phosphore/coreutils
is removed.
Hello,
I would like to disable the drag and drop and resize properties of the elements (e.g. green tab bar).
I know that DockPanel and TabBar Widgets have the "tabsMovable" property, but it still allows me to resize the panel. Is there any way to lock (at the element level, not at panel level) the drag, resize, and move properties. The goal is to have a completely static element in the DockPanel.
Commands are critical to the interaction between many parts of a lumino app, yet are very loosely-typed, and generally opaque to implementers and users. This limits the discovery, effective user interface, and reusability of commands. While these problems are likely unsolveable at compile time, runtime validation and discovery would improve all of these for the user of a lumino application, with minimal effort to implementers.
At present, commands are difficult to discover. Yes, one can listCommands
to get their ids, and then iterate over all of their option values, and try calling them.
When commands are further abstracted, it becomes basically impossible to determine whether a command execution will be well-formed, and what is just nonsense that will fail in a fully-spun-up application.
From the application perspective, commands are fire-and-forget, delegating the responsibility to individual implementations. Many commands would benefit from even minimal UI to modify their behavior, and could be, by default, presented in a single, consistent way vs some commands "just working", some opening dialogs, and other unpredictable/inconsistently accessible things that can occur.
With well-typed and documented commands, it becomes possible to generate machine-readable representations of possible command states (to-be-executed, was-executed, etc). A command palette, thus enhanced, could provide significant value.
Additionally, with discoverable commands, hybrid gui/cli applications, a la clui become possible.
Finally, the ability to understand each command's arguments and result make it possible to serialize longer chains of commands that reference each other's output: DockPanel
's layout serialization represents this in one, particular way, but more generalized approaches could truly make lumino an engine for lisp machine/smalltalk-style self-extensibility and introspection.
Selecting the validation description itself is probably neither viable nor useful: there still exists no standards-body adopted description-of-JSON-in-JSON, much less one implemented in browsers. While JSON Schema is the de facto representation, with ajv
the de facto browser validator, it's worth exploring other options... once we have something that can accept any of it, with the usual caveats of performance, security, stability, and cross-language compatibility.
I don't think any of these would require breaking changes, but it may be worth targeting/tabling this work until such a time as it would make sense. At any rate, I would be able to commit to implementing these feature, just not on what timeline.
@lumino/coreutils
JSONValidationExt
IValidator
which defines a minimal validation scheme, e.g. validate(schema, instance) => Promise<any[]>
(suitably genericized)@lumino/commands
CommandRegistry.IOptions
validator
to avalidate: {args: true, result: false}
describedby
to ICommandOptions
which returns (a promise to) a schema for args
result
(if it even makes sense to validate outputs, as many are "fat" objects, e.g. Widget
)@lumino/application
validator
to Application.IOptions
(new)@lumino/commandpalette
renderArgs
to IRenderer
examples
package.json
field, e.g. {"lumino": {"commands": {}}
which would make available commands truly discoverable.metadata
field on describedby
could allow for application/implementation specific options, such as rjsf's uiSchema
.Downstreams:
We should use RTD for our narrative and API docs.
Hi, my name is Logan McNichols. I am an intern for Jupyter Cal Poly. I am working on a tabular data editor powered by the DataGrid
along with @kgoo124 and @ryuntalan.
We would like to use lumino's Drag
class to create a column/row shadow which appears on a mouse click of a column/row header and is drag-able.
In order to do this, we would need to extend the Drag
class to change to how it updates the position of the drag image. For example, when a column header is selected we want to fix the style.top
attribute to be the top edge of the DataGrid
and keep style.left
within the bounds of the DataGrid
. The method we want to override with our child class is _moveDragImage
, but this is currently a private method of the Drag
class.
The old phosphorjs/phosphor#154 issue remains unresolved. Touchscreen laptops and larger tablets, both with touch events, could support a desktop-style web app. However Lumino DockPanel currently only responds to mouse events.
Another UX issue is that even with touch event support, the spacing between panels is a very small area to hit for resizing them. A larger handle, gesture and / or resizing mode is needed to manage them comfortably with a finger as the only pointing device.
I propose two options:
Just wanted to open this as a place for communication and further discussion regarding issue #86 and PR #87. It was discussed that some of the DataGrid
styles in the default-theme
package are critical to the operation of the DataGrid
. These styles should be refactored into from the default-theme
package into the DataGrid
package.
@mbektasbbg @afshin
I've noticed that dragging tabs in the TabBar widget feels much laggier than before. I narrowed the culprit down to the merge that migrated the CSS selectors to new 'lm-*' based prefixes (#20) while keeping the original ones. Chrome seems to have some issues when an element has two different selectors with identical stylesheets. Is there a timeline to remove the deprecated selectors from the codebase? I assume JupyterLab has fully migrated over by now.
We should add a way for a region of an application to ignore/suppress all keyboard shortcuts.
@ellisonbg brought up in the JupyterLab team meating today the interesting proptery of Lumino containing the consecutive letters LMNO. This may be a good place to start logo explorations. Other logo explorations are welcome, let's drop them here for discussion if anybody has sketches or ideas.
This is as much to verify that Throttler
and Debouncer
work as intended as it is to have full test coverage.
The Lumino code appears to be switching the class naming conventions to lm-name_
rather than the Phosphor p-_name_
style. The @lumino/default-theme repo has not been updated with the new names. Specifically I noticed that the datagrid.css file is missing the styles that allow the cellEditors to work properly.
Hi, my name is Kalen, and I am one of the Jupyter Cal Poly interns. Our team has been using the TextCell Editor
class in attempts to create an editable DataGrid for the extension my team is working on, Tabular Data Editor.
However, the cell editor renders behind the DataGrid
, and I think this is because the updatePosition
method in CellEditor
uses the styles top
and left
, but the position
isn't set.
Hi, I am one of the Cal Poly interns working on the Tabular Data Editor extension. We are looking to have some dashed borders around a cell when it has been copied, but not yet pasted. We have an issue here that has a picture of what we are looking to do.
It looks like all the potential Selections
are stored in an array that is painted in datagrid.ts
, but there is no way to isolate these selections. Some possible solutions would be using a CSS class and assigning a different render to a specific cell. The solution should be easily applied/removed. In our case, we would only want the dashed border to show up after copy, but before paste.
Hi,
I'd like to use not within a selector, but that does not seem to be working. The use case is having something apply for the whole selector except for specific children of it. Example:
{
"command": "runmenu:restart-and-run-all",
"keys": [
"Shift R"
],
"selector": ".jp-Notebook.jp-mod-commandMode :not(.jp-Stdin)"
}
Is this supported?
Currently, the number cell editor automatically uses step
of 'any'
. This results in the step for a decimal number always being 1
. I figured I would try to tackle this problem at the source.
@lmcnichols @ryuntalan
Hi, my name is Logan McNichols. I am an intern for Jupyter Cal Poly. I am working on a tabular data editor powered by the datagrid along with @kgoo124 and @ryuntalan.
We are working to get a grab cursor to display for moving rows and columns. The class BasicMouseHandler
provides much of the core functionality we want, but it is tricky to extend it, as the cursors are determined by private properties/methods.
I'm not sure if this is an issue with how Signals work or with the specific callback function I'm running into.
When the _tabCloseRequested
Signal in tabbar.ts
is emitted (on line 790) it only handles the the _onTabCloseRequested
slot that is connected on line 77 of tabpanel.ts
, any slots connect later, such as in an extension are no invoked. Specifically in the Private.emit
function in signaling/src/index.ts
on line 565, after on return from invokeSlot
(in my example it's the _onTabCloseRequested
slot) the value of signal
for every connection
in the receivers
array is set to null
.
As far as I have been able to stack trace down into the call I have been unable to find where this happens. From my understanding of the codebase, somewhere the Signal that is being handled is being disposed, and thus on return from invokeSlot
all references to it are now null
.
This means that when extra slots are added to existing Signals in extensions they will return success on connection but never triggered on emission.
In order to more easily see this issue I have recreated a demo extension that show the issue: https://github.com/ajbozarth/demo-jl-ext
The FocusTracker
tests (in focustracker.spec.ts
) pass in CI and in Chrome, but not in Firefox.
We need to test the effects of #40 against JupyterLab before making a release.
Any thoughts on how do to that cleanly?
Worst case it might entail a yarn link
for all of the lumino packages.
I've been playing around with Lumino for a few days now, and it appears to be an extremely powerful and resilient framework. However it doesn't seem particularly active: there's a decent amount of apparently ignored open issues, and pretty much no documentation, other than what is left from PhosphorJS - which could disappear any day.
I was therefore wondering if it would be possible to get an update about the development status of Lumino, and if it would be safe to use in production level software?
In the current implementation of Command Palette search input is missing clear input option. It is making user not to use single mouse click option to clear input. Forcing user to use keyboard to clear text by selection or backspace.
solution:
We can add input type to search by default and make use of useragent (browser) default clear search feature.
By default in edge clear search is visible, for webkit based browser we need to specify the type to search so that clear input will appear.
I would love to make PR if this solution is fine..
Currently, the menu widgets are either:
however, the developer API is not as convenient to use for submenus as it is for commands. For example, one can create a callback for a command to be asked about its visibility (isVisible
) or state (isEnabled
), but this does not seem to be possible for submenus:
lumino/packages/widgets/src/menu.ts
Lines 1871 to 1879 in 77ec35c
Lack of callbacks also means that the we do not have an easy way to:
This led me to use some quirky workarounds when implementing spellcheck suggestions.
One lazy way of getting what I want would be (pseudo-code follows):
type ItemType = 'command' | 'submenu' | 'separator' | 'subcommand'; // ← added
IItemOptions: {
type?: ItemType;
command?: string;
args?: ReadonlyJSONObject;
submenu?: Menu | null;
subcommand?: string; // ← added
}
this.app.commands.addCommand(
'spellchecker:suggestions',
{
label: () => anySuggestions() ? 'Adjust to' : 'No suggestions',
isEnabled: () => anySuggestions(),
/* provides the menu items options; command defaults to subcommand */
execute: () => getSuggestions().map(suggestion => {args: {name: suggestion}}) as IItemOptions[],
}
)
this.app.commands.addCommand(
'spellchecker:use-suggestion',
{
label: (args) => args.name as string,
execute: (args) => replaceToken(args.name as string),
}
)
this.app.contextMenu.addItem({
selector: '.cm-spell-error',
command: 'spellchecker:suggestions',
subcommand: 'spellchecker:use-suggestion',
type: 'subcommand'
});
Not sure how good it would be; the trick with re-using execute seems elegant but sadly the type checking would not be of much use here... Unless we would have additional addSubCommand
method with items
instead of execute
.
Also, if I am the only one struggling with this it might not be worth introducing extra complexity.
Not sure if jupyterlab has any preferences for Yarn over NPM - But if there is any interest in switching to NPM I have a working branch for NPM (it uncovered a few missing dependencies - which I will try and issue a PR for either-way).
Hi,
I've got a fairly complex layout, which involves adding and removing TabBars from a SplitLayout dynamically - however I can't figure out the correct way of removing and disposing all TabBars from the layout. I've tried
each(splitpanel.widgets, (child,i)=>{
(child as TabBar<Widget>).dispose();
});
the tab bars don't seem to get removed from the layout. Apparently, from setting the TabBar parent to null
in the dispose function (which doesn't seem to actually remove it from the SplitPanel??).
The desired behaviour can be achieved by using .hide()
instead of .dispose()
:
Although this looks correct, I obviously don't want to use it seeing as the old TabBars remain in the dom, even when they should be long gone.
Am I just misunderstanding what dispose
is supposed to be doing? What's the 'correct' way of permanently removing widgets from a layout?
I have a fairly complex layout of widgets including some that are React widgets (i.e., wrapped in UseSignal
), and multiple datagrid
tabs with custom data models and custom selection models. When I leave the page I use saveLayout
from the main DockPanel
. When I come back to the page, I try to use restoreLayout
. It does seem to restore the panels to the right positions, but the panels no longer work properly.
I thought the idea was that when I am attempting to recreate the page, I build the widgets and then tell the DockPanel
to restoreLayout
and it would put them back in the last saved positions, but I am beginning to think I am not using this properly as it looks like the restore is attempting to recreate the widgets and mine are detached from the parent.
Any advice on how to restore the layout would be appreciated.
After instaling lumino I get:
npm WARN @lumino/[email protected] requires a peer of [email protected] but none is installed. You must install peer dependencies yourself.
But after installing crypto
I get:
npm WARN deprecated [email protected]: This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in.
When debugging in JupyterLab (with the UMD bundles introduced in #40), I am seeing the ES6 bundle, we should be able to reach back to the original TS source files:
Hello,I am using jupyterlab alot and I wrote python most of time.
I need to write some plugin for jupyterlab so I am learning to use lumino now
Since there is little document for lumino, I tried to read source code to figure out how thing go.
I am ok for most part,but when I try to figure out dependencies in lumino/widgets, I found
// widget.ts
import {
Layout
} from './layout';
and
// layout.ts
import {
Widget
} from './widget';
As far as I know,this is not OK in python,this is Circular Dependency
So is this ok in typescript?I am new user for typescript
Should all of the legacy p-*
CSS selectors be renamed to lm-*
?
I am currently working on the Tabular Data Editor extension with @lmcnichols and @ryuntalan. We noticed the BasicMouseHandler
doesn't utilize the different selection modes onMouseDown
. Using these different selection modes for rows, columns, and cells will improve the UI of our extension.
We could migrate the build-extension
script here and add a method to Application
to dynamically load extensions, opening up the possibility for other applications to use module federation. We'd also need a simplified way to build the "core" application bundle. These scripts would have to be less opinionated (or more configurable) here than they are currently in JupyterLab.
Wanted to open this up for discussion. Right, now we have to register and load the translator for every extension and every Widget
inside of it, which seems inefficient.
I'm proposing that we add a translator
attribute to Widget
and take an optional parameter translator
in the constructor. If no, translator is given, we can just set the translator as the nullTranslator
(dummy-implementation that returns the same string). This would also allow us to translate labels, captions, and other common strings down at the Widget
level making it easier for current and future extensions to implement localization.
This would allow us to reduce the amount of redundant code and standardize translation since every Widget
would have a translator (possibly nullTranslator
) by default. I don't think there would be any breaking changes as this would serve as an optional parameter.
The only issue I can see is that Lumino is depending on a JupyterLab package, but I think that would be okay? Not too sure where this fits in terms of the 3.0 release but wanted to get this conversation going before we start adding translations to every extension.
Consider these two paths of mouse movement:
In the blue path, the submenu delays closing so you can get to the submenu item you are aiming for. However, if the mouse goes on the red path, the menu closes and a new top-level menu opens. This is frustrating if you are aiming for a submenu item.
Perhaps the delay at
lumino/packages/widgets/src/menu.ts
Lines 858 to 900 in e348a0d
See jupyterlab/jupyterlab#9201 for more context.
In the throttler, we have a special check:
lumino/packages/polling/src/ratelimiter.ts
Lines 130 to 132 in 5e8427c
This (I think) means that the throttle callback cannot schedule a new callback by calling invoke recursively. For example, I might have a function that tries to do a lot of work (say process 100 items in an array) by breaking it up, doing a bit (like process 10 items), then scheduling a future call by invoking the throttle recursively and yielding back to the browser. I think this current logic of not scheduling a future call if we are currently being invoked means I cannot invoke recursively.
Of course, I can do a setTimeout(() => { x.invoke() })
, but that seems like a weird workaround. Why do we have this check?
We ran into this in jupyter-widgets/ipywidgets#2732 (comment)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.