DocumentationAll ComponentsContact usChangelog

On the misson of ZUi to become micro-frontend (mFE) - ready we have found, that the old approach of global, runtime-based theming does not work in more advanced use case and for ZUi web components themselves. Thus with build time theming we also changed the internal code infrastructure for themes, to make maintenance easier and development less error-prone for ZUi.

if you are using zui version 2.x.x and want to update of the latest 3.x.x have a look at the Migrationguide.

Using themes directly from @zeiss/zui

Starting with @zeiss/zui@2.11.0-beta.7 all of the current theming utility functions are now accessible directly from @zeiss/zui itself, so you do not need to add @zeiss/zui-themes anymore to your project.:

before:

import {
  themeZbdsBase,
  themeZbdsLight,
  themeZbdsDark,
  themeZbdsTranslucent,
  registerTheme,
  setAppTheme
} from '@zeiss/zui-themes';

registerTheme(themeZbdsBase);
registerTheme(themeZbdsLight);
registerTheme(themeZbdsDark);
registerTheme(themeZbdsTranslucent);

setAppTheme('zbds-light');

This will simply change to after:

import {
  themeZbdsBase,
  themeZbdsLight,
  themeZbdsDark,
  registerTheme,
  setAppTheme
// now use it directly from zui!
} from '@zeiss/zui';

registerTheme(themeZbdsBase);
registerTheme(themeZbdsLight);
registerTheme(themeZbdsDark);

setAppTheme('zbds-light');

N.B.: Don't you worry, @zeiss/zui-themes still continues to work, because it is now just a re-export from @zeiss/zui; but it will be deprecated soon. Notice: with v3.2 @zeiss/zui-themes is deprecated.

Build Time Theming

Another design decision that we made to become mFE-ready is, that now all components are actually self-contained and bring their own themes when build time theming is used. This allows for multiple versions of the same theme (think: 'light' vs. 'zbds-light') to be used on a web site, when final mFE support is shipped.

When build time theming is enabled, the existing imperative theming API will become obsolete, meaning you do not have to make any calls to registerTheme() etc. anymore.

N.B.: Don't you worry, if you enable build time theming, you can still use the imperative API, but it won't do any harm, because it then simply does nothing.

Diabling build time theming

Because build time theming is such a big conceptual change, you have the option to disable this. We won't be supporting runtime themes in the future and there will be a point - after a certain grace period, where you will have to opt-out of it.

Diabling build time theming can be done in two different ways:

Opt-in into build time theming using a query parameter

You simply have to pass zui-feature-disable-build-themes as a query parameter (with no value). This is especially useful, if you want to compare your applications side-by-side, simply use the latest beta version of zui and open your local dev server twice and add to the second instance feature-disable-build-themes as a proper query parameter.

Have a look at:

This is the way to go, to test whether things break in your application, without having to touch your code.

(permanently) Opt-out into build time theming using session storage

You can permanently opt-out into build time theming by setting a feature flag on sessionStorage:

window.sessionStorage.setItem(
  'zui.features',
  JSON.stringify({
    'feature-disable-build-themes': true
  })
);

N.B.: You have to make sure, that this is set before any component, that should use build time theming is added to the document, i.e. either in a <script> within <head> or in case of Angular in its polyfills.ts.

Switching themes

The old API for switching themes, was simply adding a theme attribute to any DOM element. Now there is an explicit provider component for this, the zui-theme-provider, changing its theme attribute will change the themes of all descending ZUi components, regardless whether they are in nested ShadowDOM or not.

before:

<!-- [...] leaving out imperative setup for brevity -->
<div theme="light">
  <zui-button>I am a light-hearted button!</zui-button>
</div>

after:

<zui-theme-provider theme="light">
  <zui-button>I am a light-hearted button!</zui-button>
</zui-theme-provider>

N.B.: You can nest zui-theme-provider and you can still explicitly set themes on components. Explicitly set themes always win over the zui-theme-provider.

N.B.: If a component does not find a parent zui-theme-provider in the DOM, its theme will default to light.

Build Time Theming benefits

Declarative usage

Apart from being the basis for mFE-readiness, using build time theming, allows you to use ZUi completely declaratively, if you supply the various NotoSans fonts at public/fonts. @zeiss/zui conveniently ships with NotoSans in public for all your vendor-copy needs. If you need to supply them from another location, you can use the old imperative API registerTypefaces() with an URL.

Mix+Match

You can use any combination of themes; this was not possible before and you can also now securely use ZUi components in nested ShadowDOM.

Build Time Theming limitations

Visual differences

While we spent a lot of time, making sure, that we won't break the existing APIs, we figured out, that when you enable build time theming we accidentally fixed ™ bugs, i.e. there might be some minor visual differences, but they should actually be now conforming to the design guide.

Overwriting themes is not supported anymore

Now, that components are self-contained, it becomes hard to overwrite the themes or supply your own theme. While in theory this was possible with runtime theming, no one ever used it and it never worked to that extent, that it would justify retaining that API.

Rule of one

You cannot mix+match runtime theming with build time theming. While you can turn the old imperative runtime theming into build time theming, by opting in, this does not work vice versa. This also does not allow to use the 'theme' attribute on arbitrary DOM elements.

One Font to rule them all

All themes are sharing the same set of global font rules, thus fonts are consequently still added to the global scope. This is not very likely to change in the future.

Migration Guide

Migrating your code base to build time theming is very easy:

  1. Use latest beta version of @zeiss/zui(e.g. npm i --save @zeiss/zui@beta)
  2. Verify that everything works™ , by simply opting into build time theming using the query parameter.
  3. Replace the points in your application (templates), that switches the theme from a wrapper element with 'theme' attribute (e.g. <div id="theme-wrapper" theme="dark"> to <zui-theme-provider id="theme-wrapper" theme="dark">
  4. Replace imperative API setAppTheme() with code / template magic, that simply modifies the 'theme' attribute of above zui-theme-provider
  5. Remove imperative theme API calls registerTheme()
  6. Replace any left imports from @zeiss/zui-themes with @zeiss/zui
  7. Remove dependency to @zeiss/zui-themes altogether