Skip to content

PDF Generation Template Editor

Open-source visual PDF generation engine with customizable templates and developer-friendly APIs.

View on GitHub

Customize the Navigation Bar ​

One key part of customizing the UI is the customization of the navigation bar. There are several ways you may want to customize the navigation bar. To name a few:

  • Add a custom save button.
  • Remove existing tools from the navigation bar.
  • Rearrange the feature area.
  • Hide the text field tool in the sub-menus of the forms feature and move them to the right side of the navigation bar.

ComPDF for Web's WebViewer UI is built from modular components (headers, ribbon groups, grouped items and buttons) and provides flexible APIs for easy customization of the navigation bar.

To understand the structure of the navigation bar and the different types of tools, you can read The Composition of the Navigation Bar and Navigation Bar Tools. You can also jump directly to the UI Customization Samples to see examples of customizing the navigation bar.

The Composition of the Navigation Bar ​

The navigation bar is mainly divided into three parts: Navigation Tools, Feature Area, and the sub-menus of corresponding features (including sub-toolbars).

  • Navigation Tools: The icon buttons on the left and right sides of the image below (Navigation Bar) are the Navigation Tools. They are the items of the top header default-top-header, for example leftPanelButton, fullscreenButton, panToolButton, zoom-container, snippingToolButton, searchPanelToggle and menuButton.

    navigation tools example

  • Feature Area: The part inside the feature box in the middle of the navigation bar is called the Feature Area (as shown in the image below). Each feature has a different Sub-Menus. Buttons in both the Feature Area and the Sub-Menus can be modified individually. The Feature Area is the ribbon group default-ribbon-group, and each feature is a ribbon item whose dataElement is its toolbar group, such as toolbarGroup-View, toolbarGroup-Annotate, toolbarGroup-Forms, toolbarGroup-Measure, toolbarGroup-FillAndSign, toolbarGroup-Security, toolbarGroup-Redact, toolbarGroup-Compare, toolbarGroup-EditText, toolbarGroup-Document and toolbarGroup-Separation. feature-area

  • Sub-Menus: Under different Feature Areas, there are corresponding Sub-Menus showing a group of tools for that feature. ComPDF for Web provides various APIs to customize the tools within this Sub-Menus. The Sub-Menus are shown in the header tools-header, and each one is a grouped items component, such as annotateGroupedItems and formsGroupedItems. Below, the Sub-Menus for annotations and forms are shown:

    sub-menus-annotations

    sub-menus-forms

Hide/Show Navigation Bar Elements ​

Find the Data Element Attribute of the Navigation Bar

To hide or show navigation bar elements, you first need to find the element’s data-element attribute in the DOM inspector.

For Example, the image below is the DOM of the Toolbar of the Feature Area.

feature area tools

We can see that their data-element value. Now we can use this value to hide or show it.

Hiding/Showing Navigation Bar Elements

  • Hide/Show the annotation button in the Feature Area:
javascript
// Hide the annotation button in the feature area.
instance.UI.disableElements('toolbarGroup-Annotate');
// Show the annotation button in the feature area.
instance.UI.enableElements('toolbarGroup-Annotate');
  • Hide/Show multiple navigation bar elements:
javascript
// Hide the left panel button and the search button.
instance.UI.disableElements(['leftPanelButton', 'searchPanelToggle']);
// Show the left panel button and the search button.
instance.UI.enableElements(['leftPanelButton', 'searchPanelToggle']);

Switching Feature Areas ​

You can call setToolbarGroup to switch between the different feature modes in the Feature Area.

javascript
import ComPDFKitViewer from "@compdfkit_pdf_sdk/webviewer";

const viewer = document.getElementById('webviewer');

ComPDFKitViewer({
  path: '/',
  initialDoc: 'Your PDF Url',
  licenseKey: 'Input your license here'
}, viewer)
  .then((instance) => {
    // Set the current toolbar group.
    instance.UI.setToolbarGroup('toolbarGroup-Annotate');
  });

Properties and Types of Navigation Tools ​

Navigation Tools are modular components. You can add, remove, or move Navigation Tool buttons by getting a header with getModularHeader and calling its setItems method. The components are created with the classes in instance.UI.Components. If you would like to add custom tools to the navigation bar, it is crucial to understand what types of custom tools you need to add and which attributes to use. Below are the properties and types for Navigation Tools.

javascript
const { Components } = instance.UI;

instance.UI.getModularHeader('default-top-header').setItems([
  new Components.ToolButton({
    dataElement: 'panToolButton',
    toolName: 'Pan',
  }),
  new Components.ToggleElementButton({
    dataElement: 'searchPanelToggle',
    toggleElement: 'searchPanel',
    img: 'Search',
  }),
  new Components.Divider({ dataElement: 'myDivider' }),
  new Components.CustomButton({
    dataElement: 'myDownloadButton',
    label: 'Download',
    onClick: () => instance.UI.downloadPdf(),
  }),
]);

