@jupyterlab/filebrowser 4.0.0-alpha.2 → 4.0.0-alpha.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browser.d.ts +15 -18
- package/lib/browser.js +50 -64
- package/lib/browser.js.map +1 -1
- package/lib/crumbs.d.ts +1 -0
- package/lib/crumbs.js +41 -10
- package/lib/crumbs.js.map +1 -1
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -1
- package/lib/index.js.map +1 -1
- package/lib/listing.d.ts +54 -12
- package/lib/listing.js +296 -56
- package/lib/listing.js.map +1 -1
- package/lib/model.d.ts +19 -9
- package/lib/model.js +32 -11
- package/lib/model.js.map +1 -1
- package/lib/opendialog.d.ts +2 -1
- package/lib/opendialog.js +42 -10
- package/lib/opendialog.js.map +1 -1
- package/lib/tokens.d.ts +16 -8
- package/lib/tokens.js +9 -2
- package/lib/tokens.js.map +1 -1
- package/lib/upload.d.ts +4 -0
- package/lib/upload.js +1 -0
- package/lib/upload.js.map +1 -1
- package/lib/uploadstatus.js +4 -4
- package/lib/uploadstatus.js.map +1 -1
- package/package.json +27 -28
- package/src/browser.ts +444 -0
- package/src/crumbs.ts +441 -0
- package/src/index.ts +15 -0
- package/src/listing.ts +2609 -0
- package/src/model.ts +832 -0
- package/src/opendialog.ts +257 -0
- package/src/tokens.ts +122 -0
- package/src/upload.ts +119 -0
- package/src/uploadstatus.tsx +259 -0
- package/style/base.css +83 -62
- package/lib/search.d.ts +0 -15
- package/lib/search.js +0 -92
- package/lib/search.js.map +0 -1
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
// Copyright (c) Jupyter Development Team.
|
|
2
|
+
// Distributed under the terms of the Modified BSD License.
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { WidgetTracker } from '@jupyterlab/apputils';
|
|
6
|
+
import { IChangedArgs } from '@jupyterlab/coreutils';
|
|
7
|
+
import { GroupItem, ProgressBar, TextItem } from '@jupyterlab/statusbar';
|
|
8
|
+
import {
|
|
9
|
+
ITranslator,
|
|
10
|
+
nullTranslator,
|
|
11
|
+
TranslationBundle
|
|
12
|
+
} from '@jupyterlab/translation';
|
|
13
|
+
import { VDomModel, VDomRenderer } from '@jupyterlab/ui-components';
|
|
14
|
+
import { ArrayExt } from '@lumino/algorithm';
|
|
15
|
+
import React from 'react';
|
|
16
|
+
import { FileBrowser, FileBrowserModel, IUploadModel } from '.';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Half-spacing between items in the overall status item.
|
|
20
|
+
*/
|
|
21
|
+
const HALF_SPACING = 4;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* A pure function component for a FileUpload status item.
|
|
25
|
+
*
|
|
26
|
+
* @param props: the props for the component.
|
|
27
|
+
*
|
|
28
|
+
* @returns a tsx component for the file upload status.
|
|
29
|
+
*/
|
|
30
|
+
function FileUploadComponent(
|
|
31
|
+
props: FileUploadComponent.IProps
|
|
32
|
+
): React.ReactElement<FileUploadComponent.IProps> {
|
|
33
|
+
const translator = props.translator || nullTranslator;
|
|
34
|
+
const trans = translator.load('jupyterlab');
|
|
35
|
+
return (
|
|
36
|
+
<GroupItem spacing={HALF_SPACING}>
|
|
37
|
+
<TextItem source={trans.__('Uploading…')} />
|
|
38
|
+
<ProgressBar percentage={props.upload} />
|
|
39
|
+
</GroupItem>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* A namespace for FileUploadComponent statics.
|
|
45
|
+
*/
|
|
46
|
+
namespace FileUploadComponent {
|
|
47
|
+
/**
|
|
48
|
+
* The props for the FileUploadComponent.
|
|
49
|
+
*/
|
|
50
|
+
export interface IProps {
|
|
51
|
+
/**
|
|
52
|
+
* The current upload percentage, from 0 to 100.
|
|
53
|
+
*/
|
|
54
|
+
upload: number;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The language translator.
|
|
58
|
+
*/
|
|
59
|
+
translator?: ITranslator;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* The time for which to show the "Complete!" message after uploading.
|
|
65
|
+
*/
|
|
66
|
+
const UPLOAD_COMPLETE_MESSAGE_MILLIS: number = 2000;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Status bar item to display file upload progress.
|
|
70
|
+
*/
|
|
71
|
+
export class FileUploadStatus extends VDomRenderer<FileUploadStatus.Model> {
|
|
72
|
+
/**
|
|
73
|
+
* Construct a new FileUpload status item.
|
|
74
|
+
*/
|
|
75
|
+
constructor(opts: FileUploadStatus.IOptions) {
|
|
76
|
+
super(
|
|
77
|
+
new FileUploadStatus.Model(
|
|
78
|
+
opts.tracker.currentWidget && opts.tracker.currentWidget.model
|
|
79
|
+
)
|
|
80
|
+
);
|
|
81
|
+
this.translator = opts.translator || nullTranslator;
|
|
82
|
+
this._trans = this.translator.load('jupyterlab');
|
|
83
|
+
this._tracker = opts.tracker;
|
|
84
|
+
this._tracker.currentChanged.connect(this._onBrowserChange);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Render the FileUpload status.
|
|
89
|
+
*/
|
|
90
|
+
render(): JSX.Element {
|
|
91
|
+
const uploadPaths = this.model!.items;
|
|
92
|
+
if (uploadPaths.length > 0) {
|
|
93
|
+
const item = this.model!.items[0];
|
|
94
|
+
|
|
95
|
+
if (item.complete) {
|
|
96
|
+
return <TextItem source={this._trans.__('Complete!')} />;
|
|
97
|
+
} else {
|
|
98
|
+
return (
|
|
99
|
+
<FileUploadComponent
|
|
100
|
+
upload={this.model!.items[0].progress}
|
|
101
|
+
translator={this.translator}
|
|
102
|
+
/>
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
} else {
|
|
106
|
+
return <FileUploadComponent upload={100} translator={this.translator} />;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
dispose(): void {
|
|
111
|
+
super.dispose();
|
|
112
|
+
this._tracker.currentChanged.disconnect(this._onBrowserChange);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
private _onBrowserChange = (
|
|
116
|
+
tracker: WidgetTracker<FileBrowser>,
|
|
117
|
+
browser: FileBrowser | null
|
|
118
|
+
) => {
|
|
119
|
+
if (browser === null) {
|
|
120
|
+
this.model!.browserModel = null;
|
|
121
|
+
} else {
|
|
122
|
+
this.model!.browserModel = browser.model;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
private readonly translator: ITranslator;
|
|
127
|
+
private _trans: TranslationBundle;
|
|
128
|
+
private _tracker: WidgetTracker<FileBrowser>;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* A namespace for FileUpload class statics.
|
|
133
|
+
*/
|
|
134
|
+
export namespace FileUploadStatus {
|
|
135
|
+
/**
|
|
136
|
+
* The VDomModel for the FileUpload renderer.
|
|
137
|
+
*/
|
|
138
|
+
export class Model extends VDomModel {
|
|
139
|
+
/**
|
|
140
|
+
* Construct a new model.
|
|
141
|
+
*/
|
|
142
|
+
constructor(browserModel: FileBrowserModel | null) {
|
|
143
|
+
super();
|
|
144
|
+
this.browserModel = browserModel;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* The currently uploading items.
|
|
149
|
+
*/
|
|
150
|
+
get items(): IFileUploadItem[] {
|
|
151
|
+
return this._items;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* The current file browser model.
|
|
156
|
+
*/
|
|
157
|
+
get browserModel(): FileBrowserModel | null {
|
|
158
|
+
return this._browserModel;
|
|
159
|
+
}
|
|
160
|
+
set browserModel(browserModel: FileBrowserModel | null) {
|
|
161
|
+
const oldBrowserModel = this._browserModel;
|
|
162
|
+
if (oldBrowserModel) {
|
|
163
|
+
oldBrowserModel.uploadChanged.disconnect(this._uploadChanged);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
this._browserModel = browserModel;
|
|
167
|
+
this._items = [];
|
|
168
|
+
|
|
169
|
+
if (this._browserModel !== null) {
|
|
170
|
+
this._browserModel.uploadChanged.connect(this._uploadChanged);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
this.stateChanged.emit(void 0);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Handle an uploadChanged event in the filebrowser model.
|
|
178
|
+
*/
|
|
179
|
+
private _uploadChanged = (
|
|
180
|
+
browse: FileBrowserModel,
|
|
181
|
+
uploads: IChangedArgs<IUploadModel>
|
|
182
|
+
) => {
|
|
183
|
+
if (uploads.name === 'start') {
|
|
184
|
+
this._items.push({
|
|
185
|
+
path: uploads.newValue.path,
|
|
186
|
+
progress: uploads.newValue.progress * 100,
|
|
187
|
+
complete: false
|
|
188
|
+
});
|
|
189
|
+
} else if (uploads.name === 'update') {
|
|
190
|
+
const idx = ArrayExt.findFirstIndex(
|
|
191
|
+
this._items,
|
|
192
|
+
val => val.path === uploads.oldValue.path
|
|
193
|
+
);
|
|
194
|
+
if (idx !== -1) {
|
|
195
|
+
this._items[idx].progress = uploads.newValue.progress * 100;
|
|
196
|
+
}
|
|
197
|
+
} else if (uploads.name === 'finish') {
|
|
198
|
+
const finishedItem = ArrayExt.findFirstValue(
|
|
199
|
+
this._items,
|
|
200
|
+
val => val.path === uploads.oldValue.path
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
if (finishedItem) {
|
|
204
|
+
finishedItem.complete = true;
|
|
205
|
+
setTimeout(() => {
|
|
206
|
+
ArrayExt.removeFirstOf(this._items, finishedItem);
|
|
207
|
+
this.stateChanged.emit(void 0);
|
|
208
|
+
}, UPLOAD_COMPLETE_MESSAGE_MILLIS);
|
|
209
|
+
}
|
|
210
|
+
} else if (uploads.name === 'failure') {
|
|
211
|
+
ArrayExt.removeFirstWhere(
|
|
212
|
+
this._items,
|
|
213
|
+
val => val.path === uploads.newValue.path
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
this.stateChanged.emit(void 0);
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
private _items: Array<IFileUploadItem> = [];
|
|
221
|
+
private _browserModel: FileBrowserModel | null = null;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Options for creating the upload status item.
|
|
226
|
+
*/
|
|
227
|
+
export interface IOptions {
|
|
228
|
+
/**
|
|
229
|
+
* The application file browser tracker.
|
|
230
|
+
*/
|
|
231
|
+
readonly tracker: WidgetTracker<FileBrowser>;
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* The translation language bundle.
|
|
235
|
+
*/
|
|
236
|
+
readonly translator?: ITranslator;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* The interface for an item that is being uploaded to
|
|
242
|
+
* the file system.
|
|
243
|
+
*/
|
|
244
|
+
interface IFileUploadItem {
|
|
245
|
+
/**
|
|
246
|
+
* The path on the filesystem that is being uploaded to.
|
|
247
|
+
*/
|
|
248
|
+
path: string;
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* The upload progress fraction.
|
|
252
|
+
*/
|
|
253
|
+
progress: number;
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Whether the upload is complete.
|
|
257
|
+
*/
|
|
258
|
+
complete: boolean;
|
|
259
|
+
}
|
package/style/base.css
CHANGED
|
@@ -17,31 +17,36 @@
|
|
|
17
17
|
| Distributed under the terms of the Modified BSD License.
|
|
18
18
|
|----------------------------------------------------------------------------*/
|
|
19
19
|
|
|
20
|
-
.jp-FileBrowser {
|
|
20
|
+
.jp-FileBrowser .jp-SidePanel-content {
|
|
21
21
|
display: flex;
|
|
22
22
|
flex-direction: column;
|
|
23
|
-
color: var(--jp-ui-font-color1);
|
|
24
|
-
background: var(--jp-layout-color1);
|
|
25
|
-
/* This is needed so that all font sizing of children done in ems is
|
|
26
|
-
* relative to this base size */
|
|
27
|
-
font-size: var(--jp-ui-font-size1);
|
|
28
23
|
}
|
|
29
24
|
|
|
30
25
|
.jp-FileBrowser-toolbar.jp-Toolbar {
|
|
26
|
+
flex-wrap: wrap;
|
|
27
|
+
row-gap: 12px;
|
|
31
28
|
border-bottom: none;
|
|
32
29
|
height: auto;
|
|
33
|
-
margin:
|
|
30
|
+
margin: 8px 12px 0;
|
|
34
31
|
box-shadow: none;
|
|
32
|
+
padding: 0;
|
|
33
|
+
justify-content: flex-start;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.jp-FileBrowser-Panel {
|
|
37
|
+
flex: 1 1 auto;
|
|
38
|
+
display: flex;
|
|
39
|
+
flex-direction: column;
|
|
35
40
|
}
|
|
36
41
|
|
|
37
42
|
.jp-BreadCrumbs {
|
|
38
43
|
flex: 0 0 auto;
|
|
39
|
-
margin: 8px 12px
|
|
44
|
+
margin: 8px 12px;
|
|
40
45
|
}
|
|
41
46
|
|
|
42
47
|
.jp-BreadCrumbs-item {
|
|
43
|
-
margin:
|
|
44
|
-
padding:
|
|
48
|
+
margin: 0 2px;
|
|
49
|
+
padding: 0 2px;
|
|
45
50
|
border-radius: var(--jp-border-radius);
|
|
46
51
|
cursor: pointer;
|
|
47
52
|
}
|
|
@@ -51,7 +56,7 @@
|
|
|
51
56
|
}
|
|
52
57
|
|
|
53
58
|
.jp-BreadCrumbs-item:first-child {
|
|
54
|
-
margin-left:
|
|
59
|
+
margin-left: 0;
|
|
55
60
|
}
|
|
56
61
|
|
|
57
62
|
.jp-BreadCrumbs-item.jp-mod-dropTarget {
|
|
@@ -63,45 +68,18 @@
|
|
|
63
68
|
| Buttons
|
|
64
69
|
|----------------------------------------------------------------------------*/
|
|
65
70
|
|
|
66
|
-
.jp-FileBrowser-toolbar.jp-Toolbar {
|
|
67
|
-
padding: 0px;
|
|
68
|
-
margin: 8px 12px 0px 12px;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
.jp-FileBrowser-toolbar.jp-Toolbar {
|
|
72
|
-
justify-content: flex-start;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
.jp-FileBrowser-toolbar.jp-Toolbar .jp-Toolbar-item {
|
|
71
|
+
.jp-FileBrowser-toolbar > .jp-Toolbar-item {
|
|
76
72
|
flex: 0 0 auto;
|
|
77
|
-
padding-left:
|
|
73
|
+
padding-left: 0;
|
|
78
74
|
padding-right: 2px;
|
|
75
|
+
align-items: center;
|
|
76
|
+
height: unset;
|
|
79
77
|
}
|
|
80
78
|
|
|
81
|
-
.jp-FileBrowser-toolbar.jp-Toolbar .jp-ToolbarButtonComponent {
|
|
79
|
+
.jp-FileBrowser-toolbar > .jp-Toolbar-item .jp-ToolbarButtonComponent {
|
|
82
80
|
width: 40px;
|
|
83
81
|
}
|
|
84
82
|
|
|
85
|
-
.jp-FileBrowser-toolbar.jp-Toolbar
|
|
86
|
-
.jp-Toolbar-item:first-child
|
|
87
|
-
.jp-ToolbarButtonComponent {
|
|
88
|
-
width: 72px;
|
|
89
|
-
background: var(--jp-accept-color-normal, var(--jp-brand-color1));
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
.jp-FileBrowser-toolbar.jp-Toolbar
|
|
93
|
-
.jp-Toolbar-item:first-child
|
|
94
|
-
.jp-ToolbarButtonComponent:focus-visible {
|
|
95
|
-
background-color: var(--jp-accept-color-active, var(--jp-brand-color0));
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
.jp-FileBrowser-toolbar.jp-Toolbar
|
|
99
|
-
.jp-Toolbar-item:first-child
|
|
100
|
-
.jp-ToolbarButtonComponent
|
|
101
|
-
.jp-icon3 {
|
|
102
|
-
fill: white;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
83
|
/*-----------------------------------------------------------------------------
|
|
106
84
|
| Other styles
|
|
107
85
|
|----------------------------------------------------------------------------*/
|
|
@@ -118,10 +96,12 @@
|
|
|
118
96
|
display: none;
|
|
119
97
|
}
|
|
120
98
|
|
|
121
|
-
.jp-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
99
|
+
.jp-FileSize-hidden {
|
|
100
|
+
display: none;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.jp-FileBrowser .lm-AccordionPanel > h3:first-child {
|
|
104
|
+
display: none;
|
|
125
105
|
}
|
|
126
106
|
|
|
127
107
|
/*-----------------------------------------------------------------------------
|
|
@@ -136,13 +116,15 @@
|
|
|
136
116
|
}
|
|
137
117
|
|
|
138
118
|
.jp-DirListing:focus-visible {
|
|
139
|
-
|
|
119
|
+
outline: 1px solid var(--jp-brand-color1);
|
|
120
|
+
outline-offset: -2px;
|
|
140
121
|
}
|
|
141
122
|
|
|
142
123
|
.jp-DirListing-header {
|
|
143
124
|
flex: 0 0 auto;
|
|
144
125
|
display: flex;
|
|
145
126
|
flex-direction: row;
|
|
127
|
+
align-items: center;
|
|
146
128
|
overflow: hidden;
|
|
147
129
|
border-top: var(--jp-border-width) solid var(--jp-border-color2);
|
|
148
130
|
border-bottom: var(--jp-border-width) solid var(--jp-border-color1);
|
|
@@ -151,7 +133,7 @@
|
|
|
151
133
|
}
|
|
152
134
|
|
|
153
135
|
.jp-DirListing-headerItem {
|
|
154
|
-
padding: 4px 12px 2px
|
|
136
|
+
padding: 4px 12px 2px;
|
|
155
137
|
font-weight: 500;
|
|
156
138
|
}
|
|
157
139
|
|
|
@@ -169,10 +151,16 @@
|
|
|
169
151
|
text-align: right;
|
|
170
152
|
}
|
|
171
153
|
|
|
154
|
+
.jp-DirListing-headerItem.jp-id-filesize {
|
|
155
|
+
flex: 0 0 75px;
|
|
156
|
+
border-left: var(--jp-border-width) solid var(--jp-border-color2);
|
|
157
|
+
text-align: right;
|
|
158
|
+
}
|
|
159
|
+
|
|
172
160
|
.jp-id-narrow {
|
|
173
161
|
display: none;
|
|
174
162
|
flex: 0 0 5px;
|
|
175
|
-
padding: 4px
|
|
163
|
+
padding: 4px;
|
|
176
164
|
border-left: var(--jp-border-width) solid var(--jp-border-color2);
|
|
177
165
|
text-align: right;
|
|
178
166
|
color: var(--jp-border-color2);
|
|
@@ -221,6 +209,7 @@
|
|
|
221
209
|
.jp-DirListing-item {
|
|
222
210
|
display: flex;
|
|
223
211
|
flex-direction: row;
|
|
212
|
+
align-items: center;
|
|
224
213
|
padding: 4px 12px;
|
|
225
214
|
-webkit-user-select: none;
|
|
226
215
|
-moz-user-select: none;
|
|
@@ -228,6 +217,40 @@
|
|
|
228
217
|
user-select: none;
|
|
229
218
|
}
|
|
230
219
|
|
|
220
|
+
.jp-DirListing-checkboxWrapper {
|
|
221
|
+
/* Increases hit area of checkbox. */
|
|
222
|
+
padding: 4px;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.jp-DirListing-header
|
|
226
|
+
.jp-DirListing-checkboxWrapper
|
|
227
|
+
+ .jp-DirListing-headerItem {
|
|
228
|
+
padding-left: 4px;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.jp-DirListing-content .jp-DirListing-checkboxWrapper {
|
|
232
|
+
position: relative;
|
|
233
|
+
left: -4px;
|
|
234
|
+
margin: -4px 0 -4px -8px;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.jp-DirListing-checkboxWrapper.jp-mod-visible {
|
|
238
|
+
visibility: visible;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/* For devices that support hovering, hide checkboxes until hovered, selected...
|
|
242
|
+
*/
|
|
243
|
+
@media (hover: hover) {
|
|
244
|
+
.jp-DirListing-checkboxWrapper {
|
|
245
|
+
visibility: hidden;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.jp-DirListing-item:hover .jp-DirListing-checkboxWrapper,
|
|
249
|
+
.jp-DirListing-item.jp-mod-selected .jp-DirListing-checkboxWrapper {
|
|
250
|
+
visibility: visible;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
231
254
|
.jp-DirListing-item[data-is-dot] {
|
|
232
255
|
opacity: 75%;
|
|
233
256
|
}
|
|
@@ -263,13 +286,20 @@
|
|
|
263
286
|
text-align: right;
|
|
264
287
|
}
|
|
265
288
|
|
|
289
|
+
.jp-DirListing-itemFileSize {
|
|
290
|
+
flex: 0 0 90px;
|
|
291
|
+
text-align: right;
|
|
292
|
+
}
|
|
293
|
+
|
|
266
294
|
.jp-DirListing-editor {
|
|
267
295
|
flex: 1 0 64px;
|
|
268
296
|
outline: none;
|
|
269
297
|
border: none;
|
|
298
|
+
color: var(--jp-ui-font-color1);
|
|
299
|
+
background-color: var(--jp-layout-color1);
|
|
270
300
|
}
|
|
271
301
|
|
|
272
|
-
.jp-DirListing-item.jp-mod-running .jp-DirListing-itemIcon
|
|
302
|
+
.jp-DirListing-item.jp-mod-running .jp-DirListing-itemIcon::before {
|
|
273
303
|
color: var(--jp-success-color1);
|
|
274
304
|
content: '\25CF';
|
|
275
305
|
font-size: 8px;
|
|
@@ -278,7 +308,7 @@
|
|
|
278
308
|
}
|
|
279
309
|
|
|
280
310
|
.jp-DirListing-item.jp-mod-running.jp-mod-selected
|
|
281
|
-
.jp-DirListing-itemIcon
|
|
311
|
+
.jp-DirListing-itemIcon::before {
|
|
282
312
|
color: var(--jp-ui-inverse-font-color1);
|
|
283
313
|
}
|
|
284
314
|
|
|
@@ -290,20 +320,11 @@
|
|
|
290
320
|
width: 160px;
|
|
291
321
|
background-color: var(--jp-ui-inverse-font-color2);
|
|
292
322
|
box-shadow: var(--jp-elevation-z2);
|
|
293
|
-
border-radius:
|
|
323
|
+
border-radius: 0;
|
|
294
324
|
color: var(--jp-ui-font-color1);
|
|
295
325
|
transform: translateX(-40%) translateY(-58%);
|
|
296
326
|
}
|
|
297
327
|
|
|
298
|
-
.jp-DirListing-deadSpace {
|
|
299
|
-
flex: 1 1 auto;
|
|
300
|
-
margin: 0;
|
|
301
|
-
padding: 0;
|
|
302
|
-
list-style-type: none;
|
|
303
|
-
overflow: auto;
|
|
304
|
-
background-color: var(--jp-layout-color1);
|
|
305
|
-
}
|
|
306
|
-
|
|
307
328
|
.jp-Document {
|
|
308
329
|
min-width: 120px;
|
|
309
330
|
min-height: 120px;
|
package/lib/search.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { ReactWidget } from '@jupyterlab/ui-components';
|
|
2
|
-
import { DirListing } from './listing';
|
|
3
|
-
/**
|
|
4
|
-
* The class name added to the filebrowser crumbs node.
|
|
5
|
-
*/
|
|
6
|
-
export interface IFilterBoxProps {
|
|
7
|
-
listing: DirListing;
|
|
8
|
-
useFuzzyFilter: boolean;
|
|
9
|
-
placeholder?: string;
|
|
10
|
-
forceRefresh?: boolean;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* A widget which hosts a input textbox to filter on file names.
|
|
14
|
-
*/
|
|
15
|
-
export declare const FilenameSearcher: (props: IFilterBoxProps) => ReactWidget;
|
package/lib/search.js
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Jupyter Development Team.
|
|
2
|
-
// Distributed under the terms of the Modified BSD License.
|
|
3
|
-
import { InputGroup, ReactWidget } from '@jupyterlab/ui-components';
|
|
4
|
-
import { StringExt } from '@lumino/algorithm';
|
|
5
|
-
import React, { useEffect, useState } from 'react';
|
|
6
|
-
/**
|
|
7
|
-
* Perform a fuzzy search on a single item.
|
|
8
|
-
*/
|
|
9
|
-
function fuzzySearch(source, query) {
|
|
10
|
-
// Set up the match score and indices array.
|
|
11
|
-
let score = Infinity;
|
|
12
|
-
let indices = null;
|
|
13
|
-
// The regex for search word boundaries
|
|
14
|
-
const rgx = /\b\w/g;
|
|
15
|
-
let continueSearch = true;
|
|
16
|
-
// Search the source by word boundary.
|
|
17
|
-
while (continueSearch) {
|
|
18
|
-
// Find the next word boundary in the source.
|
|
19
|
-
let rgxMatch = rgx.exec(source);
|
|
20
|
-
// Break if there is no more source context.
|
|
21
|
-
if (!rgxMatch) {
|
|
22
|
-
break;
|
|
23
|
-
}
|
|
24
|
-
// Run the string match on the relevant substring.
|
|
25
|
-
let match = StringExt.matchSumOfDeltas(source, query, rgxMatch.index);
|
|
26
|
-
// Break if there is no match.
|
|
27
|
-
if (!match) {
|
|
28
|
-
break;
|
|
29
|
-
}
|
|
30
|
-
// Update the match if the score is better.
|
|
31
|
-
if (match && match.score <= score) {
|
|
32
|
-
score = match.score;
|
|
33
|
-
indices = match.indices;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
// Bail if there was no match.
|
|
37
|
-
if (!indices || score === Infinity) {
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
40
|
-
// Handle a split match.
|
|
41
|
-
return {
|
|
42
|
-
score,
|
|
43
|
-
indices
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
const FilterBox = (props) => {
|
|
47
|
-
const [filter, setFilter] = useState('');
|
|
48
|
-
if (props.forceRefresh) {
|
|
49
|
-
useEffect(() => {
|
|
50
|
-
props.listing.model.setFilter((item) => {
|
|
51
|
-
return true;
|
|
52
|
-
});
|
|
53
|
-
}, []);
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Handler for search input changes.
|
|
57
|
-
*/
|
|
58
|
-
const handleChange = (e) => {
|
|
59
|
-
const target = e.target;
|
|
60
|
-
setFilter(target.value);
|
|
61
|
-
props.listing.model.setFilter((item) => {
|
|
62
|
-
if (props.useFuzzyFilter) {
|
|
63
|
-
// Run the fuzzy search for the item and query.
|
|
64
|
-
const name = item.name.toLowerCase();
|
|
65
|
-
const query = target.value.toLowerCase();
|
|
66
|
-
let score = fuzzySearch(name, query);
|
|
67
|
-
// Ignore the item if it is not a match.
|
|
68
|
-
if (!score) {
|
|
69
|
-
item.indices = [];
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
|
-
item.indices = score.indices;
|
|
73
|
-
return true;
|
|
74
|
-
}
|
|
75
|
-
const i = item.name.indexOf(target.value);
|
|
76
|
-
if (i === -1) {
|
|
77
|
-
item.indices = [];
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
|
-
item.indices = [...Array(target.value.length).keys()].map(x => x + i);
|
|
81
|
-
return true;
|
|
82
|
-
});
|
|
83
|
-
};
|
|
84
|
-
return (React.createElement(InputGroup, { type: "text", rightIcon: "ui-components:search", placeholder: props.placeholder, onChange: handleChange, value: filter }));
|
|
85
|
-
};
|
|
86
|
-
/**
|
|
87
|
-
* A widget which hosts a input textbox to filter on file names.
|
|
88
|
-
*/
|
|
89
|
-
export const FilenameSearcher = (props) => {
|
|
90
|
-
return ReactWidget.create(React.createElement(FilterBox, { listing: props.listing, useFuzzyFilter: props.useFuzzyFilter, placeholder: props.placeholder, forceRefresh: props.forceRefresh }));
|
|
91
|
-
};
|
|
92
|
-
//# sourceMappingURL=search.js.map
|
package/lib/search.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"search.js","sourceRoot":"","sources":["../src/search.tsx"],"names":[],"mappings":"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"}
|