0
# Panel Management
1
2
Manage visibility and state of plugin panels within the dashboard interface.
3
4
## Capabilities
5
6
### Show Panel
7
8
Display a specific plugin panel by its identifier.
9
10
```typescript { .api }
11
/**
12
* Show specific plugin panel by ID
13
* Only shows panels for acquirer-type plugins
14
* @param id - Plugin identifier to show panel for
15
*/
16
showPanel(id: string): void;
17
```
18
19
**Usage Examples:**
20
21
```typescript
22
import Dashboard from "@uppy/dashboard";
23
24
const dashboard = uppy.getPlugin("Dashboard") as Dashboard;
25
26
// Show Google Drive panel
27
dashboard.showPanel("GoogleDrive");
28
29
// Show Webcam panel
30
dashboard.showPanel("Webcam");
31
32
// Show panel after plugin registration
33
uppy.use(GoogleDrive, { /* options */ });
34
dashboard.showPanel("GoogleDrive");
35
```
36
37
**Behavior:**
38
- Finds target plugin with matching ID and type 'acquirer'
39
- Sets the plugin as `activePickerPanel` in dashboard state
40
- Sets `activeOverlayType` to 'PickerPanel'
41
- Emits `dashboard:show-panel` event with plugin ID
42
43
### Hide All Panels
44
45
Hide all currently open panels and reset dashboard to default state.
46
47
```typescript { .api }
48
/**
49
* Hide all currently open panels
50
* Resets dashboard to default view state
51
*/
52
hideAllPanels(): void;
53
```
54
55
**Usage Examples:**
56
57
```typescript
58
// Hide all panels programmatically
59
dashboard.hideAllPanels();
60
61
// Hide panels after file selection
62
uppy.on("file-added", () => {
63
dashboard.hideAllPanels();
64
});
65
66
// Hide panels when modal closes
67
uppy.on("dashboard:modal-closed", () => {
68
dashboard.hideAllPanels();
69
});
70
71
// Custom panel management
72
function resetDashboardState() {
73
dashboard.hideAllPanels();
74
// Additional cleanup logic
75
}
76
```
77
78
**Behavior:**
79
- Sets `activePickerPanel` to undefined
80
- Sets `showAddFilesPanel` to false
81
- Sets `activeOverlayType` to null
82
- Sets `fileCardFor` to null
83
- Sets `showFileEditor` to false
84
- Emits `dashboard:close-panel` event with previous panel ID
85
- Optimizes state updates to avoid unnecessary re-renders
86
87
### Panel State Management
88
89
Dashboard state properties related to panel management.
90
91
```typescript { .api }
92
/**
93
* Panel-related state properties
94
*/
95
interface DashboardPanelState {
96
/** Currently active picker panel */
97
activePickerPanel: Target | undefined;
98
/** Visibility of add files panel */
99
showAddFilesPanel: boolean;
100
/** Type of active overlay */
101
activeOverlayType: string | null;
102
/** File ID for file card display */
103
fileCardFor: string | null;
104
/** File editor visibility */
105
showFileEditor: boolean;
106
}
107
108
/**
109
* Plugin target interface for panel management
110
*/
111
interface Target {
112
/** Plugin identifier */
113
id: string;
114
/** Plugin display name */
115
name: string;
116
/** Plugin type ('acquirer', 'progressindicator', 'editor') */
117
type: string;
118
}
119
```
120
121
### Panel Events
122
123
Events emitted during panel lifecycle for integration and customization.
124
125
```typescript { .api }
126
/**
127
* Panel-related events
128
*/
129
interface DashboardPanelEvents {
130
/** Emitted when a panel is shown */
131
"dashboard:show-panel": (id: string) => void;
132
/** Emitted when a panel is closed */
133
"dashboard:close-panel": (id: string | undefined) => void;
134
}
135
```
136
137
**Event Usage Examples:**
138
139
```typescript
140
// Listen for panel events
141
uppy.on("dashboard:show-panel", (pluginId) => {
142
console.log(`Panel opened for plugin: ${pluginId}`);
143
// Track analytics, update breadcrumbs, etc.
144
});
145
146
uppy.on("dashboard:close-panel", (pluginId) => {
147
console.log(`Panel closed for plugin: ${pluginId}`);
148
// Cleanup, restore previous state, etc.
149
});
150
151
// Conditional behavior based on panel events
152
uppy.on("dashboard:show-panel", (pluginId) => {
153
if (pluginId === "GoogleDrive") {
154
// Show Google Drive specific UI hints
155
showGoogleDriveHelp();
156
}
157
});
158
```
159
160
### Overlay Types
161
162
Different overlay types that can be active in the dashboard.
163
164
```typescript { .api }
165
/**
166
* Available overlay types for dashboard state
167
*/
168
type DashboardOverlayType =
169
| 'PickerPanel' // Plugin picker panel (e.g., Google Drive)
170
| 'AddFiles' // Add files selection panel
171
| 'FileCard' // Individual file metadata panel
172
| 'FileEditor' // File editor panel (e.g., image editor)
173
| null; // No overlay active
174
```
175
176
**Overlay Management Examples:**
177
178
```typescript
179
// Check current overlay state
180
const state = dashboard.getPluginState();
181
switch (state.activeOverlayType) {
182
case 'PickerPanel':
183
console.log(`Showing ${state.activePickerPanel?.name} panel`);
184
break;
185
case 'AddFiles':
186
console.log("Showing add files panel");
187
break;
188
case 'FileCard':
189
console.log(`Showing file card for ${state.fileCardFor}`);
190
break;
191
case 'FileEditor':
192
console.log("File editor is open");
193
break;
194
case null:
195
console.log("No overlay active");
196
break;
197
}
198
```
199
200
### Plugin Integration
201
202
How plugins integrate with panel management system.
203
204
```typescript { .api }
205
/**
206
* Plugin requirements for panel integration
207
*/
208
interface PanelCompatiblePlugin {
209
/** Plugin must have unique ID */
210
id: string;
211
/** Plugin must have display name */
212
title?: string;
213
/** Plugin must be 'acquirer' type for panels */
214
type: 'acquirer';
215
/** Plugin can optionally provide support check */
216
isSupported?: () => boolean;
217
/** Plugin must provide render function */
218
render: () => ComponentChild;
219
/** Plugin should provide icon */
220
icon?: () => ComponentChild;
221
}
222
```
223
224
**Plugin Panel Integration Examples:**
225
226
```typescript
227
// Plugin with panel support
228
class CustomAcquirer extends BasePlugin {
229
type = 'acquirer';
230
id = 'CustomAcquirer';
231
title = 'Custom Source';
232
233
// Render method for panel content
234
render() {
235
return h('div', { className: 'custom-panel' }, [
236
h('h3', null, 'Select from Custom Source'),
237
h('button', {
238
onclick: this.selectFiles.bind(this)
239
}, 'Browse Files')
240
]);
241
}
242
243
// Optional support check
244
isSupported() {
245
return typeof window !== 'undefined';
246
}
247
248
selectFiles() {
249
// File selection logic
250
const files = getFilesFromCustomSource();
251
files.forEach(file => this.uppy.addFile(file));
252
}
253
}
254
255
// Register plugin and show its panel
256
uppy.use(CustomAcquirer);
257
const dashboard = uppy.getPlugin('Dashboard');
258
dashboard.showPanel('CustomAcquirer');
259
```
260
261
### Automatic Panel Management
262
263
Dashboard automatically manages panels in response to various events.
264
265
```typescript { .api }
266
/**
267
* Automatic panel management triggers
268
*/
269
interface AutoPanelManagement {
270
/** Hide panels when files are added */
271
onFileAdded: () => void;
272
/** Hide panels when modal closes */
273
onModalClosed: () => void;
274
/** Show appropriate panels for plugin types */
275
onPluginAdded: (plugin: UnknownPlugin) => void;
276
/** Remove panels when plugins are removed */
277
onPluginRemoved: (plugin: UnknownPlugin) => void;
278
}
279
```
280
281
**Automatic Behavior:**
282
- Panels are automatically hidden when files are added to maintain clean UI
283
- Modal closure triggers panel cleanup
284
- Compatible plugins are automatically mounted when added to Uppy
285
- Panel targets are removed when plugins are uninstalled
286
287
### Panel Navigation
288
289
Best practices for panel navigation and user experience.
290
291
```typescript { .api }
292
/**
293
* Panel navigation patterns
294
*/
295
interface PanelNavigation {
296
/** Show specific panel */
297
showPanel(id: string): void;
298
/** Return to main dashboard view */
299
hideAllPanels(): void;
300
/** Navigate between panels */
301
switchPanel(fromId: string, toId: string): void;
302
}
303
```
304
305
**Navigation Examples:**
306
307
```typescript
308
// Sequential panel navigation
309
function navigateToNextPanel(currentPanelId: string) {
310
const availablePanels = ['GoogleDrive', 'Dropbox', 'Instagram'];
311
const currentIndex = availablePanels.indexOf(currentPanelId);
312
const nextIndex = (currentIndex + 1) % availablePanels.length;
313
314
dashboard.showPanel(availablePanels[nextIndex]);
315
}
316
317
// Breadcrumb navigation
318
function showBreadcrumb(panelId: string) {
319
const breadcrumb = document.getElementById('panel-breadcrumb');
320
breadcrumb.innerHTML = `Dashboard > ${panelId}`;
321
322
breadcrumb.onclick = () => {
323
dashboard.hideAllPanels();
324
breadcrumb.innerHTML = 'Dashboard';
325
};
326
}
327
328
// Panel history tracking
329
const panelHistory: string[] = [];
330
331
uppy.on('dashboard:show-panel', (id) => {
332
panelHistory.push(id);
333
});
334
335
function goBackToPanel() {
336
panelHistory.pop(); // Remove current
337
const previousPanel = panelHistory.pop();
338
if (previousPanel) {
339
dashboard.showPanel(previousPanel);
340
} else {
341
dashboard.hideAllPanels();
342
}
343
}
344
```