1 |
|
2 | THIS FILE IS AUTOGENERATED, DO NOT EDIT
|
3 |
|
4 | Instead, make changes to docs sources in `packages/ui-components/docs`,
|
5 | then run "jlpm docs:init" to refresh the built docs
|
6 | -->
|
7 |
|
8 | # @jupyterlab/ui-components
|
9 |
|
10 | The
|
11 | [@jupyterlab/ui-components](https://jupyterlab.github.io/jupyterlab/modules/_ui_components_src_index_.html)
|
12 | package provides UI elements that are widely used in JupyterLab core,
|
13 | and that can be reused in your own extensions.
|
14 |
|
15 | For 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
|
17 | that will be able to automatically change color to match the current
|
18 | JupyterLab 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
|
23 | icon system introduced in JupyterLab v2.0.
|
24 |
|
25 | ## How JupyterLab handles icons
|
26 |
|
27 | The @jupyterlab/ui-components package provides icons to the rest of
|
28 | JupyterLab, in the form of a set of `LabIcon` instances (currently about
|
29 | 80). All of the icons in the core JupyterLab packages are rendered using
|
30 | one of these `LabIcon` instances.
|
31 |
|
32 | ## Using the icons in your own code
|
33 |
|
34 | You can use any of JupyterLab icons in your own code via an `import`
|
35 | statement. For example, to use `jupyterIcon` you would first do:
|
36 |
|
37 | ```typescript
|
38 | import { jupyterIcon } from '@jupyterlab/ui-components';
|
39 | ```
|
40 |
|
41 | ## How to render an icon into a DOM node
|
42 |
|
43 | Icons can be added as children to any `div` or `span` nodes using the
|
44 | `icon.element(...)` method (where `icon` is any instance of `LabIcon`).
|
45 | For example, to render the Jupyter icon you could do:
|
46 |
|
47 | ```typescript
|
48 | jupyterIcon.element({
|
49 | container: elem,
|
50 | height: '16px',
|
51 | width: '16px',
|
52 | marginLeft: '2px'
|
53 | });
|
54 | ```
|
55 |
|
56 | where `elem` is any `HTMLElement` with a `div` or `span` tag. As shown
|
57 | in the above example, the icon can be styled by passing CSS parameters
|
58 | into `.element(...)`. Any valid CSS parameter can be used (one catch:
|
59 | snake 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 |
|
64 | Icons can also be rendered using React. The `icon.react` parameter holds
|
65 | a standard React component that will display the icon on render. Like
|
66 | any React component, `icon.react` can be used in various ways.
|
67 |
|
68 | For example, here is how you would add the Jupyter icon to the render
|
69 | tree of another React component:
|
70 |
|
71 | ```jsx
|
72 | public 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 |
|
84 | Alternatively, you can just render the icon directly into any existing
|
85 | DOM node `elem` by using the `ReactDOM` module:
|
86 |
|
87 | ```typescript
|
88 | ReactDOM.render(jupyterIcon.react, elem);
|
89 | ```
|
90 |
|
91 | If do you use `ReactDOM` to render, and if the `elem` node is ever
|
92 | removed from the DOM, you’ll first need to clean it up:
|
93 |
|
94 | ```typescript
|
95 | ReactDOM.unmountComponentAtNode(elem);
|
96 | ```
|
97 |
|
98 | This cleanup step is not a special property of `LabIcon`, but is instead
|
99 | needed for any React component that is rendered directly at the top
|
100 | level by `ReactDOM`: failure to call `unmountComponentAtNode` can result
|
101 | in a [memory leak](https://stackoverflow.com/a/48198011/425458).
|
102 |
|
103 | ## How to create your own custom `LabIcon`
|
104 |
|
105 | You can create your own custom icon by constructing a new instance of
|
106 | `LabIcon`:
|
107 |
|
108 | ```typescript
|
109 | export const fooIcon = new LabIcon({
|
110 | name: 'barpkg:foo',
|
111 | svgstr: '<svg>...</svg>'
|
112 | });
|
113 | ```
|
114 |
|
115 | where `name` should be of the form “your-pkg:icon-name”, and `svgstr` is
|
116 | the raw contents of your icon’s svg file.
|
117 |
|
118 | ## How to create a new `LabIcon` from an external svg file
|
119 |
|
120 | Although you can copy-and-paste an svg directly into the `LabIcon`
|
121 | constructor, the best practice is to keep the svg for each of your icons
|
122 | in its own separate svg file. You will need to have an `svg.d.ts` file
|
123 | at the root of your project’s `src` directory:
|
124 |
|
125 | ```typescript
|
126 | // svg.d.ts
|
127 |
|
128 | declare module '*.svg' {
|
129 | const value: string;
|
130 | export default value;
|
131 | }
|
132 | ```
|
133 |
|
134 | You can then `import` the contents of an svg file:
|
135 |
|
136 | ```typescript
|
137 | import fooSvgstr from 'path-to-your/foo.svg';
|
138 |
|
139 | export 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 |
|
149 | You can ensure that the colors of your custom `LabIcon` sync up to the
|
150 | colors of the current JupyterLab theme by adding appropriate `class`
|
151 | annotations to each colored element of your icon's svg.
|
152 |
|
153 | In other words, each element of your svg that a `fill="..."` or a
|
154 | `stroke="..."` property should also have a `class="jp-icon<whatever>"`
|
155 | property.
|
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 |
|
161 | All colors shown are for the standard light/dark theme, mouse over for
|
162 | hex 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 |
|
174 | Most one-color icons in JupyterLab (including the sidebar and toolbar
|
175 | icons) are colored using the `jp-icon3` class.
|
176 |
|
177 | For light/dark themes, `jp-icon0` corresponds to the darkest/lightest
|
178 | background color, while `jp-icon1` is somewhat lighter/darker, and so
|
179 | forth.
|
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 |
|
191 | For light/dark themes, `jp-icon-accent0` corresponds to the
|
192 | lightest/darkest background color, while `jp-icon-accent1` is somewhat
|
193 | darker/lighter, and so forth.
|
194 |
|
195 | ### Adding classes to a one-color icon
|
196 |
|
197 | For most simple, one-color icons, it is desirable for the icon's color
|
198 | to strongly contrast with that of the application's background. You can
|
199 | achieve 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 |
|
223 | For more complex icons, each element that needs to match the background
|
224 | should be annotated with a `jp-icon-accentX` class, while each element
|
225 | that 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 |
|
268 | Pre JupyterLab 2.0, most icons were created using the
|
269 | icons-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 |
|
292 | What you end up with is a single DOM node that has the “foo” icon as a
|
293 | background image.
|
294 |
|
295 | Post 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)
|
297 | and 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 |
|
322 | What you end up with is a DOM node (by default a ‘div’) that has an
|
323 | inline svg node as a child.
|
324 |
|
325 | ### `background-image` vs inline svg
|
326 |
|
327 | The big limitation of the old icon-as-css-background pattern is that svg
|
328 | images rendered as `background-image` are invisible to CSS. On the other
|
329 | hand, an icon rendered as an inline svg node is fully exposed to the
|
330 | CSS. This allows us to dynamically change icon styling as needed simply by
|
331 | modifying our CSS. Most importantly, this allows us to recolor icons
|
332 | according to Jupyterlab’s current theme.
|
333 |
|
\ | No newline at end of file |