Some test text!

Search
Hamburger Icon

Web / Guides / Containers

Containers

Overview

Containers are the top-level components that hold all the other components. They are responsible for the layout of the UI and can be nested to create complex layouts.

Some commonly used containers include Modular Headers, Grouped Items, and Ribbon Groups.

containers

Modular headers are the highest level of containers and can contain other containers and items. Grouped items are containers that can hold any kind of item, including other grouped items. Ribbon groups are containers that can only hold ribbon items.

Modular Header

Modular headers are the containers at the highest level. These are the containers that many other components will be placed in. The default UI only has top-aligned headers, but they are able to be placed on the top, left, right, and bottom.

modular header - placement

This means that by switching a property on the header, you can quickly move its position. In the example below, the tools header is set to be on the left.

modular header - left

There are some restrictions on modular headers, mainly:
  • Top headers allow up to two headers stacked on each other
  • The remaining positions only allow one header
DataElements are unique keys
In these guides you will see the usage of dataElements; these should be thought of as unique identifiers for each visual component. If the UI detects duplicate dataElements, it will throw a console warning and add a unique identifier. These dataElements can be used to enable or disable elements, as well as toggle their visibility. Fore more information on these APIs, please refer to the documentation .

The example below shows how to create a top header similar to the one used in the default UI. It also shows some of the options it accepts, such as grow and style. For more details on these options please refer to the API documentation for ModularHeader

Webviewer.WebComponent({
  path: '/lib',
  ui: 'beta',
}, viewerElement).then((instance) => {
  const { UI, Core } = instance;
  const { Tools } = Core;

  // First we define four items that will be placed in the header.
  // Please refer to the Items page for more info on the
  // items that can live inside headers.

  // Menu Flyout Button
  const mainMenu = new UI.Components.MainMenu();
  // View Controls
  const viewControlsToggle = new UI.Components.ViewControls();
  // Zoom Controls
  const zoomControls = new UI.Components.Zoom();
  // Pan Tool Button
  const panToolButton = new UI.Components.ToolButton({
    dataElement: 'panToolButton',
    toolName: Tools.ToolNames.PAN,
  });


  // Creater a top header where we will add the above items
  const topHeader = new instance.UI.Components.ModularHeader({
    dataElement: 'default-top-header',
    placement: 'top',
    grow: 0,
    gap: 12,
    position: 'start',
    stroke: true,
    dimension: {
      paddingTop: 8,
      paddingBottom: 8,
      borderWidth: 1
    },
    style: {},
    items: [
      mainMenu,
      viewControlsToggle,
      zoomControls,
      panToolButton,
    ]
  });

  // Set the modular header in the UI
  instance.UI.setModularHeaders([topHeader]);
});

addModularHeaders

This API allows you to add headers to the existing UI; it is an additive operation. This means that if you call this API multiple times, it will add the headers to the UI, not replace them. In the example above, if we used this API instead of setModularHeaders, the top header would have been added to the existing UI. This API is useful when you want to add a header to the default UI.

Example usage:

const { Tools } = instance.Core;
// Pan Tool Button
const panToolButton = new instance.UI.Components.ToolButton({
  dataElement: 'panToolButton',
  toolName: Tools.ToolNames.PAN,
});

const topHeader = new instance.UI.Components.ModularHeader({
  dataElement: 'default-top-header',
  placement: 'top',
  grow: 0,
  gap: 12,
  position: 'start',
  stroke: true,
  dimension: {
    paddingTop: 8,
    paddingBottom: 8,
    borderWidth: 1
  },
  style: {},
  // As an example we add the pan tool button to the top header
  items: [panToolButton]
});

instance.UI.addModularHeaders([topHeader]);

setModularHeaders

This API sets the headers for the UI, replacing any existing headers. This is useful when you want to replace the default headers with your own.

Example usage:

const { Tools } = instance.Core;
// Pan Tool Button
const panToolButton = new instance.UI.Components.ToolButton({
  dataElement: 'panToolButton',
  toolName: Tools.ToolNames.PAN,
});

const topHeader = new instance.UI.Components.ModularHeader({
  dataElement: 'default-top-header',
  placement: 'top',
  grow: 0,
  gap: 12,
  position: 'start',
  stroke: true,
  dimension: {
    paddingTop: 8,
    paddingBottom: 8,
    borderWidth: 1
  },
  style: {},
  // As an example we add the pan tool button to the top header
  items: [panToolButton]
});

instance.UI.setModularHeaders([topHeader]);

getModularHeaderList

This API will return a list of all the modular headers in the current UI. The modular headers are encapsulated in class instances that have handy methods that give you the capability to dynamically update headers. For the methods available for each class please refer to the documentation of each class.

