用户界面助手#

JupyterLab 提供了一些助手,用于向用户显示或请求简单信息。这些助手可以加快开发速度,并确保一致的外观和感觉。

对话框#

通用对话框#

要显示通用对话框,请使用 showDialog 函数,该函数来自 @jupyterlab/apputils

可用的选项有

showDialog({
  title: 'Dialog title', // Can be text or a react element
  body: 'Dialog body', // Can be text, a widget or a react element
  host: document.body, // Parent element for rendering the dialog
  buttons: [ // List of buttons
   {
     label: 'my button', // Button label
     caption: 'my button title', // Button title
     className: 'my-button', // Additional button CSS class
     accept: true, // Whether this button will discard or accept the dialog
     displayType: 'default' // applies 'default' or 'warn' styles
   }
  ],
  checkbox: { // Optional checkbox in the dialog footer
    label: 'check me', // Checkbox label
    caption: 'check me I\'magic', // Checkbox title
    className: 'my-checkbox', // Additional checkbox CSS class
    checked: true, // Default checkbox state
  },
  defaultButton: 0, // Index of the default button
  focusNodeSelector: '.my-input', // Selector for focussing an input element when dialog opens
  hasClose: false, // Whether to display a close button or not
  renderer: undefined // To define customized dialog structure
})

注意

如果未指定任何选项,则对话框将仅包含确定取消按钮。

消息对话框#

apputils 包中提供了用于向用户显示消息的辅助函数。这些对话框返回一个Promise,当用户关闭对话框时解析。

有一个助手

  • showErrorMessage:显示错误消息对话框。

输入对话框#

用于向用户请求单个输入的辅助函数在 apputils 包中的 InputDialog 命名空间中可用。有四个助手

  • getBoolean:通过复选框请求布尔值。

  • getItem:从列表中请求一个项目;列表可能是可编辑的。

  • getNumber:请求一个数字;如果用户输入不是有效的数字,则返回 NaN。

  • getText:请求一个简短的文本。

  • getPassword:请求一个简短的密码。

所有对话框都是基于标准的 Dialog 构建的。因此,辅助函数都返回一个 Promise,该 PromiseDialog.IResult 对象中解析。

// Request a boolean
InputDialog.getBoolean({ title: 'Check or not?' }).then(value => {
  console.log('boolean ' + value.value);
});

// Request a choice from a list
InputDialog.getItem({
  title: 'Pick a choice',
  items: ['1', '2']
}).then(value => {
  console.log('item ' + value.value);
});

// Request a choice from a list or specify your own choice
InputDialog.getItem({
  title: 'Pick a choice or write your own',
  items: ['1', '2'],
  editable: true
}).then(value => {
  console.log('editable item ' + value.value);
});

// Request a number
InputDialog.getNumber({ title: 'How much?' }).then(value => {
  console.log('number ' + value.value);
});

// Request a text
InputDialog.getText({ title: 'Provide a text' }).then(value => {
  console.log('text ' + value.value);
});

// Request a text
InputDialog.getPassword({ title: 'Input password' }).then(value => {
  console.log('A password was input');
});

文件对话框#

filebrowser 包中的 FileDialog 命名空间下,提供了两个辅助函数,用于询问用户打开文件或文件夹。

以下是如何请求文件的示例。

const dialog = FileDialog.getOpenFiles({
  manager, // IDocumentManager
  filter: model => model.type == 'notebook' // optional (model: Contents.IModel) => boolean
});

const result = await dialog;

if(result.button.accept){
  let files = result.value;
}

以及用于请求文件夹的示例。

const dialog = FileDialog.getExistingDirectory({
  manager // IDocumentManager
});

const result = await dialog;

if(result.button.accept){
  let folders = result.value;
}

注意

文档管理器可以通过在插件中请求 IFileBrowserFactory 令牌来获取。可以通过 factory.defaultBrowser.model.manager 访问 manager

通知#

JupyterLab 具有一个通知管理器,可以添加、更新或关闭通知。此功能由 @jupyterlab/apputils 包提供。

警告

为了尊重用户的专注力,最好限制发送的通知数量。因此,默认情况下,通知不会显示给用户。但状态栏会指示有新通知到达。因此,用户可以单击指示器查看所有通知。

尝试为重复出现的通知添加一个名为“不再显示”的按钮,以允许用户快速过滤对他们重要的通知。

通知由以下元素描述

{
  /**
   * Notification message
   *
   * ### Notes
   * Message can only be plain text with a maximum length of 140 characters.
   */
  message: string;
  /**
   * Notification type
   */
  type?:  'info' | 'in-progress' | 'success' | 'warning' | 'error' | 'default';
  /**
   * Notification options
   */
  options?: {
    /**
     * Autoclosing behavior - false (not closing automatically)
     * or number (time in milliseconds before hiding the notification)
     *
     * Set to zero if you want the notification to be retained in the notification
     * center but not displayed as toast. This is the default behavior.
     */
    autoClose?: number | false;
    /**
     * List of associated actions
     */
    actions?: Array<IAction>;
    /**
     * Data associated with a notification
     */
    data?: T;
  };
}

