浏览代码

build both ui-components README and dev docs from ui-components/docs

telamonian 5 年之前
父节点
当前提交
e9a4d66995

+ 2 - 2
.gitignore

@@ -10,14 +10,14 @@ dev_mode/stats.json
 
 docs/_build
 docs/api
-docs/source/_build
-docs/source/_markdown
+**/docs/source/_build
 
 examples/app/build
 examples/app/themes
 examples/app/schemas
 
 junit.xml
+
 jupyterlab/geckodriver
 jupyterlab/static
 jupyterlab/schemas

+ 1 - 22
docs/source/conf.py

@@ -17,8 +17,7 @@
 # add these directories to sys.path here. If the directory is relative to the
 # documentation root, use os.path.abspath to make it absolute, like shown here.
 #
-import os
-import shutil
+# import os
 # import sys
 # sys.path.insert(0, os.path.abspath('.'))
 
@@ -32,16 +31,6 @@ from recommonmark.transform import AutoStructify
 #
 # needs_sphinx = '1.0'
 
-# Path to a directory where markdown sources are kept
-md_dir = 'source/_markdown'
-
-# A list of paths to any markdown sources located above this docs dir.
-# Used to work around the fact that you generally can't link to files
-# outside of the docs build
-md_sources = [
-    '../packages/ui-components/markdown/labicon.md'
-]
-
 # Add any Sphinx extension module names here, as strings. They can be
 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
 # ones.
@@ -247,17 +236,7 @@ github_doc_root = 'https://github.com/jupyterlab/jupyterlab/tree/master/docs/'
 # markdown documents.
 linkcheck_anchors = False
 
-def copyMarkdown():
-    shutil.rmtree(md_dir, ignore_errors=True)
-    os.makedirs(md_dir)
-
-    for pth in md_sources:
-        shutil.copy(pth, md_dir)
-
 def setup(app):
-    # set up the markdown sources
-    copyMarkdown()
-
     app.add_config_value('recommonmark_config', {
         'url_resolver': lambda url: github_doc_root + url,
         'auto_toc_tree_section': 'Contents',

+ 207 - 6
docs/source/developer/ui_components.rst

@@ -4,16 +4,217 @@ 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, and that can be reused in your own extensions.
+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.
 
-.. toctree::
-   :maxdepth: 1
-   :caption: Explainer docs
+.. contents:: Explainer docs
+   :local:
+   :depth: 1
 
-   ../_markdown/labicon
+``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:
+
+-  Set up the icon’s svg as a ``background-image`` in CSS:
+
+   .. code:: 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:
+
+   .. code:: typescript
+
+      // 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 jlab-2.0, nearly all icons in core are now created using
+`LabIcon <https://github.com/jupyterlab/jupyterlab/blob/f0153e0258b32674c9aec106383ddf7b618cebab/packages/ui-components/src/icon/labicon.tsx>`__
+and the icons-as-inline-svg pattern:
+
+-  Construct a new instance of LabIcon from the icon’s name and svg:
+
+   .. code:: typescript
+
+      // 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):
+
+   .. code:: typescript
+
+      // 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.
+
+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:
+
+.. code:: typescript
+
+   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
+``LabIcon``). For example, to render the Jupyter icon you could do:
+
+.. code:: typescript
+
+   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:
+
+.. code:: jsx
+
+   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:
+
+.. code:: typescript
+
+   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:
+
+.. code:: typescript
+
+   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 <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``:
+
+.. code:: typescript
+
+   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:
+
+.. code:: typescript
+
+   // svg.d.ts
+
+   declare module '*.svg' {
+     const value: string;
+     export default value;
+   }
+
+You can then ``import`` the contents of an svg file:
+
+.. code:: typescript
+
+   import fooSvgstr from 'path-to-your/foo.svg';
+
+   export const fooIcon = new LabIcon({ name: 'barpkg:foo', svgstr: fooSvgstr });

+ 198 - 4
packages/ui-components/README.md

@@ -1,9 +1,203 @@
 # @jupyterlab/ui-components
 
-The @jupyterlab/ui-components package provides UI elements that are widely used in JupyterLab core, and that can be reused in your own extensions.
+The
+[@jupyterlab/ui-components](http://jupyterlab.github.io/jupyterlab/ui-components/index.html)
+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.
+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.
 
-## User guides
+# `LabIcon` - set up and render icons
 
-- [`LabIcon` - set up and render icons](markdown/labicon.md)
+`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:
+
+- Set up the icon’s svg as a `background-image` in CSS:
+
+  ```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
+  // 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 jlab-2.0, nearly all icons in core are now created using
+[LabIcon](https://github.com/jupyterlab/jupyterlab/blob/f0153e0258b32674c9aec106383ddf7b618cebab/packages/ui-components/src/icon/labicon.tsx)
+and the icons-as-inline-svg pattern:
+
+- Construct a new instance of LabIcon from the icon’s name and svg:
+
+  ```typescript
+  // 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
+  // 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.
+
+## 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:
+
+```typescript
+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 `LabIcon`).
+For example, to render the Jupyter icon you could do:
+
+```typescript
+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:
+
+```jsx
+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:
+
+```typescript
+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:
+
+```typescript
+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](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`:
+
+```typescript
+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:
+
+```typescript
+// svg.d.ts
+
+declare module '*.svg' {
+  const value: string;
+  export default value;
+}
+```
+
+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 });
+```

+ 34 - 0
packages/ui-components/docs/build.sh

@@ -0,0 +1,34 @@
+#!/usr/bin/env bash
+
+# get this script's parent dir
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
+
+# set some project dirs
+SOURCE=$DIR/source
+BUILD=$SOURCE/_build
+PKG_ROOT=$(realpath $DIR/..)
+MONOREPO_DEVDOC=$(realpath $PKG_ROOT/../../docs/source/developer)
+
+# echo "SOURCE=$SOURCE"
+# echo "BUILD=$BUILD"
+# echo "PKG_ROOT=$PKG_ROOT"
+# echo "MONOREPO_DEVDOC=$MONOREPO_DEVDOC"
+
+# make the docs build dir
+mkdir -p $BUILD
+
+# paths in rst include directives are resovled relative to pwd
+pushd $SOURCE > /dev/null
+
+# make a copy of labicon.rst with section levels shifted down
+pandoc $SOURCE/labicon.rst -f rst -t rst --wrap=preserve --shift-heading-level-by=1 -o $BUILD/labicon.rst
+
+# make the README.md at package root
+pandoc $SOURCE/README.rst -f rst -t gfm -o $PKG_ROOT/README.md    #--resource-path=$SOURCE
+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
+echo "built $MONOREPO_DEVDOC/ui_components.rst"
+
+popd > /dev/null

+ 6 - 0
packages/ui-components/docs/source/README.rst

@@ -0,0 +1,6 @@
+@jupyterlab/ui-components
+=========================
+
+.. include:: intro.rst
+
+.. include:: labicon.rst

+ 8 - 0
packages/ui-components/docs/source/intro.rst

@@ -0,0 +1,8 @@
+The `@jupyterlab/ui-components <http://jupyterlab.github.io/jupyterlab/ui-components/index.html>`__
+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.

