UNPKG

11.9 kBMarkdownView Raw
1<!--
2THIS FILE IS AUTOGENERATED, DO NOT EDIT
3
4Instead, make changes to docs sources in `packages/ui-components/docs`,
5then run "jlpm docs:init" to refresh the built docs
6-->
7
8# @jupyterlab/ui-components
9
10The
11[@jupyterlab/ui-components](https://jupyterlab.github.io/jupyterlab/modules/_ui_components_src_index_.html)
12package provides UI elements that are widely used in JupyterLab core,
13and that can be reused in your own extensions.
14
15For example, all of the icons in JupyterLab core can be reused via
16`LabIcon`. You can also use `LabIcon` to create your own custom icons
17that will be able to automatically change color to match the current
18JupyterLab theme.
19
20# `LabIcon` - set up and render icons
21
22`LabIcon` is the icon class used by JupyterLab, and is part of the new
23icon system introduced in JupyterLab v2.0.
24
25## How JupyterLab handles icons
26
27The @jupyterlab/ui-components package provides icons to the rest of
28JupyterLab, in the form of a set of `LabIcon` instances (currently about
2980). All of the icons in the core JupyterLab packages are rendered using
30one of these `LabIcon` instances.
31
32## Using the icons in your own code
33
34You can use any of JupyterLab icons in your own code via an `import`
35statement. For example, to use `jupyterIcon` you would first do:
36
37```typescript
38import { jupyterIcon } from '@jupyterlab/ui-components';
39```
40
41## How to render an icon into a DOM node
42
43Icons can be added as children to any `div` or `span` nodes using the
44`icon.element(...)` method (where `icon` is any instance of `LabIcon`).
45For example, to render the Jupyter icon you could do:
46
47```typescript
48jupyterIcon.element({
49 container: elem,
50 height: '16px',
51 width: '16px',
52 marginLeft: '2px'
53});
54```
55
56where `elem` is any `HTMLElement` with a `div` or `span` tag. As shown
57in the above example, the icon can be styled by passing CSS parameters
58into `.element(...)`. Any valid CSS parameter can be used (one catch:
59snake case params do have to be converted to camel case: instead of
60`foo-bar: '8px'`, you’d need to use `fooBar: '8px'`.
61
62## How to render an icon as a React component
63
64Icons can also be rendered using React. The `icon.react` parameter holds
65a standard React component that will display the icon on render. Like
66any React component, `icon.react` can be used in various ways.
67
68For example, here is how you would add the Jupyter icon to the render
69tree of another React component:
70
71```jsx
72public render() {
73 return (
74 <div className="outer">
75 <div className="inner">
76 <jupyterIcon.react tag="span" right="7px" top="5px" />
77 "and here's a text node"
78 </div>
79 </div>
80 );
81}
82```
83
84Alternatively, you can just render the icon directly into any existing
85DOM node `elem` by using the `ReactDOM` module:
86
87```typescript
88ReactDOM.render(jupyterIcon.react, elem);
89```
90
91If do you use `ReactDOM` to render, and if the `elem` node is ever
92removed from the DOM, you’ll first need to clean it up:
93
94```typescript
95ReactDOM.unmountComponentAtNode(elem);
96```
97
98This cleanup step is not a special property of `LabIcon`, but is instead
99needed for any React component that is rendered directly at the top
100level by `ReactDOM`: failure to call `unmountComponentAtNode` can result
101in a [memory leak](https://stackoverflow.com/a/48198011/425458).
102
103## How to create your own custom `LabIcon`
104
105You can create your own custom icon by constructing a new instance of
106`LabIcon`:
107
108```typescript
109export const fooIcon = new LabIcon({
110 name: 'barpkg:foo',
111 svgstr: '<svg>...</svg>'
112});
113```
114
115where `name` should be of the form “your-pkg:icon-name”, and `svgstr` is
116the raw contents of your icon’s svg file.
117
118## How to create a new `LabIcon` from an external svg file
119
120Although you can copy-and-paste an svg directly into the `LabIcon`
121constructor, the best practice is to keep the svg for each of your icons
122in its own separate svg file. You will need to have an `svg.d.ts` file
123at the root of your project’s `src` directory:
124
125```typescript
126// svg.d.ts
127
128declare module '*.svg' {
129 const value: string;
130 export default value;
131}
132```
133
134You can then `import` the contents of an svg file:
135
136```typescript
137import fooSvgstr from 'path-to-your/foo.svg';
138
139export const fooIcon = new LabIcon({
140 name: 'barpkg:foo',
141 svgstr: fooSvgstr
142});
143```
144
145## Sync icon color to JupyterLab theme
146
147<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>
148
149You can ensure that the colors of your custom `LabIcon` sync up to the
150colors of the current JupyterLab theme by adding appropriate `class`
151annotations to each colored element of your icon's svg.
152
153In other words, each element of your svg that a `fill="..."` or a
154`stroke="..."` property should also have a `class="jp-icon<whatever>"`
155property.
156
157### Available icon classes
158
159<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>
160
161All colors shown are for the standard light/dark theme, mouse over for
162hex values.
163
164#### `jp-iconX`: contrast to theme background
165
166<ul>
167<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>
168<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>
169<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>
170<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>
171<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>
172</ul>
173
174Most one-color icons in JupyterLab (including the sidebar and toolbar
175icons) are colored using the `jp-icon3` class.
176
177For light/dark themes, `jp-icon0` corresponds to the darkest/lightest
178background color, while `jp-icon1` is somewhat lighter/darker, and so
179forth.
180
181#### `jp-icon-accentX`: match to theme background
182
183<ul>
184<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>
185<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>
186<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>
187<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>#616161</title></svg></li>
188<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>
189</ul>
190
191For light/dark themes, `jp-icon-accent0` corresponds to the
192lightest/darkest background color, while `jp-icon-accent1` is somewhat
193darker/lighter, and so forth.
194
195### Adding classes to a one-color icon
196
197For most simple, one-color icons, it is desirable for the icon's color
198to strongly contrast with that of the application's background. You can
199achieve this using one of the `jp-iconX` classes.
200
201**Example: check icon**
202
203_svg source:_
204
205```html
206<svg xmlns="http://www.w3.org/2000/svg" width="100" viewBox="0 0 24 24">
207 <path
208 class="jp-icon3"
209 fill="#616161"
210 d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"
211 />
212</svg>
213```
214
215_rendered icon:_
216
217<svg xmlns="http://www.w3.org/2000/svg" width="100" viewBox="0 0 24 24">
218 <path class="jp-icon3" fill="#616161" d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/>
219</svg>
220
221### Adding classes to a multi-colored icon
222
223For more complex icons, each element that needs to match the background
224should be annotated with a `jp-icon-accentX` class, while each element
225that needs to contrast with the background should be annotated with a
226`jp-iconX` class.
227
228**Example: close-circle icon**
229
230_svg source:_
231
232```html
233<svg xmlns="http://www.w3.org/2000/svg" width="100" viewBox="0 0 24 24">
234 <circle class="jp-icon3" fill="#616161" cx="12" cy="12" r="11" />
235 <rect
236 class="jp-icon-accent0"
237 fill="#fff"
238 height="18"
239 width="2"
240 x="11"
241 y="3"
242 transform="rotate(315, 12, 12)"
243 />
244 <rect
245 class="jp-icon-accent0"
246 fill="#fff"
247 height="18"
248 width="2"
249 x="11"
250 y="3"
251 transform="rotate(45, 12, 12)"
252 />
253</svg>
254```
255
256_rendered icon:_
257
258<svg xmlns="http://www.w3.org/2000/svg" width="100" viewBox="0 0 24 24">
259 <circle class="jp-icon3" fill="#616161" cx="12" cy="12" r="11"/>
260 <rect class="jp-icon-accent0" fill="#fff" height="18" width="2" x="11" y="3" transform="rotate(315, 12, 12)"/>
261 <rect class="jp-icon-accent0" fill="#fff" height="18" width="2" x="11" y="3" transform="rotate(45, 12, 12)"/>
262</svg>
263
264## Background
265
266### Icon handling in Jupyterlab
267
268Pre JupyterLab 2.0, most icons were created using the
269icons-as-css-background pattern:
270
271- Set up the icon’s svg as a `background-image` in CSS:
272
273 ```css
274 /* CSS */
275
276 .jp-FooIcon {
277 background-image: url('path-to-your/foo.svg');
278 }
279 ```
280
281- Add the icon to the DOM by constructing an otherwise empty DOM node
282 with the appropriate class:
283
284 ```typescript
285 // typescript
286
287 const e = document.createElement('div');
288 e.className = 'jp-FooIcon';
289 document.body.append(e);
290 ```
291
292What you end up with is a single DOM node that has the “foo” icon as a
293background image.
294
295Post JupyterLab 2.0, nearly all icons in core are now created using
296[LabIcon](https://github.com/jupyterlab/jupyterlab/blob/f0153e0258b32674c9aec106383ddf7b618cebab/packages/ui-components/src/icon/labicon.tsx)
297and the icons-as-inline-svg pattern:
298
299- Construct a new instance of LabIcon from the icon’s name and svg:
300
301 ```typescript
302 // typescript
303
304 // svgstr is the raw contents of an icon's svg file
305 export const fooIcon = new LabIcon({
306 name: 'barpkg:foo',
307 svgstr: '<svg>...</svg>'
308 });
309 ```
310
311- Add the icon to the DOM using the appropriate property of your
312 LabIcon instance (either LabIcon.element() to directly create a DOM
313 node, or LabIcon.react to get the icon as a react component):
314
315 ```typescript
316 // typescript
317
318 const e = fooIcon.element();
319 document.body.append(e);
320 ```
321
322What you end up with is a DOM node (by default a ‘div’) that has an
323inline svg node as a child.
324
325### `background-image` vs inline svg
326
327The big limitation of the old icon-as-css-background pattern is that svg
328images rendered as `background-image` are invisible to CSS. On the other
329hand, an icon rendered as an inline svg node is fully exposed to the
330CSS. This allows us to dynamically change icon styling as needed simply by
331modifying our CSS. Most importantly, this allows us to recolor icons
332according to Jupyterlab’s current theme.
333
\No newline at end of file