重用JupyterLab用户界面#

@jupyterlab/ui-components 包提供了在 JupyterLab 核心中广泛使用的 UI 元素,这些元素可以在您自己的扩展中重复使用。

例如,JupyterLab核心中的所有图标都可以通过LabIcon重新使用。你也可以使用LabIcon来创建你自己的自定义图标,这些图标将能够自动改变颜色以匹配当前的JupyterLab主题。

LabIcon - 设置和渲染图标#

LabIcon 是 JupyterLab 使用的图标类,是 JupyterLab v2.0 中引入的新图标系统的一部分。

JupyterLab如何处理图标#

@jupyterlab/ui-components 包为 JupyterLab 的其他部分提供图标,这些图标以一组 LabIcon 实例的形式存在(目前大约有 80 个)。核心 JupyterLab 包中的所有图标都是使用这些 LabIcon 实例之一来渲染的。

在您自己的代码中使用图标#

你可以通过import语句在你自己的代码中使用任何JupyterLab图标。例如,要使用jupyterIcon,你首先需要这样做:

import { jupyterIcon } from '@jupyterlab/ui-components';

如何将图标渲染到DOM节点#

图标可以作为子元素添加到任何divspan节点中,使用icon.element(...)方法(其中iconLabIcon的任何实例)。例如,要渲染Jupyter图标,你可以这样做:

jupyterIcon.element({
  container: elem,
  height: '16px',
  width: '16px',
  marginLeft: '2px'
});