Example usage:

const modularHeaders = instance.UI.getModularHeaderList();

getModularHeader

If you already know the dataElement of the header you wish to manipulate you can use this API. You can find the dataElements by inspecting the UI using your browser’s dev tools.

Example usage:

const defaultHeader = instance.UI.getModularHeader('default-top-header')

getGroupedItems

Returns the grouped items contained in the header. Note that it will only return the grouped items contained at the top level - it will not recursively find all grouped items contained within this header.

Example usage:

const topHeader = instance.UI.getModularHeader('default-top-header')
const topHeaderGroupedItems = topHeader.getGroupedItems()

getItems

This method will return all the items contained in the header. It takes an optional parameter of itemType; if passed it will return the items contained in the header that match this type.

Example usage:

const topHeader = instance.UI.getModularHeader('default-top-header')
// Returns all items contained in the header
const topHeaderItems = topHeader.getItems()
// Returns all items of type toggleButton
const topHeaderToggleButtons = topHeader.getItems('toggleButton')

setGap

This method allows you to set the gap between header items. It takes an integer value in pixels.

Example usage:

const topHeader = instance.UI.getModularHeader('default-top-header')
topHeader.setGap(50)

setItems

Sets the child items of the modular header. This method will remove any invalid items.

Example usage:

const topHeader = instance.UI.getModularHeader('default-top-header')
const stylePanelToggle = new instance.UI.Components.ToggleElementButton({
    dataElement: 'stylePanelToggle',
    toggleElement: instance.UI.Panels.STYLE,
    img: 'icon-style-panel-toggle',
    title: 'Style Panel',
  });

// This replaces all items in the header
topHeader.setItems([stylePanelToggle])

setJustifyContent

Sets the content justification within a header. The header can be thought of as a flex container and this is the property to set the justification of the flex items. The value can be one of start, end, center, space-between, space-around, or space-evenly.

Example usage:

const toolsHeader = instance.UI.getModularHeader('tools-header')
toolsHeader.setJustifyContent('start')

setStyle

This method allows you to pass your own style object, overriding the default styles.

Example usage:

const topHeader = instance.UI.getModularHeader('default-top-header')
topHeader.setStyle({
    background: 'aliceblue',
    border: '8px dashed',
    padding: '8px 12px'
});

Grouped Items

Grouped items are light-weight containers that are placed in other containers and can house any kind of item. In the WebViewer default modular UI, grouped items are used mainly for holding tool buttons and action buttons that interact with the document. They can also house other grouped items. They work similarly to flex-box containers and can be styled like them.

grouped items

If there is not enough space for all grouped items to be displayed in their container, there will be a more button (...) that will show in the container which will allow the user to see the rest of the items.

grouped items

In the default UI, grouped items are used to hold the buttons in the top header. The example below shows how to create a grouped item similar to one the default UI.

const { Tools } = instance.Core;

// Create some components that can go into a grouped items container
// Menu Flyout Button
const mainMenu = new instance.UI.Components.MainMenu();
// View Controls
const viewControlsToggle = new instance.UI.Components.ViewControls();
// Zoom Controls
const zoomControls = new instance.UI.Components.Zoom();
// Pan Tool Button
const panToolButton = new instance.UI.Components.ToolButton({
  dataElement: 'panToolButton',
  toolName: Tools.ToolNames.PAN,
});
// create the grouped items container
const groupedLeftHeaderButtons = new instance.UI.Components.GroupedItems({
  dataElement: 'groupedLeftHeaderButtons',
  grow: 0,
  gap: 12,
  position: 'start',
  style: {},
  items: [
    mainMenu,
    viewControlsToggle,
    zoomControls,
  ],
  // either make this visible all the time or only when active
  alwaysVisible: true,
});

// now we can add this grouped items container to a modular header
const defaultTopHeader = new instance.UI.Components.ModularHeader({
  dataElement: 'default-top-header',
  placement: 'top',
  grow: 0,
  gap: 12,
  position: 'start',
  stroke: true,
  dimension: {
    paddingTop: 8,
    paddingBottom: 8,
    borderWidth: 1
  },
  style: {},
  items: [
    groupedLeftHeaderButtons,
  ]
});

instance.UI.setModularHeaders([defaultTopHeader]);
If a grouped items container is set to 'alwaysVisible: true', it will always be visible, even if it is not active. If it is set to 'alwaysVisible: false', it will only be visible when it is active (i.e. set by a Ribbon Item). The default value is false.

You can also add a grouped items container to a modular header after it has been created. Let's reuse our example from above and add the grouped items container to the top header.

