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

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales