1 | import { IChangedArgs } from '@jupyterlab/coreutils';
|
2 | import { IObservableList } from '@jupyterlab/observables';
|
3 | import { IDisposable } from '@lumino/disposable';
|
4 | import { Message } from '@lumino/messaging';
|
5 | import { ISignal, Signal } from '@lumino/signaling';
|
6 | import { PanelLayout, Widget } from '@lumino/widgets';
|
7 |
|
8 |
|
9 |
|
10 | export declare abstract class WindowedListModel implements WindowedList.IModel {
|
11 | |
12 |
|
13 |
|
14 |
|
15 |
|
16 | constructor(options?: WindowedList.IModelOptions);
|
17 | /**
|
18 | * Provide a best guess for the widget size at position index
|
19 | *
|
20 | * #### Notes
|
21 | *
|
22 | * This function should be very light to compute especially when
|
23 | * returning the default size.
|
24 | * The default value should be constant (i.e. two calls with `null` should
|
25 | * return the same value). But it can change for a given `index`.
|
26 | *
|
27 | * @param index Widget position
|
28 | * @returns Estimated widget size
|
29 | */
|
30 | abstract estimateWidgetSize: (index: number) => number;
|
31 | /**
|
32 | * Widget factory for the list items.
|
33 | *
|
34 | * Caching the resulting widgets should be done by the callee.
|
35 | *
|
36 | * @param index List index
|
37 | * @returns The widget at the given position
|
38 | */
|
39 | abstract widgetRenderer: (index: number) => Widget;
|
40 | /**
|
41 | * List widget height
|
42 | */
|
43 | get height(): number;
|
44 | set height(h: number);
|
45 | /**
|
46 | * Test whether the model is disposed.
|
47 | */
|
48 | get isDisposed(): boolean;
|
49 | /**
|
50 | * Items list to be rendered
|
51 | */
|
52 | get itemsList(): IObservableList<any> | null;
|
53 | set itemsList(v: IObservableList<any> | null);
|
54 | /**
|
55 | * Number of widgets to render in addition to those
|
56 | * visible in the viewport.
|
57 | */
|
58 | get overscanCount(): number;
|
59 | set overscanCount(newValue: number);
|
60 | /**
|
61 | * Viewport scroll offset.
|
62 | */
|
63 | get scrollOffset(): number;
|
64 | set scrollOffset(offset: number);
|
65 | /**
|
66 | * Total number of widgets in the list
|
67 | */
|
68 | get widgetCount(): number;
|
69 | set widgetCount(newValue: number);
|
70 | /**
|
71 | * Whether windowing is active or not.
|
72 | *
|
73 | * This is true by default.
|
74 | */
|
75 | get windowingActive(): boolean;
|
76 | set windowingActive(newValue: boolean);
|
77 | /**
|
78 | * A signal emitted when any model state changes.
|
79 | */
|
80 | get stateChanged(): ISignal<WindowedListModel, IChangedArgs<any, any, 'count' | 'index' | 'list' | 'overscanCount' | 'windowingActive'>>;
|
81 | /**
|
82 | * Dispose the model.
|
83 | */
|
84 | dispose(): void;
|
85 | /**
|
86 | * Get the total list size.
|
87 | *
|
88 | * @returns Total estimated size
|
89 | */
|
90 | getEstimatedTotalSize(): number;
|
91 | /**
|
92 | * Get the scroll offset to display an item in the viewport.
|
93 | *
|
94 | * By default, the list will scroll as little as possible to ensure the item is visible. You can control the alignment of the item though by specifying a second alignment parameter. Acceptable values are:
|
95 | *
|
96 | * auto (default) - Scroll as little as possible to ensure the item is visible. (If the item is already visible, it won't scroll at all.)
|
97 | * smart - If the item is already visible (including the margin), don't scroll at all. If it is less than one viewport away, scroll so that it becomes visible (including the margin). If it is more than one viewport away, scroll so that it is centered within the list.
|
98 | * center - Center align the item within the list.
|
99 | * end - Align the item to the end of the list
|
100 | * start - Align the item to the beginning of the list
|
101 | *
|
102 | * @param index Item index
|
103 | * @param align Where to align the item in the viewport
|
104 | * @param margin In 'smart' mode the viewport proportion to add
|
105 | * @returns The needed scroll offset
|
106 | */
|
107 | getOffsetForIndexAndAlignment(index: number, align?: WindowedList.ScrollToAlign, margin?: number): number;
|
108 | /**
|
109 | * Compute the items range to display.
|
110 | *
|
111 | * It returns ``null`` if the range does not need to be updated.
|
112 | *
|
113 | * @returns The current items range to display
|
114 | */
|
115 | getRangeToRender(): WindowedList.WindowIndex | null;
|
116 | /**
|
117 | * Return the viewport top position and height for range spanning from
|
118 | * ``startIndex`` to ``stopIndex``.
|
119 | *
|
120 | * @param startIndex First item in viewport index
|
121 | * @param stopIndex Last item in viewport index
|
122 | * @returns The viewport top position and its height
|
123 | */
|
124 | getSpan(startIndex: number, stopIndex: number): [number, number];
|
125 | /**
|
126 | * WindowedListModel caches offsets and measurements for each index for performance purposes.
|
127 | * This method clears that cached data for all items after (and including) the specified index.
|
128 | *
|
129 | * The list will automatically re-render after the index is reset.
|
130 | *
|
131 | * @param index
|
132 | */
|
133 | resetAfterIndex(index: number): void;
|
134 | /**
|
135 | * Update item sizes.
|
136 | *
|
137 | * This should be called when the real item sizes has been
|
138 | * measured.
|
139 | *
|
140 | * @param sizes New sizes per item index
|
141 | * @returns Whether some sizes changed or not
|
142 | */
|
143 | setWidgetSize(sizes: {
|
144 | index: number;
|
145 | size: number;
|
146 | }[]): boolean;
|
147 | /**
|
148 | * Callback on list changes
|
149 | *
|
150 | * @param list List items
|
151 | * @param changes List change
|
152 | */
|
153 | protected onListChanged(list: IObservableList<Widget>, changes: IObservableList.IChangedArgs<Widget>): void;
|
154 | private _getItemMetadata;
|
155 | private _findNearestItem;
|
156 | private _findNearestItemBinarySearch;
|
157 | private _findNearestItemExponentialSearch;
|
158 | private _getRangeToRender;
|
159 | private _getStartIndexForOffset;
|
160 | private _getStopIndexForStartIndex;
|
161 | /**
|
162 | * Default widget size estimation
|
163 | */
|
164 | protected _estimatedWidgetSize: number;
|
165 | protected _stateChanged: Signal<WindowedListModel, IChangedArgs<any, any, "list" | "index" | "count" | "overscanCount" | "windowingActive">>;
|
166 | private _currentWindow;
|
167 | private _height;
|
168 | private _isDisposed;
|
169 | private _itemsList;
|
170 | private _lastMeasuredIndex;
|
171 | private _overscanCount;
|
172 | private _scrollOffset;
|
173 | private _widgetCount;
|
174 | private _widgetSizers;
|
175 | private _windowingActive;
|
176 | }
|
177 | /**
|
178 | * Windowed list widget
|
179 | */
|
180 | export declare class WindowedList<T extends WindowedList.IModel = WindowedList.IModel> extends Widget {
|
181 | |
182 |
|
183 |
|
184 | static readonly DEFAULT_WIDGET_SIZE = 50;
|
185 | |
186 |
|
187 |
|
188 |
|
189 |
|
190 | constructor(options: WindowedList.IOptions<T>);
|
191 | /**
|
192 | * Whether the parent is hidden or not.
|
193 | *
|
194 | * This should be set externally if a container is hidden to
|
195 | * stop updating the widget size when hidden.
|
196 | */
|
197 | get isParentHidden(): boolean;
|
198 | set isParentHidden(v: boolean);
|
199 | /**
|
200 | * Widget layout
|
201 | */
|
202 | get layout(): WindowedLayout;
|
203 | /**
|
204 | * Viewport
|
205 | */
|
206 | get viewportNode(): HTMLDivElement;
|
207 | /**
|
208 | * Windowed list view model
|
209 | */
|
210 | protected get viewModel(): T;
|
211 | /**
|
212 | * Callback on event.
|
213 | *
|
214 | * @param event Event
|
215 | */
|
216 | handleEvent(event: Event): void;
|
217 | /**
|
218 | * Scroll to the specified offset `scrollTop`.
|
219 | *
|
220 | * @param scrollOffset Offset to scroll
|
221 | *
|
222 | * @deprecated since v4 This is an internal helper. Prefer calling `scrollToItem`.
|
223 | */
|
224 | scrollTo(scrollOffset: number): void;
|
225 | /**
|
226 | * Scroll to the specified item.
|
227 | *
|
228 | * By default, the list will scroll as little as possible to ensure the item is visible. You can control the alignment of the item though by specifying a second alignment parameter. Acceptable values are:
|
229 | *
|
230 | * auto (default) - Scroll as little as possible to ensure the item is visible. (If the item is already visible, it won't scroll at all.)
|
231 | * smart - If the item is already visible (including the margin), don't scroll at all. If it is less than one viewport away, scroll so that it becomes visible (including the margin). If it is more than one viewport away, scroll so that it is centered within the list.
|
232 | * center - Center align the item within the list.
|
233 | * end - Align the item to the end of the list
|
234 | * start - Align the item to the beginning of the list
|
235 | *
|
236 | * @param index Item index to scroll to
|
237 | * @param align Type of alignment
|
238 | * @param margin In 'smart' mode the viewport proportion to add
|
239 | */
|
240 | scrollToItem(index: number, align?: WindowedList.ScrollToAlign, margin?: number): Promise<void>;
|
241 | /**
|
242 | * A message handler invoked on an `'after-attach'` message.
|
243 | */
|
244 | protected onAfterAttach(msg: Message): void;
|
245 | /**
|
246 | * A message handler invoked on an `'before-detach'` message.
|
247 | */
|
248 | protected onBeforeDetach(msg: Message): void;
|
249 | /**
|
250 | * Callback on scroll event
|
251 | *
|
252 | * @param event Scroll event
|
253 | */
|
254 | protected onScroll(event: Event): void;
|
255 | /**
|
256 | * A message handler invoked on an `'resize-request'` message.
|
257 | */
|
258 | protected onResize(msg: Widget.ResizeMessage): void;
|
259 | /**
|
260 | * Callback on view model change
|
261 | *
|
262 | * @param model Windowed list model
|
263 | * @param changes Change
|
264 | */
|
265 | protected onStateChanged(model: WindowedList.IModel, changes: IChangedArgs<number | boolean, number | boolean, string>): void;
|
266 | /**
|
267 | * A message handler invoked on an `'update-request'` message.
|
268 | *
|
269 | * #### Notes
|
270 | * The default implementation of this handler is a no-op.
|
271 | */
|
272 | protected onUpdateRequest(msg: Message): void;
|
273 | private _addListeners;
|
274 | private _applyNoWindowingStyles;
|
275 | private _removeListeners;
|
276 | private _update;
|
277 | private _onWidgetResize;
|
278 | private _resetScrollToItem;
|
279 | protected _viewModel: T;
|
280 | private _innerElement;
|
281 | private _isParentHidden;
|
282 | private _isScrolling;
|
283 | private _needsUpdate;
|
284 | private _windowElement;
|
285 | private _resetScrollToItemTimeout;
|
286 | private _resizeObserver;
|
287 | private _scrollRepaint;
|
288 | private _scrollToItem;
|
289 | private _scrollUpdateWasRequested;
|
290 | }
|
291 | /**
|
292 | * Customized layout for windowed list container.
|
293 | */
|
294 | export declare class WindowedLayout extends PanelLayout {
|
295 | |
296 |
|
297 |
|
298 | constructor();
|
299 | /**
|
300 | * Specialized parent type definition
|
301 | */
|
302 | get parent(): WindowedList | null;
|
303 | set parent(value: WindowedList | null);
|
304 | /**
|
305 | * Attach a widget to the parent's DOM node.
|
306 | *
|
307 | * @param index - The current index of the widget in the layout.
|
308 | *
|
309 | * @param widget - The widget to attach to the parent.
|
310 | *
|
311 | * #### Notes
|
312 | * This method is called automatically by the panel layout at the
|
313 | * appropriate time. It should not be called directly by user code.
|
314 | *
|
315 | * The default implementation adds the widgets's node to the parent's
|
316 | * node at the proper location, and sends the appropriate attach
|
317 | * messages to the widget if the parent is attached to the DOM.
|
318 | *
|
319 | * Subclasses may reimplement this method to control how the widget's
|
320 | * node is added to the parent's node.
|
321 | */
|
322 | protected attachWidget(index: number, widget: Widget): void;
|
323 | /**
|
324 | * Detach a widget from the parent's DOM node.
|
325 | *
|
326 | * @param index - The previous index of the widget in the layout.
|
327 | *
|
328 | * @param widget - The widget to detach from the parent.
|
329 | *
|
330 | * #### Notes
|
331 | * This method is called automatically by the panel layout at the
|
332 | * appropriate time. It should not be called directly by user code.
|
333 | *
|
334 | * The default implementation removes the widget's node from the
|
335 | * parent's node, and sends the appropriate detach messages to the
|
336 | * widget if the parent is attached to the DOM.
|
337 | *
|
338 | * Subclasses may reimplement this method to control how the widget's
|
339 | * node is removed from the parent's node.
|
340 | */
|
341 | protected detachWidget(index: number, widget: Widget): void;
|
342 | /**
|
343 | * Move a widget in the parent's DOM node.
|
344 | *
|
345 | * @param fromIndex - The previous index of the widget in the layout.
|
346 | *
|
347 | * @param toIndex - The current index of the widget in the layout.
|
348 | *
|
349 | * @param widget - The widget to move in the parent.
|
350 | *
|
351 | * #### Notes
|
352 | * This method is called automatically by the panel layout at the
|
353 | * appropriate time. It should not be called directly by user code.
|
354 | *
|
355 | * The default implementation moves the widget's node to the proper
|
356 | * location in the parent's node and sends the appropriate attach and
|
357 | * detach messages to the widget if the parent is attached to the DOM.
|
358 | *
|
359 | * Subclasses may reimplement this method to control how the widget's
|
360 | * node is moved in the parent's node.
|
361 | */
|
362 | protected moveWidget(fromIndex: number, toIndex: number, widget: Widget): void;
|
363 | /**
|
364 | * A message handler invoked on an `'update-request'` message.
|
365 | *
|
366 | * #### Notes
|
367 | * This is a reimplementation of the base class method,
|
368 | * and is a no-op.
|
369 | */
|
370 | protected onUpdateRequest(msg: Message): void;
|
371 | }
|
372 | /**
|
373 | * A namespace for windowed list
|
374 | */
|
375 | export declare namespace WindowedList {
|
376 | |
377 |
|
378 |
|
379 | interface IModel extends IDisposable {
|
380 | |
381 |
|
382 |
|
383 |
|
384 |
|
385 |
|
386 |
|
387 |
|
388 |
|
389 |
|
390 |
|
391 |
|
392 |
|
393 | estimateWidgetSize: (index: number) => number;
|
394 | |
395 |
|
396 |
|
397 |
|
398 |
|
399 | getEstimatedTotalSize(): number;
|
400 | |
401 |
|
402 |
|
403 |
|
404 |
|
405 |
|
406 |
|
407 |
|
408 |
|
409 |
|
410 |
|
411 |
|
412 |
|
413 |
|
414 |
|
415 |
|
416 | getOffsetForIndexAndAlignment(index: number, align?: ScrollToAlign, margin?: number): number;
|
417 | |
418 |
|
419 |
|
420 |
|
421 |
|
422 |
|
423 |
|
424 | getRangeToRender(): WindowIndex | null;
|
425 | |
426 |
|
427 |
|
428 |
|
429 |
|
430 |
|
431 |
|
432 |
|
433 | getSpan(start: number, stop: number): [number, number];
|
434 | |
435 |
|
436 |
|
437 | height: number;
|
438 | |
439 |
|
440 |
|
441 | itemsList: {
|
442 | length: number;
|
443 | changed: ISignal<any, IObservableList.IChangedArgs<any>>;
|
444 | } | null;
|
445 | |
446 |
|
447 |
|
448 |
|
449 | overscanCount: number;
|
450 | |
451 |
|
452 |
|
453 |
|
454 |
|
455 |
|
456 |
|
457 |
|
458 | resetAfterIndex(index: number): void;
|
459 | |
460 |
|
461 |
|
462 | scrollOffset: number;
|
463 | |
464 |
|
465 |
|
466 |
|
467 |
|
468 |
|
469 |
|
470 |
|
471 |
|
472 | setWidgetSize(sizes: {
|
473 | index: number;
|
474 | size: number;
|
475 | }[]): boolean;
|
476 | |
477 |
|
478 |
|
479 | readonly stateChanged: ISignal<IModel, IChangedArgs<any, any, 'count' | 'index' | 'list' | 'overscanCount' | 'windowingActive'>>;
|
480 | |
481 |
|
482 |
|
483 | widgetCount: number;
|
484 | |
485 |
|
486 |
|
487 | windowingActive: boolean;
|
488 | |
489 |
|
490 |
|
491 |
|
492 |
|
493 |
|
494 |
|
495 |
|
496 | widgetRenderer: (index: number) => Widget;
|
497 | }
|
498 | |
499 |
|
500 |
|
501 | interface IModelOptions {
|
502 | |
503 |
|
504 |
|
505 |
|
506 |
|
507 |
|
508 | count?: number;
|
509 | |
510 |
|
511 |
|
512 | itemsList?: IObservableList<any>;
|
513 | |
514 |
|
515 |
|
516 |
|
517 | overscanCount?: number;
|
518 | |
519 |
|
520 |
|
521 |
|
522 |
|
523 | windowingActive?: boolean;
|
524 | }
|
525 | |
526 |
|
527 |
|
528 | interface IOptions<T extends WindowedList.IModel = WindowedList.IModel> {
|
529 | |
530 |
|
531 |
|
532 | model: T;
|
533 | |
534 |
|
535 |
|
536 | layout?: WindowedLayout;
|
537 | }
|
538 | |
539 |
|
540 |
|
541 | type ItemMetadata = {
|
542 | |
543 |
|
544 |
|
545 | offset: number;
|
546 | |
547 |
|
548 |
|
549 | size: number;
|
550 | |
551 |
|
552 |
|
553 | measured?: boolean;
|
554 | };
|
555 | |
556 |
|
557 |
|
558 | type ScrollToAlign = 'auto' | 'smart' | 'center' | 'start' | 'end';
|
559 | |
560 |
|
561 |
|
562 | type WindowIndex = [number, number, number, number];
|
563 | }
|