Skip to content

Commit

Permalink
added "Sync icon color to JupyterLab theme" section to LabIcon docs
Browse files Browse the repository at this point in the history
  • Loading branch information
telamonian committed Apr 25, 2020
1 parent e9a4d66 commit 0dce89c
Show file tree
Hide file tree
Showing 4 changed files with 371 additions and 15 deletions.
141 changes: 129 additions & 12 deletions docs/source/developer/ui_components.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.. _ui_components:

Reusing JupyterLab UI
---------------------
=====================

The `@jupyterlab/ui-components <http://jupyterlab.github.io/jupyterlab/ui-components/index.html>`__
package provides UI elements that are widely used in JupyterLab core,
Expand All @@ -17,16 +17,16 @@ current JupyterLab theme.
:depth: 1

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

Background
^^^^^^^^^^
~~~~~~~~~~

Icon handling in Jupyterlab
'''''''''''''''''''''''''''
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Pre jlab-2.0, most icons were created using the icons-as-css-background
pattern:
Expand Down Expand Up @@ -86,7 +86,7 @@ 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
Expand All @@ -96,15 +96,15 @@ simply by modifying our CSS. Most importantly, this allows us to recolor
icons according to Jupyterlab’s current theme.

How JupyterLab handles icons
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The @jupyterlab/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:
Expand All @@ -114,7 +114,7 @@ statement. For example, to use ``jupyterIcon`` you would first do:
import { jupyterIcon } from '@jupyterlab/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
Expand All @@ -136,7 +136,7 @@ parameters into ``.element(...)``. Any valid CSS parameter can be used
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.
Expand Down Expand Up @@ -179,7 +179,7 @@ can result in a `memory
leak <https://stackoverflow.com/a/48198011/425458>`__.

How to create your own custom ``LabIcon``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

You can create your own custom icon by constructing a new instance of
``LabIcon``:
Expand All @@ -195,7 +195,7 @@ 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
Expand All @@ -217,4 +217,121 @@ 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 });
export const fooIcon = new LabIcon({
name: 'barpkg:foo',
svgstr: fooSvgstr
});
Sync icon color to JupyterLab theme
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. raw:: html

<em>Example svgs with class annotation can be found in <a href="https://github.com/jupyterlab/jupyterlab/tree/f0153e0258b32674c9aec106383ddf7b618cebab/packages/ui-components/style/icons">ui-components/style/icons</a></em>

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

.. raw:: html

<em>Icon-related CSS classes are defined in <a href="https://github.com/jupyterlab/jupyterlab/blob/f0153e0258b32674c9aec106383ddf7b618cebab/packages/ui-components/style/icons.css">ui-components/style/icons.css</a></em>

|
| All colors shown are for the standard light/dark theme, mouse over for hex values.
``jp-iconX``: contrast to theme background
''''''''''''''''''''''''''''''''''''''''''

.. raw:: html

<ul>
<li>jp-icon0: <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#111"/><title>#111</title></svg> / <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#fff"/><title>#fff</title></svg></li>
<li>jp-icon1: <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#212121"/><title>#212121</title></svg> / <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#fff"/><title>#fff</title></svg></li>
<li>jp-icon2: <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#424242"/><title>#424242</title></svg> / <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#eee"/><title>#eee</title></svg></li>
<li>jp-icon3: <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#616161"/><title>#616161</title></svg> / <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#bdbdbd"/><title>#bdbdbd</title></svg></li>
<li>jp-icon4: <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#757575"/><title>#757575</title></svg> / <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#757575"/><title>#757575</title></svg></li>
</ul>

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

.. raw:: html

<ul>
<li>jp-icon-accent0: <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#fff"/><title>#fff</title></svg> / <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#111"/><title>#111</title></svg></li>
<li>jp-icon-accent1: <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#fff"/><title>#fff</title></svg> / <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#212121"/><title>#212121</title></svg></li>
<li>jp-icon-accent2: <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#eee"/><title>#eee</title></svg> / <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#424242"/><title>#424242</title></svg></li>
<li>jp-icon-accent3: <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#bdbdbd"/><title>#bdbdbd</title></svg> / <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#616161"/><title>#616161bdbdbd</title></svg></li>
<li>jp-icon-accent4: <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#757575"/><title>#757575</title></svg> / <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#757575"/><title>#757575</title></svg></li>
</ul>

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

.. code:: html

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

.. raw:: html

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

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

.. code:: html

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

.. raw:: html

<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>
124 changes: 123 additions & 1 deletion packages/ui-components/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,5 +199,127 @@ You can then `import` the contents of an svg file:
```typescript
import fooSvgstr from 'path-to-your/foo.svg';

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

## Sync icon color to JupyterLab theme

<em>Example svgs with class annotation can be found in <a href="https://github.com/jupyterlab/jupyterlab/tree/f0153e0258b32674c9aec106383ddf7b618cebab/packages/ui-components/style/icons">ui-components/style/icons</a></em>

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

<em>Icon-related CSS classes are defined in <a href="https://github.com/jupyterlab/jupyterlab/blob/f0153e0258b32674c9aec106383ddf7b618cebab/packages/ui-components/style/icons.css">ui-components/style/icons.css</a></em>

All colors shown are for the standard light/dark theme, mouse over for
hex values.

#### `jp-iconX`: contrast to theme background

<ul>
<li>jp-icon0: <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#111"/><title>#111</title></svg> / <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#fff"/><title>#fff</title></svg></li>
<li>jp-icon1: <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#212121"/><title>#212121</title></svg> / <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#fff"/><title>#fff</title></svg></li>
<li>jp-icon2: <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#424242"/><title>#424242</title></svg> / <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#eee"/><title>#eee</title></svg></li>
<li>jp-icon3: <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#616161"/><title>#616161</title></svg> / <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#bdbdbd"/><title>#bdbdbd</title></svg></li>
<li>jp-icon4: <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#757575"/><title>#757575</title></svg> / <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#757575"/><title>#757575</title></svg></li>
</ul>

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

<ul>
<li>jp-icon-accent0: <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#fff"/><title>#fff</title></svg> / <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#111"/><title>#111</title></svg></li>
<li>jp-icon-accent1: <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#fff"/><title>#fff</title></svg> / <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#212121"/><title>#212121</title></svg></li>
<li>jp-icon-accent2: <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#eee"/><title>#eee</title></svg> / <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#424242"/><title>#424242</title></svg></li>
<li>jp-icon-accent3: <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#bdbdbd"/><title>#bdbdbd</title></svg> / <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#616161"/><title>#616161bdbdbd</title></svg></li>
<li>jp-icon-accent4: <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#757575"/><title>#757575</title></svg> / <svg width="16" viewBox="0 0 1 1"><rect width="1" height="1" fill="#757575"/><title>#757575</title></svg></li>
</ul>

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

```html
<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:_

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

### 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:_

```html
<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:_

<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>
2 changes: 1 addition & 1 deletion packages/ui-components/docs/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pandoc $SOURCE/README.rst -f rst -t gfm -o $PKG_ROOT/README.md #--resource-pa
echo "built $PKG_ROOT/README.md"

# make the dev docs for the monorepo's docs
pandoc $SOURCE/ui_components.rst -f rst -t rst --wrap=preserve --shift-heading-level-by=1 -o $MONOREPO_DEVDOC/ui_components.rst
pandoc $SOURCE/ui_components.rst -f rst -t rst --wrap=preserve -o $MONOREPO_DEVDOC/ui_components.rst
echo "built $MONOREPO_DEVDOC/ui_components.rst"

popd > /dev/null
Loading

0 comments on commit 0dce89c

Please sign in to comment.