1. Set the Header

getModularHeader(dataElement) returns the header object. It provides getItems, setItems, getGroupedItems, setGap, setJustifyContent, setMaxWidth, setMaxHeight and setStyle to perform corresponding operations on navigation tools. getModularHeaderList() returns all headers, including the top header default-top-header and the sub-menu header tools-header.

javascript
// Get all items of the top header.
const items = instance.UI.getModularHeader('default-top-header').getItems();
console.log(items);

2. Custom Button

A custom button can trigger an action. Clicking it does not toggle a selected state; use isActive to show it as selected. Its properties include:

  • dataElement (string) - Set the data-element value of the button element. It can be used to disable/enable the element.
  • img (string, optional) - The name of a built-in icon (such as Download or Search), path to an image, base64 data or an SVG string.
  • onClick (function) - Function to be triggered on click.
  • isActive (boolean | function, optional) - Shows the button as selected, with the same look as an active tool button. A boolean, or a function that returns one. Change it with instance.UI.updateElement(dataElement, { isActive }).
  • title (string, optional) - Tooltip of the button.
  • label (string, optional) - Set the text displayed for the button.
  • style (object, optional) - Inline styles of the button.
  • hidden (array of strings, optional) - Option to hide the element at certain screen sizes. Accepted strings are desktop, tablet, mobile and small-mobile.
javascript
const newCustomButton = new instance.UI.Components.CustomButton({
  img: 'Search', // A built-in icon name. An image URL or an SVG string also works.
  label: 'Alert',
  onClick: () => {
    alert('Hello world!');
  },
  dataElement: 'alertButton'
});

// Show the button as selected.
instance.UI.updateElement('alertButton', { isActive: true });

3. State Button

The state button is a customizable button. You can decide how many states it has, what state is active, and when to update the state. Its properties include:

  • initialState (string) - String that is one of states object's keys.
  • states (object) - The shape of the object looks like: { nameOfState1: state1, nameOfState2: state2, ... }
  • The properties of states include:
    • img (string, optional): Path to an image, base64 data or an SVG string.
    • title (string, optional): Tooltip of the button in this state.
    • getContent (function, optional): Function to be called when you update the state. Define this property if you don't use the img property for this button. getContent has a parameter activeState. activeState is the object of the active state in states.
    • onClick (function): A function that is triggered when clicked. onClick has two parameters: update and activeState. activeState is the object of the active state in states. Call update() to update the button after changing activeState, or update(nameOfState) to switch to another state.
    • More properties you need.
  • mount (function, optional) - Function to be called after the button is mounted into DOM. It has a parameter update, the same function as in onClick.
  • unmount (function, optional) - Function to be called before the button is unmounted from DOM.
  • title (string, optional) - Tooltip of the button.
  • dataElement (string) - String to set data-element value of the button element.
  • hidden (array of strings, optional) - Option to hide the element at certain screen sizes. Accepted strings are desktop, tablet, mobile and small-mobile.

Examples:

A stateful button that shows the count. When you click it, it will increment the counter by 1.

javascript
const countButton = new instance.UI.Components.StatefulButton({
  initialState: 'Count',
  states: {
    Count: {
      number: 1,
      getContent: activeState => {
        return activeState.number;
      },
      onClick: (update, activeState) => {
        activeState.number += 1;
        update();
      }
    }
  },
  dataElement: 'countButton'
});

A state button showing the current page number. When you click it, the document will go to the next page. If you are on the last page, the document will turn to the first page.

javascript
const { documentViewer } = instance.Core;

const nextPageButton = new instance.UI.Components.StatefulButton({
  initialState: 'Page',
  states: {
    Page: {
      getContent: () => documentViewer.getCurrentPage(),
      onClick: (update) => {
        const currentPage = documentViewer.getCurrentPage();
        const totalPages = documentViewer.getPageCount();
        const atLastPage = currentPage === totalPages;

        if (atLastPage) {
          documentViewer.setCurrentPage(1);
        } else {
          documentViewer.setCurrentPage(currentPage + 1);
        }
        update();
      }
    }
  },
  mount: () => {
    // Execute after mounting.
    console.log('Mounted.');
  },
  unmount: () => {
    // Execute before destruction.
    console.log('Destroyed.');
  },
  dataElement: 'nextPageButton'
});

4. Toggle Element Button

The toggle element button is used to open/close a specified UI element. When the UI element is open, the button is in an active state.