其中 elem 是任何带有 divspan 标签的 HTMLElement。如 上例所示,可以通过将 CSS 参数传递到 .element(...) 中来设置图标的样式。可以使用任何有效的 CSS 参数 (一个注意事项:蛇形命名法的参数必须转换为驼峰命名法: 而不是 foo-bar: '8px',你需要使用 fooBar: '8px'

如何将图标渲染为React组件#

图标也可以使用React来渲染。icon.react参数 持有一个标准的React组件,该组件将在渲染时显示图标。 像任何React组件一样,icon.react可以以多种方式使用。

例如,以下是如何将 Jupyter 图标添加到另一个 React 组件的渲染树中:

public render() {
  return (
    <div className="outer">
      <div className="inner">
        <jupyterIcon.react tag="span" right="7px" top="5px" />
        "and here's a text node"
      </div>
    </div>
  );
}

或者,你可以直接使用ReactDOM模块将图标渲染到任何现有的DOM节点elem中:

ReactDOM.render(jupyterIcon.react, elem);

如果你使用 ReactDOM 进行渲染,并且如果 elem 节点从 DOM 中被移除,你需要首先清理它:

ReactDOM.unmountComponentAtNode(elem);

这个清理步骤并不是LabIcon的特殊属性,而是任何由ReactDOM直接渲染在顶层的React组件所需要的:如果不调用unmountComponentAtNode可能会导致内存泄漏。

如何创建您自己的自定义LabIcon#

你可以通过构建一个新的LabIcon实例来创建你自己的自定义图标:

export const fooIcon = new LabIcon({
  name: 'barpkg:foo',
  svgstr: '<svg>...</svg>'
});

其中 name 应为“your-pkg:icon-name”的形式,而 svgstr 是您图标svg文件的原始内容。

如何从外部svg文件创建新的LabIcon#

虽然你可以直接将svg复制粘贴到LabIcon构造函数中,但最佳实践是将每个图标的svg保存在其单独的svg文件中。你需要在项目的src文件夹的根目录下有一个svg.d.ts文件:

// svg.d.ts

declare module '*.svg' {
  const value: string;
  export default value;
}

然后你可以import一个svg文件的内容:

import fooSvgstr from 'path-to-your/foo.svg';

export const fooIcon = new LabIcon({
  name: 'barpkg:foo',
  svgstr: fooSvgstr
});

将图标颜色同步到JupyterLab主题#

Example svgs with class annotation can be found in ui-components/style/icons

You can ensure that the colors of your custom LabIcon sync up to the colors of the current JupyterLab theme by adding appropriate class annotations to each colored element of your icon’s svg.

In other words, each element of your svg that a fill="..." or a stroke="..." property should also have a class="jp-icon<whatever>" property.

可用的图标类#

Icon-related CSS classes are defined in ui-components/style/icons.css

All colors shown are for the standard light/dark theme, mouse over for hex values.
jp-iconX: 与主题背景的对比#
  • jp-icon0: #111 / #fff
  • jp-icon1: #212121 / #fff
  • jp-icon2: #424242 / #eee
  • jp-icon3: #616161 / #bdbdbd
  • jp-icon4: #757575 / #757575

JupyterLab 中的大多数单色图标(包括侧边栏和工具栏图标)都是使用 jp-icon3 类进行着色的。

对于浅色/深色主题,jp-icon0 对应于最暗/最亮的背景颜色,而 jp-icon1 则稍微亮一些/暗一些,依此类推。

jp-icon-accentX: 匹配主题背景#
  • jp-icon-accent0: #fff / #111
  • jp-icon-accent1: #fff / #212121
  • jp-icon-accent2: #eee / #424242
  • jp-icon-accent3: #bdbdbd / #616161
  • jp-icon-accent4: #757575 / #757575

对于浅色/深色主题,jp-icon-accent0 对应于最浅/最深的背景颜色,而 jp-icon-accent1 则稍微更深/更浅,依此类推。

为单色图标添加类#

对于大多数简单的单色图标,希望图标的颜色与应用程序背景的颜色形成强烈对比。您可以使用jp-iconX类之一来实现这一点。

示例:检查图标

svg 来源:

<svg xmlns="http://www.w3.org/2000/svg" width="100" viewBox="0 0 24 24">
  <path class="jp-icon3" fill="#616161" d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/>
</svg>

渲染的图标:

向多色图标添加类#

对于更复杂的图标,每个需要与背景匹配的元素应使用jp-icon-accentX类进行注释,而每个需要与背景形成对比的元素应使用jp-iconX类进行注释。

示例:关闭圆圈图标

svg 来源:

<svg xmlns="http://www.w3.org/2000/svg" width="100" viewBox="0 0 24 24">
  <circle class="jp-icon3" fill="#616161" cx="12" cy="12" r="11"/>
  <rect class="jp-icon-accent0" fill="#fff" height="18" width="2" x="11" y="3" transform="rotate(315, 12, 12)"/>
  <rect class="jp-icon-accent0" fill="#fff" height="18" width="2" x="11" y="3" transform="rotate(45, 12, 12)"/>
</svg>

渲染的图标:

背景#

Jupyterlab中的图标处理#

在 JupyterLab 2.0 之前,大多数图标都是使用图标作为 CSS 背景的模式创建的:

  • 将图标的svg设置为CSS中的background-image

    /* CSS */
    
    .jp-FooIcon {
      background-image: url('path-to-your/foo.svg');
    }
    
  • 通过构建一个具有适当类的空DOM节点将图标添加到DOM中:

    // typescript
    
    const e = document.createElement('div');
    e.className = 'jp-FooIcon';
    document.body.append(e);
    

最终你会得到一个单一的DOM节点,该节点以“foo”图标作为背景图像。

在JupyterLab 2.0之后,核心中的几乎所有图标现在都是使用 LabIcon 和图标作为内联SVG的模式创建的:

  • 从图标的名称和svg构造一个新的LabIcon实例:

    // typescript
    
    // svgstr是图标svg文件的原始内容
    export const fooIcon = new LabIcon({
      name: 'barpkg:foo',
      svgstr: '...'
    });
    
  • 使用LabIcon实例的适当属性将图标添加到DOM中(可以使用LabIcon.element()直接创建DOM节点,或者使用LabIcon.react将图标作为React组件获取):

    // typescript
    
    const e = fooIcon.element();
    document.body.append(e);
    

最终得到的是一个DOM节点(默认是一个‘div’),它有一个内联的svg节点作为子节点。

background-image 对比 内联SVG#

旧图标作为CSS背景模式的重大限制是,作为background-image渲染的svg图像对CSS是不可见的。另一方面,作为内联svg节点渲染的图标完全暴露于CSS。这使我们能够根据需要简单地通过修改CSS来动态更改图标样式。最重要的是,这使我们能够根据Jupyterlab的当前主题重新着色图标。