npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@evolab/ui-components

v2.2.0

Published

JupyterLab - UI components written in React

Downloads

31

Readme

@evolab/ui-components

The @evolab/ui-components package provides UI elements that are widely used in JupyterLab core, and that can be reused in your own extensions.

For example, all of the icons in JupyterLab core can be reused via LabIcon. You can also use LabIcon to create your own custom icons that will be able to automatically change color to match the current JupyterLab theme.

LabIcon - set up and render icons

LabIcon is the icon class used by JupyterLab, and is part of the new icon system introduced in JupyterLab v2.0.

How JupyterLab handles icons

The @evolab/ui-components package provides icons to the rest of JupyterLab, in the form of a set of LabIcon instances (currently about 80). All of the icons in the core JupyterLab packages are rendered using one of these LabIcon instances.

Using the icons in your own code

You can use any of JupyterLab icons in your own code via an import statement. For example, to use jupyterIcon you would first do:

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

How to render an icon into a DOM node

Icons can be added as children to any div or span nodes using the icon.element(...) method (where icon is any instance of LabIcon). For example, to render the Jupyter icon you could do:

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

where elem is any HTMLElement with a div or span tag. As shown in the above example, the icon can be styled by passing CSS parameters into .element(...). Any valid CSS parameter can be used (one catch: snake case params do have to be converted to camel case: instead of foo-bar: '8px', you’d need to use fooBar: '8px'.

How to render an icon as a React component

Icons can also be rendered using React. The icon.react parameter holds a standard React component that will display the icon on render. Like any React component, icon.react can be used in various ways.

For example, here is how you would add the Jupyter icon to the render tree of another React component:

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>
  );
}

Alternatively, you can just render the icon directly into any existing DOM node elem by using the ReactDOM module:

ReactDOM.render(jupyterIcon.react, elem);

If do you use ReactDOM to render, and if the elem node is ever removed from the DOM, you’ll first need to clean it up:

ReactDOM.unmountComponentAtNode(elem);

This cleanup step is not a special property of LabIcon, but is instead needed for any React component that is rendered directly at the top level by ReactDOM: failure to call unmountComponentAtNode can result in a memory leak.

How to create your own custom LabIcon

You can create your own custom icon by constructing a new instance of LabIcon:

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

where name should be of the form “your-pkg:icon-name”, and svgstr is the raw contents of your icon’s svg file.

How to create a new LabIcon from an external svg file

Although you can copy-and-paste an svg directly into the LabIcon constructor, the best practice is to keep the svg for each of your icons in its own separate svg file. You will need to have an svg.d.ts file at the root of your project’s src directory:

// svg.d.ts

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

You can then import the contents of an svg file:

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

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

Sync icon color to JupyterLab theme

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 JuptyerLab 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.

Available icon classes

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: contrast to theme background

Most one-color icons in JupyterLab (including the sidebar and toolbar icons) are colored using the jp-icon3 class.

For light/dark themes, jp-icon0 corresponds to the darkest/lighest background color, while jp-icon1 is somewhat lighter/darker, and so forth.

jp-icon-accentX: match to theme background

For light/dark themes, jp-icon-accent0 corresponds to the lighest/darkest background color, while jp-icon-accent1 is somewhat darker/lighter, and so forth.

Adding classes to a one-color icon

For most simple, one-color icons, it is desirable for the icon's color to strongly constrast with that of the application's background. You can acheive this using one of the jp-iconX classes.

Example: check icon

svg source:

<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>

rendered icon:

Adding classes to a multi-colored icon

For more complex icons, each element that needs to match the background should be annotated with a jp-icon-accentX class, while each element that needs to contrast with the background should be annotated with a jp-iconX class.

Example: close-circle icon

svg source:

<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>

rendered icon:

Background

Icon handling in Jupyterlab

Pre JupyterLab 2.0, most icons were created using the icons-as-css-background pattern:

  • Set up the icon’s svg as a background-image in CSS:

    /* CSS */
    
    .jp-FooIcon {
      background-image: url('path-to-your/foo.svg');
    }
  • Add the icon to the DOM by constructing an otherwise empty DOM node with the appropriate class:

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

What you end up with is a single DOM node that has the “foo” icon as a background image.

Post JupyterLab 2.0, nearly all icons in core are now created using LabIcon and the icons-as-inline-svg pattern:

  • Construct a new instance of LabIcon from the icon’s name and svg:

    // typescript
    
    // svgstr is the raw contents of an icon's svg file
    export const fooIcon = new LabIcon({
      name: 'barpkg:foo',
      svgstr: '<svg>...</svg>'
    });
  • Add the icon to the DOM using the appropriate property of your LabIcon instance (either LabIcon.element() to directly create a DOM node, or LabIcon.react to get the icon as a react component):

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

What you end up with is a DOM node (by default a ‘div’) that has an inline svg node as a child.

background-image vs inline svg

The big limitation of the old icon-as-css-background pattern is that svg images rendered as background-image are invisible to CSS. On the other hand, an icon rendered as an inline svg node is fully exposed to the CSS. This allows us to dynamicly change icon styling as needed simply by modifying our CSS. Most importantly, this allows us to recolor icons according to Jupyterlab’s current theme.