Its properties include:

  • dataElement (string) - Set the data-element value of the button element. It can be used for showing/hiding that element.
  • toggleElement (string) - The data-element value of the UI element to be opened/closed.
  • img (string, optional) - The name of a built-in icon, such as Search or Pageset.
  • title (string, optional) - Tooltip text for the button.
  • label (string, optional) - Set the text displayed for the button.
  • hidden (array of strings, optional) - Option to hide the element at certain screen sizes. Accepted strings are desktop, tablet, mobile and small-mobile.
javascript
const newToggleButton = new instance.UI.Components.ToggleElementButton({
  img: 'Pageset',
  toggleElement: 'pageModePanel',
  dataElement: 'pageModePanelButton',
  hidden: [ 'mobile' ]
});

5. Tool Button

The tool button is the button in the sub-menus under the feature module. For example, in the Form feature mode, you can create a button for a text field function by customizing a tool button and specifying its tool name as TextFormFieldCreateTool. You can place the tool buttons you need to customize anywhere. When the tool is activated, the button is in an active state.

Its properties include:

  • dataElement (string) - Set the data-element value of the button element. It can be used for showing/hiding that element.
  • toolName (string) - The name of the target tool, such as Pan, AnnotationCreateLine or TextFormFieldCreateTool.
  • img (string, optional) - The name of a built-in icon, such as TextFieldIcon or LineTool. When it is not set, the icon registered with registerTool is used.
  • title (string, optional) - Tooltip of the button.
  • label (string, optional) - Set the text displayed for the button.
  • hidden (array of strings, optional) - Option to hide the element at certain screen sizes. Accepted strings are desktop, tablet, mobile and small-mobile.
javascript
const newToolButton = new instance.UI.Components.ToolButton({
  toolName: 'TextFormFieldCreateTool',
  img: 'TextFieldIcon',
  dataElement: 'textfieldButton'
});

6. Spacer

The spacer is an empty grouped items component with grow set to 1, used to occupy any remaining space in the tool. It is used to push buttons to each side of the default title.

Its properties include:

  • dataElement (string) - Set the data-element value of the spacer.
  • items (array) - Must be set to an empty array [].
  • grow (number) - Must be set to 1 to occupy the remaining space.
  • alwaysVisible (boolean) - Must be set to true to always show the spacer.
  • hidden (array of strings, optional) - Option to hide the element at certain screen sizes. Accepted strings are desktop, tablet, mobile and small-mobile.
javascript
const newSpacer = new instance.UI.Components.GroupedItems({
  dataElement: 'newSpacer',
  items: [],
  grow: 1,
  alwaysVisible: true,
  hidden: [ 'mobile', 'small-mobile' ]
});

7. Divider

Divider renders a vertical bar with some margin to separate item groups.

Its properties include:

  • dataElement (string) - Set the data-element value of the divider.
  • hidden (array of strings, optional) - Option to hide the element at certain screen sizes. Accepted strings are desktop, tablet, mobile and small-mobile.
javascript
const newDivider = new instance.UI.Components.Divider({
  dataElement: 'newDivider',
  hidden: [ 'mobile', 'small-mobile' ]
});

Examples of Custom UI ​

Add a custom save button:

javascript
const header = instance.UI.getModularHeader('default-top-header');
const mySaveButton = new instance.UI.Components.CustomButton({
  dataElement: 'mySaveButton',
  img: `<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
          <path d="M13 1L1 13" stroke="#BABABA" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
          <path d="M1 1L13 13" stroke="#BABABA" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
        </svg>`,
  onClick: function() {
    instance.UI.downloadPdf();
  }
});
header.setItems([...header.getItems(), mySaveButton]);

Hide the free text tool in the annotation sub-menus and put it on the right side of the navigation bar:

javascript
const { Components } = instance.UI;
const annotateItems = instance.UI.getGroupedItems('annotateGroupedItems');
const header = instance.UI.getModularHeader('default-top-header');
// get the free text tool.
const freetext = annotateItems.items.find(item => item.dataElement === 'freeTextToolButton');
annotateItems.setItems(annotateItems.items.filter(item => item !== freetext));
// add the line tool and the free text tool to the top header.
header.setItems([
  ...header.getItems(),
  new Components.ToolButton({
    toolName: 'AnnotationCreateLine',
    img: 'LineTool',
    dataElement: 'lineButton'
  }),
  freetext
]);

Remove existing buttons from the top header, leaving only the ribbon:

javascript
const header = instance.UI.getModularHeader('default-top-header');
const items = header.getItems().filter(item => item.dataElement === 'default-ribbon-group');
header.setItems(items);

Display and hide of bottom page box:

javascript
// Hide bottom page box.
instance.UI.disableElements('page-nav-floating-header');
// Show bottom page box.
instance.UI.enableElements('page-nav-floating-header');