Skip to content

How it works

The ZDS development libraries try to adapt to the multiple use cases that we have inside Zurich when it comes to applications development. That requires to have tooling that is flexible, progressive, and that can deal with all the minor issues by hiding the management of the complexity of use and configuration under simplified interfaces that are still giving the control to the developer and the app environment to make the integration as easy as possible.

Design tokens

In order to simplify the design, improve consistency, allow customization, and make the whole ZDS more systematic, we use the concept of design token during the design phase (by using Figma variables) and for our development libraries (by using CSS custom properties, AKA CSS variables).

The main difference between this type of variables and the ones used in CSS preprocessors like Sass (SCSS) is that these variables work at runtime and keep the references, they are not simple placeholders substituted in transpilation time.

This is translated in the end into a base NPM package called @zurich/design-tokens that any other web-based components package will be using.

Multi-paradigm

We need to give support to multiple platforms, frameworks, and workflows with this design system. That's why we have develop two different approaches to use the designed components:

  • CSS components: based in pure HTML and CSS with no extra libraries required. It's the one implemented in the @zurich/css-components package. Uses custom HTML attributes for the CSS selectors that are not part of the standard ones and also the standard ones of each HTML standard tag.

  • Web components: uses Lit as the only dependency and are JS-based components that have the CSS already included inside the JS files. Each component has also a wrapper to be used as a "native" component for the three main frontend frameworks: Angular, React and Vue. It's the one implemented in the @zurich/web-components package.

  • Native mobile components: we offer also libraries for frameworks that allow the development of native apps like React Native with our @zurich/react-native package.

In the documentation of each component you will find a select in to top-right corner of the page to change between the different explanations of the implementations (for paradigm and target framework). In the cases where the component it's only implemented via WebComponent, the CSS option won't appear.

Local installation vs Remote code

Every package can be installed locally, or imported via URL as part of the meta of the HTML document (except for the SCSS tooling of @zurich/dev-utils, since it requires transpilation to CSS in order to be usable).

Each option has pros and cons:

  • Remote code: it's done through <script> and/or <link rel="stylesheet"> tags in the <head> or <body> of the document and are the easiest way of start using the ZDS. For further information about the import process of each package; check the corresponding installation guide. And for consuming assets: check the consumables description.

    This approach doesn't require development dependencies and allow to use the design system directly from the HTML documents. Allows to have a more fine control over the necessary assets to improve performance and doesn't require a bundler.

  • Local installation: it's done via NPM packages and requires further configuration depending on the framework used. One of the advantages of the local installation is that we could be using all the TypeScript and JSDocs features of the components. Check the corresponding installation guide per package.

    This approach offers the best developer Experience (DX) since allows the use of TypeScript and JSDocs to receive hints, errors, autocompletion, and documentation about all the aspects of the ZDS directly in the IDE.

Customization

By using the overwrite of some defined CSS variables we can customize the design system if it's required for a certain project. We explicitly expose those variables as part of the documentation so you have no issues with the customization and can make everything work with very easy steps.

There are three customization categories or levels to consider:

  • General: by changing the design token in the :root CSS pseudo-element or under the body selector, we can change variables for the whole site to adapt the design system to our requirements. The last option (with body) even allow us to create different theme based on complementary selectors (ex.: body.my-theme or body[theme="my-theme"]).

    Some examples of this selectors:

    css
    :root {
      --z-button--bg: red;
    }
    css
    body {
      --z-button--bg: red;
    }
    css
    body[theme="scarlet"] {
      --z-button--bg: red;
    }

    In every example, the value of the variable --z-heading--color is changed to red for the entire page.

  • Contextual: by using selector for specific container components (ex.: #my-container) or direct injection in the style attribute the customization can be scoped under that container or under circumstances. This is basically how our z-theme works.

    html
    <section id="my-container">
      <z-button>Click me!</z-button>
    </section>
    css
    #my-container {
      --z-button--bg: red;
    }
  • Instance: as with the contextual customization, the modifications can de applied to a single tag or component instance to make adjustments or fine component customization.

    html
    <z-button style="--z-button--bg: red;">Click me!</z-button>

Custom theme

By using the semantic tokens we can create custom theme as variations of the default ZDS look-and-feel in order to customize the UI for specific brands or purposes. These variables can be override on any of the previously mentioned levels.

The previously mentioned "contextual customization" approach allows to have multiple themes at the same time by using different selectors.

Custom components

Each component has it's own custom variables exposed with the naming convention --z-<component_name>--<property> as you can check in here, for example. This eases the process of adapting the components without the overhead of having to deal directly with the CSS and in a controlled and tested way.

These variables can be override on any of the previously mentioned levels.