0
# Icon System
1
2
Interfaces for defining and rendering icons within the JupyterLab interface, supporting both SVG-based and custom renderers.
3
4
## Capabilities
5
6
### LabIcon Namespace
7
8
The LabIcon namespace contains interfaces for icon definition and rendering within JupyterLab.
9
10
```typescript { .api }
11
namespace LabIcon {
12
/**
13
* The simplest possible interface for defining a generic icon
14
*/
15
interface IIcon {
16
/**
17
* The name of the icon. By convention, the icon name will be namespaced
18
* as so: "pkg-name:icon-name"
19
*/
20
readonly name: string;
21
/** A string containing the raw contents of an svg file */
22
svgstr: string;
23
}
24
25
/**
26
* Interface for generic renderer
27
*/
28
interface IRenderer {
29
readonly render: (container: HTMLElement, options?: any) => void;
30
readonly unrender?: (container: HTMLElement, options?: any) => void;
31
}
32
33
/**
34
* A type that can be resolved to a LabIcon instance
35
*/
36
type IResolvable = string | (IIcon & Partial<IRenderer>);
37
}
38
```
39
40
### IIcon Interface
41
42
Defines a basic icon with a name and SVG content.
43
44
**Usage Example:**
45
46
```typescript
47
import { IRenderMime } from "@jupyterlab/rendermime-interfaces";
48
49
// Define custom icons for file types
50
const dataVisualizationIcon: IRenderMime.LabIcon.IIcon = {
51
name: 'my-extension:data-viz',
52
svgstr: `
53
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
54
<rect x="2" y="12" width="2" height="2" fill="#4CAF50"/>
55
<rect x="6" y="8" width="2" height="6" fill="#2196F3"/>
56
<rect x="10" y="4" width="2" height="10" fill="#FF9800"/>
57
<rect x="14" y="6" width="2" height="8" fill="#9C27B0"/>
58
</svg>
59
`
60
};
61
62
const documentIcon: IRenderMime.LabIcon.IIcon = {
63
name: 'my-extension:document',
64
svgstr: `
65
<svg width="16" height="16" viewBox="0 0 16 16">
66
<path d="M3 2v12h10V5l-3-3H3z" fill="#E3F2FD" stroke="#1976D2"/>
67
<path d="M10 2v3h3" fill="none" stroke="#1976D2"/>
68
<line x1="5" y1="7" x2="11" y2="7" stroke="#1976D2"/>
69
<line x1="5" y1="9" x2="11" y2="9" stroke="#1976D2"/>
70
<line x1="5" y1="11" x2="9" y2="11" stroke="#1976D2"/>
71
</svg>
72
`
73
};
74
75
// Use in file type definitions
76
const fileTypeWithIcon: IRenderMime.IFileType = {
77
name: 'data-visualization',
78
mimeTypes: ['application/data-viz'],
79
extensions: ['.dviz'],
80
displayName: 'Data Visualization',
81
icon: dataVisualizationIcon
82
};
83
```
84
85
### IRenderer Interface
86
87
Defines custom rendering behavior for icons.
88
89
**Usage Example:**
90
91
```typescript
92
import { IRenderMime } from "@jupyterlab/rendermime-interfaces";
93
94
// Custom icon renderer with animation
95
const animatedIconRenderer: IRenderMime.LabIcon.IRenderer = {
96
render: (container: HTMLElement, options?: any) => {
97
// Create SVG element
98
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
99
svg.setAttribute('width', '16');
100
svg.setAttribute('height', '16');
101
svg.setAttribute('viewBox', '0 0 16 16');
102
103
// Add spinning animation
104
svg.innerHTML = `
105
<circle cx="8" cy="8" r="6" fill="none" stroke="#2196F3" stroke-width="2" opacity="0.3"/>
106
<path d="M14 8c0-3.3-2.7-6-6-6" stroke="#2196F3" stroke-width="2" stroke-linecap="round">
107
<animateTransform attributeName="transform" type="rotate" values="0 8 8;360 8 8"
108
dur="1s" repeatCount="indefinite"/>
109
</path>
110
`;
111
112
container.appendChild(svg);
113
114
// Apply options if provided
115
if (options?.size) {
116
svg.setAttribute('width', options.size);
117
svg.setAttribute('height', options.size);
118
}
119
if (options?.color) {
120
svg.style.color = options.color;
121
}
122
},
123
124
unrender: (container: HTMLElement) => {
125
// Clean up rendered content
126
const svg = container.querySelector('svg');
127
if (svg) {
128
container.removeChild(svg);
129
}
130
}
131
};
132
133
// Icon with custom renderer
134
const animatedIcon: IRenderMime.LabIcon.IIcon & Partial<IRenderMime.LabIcon.IRenderer> = {
135
name: 'my-extension:loading',
136
svgstr: '', // Not used when custom renderer is provided
137
render: animatedIconRenderer.render,
138
unrender: animatedIconRenderer.unrender
139
};
140
```
141
142
### IResolvable Type
143
144
Flexible type that can be either a string reference or a full icon definition.
145
146
**Usage Examples:**
147
148
```typescript
149
import { IRenderMime } from "@jupyterlab/rendermime-interfaces";
150
151
// Using string reference to existing icon
152
const stringIconFileType: IRenderMime.IFileType = {
153
name: 'text-file',
154
mimeTypes: ['text/plain'],
155
extensions: ['.txt'],
156
icon: 'document' // String reference
157
};
158
159
// Using full icon object
160
const customIconFileType: IRenderMime.IFileType = {
161
name: 'special-format',
162
mimeTypes: ['application/special'],
163
extensions: ['.spec'],
164
icon: {
165
name: 'my-extension:special',
166
svgstr: '<svg>...</svg>'
167
}
168
};
169
170
// Using icon with custom renderer
171
const animatedIconFileType: IRenderMime.IFileType = {
172
name: 'dynamic-content',
173
mimeTypes: ['application/dynamic'],
174
extensions: ['.dyn'],
175
icon: {
176
name: 'my-extension:dynamic',
177
svgstr: '<svg>...</svg>',
178
render: (container, options) => {
179
// Custom rendering logic
180
}
181
}
182
};
183
184
// Utility function to handle IResolvable
185
function resolveIcon(icon: IRenderMime.LabIcon.IResolvable): string {
186
if (typeof icon === 'string') {
187
return icon; // Return icon name for lookup
188
} else {
189
return icon.name; // Return the name from the icon object
190
}
191
}
192
193
// Function to render an icon
194
function renderIcon(
195
icon: IRenderMime.LabIcon.IResolvable,
196
container: HTMLElement,
197
options?: any
198
): void {
199
if (typeof icon === 'string') {
200
// Handle string reference - would typically lookup in icon registry
201
console.log(`Rendering icon by name: ${icon}`);
202
} else {
203
// Handle icon object
204
if (icon.render) {
205
// Use custom renderer
206
icon.render(container, options);
207
} else {
208
// Use default SVG rendering
209
container.innerHTML = icon.svgstr;
210
}
211
}
212
}
213
```
214
215
## Icon Usage Patterns
216
217
### File Type Icons
218
219
```typescript
220
// Different ways to specify icons for file types
221
const fileTypes: IRenderMime.IFileType[] = [
222
{
223
name: 'python-file',
224
mimeTypes: ['text/x-python'],
225
extensions: ['.py'],
226
icon: 'python' // Reference to built-in icon
227
},
228
{
229
name: 'config-file',
230
mimeTypes: ['application/json'],
231
extensions: ['.config.json'],
232
iconClass: 'jp-MaterialIcon jp-SettingsIcon' // CSS class approach
233
},
234
{
235
name: 'custom-format',
236
mimeTypes: ['application/custom'],
237
extensions: ['.cust'],
238
icon: {
239
name: 'my-package:custom-format',
240
svgstr: '<svg width="16" height="16">...</svg>'
241
}
242
}
243
];
244
```
245
246
### Dynamic Icon Rendering
247
248
```typescript
249
// Icon that changes based on file state
250
const stateAwareIcon: IRenderMime.LabIcon.IIcon & Partial<IRenderMime.LabIcon.IRenderer> = {
251
name: 'my-extension:state-aware',
252
svgstr: '', // Not used
253
254
render: (container: HTMLElement, options?: { state?: string }) => {
255
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
256
svg.setAttribute('width', '16');
257
svg.setAttribute('height', '16');
258
259
// Change appearance based on state
260
switch (options?.state) {
261
case 'processing':
262
svg.innerHTML = '<circle cx="8" cy="8" r="4" fill="#FF9800"/>';
263
break;
264
case 'complete':
265
svg.innerHTML = '<circle cx="8" cy="8" r="4" fill="#4CAF50"/>';
266
break;
267
case 'error':
268
svg.innerHTML = '<circle cx="8" cy="8" r="4" fill="#F44336"/>';
269
break;
270
default:
271
svg.innerHTML = '<circle cx="8" cy="8" r="4" fill="#9E9E9E"/>';
272
}
273
274
container.appendChild(svg);
275
}
276
};
277
```