const { Tools } = instance.Core;

// Create some components that can go into a grouped items container
// Menu Flyout Button
const mainMenu = new instance.UI.Components.MainMenu();
// View Controls
const viewControlsToggle = new instance.UI.Components.ViewControls();
// Zoom Controls
const zoomControls = new instance.UI.Components.Zoom();
// Pan Tool Button
const panToolButton = new instance.UI.Components.ToolButton({
  dataElement: 'panToolButton',
  toolName: Tools.ToolNames.PAN,
});
// create the grouped items container
const groupedLeftHeaderButtons = new instance.UI.Components.GroupedItems({
  dataElement: 'groupedLeftHeaderButtons',
  grow: 0,
  gap: 12,
  position: 'start',
  style: {},
  items: [
    mainMenu,
    viewControlsToggle,
    zoomControls,
  ],
  // either make this visible all the time or only when active
  alwaysVisible: true,
});

const topHeader = instance.UI.getModularHeader('default-top-header')

// or you can add the grouped items to the header after it has been created
topHeader.setItems([groupedLeftHeaderButtons])

Grouped items can be modified in two ways: by calling methods directly on the class instances, or by calling several generic APIs. The generic APIs can modify properties of specific grouped items, or all grouped items, depending on the options passed.

The following APIs have a requirement that the grouped items are already part of the UI - if they have not been added with as part of a header 'addModularHeaders' or 'setModularHeaders' the APIs will have no effect

setGroupedItemsGap

Used to set the gap in pixels for items inside grouped items containers. This can set the property on all grouped items if the second parameter is not provided, or can set it on a specific container if the second parameter is provided with the dataElement of the container being updated.

// Setting the gap of all Grouped Items
instance.UI.setGroupedItemsGap(20);

// Setting the gap on Grouped Items with a specific data element
instance.UI.setGroupedItemsGap(30, {
  groupedItemsDataElement: 'annotateGroupedItems'
});

setGroupedItemsGrow

Used to set the grow property of a grouped items container. The grow property is a number specifying how much the item wil grow relative to the rest of the items; it is equivalent to the grow property for flex boxes. This API can set the property on all grouped items if the second parameter is not provided, or can set it on a specific container if the second parameter is provided with the dataElement of the container being updated.

// Setting the grow property of all Grouped Items
instance.UI.setGroupedItemsGrow(1);

// Setting the grow property of all Grouped Items with a specific data element
instance.UI.setGroupedItemsGrow(1, {
  groupedItemsDataElement: 'group-1'
});

setGroupedItemsJustifyContent

Used to set the justifyContent property of a grouped items container. This can set the property on all grouped items if the second parameter is not provided, or can set it on a specific container if the second parameter is provided with the dataElement of the container being updated.

// Setting the justifyContent property of all Grouped Items
instance.UI.setGroupedItemsJustifyContent('start');

// Setting the justifyContent property of all Grouped Items with a specific data element
instance.UI.setGroupedItemsJustifyContent('space-between', {
  groupedItemsDataElement: 'group-1'
});

Grouped Items Class Methods

These APIs apply to all objects of the Grouped Items class (including Ribbon Group):

setGap(int): Sets the gap between items. Takes a value in pixels.

const topHeader = instance.UI.getModularHeader('default-top-header')
const groupedLeftItems = topHeader.getGroupedItems()[0]
groupedLeftItems.setGap(20)

setGrow(number): Sets the flex-grow property of the items container. The grow property is a number specifying how much the item wil grow relative to the rest of the items; it is equivalent to the grow property for flex boxes.

const topHeader = instance.UI.getModularHeader('default-top-header')
const groupedLeftItems = topHeader.getGroupedItems()[0]
groupedLeftItems.setGrow(1)

setItems(Array): Sets the items in the group, replacing the existing items.

const topHeader = instance.UI.getModularHeader('default-top-header')
const groupedLeftItems = topHeader.getGroupedItems()[0];
const stylePanelToggle = new instance.UI.Components.ToggleElementButton({
    dataElement: 'stylePanelToggle',
    toggleElement: instance.UI.Panels.STYLE,
    img: 'icon-style-panel-toggle',
    title: 'component.notesPanel',
  });
const notesPanelToggle = new instance.UI.Components.ToggleElementButton({
    dataElement: 'notesPanelToggle',
    toggleElement: 'notesPanel',
    img: 'icon-header-chat-line',
    title: 'component.notesPanel',
  });

// Replace all items with these two toggle buttons
groupedLeftItems.setItems([notesPanelToggle, stylePanelToggle])

