UNPKG

@jupyterlab/filebrowser

Version:
768 lines (767 loc) 25.3 kB
import { Time } from '@jupyterlab/coreutils'; import { DocumentRegistry } from '@jupyterlab/docregistry'; import { Contents } from '@jupyterlab/services'; import { IStateDB } from '@jupyterlab/statedb'; import { ITranslator, TranslationBundle } from '@jupyterlab/translation'; import { Drag } from '@lumino/dragdrop'; import { Message } from '@lumino/messaging'; import { ISignal } from '@lumino/signaling'; import { Widget } from '@lumino/widgets'; import { FilterFileBrowserModel } from './model'; /** * A widget which hosts a file list area. */ export declare class DirListing extends Widget { /** * Construct a new file browser directory listing widget. * * @param options The constructor options */ constructor(options: DirListing.IOptions); /** * Dispose of the resources held by the directory listing. */ dispose(): void; /** * Get the model used by the listing. */ get model(): FilterFileBrowserModel; /** * Get the dir listing header node. * * #### Notes * This is the node which holds the header cells. * * Modifying this node directly can lead to undefined behavior. */ get headerNode(): HTMLElement; /** * Get the dir listing content node. * * #### Notes * This is the node which holds the item nodes. * * Modifying this node directly can lead to undefined behavior. */ get contentNode(): HTMLElement; /** * The renderer instance used by the directory listing. */ get renderer(): DirListing.IRenderer; /** * The current sort state. */ get sortState(): DirListing.ISortState; /** * A signal fired when an item is opened. */ get onItemOpened(): ISignal<DirListing, Contents.IModel>; /** * Create an iterator over the listing's selected items. * * @returns A new iterator over the listing's selected items. */ selectedItems(): IterableIterator<Contents.IModel>; /** * Create an iterator over the listing's sorted items. * * @returns A new iterator over the listing's sorted items. */ sortedItems(): IterableIterator<Contents.IModel>; /** * Sort the items using a sort condition. */ sort(state: DirListing.ISortState): void; /** * Rename the first currently selected item. * * @returns A promise that resolves with the new name of the item. */ rename(): Promise<string>; /** * Cut the selected items. */ cut(): void; /** * Copy the selected items. */ copy(): void; /** * Paste the items from the clipboard. * * @returns A promise that resolves when the operation is complete. */ paste(): Promise<void>; /** * Delete the currently selected item(s). * * @returns A promise that resolves when the operation is complete. */ delete(): Promise<void>; /** * Duplicate the currently selected item(s). * * @returns A promise that resolves when the operation is complete. */ duplicate(): Promise<void>; /** * Download the currently selected item(s). */ download(): Promise<void>; /** * Restore the state of the file browser listing. * * @param id - The unique ID that is used to construct a state database key. * */ restore(id: string): Promise<void>; private _stateColumnsKey; /** * Shut down kernels on the applicable currently selected items. * * @returns A promise that resolves when the operation is complete. */ shutdownKernels(): Promise<void>; /** * Select next item. * * @param keepExisting - Whether to keep the current selection and add to it. */ selectNext(keepExisting?: boolean): void; /** * Select previous item. * * @param keepExisting - Whether to keep the current selection and add to it. */ selectPrevious(keepExisting?: boolean): void; /** * Select the first item that starts with prefix being typed. */ selectByPrefix(): void; /** * Get whether an item is selected by name. * * @param name - The name of of the item. * * @returns Whether the item is selected. */ isSelected(name: string): boolean; /** * Find a model given a click. * * @param event - The mouse event. * * @returns The model for the selected file. */ modelForClick(event: MouseEvent): Contents.IModel | undefined; /** * Clear the selected items. */ clearSelectedItems(): void; /** * Select an item by name. * * @param name - The name of the item to select. * @param focus - Whether to move focus to the selected item. * * @returns A promise that resolves when the name is selected. */ selectItemByName(name: string, focus?: boolean): Promise<void>; /** * Select an item by name. * * @param name - The name of the item to select. * @param focus - Whether to move focus to the selected item. * @param force - Whether to proceed with selection even if the file was already selected. * * @returns A promise that resolves when the name is selected. */ private _selectItemByName; /** * Handle the DOM events for the directory listing. * * @param event - The DOM event sent to the widget. * * #### Notes * This method implements the DOM `EventListener` interface and is * called in response to events on the panel's DOM node. It should * not be called directly by user code. */ handleEvent(event: Event): void; /** * A message handler invoked on an `'after-attach'` message. */ protected onAfterAttach(msg: Message): void; /** * A message handler invoked on a `'before-detach'` message. */ protected onBeforeDetach(msg: Message): void; /** * A message handler invoked on an `'after-show'` message. */ protected onAfterShow(msg: Message): void; private _onContentResize; private _computeContentWidth; /** * Update the modified column's size */ private _updateModifiedSize; /** * Rerender item nodes' modified dates, if the modified style has changed. */ private _updateModifiedStyleAndSize; /** * Update only the modified dates. */ protected updateModified(items: Contents.IModel[], nodes: HTMLElement[]): void; protected updateNodes(items: Contents.IModel[], nodes: HTMLElement[], sizeOnly?: boolean): void; /** * A handler invoked on an `'update-request'` message. */ protected onUpdateRequest(msg: Message): void; onResize(msg: Widget.ResizeMessage): void; setColumnVisibility(name: DirListing.ToggleableColumn, visible: boolean): void; private _updateColumnSizes; private get _visibleColumns(); private _setColumnSize; /** * Update the setting to sort notebooks above files. * This sorts the items again if the internal value is modified. */ setNotebooksFirstSorting(isEnabled: boolean): void; /** * Update the setting to allow single click navigation. * This enables opening files/directories with a single click. */ setAllowSingleClickNavigation(isEnabled: boolean): void; /** * Would this click (or other event type) hit the checkbox by default? */ protected isWithinCheckboxHitArea(event: Event): boolean; /** * Handle the `'click'` event for the widget. */ private _evtClick; /** * Handle the `'scroll'` event for the widget. */ private _evtScroll; /** * Handle the `'mousedown'` event for the widget. */ private _evtMousedown; /** * Handle the `'mouseup'` event for the widget. */ private _evtMouseup; /** * Handle the `'mousemove'` event for the widget. */ private _evtMousemove; /** * Handle the opening of an item. */ protected handleOpen(item: Contents.IModel): void; /** * Calculate the next focus index, given the current focus index and a * direction, keeping within the bounds of the directory listing. * * @param index Current focus index * @param direction -1 (up) or 1 (down) * @returns The next focus index, which could be the same as the current focus * index if at the boundary. */ private _getNextFocusIndex; /** * Handle the up or down arrow key. * * @param event The keyboard event * @param direction -1 (up) or 1 (down) */ private _handleArrowY; /** * cd .. * * Go up one level in the directory tree. */ goUp(): Promise<void>; /** * Handle the `'keydown'` event for the widget. */ protected evtKeydown(event: KeyboardEvent): void; /** * Handle the `'dblclick'` event for the widget. */ protected evtDblClick(event: MouseEvent): void; /** * Handle the `drop` event for the widget. */ protected evtNativeDrop(event: DragEvent): void; /** * Signal emitted on when all files were uploaded after native drag. */ protected get allUploaded(): ISignal<DirListing, void>; /** * Handle the `'lm-dragenter'` event for the widget. */ protected evtDragEnter(event: Drag.Event): void; /** * Handle the `'lm-dragleave'` event for the widget. */ protected evtDragLeave(event: Drag.Event): void; /** * Handle the `'lm-dragover'` event for the widget. */ protected evtDragOver(event: Drag.Event): void; /** * Handle the `'lm-drop'` event for the widget. */ protected evtDrop(event: Drag.Event): void; /** * Start a drag event. */ private _startDrag; /** * Handle selection on a file node. */ protected handleFileSelect(event: MouseEvent): void; /** * (Re-)focus an item in the directory listing. * * @param index The index of the item node to focus */ private _focusItem; /** * Are all of the items between two provided indices selected? * * The items at the indices are not considered. * * @param j Index of one item. * @param k Index of another item. Note: may be less or greater than first * index. * @returns True if and only if all items between the j and k are selected. * Returns undefined if j and k are the same. */ private _allSelectedBetween; /** * Handle a multiple select on a file item node. */ private _handleMultiSelect; /** * Copy the selected items, and optionally cut as well. */ private _copy; /** * Delete the files with the given paths. */ private _delete; /** * Allow the user to rename item on a given row. */ private _doRename; /** * Select a given item. */ private _selectItem; /** * Handle the `refreshed` signal from the model. */ private _onModelRefreshed; /** * Handle a `pathChanged` signal from the model. */ private _onPathChanged; /** * Handle a `fileChanged` signal from the model. */ private _onFileChanged; /** * Handle an `activateRequested` signal from the manager. */ private _onActivateRequested; protected translator: ITranslator; protected _model: FilterFileBrowserModel; private _trans; private _editNode; private _items; private _sortedItems; private _sortState; private _handleOpenFile; private _onItemOpened; private _drag; private _dragData; private _resizeData; private _selectTimer; private _isCut; private _prevPath; private _clipboard; private _manager; private _softSelection; protected selection: { [key: string]: boolean; }; private _renderer; private _searchPrefix; private _searchPrefixTimer; private _inRename; private _isDirty; private _hiddenColumns; private _columnSizes; private _sortNotebooksFirst; private _allowSingleClick; private _focusIndex; private _modifiedWidth; private _modifiedStyle; private _allUploaded; private _width; private _state; private _contentScrollbarWidth; private _contentSizeObserver; private _paddingWidth; private _handleWidth; private _lastRenderedState; } /** * The namespace for the `DirListing` class statics. */ export declare namespace DirListing { /** * An options object for initializing a file browser directory listing. */ export interface IOptions { /** * A file browser model instance. */ model: FilterFileBrowserModel; /** * A renderer for file items. * * The default is a shared `Renderer` instance. */ renderer?: IRenderer; /** * A language translator. */ translator?: ITranslator; /** * An optional state database. If provided, the widget will restore * the columns sizes */ state?: IStateDB; /** * Callback overriding action performed when user asks to open a file. * The default is to open the file in the main area if it is not open already, or to reveal it otherwise. */ handleOpenFile?: (path: string) => void; } /** * A sort state. */ export interface ISortState { /** * The direction of sort. */ direction: 'ascending' | 'descending'; /** * The sort key. */ key: SortableColumn; } /** * Toggleable columns. */ export type ToggleableColumn = 'last_modified' | 'is_selected' | 'file_size'; /** * Resizable columns. */ export type ResizableColumn = 'name' | 'last_modified' | 'file_size'; /** * Sortable columns. */ export type SortableColumn = 'name' | 'last_modified' | 'file_size'; /** * A file contents model thunk. * * Note: The content of the model will be empty. * To get the contents, call and await the `withContent` * method. */ export interface IContentsThunk { /** * The contents model. */ model: Contents.IModel; /** * Fetches the model with contents. */ withContent: () => Promise<Contents.IModel>; } /** * The render interface for file browser listing options. */ export interface IRenderer { /** * Create the DOM node for a dir listing. */ createNode(): HTMLElement; /** * Populate and empty header node for a dir listing. * * @param node - The header node to populate. */ populateHeaderNode(node: HTMLElement, translator?: ITranslator, hiddenColumns?: Set<DirListing.ToggleableColumn>, columnsSizes?: Record<IColumn['id'], number | null>): void; /** * Handle a header click. * * @param node - A node populated by [[populateHeaderNode]]. * * @param event - A click event on the node. * * @returns The sort state of the header after the click event. */ handleHeaderClick(node: HTMLElement, event: MouseEvent): ISortState | null; /** * Create a new item node for a dir listing. * * @returns A new DOM node to use as a content item. */ createItemNode(hiddenColumns?: Set<DirListing.ToggleableColumn>, columnsSizes?: Record<IColumn['id'], number | null>): HTMLElement; /** * Update an item's last modified date. * * @param modified - Element containing the file's last modified date. * * @param modifiedDate - String representation of the last modified date. * * @param modifiedStyle - The date style for the modified column: narrow, short, or long */ updateItemModified?(modified: HTMLElement, modifiedDate: string, modifiedStyle: Time.HumanStyle): void; /** * Update an item node to reflect the current state of a model. * * @param node - A node created by [[createItemNode]]. * * @param model - The model object to use for the item state. * * @param modifiedStyle - The date style for the modified column: narrow, short, or long * * @param fileType - The file type of the item, if applicable. */ updateItemNode(node: HTMLElement, model: Contents.IModel, fileType?: DocumentRegistry.IFileType, translator?: ITranslator, hiddenColumns?: Set<DirListing.ToggleableColumn>, selected?: boolean, modifiedStyle?: Time.HumanStyle, columnsSizes?: Record<IColumn['id'], number | null>): void; /** * Update size of item nodes, assuming that model has not changed. */ updateItemSize?(node: HTMLElement, model: Contents.IModel, modifiedStyle?: Time.HumanStyle, columnsSizes?: Record<IColumn['id'], number | null>): void; /** * Get the node containing the file name. * * @param node - A node created by [[createItemNode]]. * * @returns The node containing the file name. */ getNameNode(node: HTMLElement): HTMLElement; /** * Get the checkbox input element node. * * Downstream interface implementations,such as jupyterlab-unfold, that * don't support checkboxes should simply always return null for this * function. * * @param node A node created by [[createItemNode]] or * [[createHeaderItemNode]] * * @returns The checkbox node. */ getCheckboxNode: (node: HTMLElement) => HTMLInputElement | null; /** * Create an appropriate drag image for an item. * * @param node - A node created by [[createItemNode]]. * * @param count - The number of items being dragged. * * @param fileType - The file type of the item, if applicable. * * @returns An element to use as the drag image. */ createDragImage(node: HTMLElement, count: number, trans: TranslationBundle, fileType?: DocumentRegistry.IFileType): HTMLElement; } interface IBaseColumn { /** * Name of the header class, must be unique among other columns. */ className: string; /** * Name of the item class, must be unique among other columns. */ itemClassName: string; /** * Minimum size the column should occupy. */ minWidth: number; /** * Unitless number representing the proportion by which the column * should grow when the listing is resized. */ grow: number; } interface IFixedColumn extends IBaseColumn { id: 'is_selected'; resizable: false; sortable: false; grow: 0; } /** * Sortable column. */ export interface ISortableColumn extends IBaseColumn { id: SortableColumn; sortable: true; caretSide: 'left' | 'right'; } /** * Resizable column. */ export interface IResizableColumn extends IBaseColumn { id: ResizableColumn; resizable: true; } /** * Columns types supported by DirListing. */ export type IColumn = IFixedColumn | ISortableColumn | IResizableColumn | (ISortableColumn & IResizableColumn); /** * Column definitions. */ export const columns: IColumn[]; /** * The default implementation of an `IRenderer`. */ export class Renderer implements IRenderer { /** * Create the DOM node for a dir listing. */ createNode(): HTMLElement; /** * Populate and empty header node for a dir listing. * * @param node - The header node to populate. */ populateHeaderNode(node: HTMLElement, translator?: ITranslator, hiddenColumns?: Set<DirListing.ToggleableColumn>, columnsSizes?: Record<DirListing.IColumn['id'], number | null>): void; /** * Handle a header click. * * @param node - A node populated by [[populateHeaderNode]]. * * @param event - A click event on the node. * * @returns The sort state of the header after the click event. */ handleHeaderClick(node: HTMLElement, event: MouseEvent): ISortState | null; /** * Create a new item node for a dir listing. * * @returns A new DOM node to use as a content item. */ createItemNode(hiddenColumns?: Set<DirListing.ToggleableColumn>, columnsSizes?: Record<DirListing.IColumn['id'], number | null>): HTMLElement; /** * Creates a node containing a checkbox. * * We wrap the checkbox in a label element in order to increase its hit * area. This is because the padding of the checkbox itself cannot be * increased via CSS, as the CSS/form compatibility table at the following * url from MDN shows: * https://developer.mozilla.org/en-US/docs/Learn/Forms/Property_compatibility_table_for_form_controls#check_boxes_and_radio_buttons * * @param [options] * @params options.alwaysVisible Should the checkbox be visible even when * not hovered? * @returns A new DOM node that contains a checkbox. */ createCheckboxWrapperNode(options?: { alwaysVisible: boolean; headerNode?: boolean; }): HTMLElement; /** * Update an item's last modified date. * * @param modified - Element containing the file's last modified date. * * @param modifiedDate - String representation of the last modified date. * * @param modifiedStyle - The date style for the modified column: narrow, short, or long */ updateItemModified(modified: HTMLElement, modifiedDate: string, modifiedStyle: Time.HumanStyle): void; /** * Update an item node to reflect the current state of a model. * * @param node - A node created by [[createItemNode]]. * * @param model - The model object to use for the item state. * * @param fileType - The file type of the item, if applicable. * */ updateItemNode(node: HTMLElement, model: Contents.IModel, fileType?: DocumentRegistry.IFileType, translator?: ITranslator, hiddenColumns?: Set<DirListing.ToggleableColumn>, selected?: boolean, modifiedStyle?: Time.HumanStyle, columnsSizes?: Record<DirListing.IColumn['id'], number | null>): void; /** * Update size of item nodes, assuming that model has not changed. */ updateItemSize(node: HTMLElement, model: Contents.IModel, modifiedStyle?: Time.HumanStyle, columnsSizes?: Record<DirListing.IColumn['id'], number | null>): void; /** * Get the node containing the file name. * * @param node - A node created by [[createItemNode]]. * * @returns The node containing the file name. */ getNameNode(node: HTMLElement): HTMLElement; /** * Get the checkbox input element node. * * @param node A node created by [[createItemNode]] or * [[createHeaderItemNode]] * * @returns The checkbox node. */ getCheckboxNode(node: HTMLElement): HTMLInputElement | null; /** * Create a drag image for an item. * * @param node - A node created by [[createItemNode]]. * * @param count - The number of items being dragged. * * @param fileType - The file type of the item, if applicable. * * @returns An element to use as the drag image. */ createDragImage(node: HTMLElement, count: number, trans: TranslationBundle, fileType?: DocumentRegistry.IFileType): HTMLElement; /** * Factories for individual parts of the item. */ protected itemFactories: { name: () => HTMLSpanElement; last_modified: () => HTMLSpanElement; file_size: () => HTMLSpanElement; is_selected: () => HTMLElement; }; /** * Create a node for a header item. */ protected createHeaderItemNode(label: string): HTMLElement; /** * Create a node for a header item with multiple sizes. */ private _createHeaderItemNodeWithSizes; /** * Register of most recent arguments for last modified column update. */ private _modifiedColumnLastUpdate; private _lastRenderedState; } /** * The default `IRenderer` instance. */ export const defaultRenderer: Renderer; export {}; }