Components
The UI is a Vue 3 component tree rooted at App/index.vue. This guide maps the component directory structure and the key areas, so you know where to look when forking or extending the UI.
Mount chain
main.js → createApp(App = components/Suspenser.vue)
→ setupStore(app) + i18n(app)
→ mount('#app')
Suspenser.vue → <Suspense> fallback="loading…" → <App/>
App/index.vue → the actual viewer rootSuspenser.vue wraps App/index.vue in <Suspense> because App uses top-level await (i18nextPromise, loadConfig).
Root App/index.vue
Renders the chrome and wires the engine:
- Applies the dark-theme class on
#outerContainer. - Renders
<Header />(hidden whenheaderis disabled), then a.contentrow with the document area + side panels + overlays. - Mounts the PDF surface:
<DocumentContainer />,<CompareDocumentContainer />, and conditionally<DocumentEditorContainer />(only indocumenttool mode). - Renders every panel from
useViewer.getGenericPanelsviav-for, wrapped in the generic<Panel>shell. Inner components resolve viaNoLazyComponents(eager),LazyLoadComponents(lazy), or<CustomElement>(userrender). - Mounts global masks: download loading/error mask,
<SignCreatePanel>,<SignCreateDialog>,<CustomStamp>. - On setup:
initDocument,defineWebViewerInstanceUIAPIs, loads hash params (css,theme,header), and postsviewerLoadedtowindow.parent. Defineswindow.instance.changeFile.
Key component directories
| Directory | Purpose |
|---|---|
App/ | Root application component. |
Header/ | The top bar (Header.vue). |
HeaderItems/ | Generic toolbar renderer (HeaderItems.vue) + HeaderItemsListener.js sync hub. |
Ribbons/ | Toolbar-group switcher. |
ToolsHeader/ | Secondary contextual toolbar row. |
FormBoard/ | Form-field creation palette. |
DocumentContainer/ | PDF render surface + document-scoped overlays (largest component, ~31k). |
CompareDocumentContainer/ | Compare-mode viewer (registers instances 2 & 3). |
DocumentEditorContainer/ | Page editor (insert/delete/rotate/extract/merge/move/crop). |
LeftPanel/ | Tabbed left sidebar (thumbnails, outlines, annotations, layers, signatures, search). |
RightPanel/ | Form-field properties (General/Appearance/Preferences). |
Panel/ | Generic slide-in panel shell. |
StylePanel/ | Annotation & measurement properties. |
StampPanel/ | Stamp picker. |
LinkPanel/, ContentEditorPanel/, RedactionPanel/, ColorSeparationPanel/, RightPanelPageMode/ | Other built-in panels. |
Popups/ | AnnotationPopup, TextPopup, FreetextPopup, CropPagePopup, ContentEditorPopup. |
Dialogs/ | Modal dialogs (page ops, signature, compare, measurement, stamp, redaction, settings). |
Signatures/ | SignCreatePanel, SignCreateDialog, DigitalSignCreatePanel, DigitalKeyboardCreatePanel. |
SignatureContainer/ | Left-panel signature tab. |
Icon/ | ~270 SVG-as-Vue icon components, referenced by name string. |
Button/, CustomButton/, Dropdown/, CustomElement/ | Primitives used by HeaderItems and Popups. |
Message/ | Global toast (window.$message). |
AnnotationContainer/, Outlines/, LayerContainer/, SearchContainer/ | Left-panel tab contents. |
MeasurementBoard/, MeasureCurveGuide/, MeasurePanel/ | Measurement tools. |
Password/ | Password entry/set dialogs. |
SecurityToolbar/, SignatureToolBar/, ComparedToolbar/, FillForm/ | Mode-specific toolbars. |
LazyLoadWrapper/ | Async-component + Suspense wrapper and the panel registry. |
CustomModal/, ModalContainer/ | UI.addCustomModal plumbing. |
PageNavOverlay/, ZoomOverlay/ | Floating overlays. |
Header / HeaderItems
Header.vue renders <HeaderItems :items="useViewer.getActiveHeaderItems" /> (the array for activeHeaderGroup). HeaderItems.vue dispatches on item.type (toolButton, toggleElementButton, actionButton, statefulButton, customElement, spacer, divider), computes visibleItems (mobile/PC + isElementDisabled), and applies responsive hide classes. HeaderItemsListener.js keeps toolbar buttons in sync with selection/tool state.
DocumentContainer
The .document-container sizes against panelSpace and topSpace. The inner .document div is the PDF render surface, wired with click/touch/mousedown/dblclick/contextmenu handlers that dispatch onto core.eventBus(). initViewer() calls core.initializeViewer({ container, viewer, thumbnailView, outlineView, findbarView, toggleButton }) and registers engine event listeners. It also hosts all five Popups and most document-scoped dialogs.
Popups
Five floating, position-computed popovers (via helpers/getPopupPosition), driven by useViewer.getPopupItems(<key>) and filtered by isElementDisabled. See Popups.
Icon library
components/Icon/ contains ~270 single-purpose SVG-as-Vue-render-function icon components, referenced by name strings (e.g. icon: 'Pantool') in header-item descriptors and popup items, not imported directly at call sites.
Customization hooks at the component layer
- Toolbar:
UI.setHeaderItems(cb)mutatesheadersin the store;HeaderItems.vuere-renders. - Panels:
UI.addPanelappends togenericPanels; the rootApprenders them throughPanel.vue+<CustomElement>. - Popups:
UI.annotationPopup/textPopup/contentEditorPopup/cropPagePopupmutate popup item arrays. - Modals:
UI.addCustomModalappends tocustomModals;CustomModal+ModalContainerrender them. - Element state:
openElement/closeElement/disableElementsdrive visibility through the store'sactiveElements/disabledElementsmaps.