在创建时,通知将收到一个唯一的标识符。

可以将操作链接到通知,但界面取决于通知的处理方式。

与通知交互有两种方式:通过 API 或通过命令。唯一的区别是,使用 API 时,与通知关联的操作可以具有任意回调。但使用命令调用创建通知时,只能将命令设置为操作。

使用 API#

要创建通知,您需要提供一条消息,并且可以使用以下辅助程序来自动设置类型(或使用 notify 手动设置类型)

/**
 * Helper function to emit an error notification.
 */
Notification.error(message: string, options?: IOptions): string;

/**
 * Helper function to emit an info notification.
 */
Notification.info(message: string, options?: IOptions): string;

/**
 * Helper function to emit a success notification.
 */
Notification.success(message: string, options?: IOptions): string;

/**
 * Helper function to emit a warning notification.
 */
Notification.warning(message: string, options?: IOptions): string;

/**
 * Helper function to emit a in-progress notification. Then
 * it will update it with a error or success notification
 * depending on the promise resolution.
 */
Notification.promise(
  promise: Promise,
  {
    pending: { message: string, options?: IOptions },
    /**
     * If not set `options.data` will be set to the promise result.
     */
    success: { message: (result, data) => string, options?: IOptions },
    /**
     * If not set `options.data` will be set to the promise rejection error.
     */
    error: { message: (reason, data) => string, options?: IOptions }
  }
): string;

/**
 * Helper function to emit a notification.
 */
Notification.emit(
  message: string,
  type: 'info' | 'in-progress' | 'success' | 'warning' | 'error' | 'default' = 'default',
  options?: IOptions
): string;

使用 API 时,操作由以下定义

{
  /**
   * The action label.
   *
   * This should be a short description.
   */
  label: string;
  /**
   * Callback function to trigger
   *
   * ### Notes
   * By default execution of the callback will close the toast
   * and dismiss the notification. You can prevent this by calling
   * `event.preventDefault()` in the callback.
   */
  callback: (event: MouseEvent) => void;
  /**
   * The action caption.
   *
   * This can be a longer description of the action.
   */
  caption?: string;
  /**
   * The action display type.
   *
   * This will be used to modify the action button style.
   */
  displayType?: 'default' | 'accent' | 'warn' | 'link';
}

您可以使用以下方法更新通知

Notification.update({
  id: string;
  message: string;
  type?:  'info' | 'in-progress' | 'success' | 'warning' | 'error' | 'default';
  autoClose?: number | false;
  actions?: Array<IAction>;
  data?: ReadonlyJsonValue;
}): boolean;

注意

更新后,通知将被移至通知堆栈的开头。

您可以使用以下方法关闭通知(如果您提供 id)或关闭所有通知

Notification.dismiss(id?: string): void;

注意

关闭通知会将其从通知列表中删除,而不会知道用户是否已看到它。因此,建议不要关闭通知。

使用命令#

有三个可用的命令。

'apputils:notify' 用于创建通知

commands.execute('apputils:notify', {
   message: string;
   type?: 'info' | 'in-progress' | 'success' | 'warning' | 'error' | 'default';
   options?: {
     autoClose?: number | false;
     actions?: Array<IAction>;
     data?: T;
   };
});

结果是通知的唯一标识符。

操作由以下定义

{
  /**
   * The action label.
   *
   * This should be a short description.
   */
  label: string;
  /**
   * Callback command id to trigger
   */
  commandId: string;
  /**
   * Command arguments
   */
  args?: ReadonlyJsonObject;
  /**
   * The action caption.
   *
   * This can be a longer description of the action.
   */
  caption?: string;
  /**
   * The action display type.
   *
   * This will be used to modify the action button style.
   */
  displayType?: 'default' | 'accent' | 'warn' | 'link';
}

'apputils:update-notification' 用于更新通知

commands.execute('apputils:update-notification', {
  id: string;
  message: string;
  type?: 'info' | 'in-progress' | 'success' | 'warning' | 'error' | 'default';
  autoClose?: number | false;
  actions?: Array<IAction>;
  data?: T;
});

结果是一个布尔值,指示更新是否成功。特别是,更新不存在的通知将失败。

'apputils:dismiss-notification' 用于关闭通知

commands.execute('apputils:dismiss-notification', {
  id: string;
});

注意

关闭通知会将其从通知列表中删除,而不会知道用户是否已看到它。因此,建议不要关闭通知。