+ 202 - 0
packages/ui-components/docs/source/labicon.rst

@@ -0,0 +1,202 @@
+``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:
+
+-  Set up the icon’s svg as a ``background-image`` in CSS:
+
+   .. code:: 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:
+
+   .. code:: typescript
+
+      // 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 jlab-2.0, nearly all icons in core are now created using
+`LabIcon <https://github.com/jupyterlab/jupyterlab/blob/f0153e0258b32674c9aec106383ddf7b618cebab/packages/ui-components/src/icon/labicon.tsx>`__
+and the icons-as-inline-svg pattern:
+
+-  Construct a new instance of LabIcon from the icon’s name and svg:
+
+   .. code:: typescript
+
+      // 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):
+
+   .. code:: typescript
+
+      // 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.
+
+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:
+
+.. code:: typescript
+
+   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
+``LabIcon``). For example, to render the Jupyter icon you could do:
+
+.. code:: typescript
+
+   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:
+
+.. code:: jsx
+
+     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:
+
+.. code:: typescript
+
+   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:
+
+.. code:: typescript
+
+   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 <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``:
+
+.. code:: typescript
+
+   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:
+
+.. code:: typescript
+
+   // svg.d.ts
+
+   declare module '*.svg' {
+     const value: string;
+     export default value;
+   }
+
+You can then ``import`` the contents of an svg file:
+
+.. code:: typescript
+
+   import fooSvgstr from 'path-to-your/foo.svg';
+
+   export const fooIcon = new LabIcon({ name: 'barpkg:foo', svgstr: fooSvgstr });

+ 12 - 0
packages/ui-components/docs/source/ui_components.rst

@@ -0,0 +1,12 @@
+.. _ui_components:
+
+Reusing JupyterLab UI
+=====================
+
+.. include:: intro.rst
+
+\.. contents:: Explainer docs
+   \:local:
+   \:depth: 1
+
+.. include:: _build/labicon.rst

+ 0 - 154
packages/ui-components/markdown/labicon.md

@@ -1,154 +0,0 @@
-# `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:
-
-- Set up the icon's svg as a `background-image` in CSS:
-
-  ```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
-  // 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 jlab-2.0, nearly all icons in core are now created using [LabIcon](https://github.com/jupyterlab/jupyterlab/blob/f0153e0258b32674c9aec106383ddf7b618cebab/packages/ui-components/src/icon/labicon.tsx) and the icons-as-inline-svg pattern:
-
-- Construct a new instance of LabIcon from the icon's name and svg:
-
-  ```typescript
-  // 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
-  // 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.
-
-## 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:
-
-```typescript
-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 `LabIcon`). For example, to render the Jupyter icon you could do:
-
-```typescript
-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:
-
-```jsx
-  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:
-
-```typescript
-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:
-
-```typescript
-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](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`:
-
-```typescript
-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:
-
-```typescript
-// svg.d.ts
-
-declare module '*.svg' {
-  const value: string;
-  export default value;
-}
-```
-
-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 });
-```

+ 1 - 0
packages/ui-components/package.json

@@ -30,6 +30,7 @@
     "clean": "rimraf lib",
     "cleansvg": "svgo --config svgo.yaml",
     "docs": "typedoc src",
+    "docs:init": "bash docs/build.sh",
     "prepublishOnly": "npm run build",
     "storybook": "start-storybook -p 9001 -c .storybook",
     "watch": "tsc -b --watch"