setJustifyContent(string): Sets the content of the grouped items container. You can think of the container as a flex container, and this is the property to set the justification of the flex items.

const topHeader = instance.UI.getModularHeader('default-top-header')
const groupedLeftItems = topHeader.getGroupedItems()[0]
groupedLeftItems.setJustifyContent('end')

setStyle(Object): Sets the CSS style of the grouped items. This method allows you to pass your own style object, overriding the default styles.

const topHeader = instance.UI.getModularHeader('default-top-header')
const groupedLeftItems = topHeader.getGroupedItems()[0]
groupedLeftItems.setStyle({
  background: 'aliceblue',
  border: '8px dashed',
  padding: '8px 12px'
});

Ribbon Group

Ribbon Groups are just like grouped items with one exception: they can only house Ribbon Items. This is to ensure consistent styling throughout the UI for things such as the currently active ribbon.

If a non-ribbon item is included in the set of items for a ribbon group, it will be ignored.

ribbon group

If there is not enough space for all ribbon items to be displayed in their container, there will be a more button (...) that will show in the container which will allow the user to see the rest of the items.

ribbon group

If there is only enough space for one ribbon item, the ribbon group turns into a dropdown to take up less space.

ribbon group

The following code sample shows how to create a ribbon group with two ribbon items, each mapping to different grouped items container with certain tools.

const { Tools } = instance.Core;
// First let's define some tools that we can place in the grouped items containers
const highlightToolButton = new instance.UI.Components.ToolButton({
  dataElement: 'my-highlightToolButton-',
  toolName: Tools.ToolNames.HIGHLIGHT,
});

const freeTextToolButton = new instance.UI.Components.ToolButton({
  dataElement: 'my-freeTextToolButto',
  toolName: Tools.ToolNames.FREETEXT,
});

const rectangleToolButton = new instance.UI.Components.ToolButton({
  dataElement: 'my-rectangleToolButton',
  toolName: Tools.ToolNames.RECTANGLE,
});

const polylineToolButton = new instance.UI.Components.ToolButton({
    dataElement: 'my-polylineToolButton',
    toolName: Tools.ToolNames.POLYLINE,
});

// Now we can create two grouped items containers to hold the tools
const textToolsGroupedItems = new instance.UI.Components.GroupedItems({
  dataElement: 'textToolsGroupedItems',
  items: [
    freeTextToolButton,
    highlightToolButton,
  ],
});

const shapeToolsGroupedItems = new instance.UI.Components.GroupedItems({
  dataElement: 'shapeToolsGroupedItems',
  style: {},
  items: [
    rectangleToolButton,
    polylineToolButton,
  ],
});

// Now we can create the ribbon items that will map to the grouped items containers
const textRibbonItem = new instance.UI.Components.RibbonItem({
  dataElement: 'textRibbonItem',
  label: 'Text Tools',
  // Ribbon items can support Icons
  img: 'icon-tool-text-free-text',
  groupedItems: ['textToolsGroupedItems'],
});

const shapeRibbonItem = new instance.UI.Components.RibbonItem({
  dataElement: 'shapeRibbonItem',
  label: 'Shape Tools',
  img: 'icon-tool-shape-rectangle',
  // This maps to the grouped items container - a ribbon item can map to one or more grouped items containers
  groupedItems: ['shapeToolsGroupedItems'],
});

// Now we can create the ribbon group that will hold the ribbon items
const ribbonGroup = new instance.UI.Components.RibbonGroup({
  dataElement: 'my-ribbon-group',
  title: 'Cusotm Ribbon Group',
  items: [
    textRibbonItem,
    shapeRibbonItem,
  ],
});

// Now let's bring it home by adding the ribbon group to the UI
const topHeader = instance.UI.getModularHeader('default-top-header')
topHeader.setItems([ribbonGroup])
// We can also modify the justification in the header so it's centered
topHeader.setJustifyContent('center')

// And let's also add the tools grouped items to the tools header
const toolsHeader = instance.UI.getModularHeader('tools-header')
toolsHeader.setItems([textToolsGroupedItems, shapeToolsGroupedItems])

Running the above code will create the following UI: custom-ribbons

Alternatively, you can create a new header and add your ribbon.

// create the modular header with the ribbon group set in items
const defaultTopHeader = new instance.UI.Components.ModularHeader({
  ...
  items: [
    ribbonGroup,
    ...
  ]
});

Ribbon Group Methods

Since Ribbon Groups are a subclass of Grouped Items, they have all the same methods as Grouped Items. See the Grouped Items Class Methods for more information. This means that you can modify the ribbon that is shipped by default using these APIs, instead of creating your own from scratch.

Get the answers you need: Chat with us