DocumentationAll ComponentsContact usChangelog

Introduction

The ZUi library ships with library code and components to use portals with web components.
As portals we understand any kind of elements that should break out the current DOM tree.
This is useful e.g. for dialogs, modals, snackbars, tooltips, popovers, select menus, and so on.

Some ZUi components already use this internally to place detached contents without interfering with overflows or layouts, like the zui-select component or the zui-tooltip-directive.

In most cases, you don't need to care for portals because by default all ZUi components create portals dynamically if needed.

Portals can be defined explicitly anywhere in the DOM by creating a zui-portal component.
This element can be reused by referring to its name.

If not, it'll be created dynamically if needed and injected as last element into the body element.
Every implicit usage creates a new portal as required, thus, the latest portal will stay on top.

N.B.: This does currently not work, it is planned for the future.

Convenience directives

In order to use portals, we introduced some directives for convenience. Those can be used to implement several types of detached contents:

╭──────────────────────╮    ╭───────────────────────╮    ╭───────────────────────╮
│ zui-portal-directive │    │ zui-overlay-directive │    │ zui-tooltip-directive │
│ -------------------- ├────┤ --------------------- ├────┤ --------------------- │
│ * static placement   │    │ * dynamic placement   │    │ * dynamic placement   │
│ * centered content   │    │ * relative to host    │    │ * relative to host or │
│                      │    │                       │    │   mouse cursor        │
╰──────────────────────╯    ╰───────────────────────╯    ╰───────────────────────╯

Further documentation can be found at each directive individually.

N.B.: While in theory this could work with your very own components as well, we do not recommend using the zui-portal-directive, nor the zui-overlay-directive any more, because there seem to be so many use cases, that are very hard for us to support.

You are better suited, by using the portal technologies (sic!) of the framework you are using, e.g. createPortal when using React for your own components, for our components you should use the zui-portal if we have implemented user-supplied portal insertion points.

Usage with 3rd party implementations

Basically, our portal implementation shouldn't interfere with others. But due to its nature, there might be conflicts regarding the stacking level. This can be the case when other libraries or tools use a similar technique (z-index) to put detached content on the page. A typical issue is when ZUi components are used in dialogs and some part of a ZUi component (i.e. the drop-down of the zui-select or the picker of the zui-textfield-date-picker) is not visible because it's "below" the dialog.

We provide two ways to solve these issues:

Global level for ZUi components

You can define a global level (think of it as z-index) for all ZUi components. All ZUi components will use this level as a basis for their detached content. This is done by defining a css custom-property --zui-portal-level.

<style>
html {
   --zui-portal-level: 1000;
}
</style>

CSS custom properties are a very flexible solution because it allows you to control for which components the value applies and you can use different values for different parts of your app by adjusting the CSS selector, i.e:

.parent-div {
   --zui-portal-level: 1000;
}

.child-div {
    --zui-portal-level: 1500;
}

In this example, all ZUi components that are children of "parent-div" will have a portal level of 1000 and components under "child-div" will have a value of 1500.

Which value to use depends on the environment of your app, i.e. which third-party libraries you are using. For example, Material UI uses z-index values between 1000 and 1500 (see here). Typically, you should use a value higher then those of other dialogs so that detached content of ZUi components is still visible when used in a third-party dialog.

Examples with angular / react

We provide small example apps that showcase the usage of ZUi components in Angular and React. In these apps, you can also see the usage of portals.

React app

See Usage React for more information on how to use the example app. In the react app a global portal level is set in src/App.css.

On the /portals page you can see an example where both a ZUi dialog and a Material-UI dialog is shown in comparison.

Angula app

See Usage Angular for more information on how to use the example app. In the angular app a global portal level is set in src/styles.css.

On the /portals page you can see an example where a a ZUi dialog and a Material-UI dialog (with Angular CDK) is shown in comparison.

Known issues

There is no well accepted solution to this problem in the web community yet and therefore there are many issues when different libraries with different solutions are combined. As this APIs are quite new, you may experience some issues with them.
Please fill a bug ticket if so and let us know.