Panels
Panels are the slide-in sidebars on the left and right of the viewer. This guide covers the built-in panels, the generic Panel shell, and the APIs to add, replace, and inspect panels.
UI APIs
UI.addPanel(panel)
Add a custom panel to the left or right side.
/**
* @method UI.addPanel
* @param {Object<PanelProperties>} panel
* @param {string} panel.dataElement Unique id.
* @param {string} panel.location 'left' | 'right'
* @param {string | UI.renderCustomPanel} panel.render Predefined panel name or () => HTMLElement
*/
UI.addPanel({
dataElement: 'myPanel',
location: 'right',
render: () => {
const el = document.createElement('div');
el.textContent = 'My panel';
return el;
},
});render may be either a predefined panel name (see UI.Panels) or a function returning an HTMLElement (rendered through the generic CustomElement host). addPanel accepts a Panel instance (calls toObject()) or a plain object, then appends to the store's genericPanels list.
UI.setPanels(panelList)
Replace the entire panel list.
/**
* @method UI.setPanels
* @param {array} panelList The new list of panels to use in the UI.
*/
UI.setPanels([ /* PanelProperties[] */ ]);Each entry is normalized through Panel.toObject() if it is a Panel instance.
UI.getPanels()
Return the current panels.
/**
* @method UI.getPanels
* @return {Array<UI.Components.Panel | UI.Components.TabPanel>}
*/
const panels = UI.getPanels();Returns deep-cloned entries wrapped in UI.Components.Panel instances.
UI.Components.Panel class
| Member | Signature | Purpose |
|---|---|---|
dataElement | string (get/set) | The panel's data-element; setter re-syncs the store. |
render | string|function (get/set) | Render spec; setter re-syncs the store. |
location | 'left'|'right' (get/set) | Side; invalid → 'right'; setter re-syncs the store. |
setLocation(location) | (location: string) => void | Explicitly set the side. |
delete() | () => void | Remove the panel from the store. |
Each mutation calls resetPanels() then setGenericPanels(panels) on the store.
Built-in panels
The default genericPanels list (9 entries):
dataElement | Location | Purpose |
|---|---|---|
leftPanel | left (full-height) | Tabbed sidebar: thumbnails, outlines, annotations, layers, signatures, search. |
rightPanel | right | Form-field properties (General / Appearance / Preferences tabs). |
stylePanel | right | Annotation & measurement properties. |
pageModePanel | right | Page display mode (single/double, scroll direction). |
stampPanel | right | Stamp picker (Standard / Dynamic / Custom). |
linkPanel | right | Link-annotation properties. |
contentEditorPanel | right | Content-editor selection properties. |
colorSeparationPanel | right | Color-separation view. |
redactionPanel | right | Redaction-mark properties. |
Left panel tabs
Switched by UI.setActiveElementTab('leftPanel', tab):
| Tab constant | Contents |
|---|---|
ThumbnailsButton (THUMBS) | Page thumbnails — the .thumbnail-view mount target handed to core.initializeViewer. |
OutlinesButton (OUTLINE) | Bookmark / table-of-contents tree. |
AnnotationButton (ANNOTATION_TAB) | Annotation list (header + content). |
LayersButton (LAYER) | PDF layer visibility. |
SignatureButton (SIGNATURE_TAB) | Signature list. |
SearchButton (SEARCH_TAB) | Find bar. |
Right panel tabs
UI.setActiveElementTab('rightPanel', tab):
| Tab constant | Contents |
|---|---|
General | Field name, button text, visibility, required/indicator flags. |
Appearance | Fill color, font color/family/style/size (hidden for signature fields). |
Preference | Alignment, default value, multi-line, button style, options (hidden for signature fields). |
The generic Panel shell
All panels render through components/Panel/Panel.vue — a fixed-position slide-in container (.left / .right, .mobile, .full, .closed uses translateX/translateY). It reads isOpen / isDisabled from useViewer.isElementOpen / isElementDisabled(dataElement), reserves panelSpace (260px when a side has an open panel) so DocumentContainer can shrink, and is 260px wide on desktop / 100vw on mobile.
Mounting strategy
The root App/index.vue renders every panel from useViewer.getGenericPanels via v-for, wrapping each in the Panel shell. The inner component is resolved three ways:
- Eager (
NoLazyComponents) forstylePanel,leftPanel,rightPanel,linkPanel,colorSeparationPanel,contentEditorPanel,redactionPanel. - Lazy (
LazyLoadComponents,defineAsyncComponent) forpageModePanel,stampPanel, andCustomModal. <CustomElement>for any user-suppliedrenderfunction (custom panels).
The eager/lazy names are defined in constants/panel.js (noLazyPanelNames / panelNames).
Examples
Add and open a custom left panel
UI.addPanel({
dataElement: 'commentsPanel',
location: 'left',
render: () => {
const el = document.createElement('div');
el.className = 'comments';
el.innerHTML = '<h3>Comments</h3><ul><li>None yet</li></ul>';
return el;
},
});
UI.openElement('commentsPanel');Move a panel to the other side
const [panel] = UI.getPanels().filter(p => p.dataElement === 'myPanel');
panel.setLocation('left');Remove a panel
const [panel] = UI.getPanels().filter(p => p.dataElement === 'myPanel');
panel.delete();Replace all panels
UI.setPanels([
{ dataElement: 'leftPanel', location: 'left', render: 'leftPanel' },
{ dataElement: 'myPanel', location: 'right', render: () => myEl },
]);Related
- Show / Hide Elements — open/close panels.
- Components — the
Panel,LeftPanel,RightPanel,StylePanelcomponent trees. - API Reference