Toolbar Customization Showcase Demo Code Sample

Requirements
View Demo

Easily customize UI elements in the viewer's toolbar, buttons, and menus. Change their colors or use your own icons.

This demo allows you to:

  • Hover over the listed UI elements to highlight them
  • Visually identify the element
  • Show or hide specific elements using checkboxes

Implementation steps
To add Toolbar Customization capability with WebViewer:

Step 1: Choose your preferred web stack
Step 2: Add the ES6 JavaScript sample code provided in this guide

Once you generate your license key, it will automatically be included in your sample code below.

License Key

1// ES6 Compliant Syntax
2// Copilot name: GitHub Copilot, version: 1.0.0, model: GPT-4, version: 2024-06, date: 2025-09-29
3// File: toolbar-customization/index.js
4
5import WebViewer from '@pdftron/webviewer';
6
7const licenseKey = 'YOUR_WEBVIEWER_LICENSE_KEY';
8
9
10function initializeWebViewer() {
11 WebViewer(
12 {
13 path: '/lib',
14 initialDoc: 'https://apryse.s3.us-west-1.amazonaws.com/public/files/samples/WebviewerDemoDoc.pdf',
15 enableFilePicker: true, // Enable file picker to open files. In WebViewer -> menu icon -> Open File
16 enableMeasurement: true,
17 licenseKey: licenseKey, // Replace with your license key
18 },
19 document.getElementById('viewer')
20 ).then((instance) => {
21
22 // Collect webViewer data
23 collectWebViewerData(instance);
24
25 // Customize the webviewer left panel after the load completion
26 instance.Core.documentViewer.addEventListener('documentLoaded', () => {
27 customizeUI();
28 });
29
30 console.log('WebViewer loaded successfully.');
31 }).catch((error) => {
32 console.error('Failed to initialize WebViewer:', error);
33 });
34}
35
36// UI elements section
37
38
39// Object to hold WebViewer related data
40const webViewerData = {
41 instance: null,
42 wcViewer: null,
43 windowDoc: null,
44 defaultBackgroundColor: '',
45};
46
47// Collect webViewer data
48const collectWebViewerData = (instance) => {
49 webViewerData.instance = instance;
50 webViewerData.wcViewer = document.getElementById('wc-viewer');
51 webViewerData.windowDoc = webViewerData.wcViewer?.shadowRoot;
52 let uiElement = webViewerData.windowDoc.querySelector(`[data-element='${UIElements.uiElementsMap[0].id}']`);
53 if (uiElement.style.backgroundColor !== null && uiElement.style.backgroundColor !== '')
54 webViewerData.defaultBackgroundColor = uiElement.style.backgroundColor;
55};
56
57// Customize the webviewer left panel
58const customizeUI = () => {
59 const { UI } = webViewerData.instance;
60
61 // Enable the customizable UI feature flag
62 UI.enableFeatureFlag(UI.FeatureFlags.CUSTOMIZABLE_UI);
63
64 // Enable all UI elements initially
65 UI.enableAllElements();
66
67 // Fit the page to the viewer width
68 UI.setFitMode(UI.FitMode.FitPage);
69
70 // Set the layout to single page mode
71 UI.setLayoutMode(UI.LayoutMode.Single);
72
73 // Keep the page navigation component on screen all the time
74 UI.disableFadePageNavigationComponent();
75
76 // Enable the annotation toolbar group
77 UI.enableElements(['toolbarGroup-Annotate']);
78
79 // Close the tab panel (if it's open) for refreshment.
80 UI.closeElements([UIElements.tabPanel.dataElement]);
81
82 // Get the list of registered panels in the webviewer
83 UIElements.viewerPanels = UI.getPanels();
84
85 // Find the Tab Panel to modify. The customize toolbar sub-panel will be added to this Tab panel.
86 UIElements.tabPanel.handle = UIElements.viewerPanels.find((panel) => panel.dataElement === UIElements.tabPanel.dataElement);
87
88 // Register the customize toolbar sub-panel
89 RegisterCustomizeToolbarPanel();
90
91 // Add the new customize toolbar sub-panel to list of sub-panels under the Tab Panel
92 UIElements.customizeToolbarPanel.handle = { render: UIElements.customizeToolbarPanel.dataElement };
93 UIElements.tabPanel.handle.panelsList = [UIElements.customizeToolbarPanel.handle, ...UIElements.tabPanel.handle.panelsList];
94
95 UI.openElements([UIElements.tabPanel.dataElement]);
96};
97
98// Register the customize toolbar sub-panel
99const RegisterCustomizeToolbarPanel = () => {
100 UIElements.customizeToolbarPanel.render = UIElements.createCustomizeToolbarPanelElements();
101 webViewerData.instance.UI.addPanel({
102 dataElement: UIElements.customizeToolbarPanel.dataElement,
103 location: 'left',
104 icon: '<svg fill="#000000" width="18px" height="18px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M30 2.994h-28c-1.099 0-2 0.9-2 2v17.006c0 1.099 0.9 1.999 2 1.999h13v3.006h-5c-0.552 0-1 0.448-1 1s0.448 1 1 1h12c0.552 0 1-0.448 1-1s-0.448-1-1-1h-5v-3.006h13c1.099 0 2-0.9 2-1.999v-17.006c0-1.1-0.901-2-2-2zM30 22h-28v-17.006h28v17.006z"></path></svg>',
105 title: 'Customize Toolbar',
106 render: () => UIElements.customizeToolbarPanel.render,
107 });
108};
109
110// Enable or disable a UI element visibility
111//Made global to be accessible in ui-elements.js
112window.toggleElementVisibility = (element) => {
113 (webViewerData.instance.UI.isElementDisabled(element.id)) ?
114 webViewerData.instance.UI.enableElements([element.id]) :
115 webViewerData.instance.UI.disableElements([element.id]);
116};
117
118// Handle mouse over event, either for a checkbox or label control:
119// - change cursor to pointer
120// - toggle the UI element highlight
121window.controlOnMouseOver = (control, element) => {
122 control.style.cursor = 'pointer';
123
124 // Open the menu overlay when mouse is over the download or print button checkbox/label
125 if (element.id === 'downloadButton' || element.id === 'printButton') {
126 if (webViewerData.instance.UI.isElementDisabled('menuOverlay'))
127 webViewerData.instance.UI.enableElements('menuOverlay');
128
129 if (!webViewerData.instance.UI.isElementOpen('menuOverlay'))
130 webViewerData.instance.UI.openElements('menuOverlay');
131 }
132
133 toggleElementHighlight(element);
134};
135
136// Handle mouse leave event, either for a checkbox or label control:
137// - change cursor to default
138// - toggle the UI element highlight
139window.controlOnMouseLeave = (control, element) => {
140 control.style.cursor = 'default';
141
142 // Close the menu overlay when mouse leaves the download or print button checkbox/label
143 if (element.id === 'downloadButton' || element.id === 'printButton') {
144 if (webViewerData.instance.UI.isElementDisabled('menuOverlay'))
145 webViewerData.instance.UI.enableElements('menuOverlay');
146
147 if (webViewerData.instance.UI.isElementOpen('menuOverlay'))
148 webViewerData.instance.UI.closeElements('menuOverlay');
149 }
150
151 toggleElementHighlight(element);
152};
153
154// Highlight or reset highlight of a UI element
155window.toggleElementHighlight = (element) => {
156 let uiElement = webViewerData.windowDoc.querySelector(`[data-element='${element.id}']`);
157 if (uiElement !== null) {
158 if (uiElement.style.backgroundColor === 'orange')
159 uiElement.style.backgroundColor = webViewerData.defaultBackgroundColor;
160 else
161 uiElement.style.backgroundColor = 'orange';
162 }
163};
164
165//helper function to load the ui-elements.js script
166function loadUIElementsScript() {
167 return new Promise((resolve, reject) => {
168 if (window.UIElements) {
169 console.log('UIElements already loaded');
170 resolve();
171 return;
172 }
173
174 const script = document.createElement('script');
175 script.src = '/showcase-demos/toolbar-customization/ui-elements.js';
176 script.onload = function () {
177 console.log('✅ UIElements script loaded successfully');
178 resolve();
179 };
180 script.onerror = function () {
181 console.error('Failed to load UIElements script');
182 reject(new Error('Failed to load ui-elements.js'));
183 };
184 document.head.appendChild(script);
185 });
186}
187
188// Load UIElements script first, then initialize WebViewer
189loadUIElementsScript().then(() => {
190 initializeWebViewer();
191}).catch((error) => {
192 console.error('Failed to load UIElements:', error);
193});
194

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales