Skip to content

CSS components

Prod:

The @zurich/css-components NPM package is a package fully based on CSS (but with JavaScript helpers for some extra functionality).

It uses a combination of custom attributes inside the HTML tags in order to stablish and configure the different components. Each component forces an specific tree of HTML for a proper configuration, so it is important to follow the code snippets and the code guidelines in order to make the component work. Not every available component is implemented in this library since, in case of requiring some JavaScript for the functionalities, the component is considered not feasible for this library.

In some occasions, we will use some tricks with HTML tags and CSS selectors that might not be entirely compatible between browsers, so make sure to check the compatibility.

Disclaimer

Read first the @zurich/design-tokens installation guide since this package depends on that one.

...

Attention!

As we will do with the Web components, we should never use more than one CSS component inside the same HTML tag. If so, the component can be completely broken or cause glitches.

Javascript

Some components, like the inputs, might require some JavaScript to properly work as in the specifications.

This can be done directly from the HTML, by injecting the scripts in the oninput, onchange or any corresponding event callback as HTML attribute. But to make things easier, we have set up everything necessary in a small script that you can directly imported.

Attention!

Most inputs require this extra actions, so make sure you import this file or set the attributes.

Since this file should only appear once per page, the specification of use being done in the frameworks section might be different depending on the setup.

Install

We can use two different approaches for the <SRC> value:

Local installation

For NPM-style build systems or/and local development, you can install @zurich/css-components via NPM. Just use the installation command of you favorite package manager (NPM, Yarn, PNPM, Bun, etc.). The @zurich/design-tokens packages is set as a dependency of @zurich/css-components, so we don't require to explicitly install the package.

bash
npm i @zurich/css-components

Then access the CSS files inside the distribution folder and import the CSS in your JS/TS. Remember that the @zurich/design-tokens import needs to be done also first for the components to utilize the tokens:

ts
import '@zurich/css-components/javascript.js';
import '@zurich/css-components';

Individual components can be also imported for better WPO, keeping the @zurich/css-components/base.css import:

ts
import '@zurich/css-components/base';
import '@zurich/css-components/SafeSpace.css';
import '@zurich/css-components/Profile.css';
import '@zurich/css-components/Button.css';

Via CDN

The fastest way to get going with @zurich/css-components is to load it via a CDN. Just import the https://zds.zurich.com/0.5.22/@zurich/css-components/index.css file to the <head> of your HTML and start using the CSS components.

Here's an example on how we use the CSS components in a vanilla HTML file.

You can also import individual components using the name of the component. Here's an example with the icon component, but remember that this one requires also the used icon tokens to present the images.

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <link rel="stylesheet" href="https://zds.zurich.com/0.5.22/@zurich/css-components/index.css" />
    <script type="module" src="https://zds.zurich.com/0.5.22/@zurich/css-components/javascript.js"></script>
  </head>
</html>
html
<!DOCTYPE html>
<html lang="en">
  <head>
    <link rel="stylesheet" href="https://zds.zurich.com/0.5.22/@zurich/design-tokens/index.css" />
    <link rel="stylesheet" href="https://zds.zurich.com/0.5.22/@zurich/design-tokens/Icons.css" />
    <link rel="stylesheet" href="https://zds.zurich.com/0.5.22/@zurich/css-components/Icon.css" />
    <script type="module" src="https://zds.zurich.com/0.5.22/@zurich/css-components/javascript.js"></script>
  </head>
</html>

Here's an example on how we use the icon component in a vanilla HTML file.

html

<body z-theme="dark">
  <link
    rel="stylesheet"
    href="../@zurich/design-tokens/Icons.css"
  />
  <link
    rel="stylesheet"
    href="../@zurich/css-components/index.css"
  />

  <i
    z-icon="l"
    icon="arrow-down:line"
  ></i>
</body>

Imports

The main imports of the packages are:

  • ./index.css: the main file that includes all the components. This export already includes the ./index.css export of the @zurich/design-tokens package.
  • ./main.css: the main file that contains the default required CSS rules of the package. Does not include the data components.
  • ./atoms.css: just includes the atom components.
  • ./inputs.css: just includes the input components and the required atom components for the inputs.
  • ./data.css: the file that includes all the data components.
  • ./base.css: a reduced version of the default /index.css with just the basics like the scrollbar styles.

The types are available under:

  • ./types.d.ts: the file with the TypeScript definitions for the HTML attributes.

We can import single components by name using their standalone CSS stylesheet by using the component name in PascalCase and the .css extension.

Examples:

All of them require to have the @zurich/design-tokens package imported to use the tokens.

Import tree

Here's an schema of the imports tree:

Import tree

Frameworks

Since this version of the components are just CSS stylesheets and HTML specifications, they are compatible with every web technology. But here are some guides and suggestion on how to use them with the frameworks we considered relevant and how to enable the tooling what we have developed for them and the considered IDE (VS Code).

The considered frameworks are Angular, React and Vue.

Angular

Angular global use
json
{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "newProjectRoot": "projects",
  "projects": {
    "my-app": {
      "architect": {
        "build": {
          "styles": [
            "node_modules/@zurich/css-components/dist/index.css", 
          ],
          "scripts": [
            "node_modules/@zurich/css-components/dist/javascript.js", 
          ]
        },
      },
    }
  }
}
ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent {
  constructor () { }

  ngOnInit (): void { }
}
html
<i z-icon icon="close:line"></i>
Angular in-component use

In this case, we strongly recommend to import the @zurich/css-components/base.css globally and then import the used component per components as this:

ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: [
    './app.component.scss',
    '../../node_modules/@zurich/design-tokens/dist/icons/action/outline.css',  // Import icons collection 
    '../../node_modules/@zurich/css-components/dist/Icon.css',  // Import icon style
  ], 
})
export class AppComponent {
  constructor () { }

  ngOnInit (): void { }
}
html
<i z-icon icon="close:line"></i>
json
{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "newProjectRoot": "projects",
  "projects": {
    "my-app": {
      "architect": {
        "build": {
          "styles": [
            "node_modules/@zurich/css-components/dist/base.css",  
          ],
          "scripts": [
            "node_modules/@zurich/css-components/dist/javascript.js", 
          ]
        },
      },
    }
  }
}

The HTML would be as the example of the global installation.

TypeScript support

Despite being fully based on TypeScript, there are some typing approaches in Angular that are more complicated. We haven't found yet a proper way of typing our CSS components in Angular. So as an alternative, you cans use the HTML Docs support we also provide if you are using VSCode. Have a look here about how to configure this option.

React

React global import

The library requires to use version 16 or higher in order to properly work (requires custom DOM attributes).

We directly import everything in the main.tsx file to make styles globally available for the whole React app.

In order to have TypeScript support, just add in the tsconfig.json the following type references:

tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.tsx';

import '@zurich/css-components';  // Import all styles
import '@zurich/css-components/javascript.js';   // Import scripts

const root = document.getElementById('root') as HTMLElement;

ReactDOM
  .createRoot(root)
  .render(
    <React.StrictMode>
      <App />
    </React.StrictMode>,
  );
json
{
  "compilerOptions": {
    "types": [
      "@zurich/css-components/react-types",
    ]
  },
}
React in-component use

In this case, we strongly recommend to import the @zurich/css-components/base.css globally and then import the used component per components as it follows.

tsx
import '@zurich/design-tokens/icons/action/outline.css';   // Import icons collection
import '@zurich/css-components/Icon.css';   // Import icon style

export default function Component () {
  return (
    <i z-icon icon="close:line"></i>
  );
}
tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.tsx';

import '@zurich/css-components/base.css';   // Import base styles 
import '@zurich/css-components/javascript.js';   // Import scripts

const root = document.getElementById('root') as HTMLElement;

ReactDOM
  .createRoot(root)
  .render(
    <React.StrictMode>
      <App />
    </React.StrictMode>,
  );
React library

Coming soon!

This is still a WIP. We don't recommend to use them yet in production!

There's an option of using the Vue components that implement the CSS approach as an encapsulation.

Can be imported from @zurich/css-components/react and they use the prefix React*.

tsx
import { ReactIcon } from '@zurich/css-components/react';

export default function Component () {
  return (
    <ReactIcon icon="close:line"/>
  );
}

Attention!

They still require to import @zurich/css-components/base.css globally.

The API of these components is the same as the one in the WebComponents counterpart as React wrappers, except for some small details:

  • Instead of slot for custom content, use JSX.Element as props only, as explained here.

    tsx
    import { ReactTextInput } from '@zurich/css-components/react';
    
    function InputLabel () {
      return (
        <em>Input label</em>
      );
    }
    
    export default function Component () {
      return (
        <ReactTextInput label={<InputLabel/>}/>
      );
    }
  • They self-import the required components and CSS of the components, so no need to import styles except for @zurich/css-components/base.css.

...

INFO

More info coming soon

Vue

Vue global import

We can directly import the styles the main.ts file to make them globally available.

In order to have TypeScript support, add in the main.ts or the vite-env.d.ts in case you are using Vite the following declaration.

As an alternative, in case you don't use TypeScript, you can use the HTML Docs support we also provide if you are using VSCode. Have a look here about how to configure this option.

ts
import { createApp } from 'vue';
import App from './App.vue';

import '@zurich/css-components';  // Import all styles
import '@zurich/css-components/javascript.js';   // Import scripts

createApp(App)
  .mount('#app');
html
<script lang="ts" setup>
</script>

<template>
  <i z-icon icon="close:line"></i>
</template>
ts
import type { VueZDSAttr } from '@zurich/css-components/vue';

declare module '@vue/runtime-dom' {
  interface HTMLAttributes extends VueZDSAttr { }
}
Vue in-component use

In this case, we strongly recommend to import the @zurich/css-components/base.css globally and then import the used component per components as the following examples.

html
<script lang="ts" setup>
import '@zurich/design-tokens/icons/action/outline.css';   // Import icons collection
import '@zurich/css-components/Icon.css';   // Import icon style
</script>

<template>
  <i z-icon icon="close:line"></i>
</template>
ts
import { createApp } from 'vue';
import App from './App.vue';

import '@zurich/css-components/base.css';   // Import base styles 
import '@zurich/css-components/javascript.js';   // Import scripts

createApp(App)
  .mount('#app');
Vue library

There's an option of using the Vue components that implement the CSS approach as an encapsulation. These are the ones used for this documentation in the CSS playgrounds.

Can be imported from @zurich/css-components/vue and they use the prefix Vue*.

vue
<script lang="ts" setup>
import { VueIcon } from '@zurich/css-components/vue';
</script>

<template>
  <vue-icon icon="close:line"/>
</template>

Attention!

They still require to import @zurich/css-components/base.css globally.

The API of these components is the same as the one in the WebComponents counterpart as Vue wrappers, except for some small details:

  • Instead of slot for custom content, use Vue named slots.

    vue
    <script lang="ts" setup>
    import { VueTextInput } from '@zurich/css-components/vue';
    </script>
    
    <template>
      <vue-text-input>
        <template #label>Input&nbsp;<b>label</b></template>
      </vue-text-input>
    </template>

    This will render in the and as:

  • They self-import the required components and CSS of the components, so no need to import styles except for @zurich/css-components/base.css.

Next.js

Since Next.js combines the Node runtime with browser components, it requires an specific compilation mode to make it 100% compatible with the approach: commonJS.

This approach still requires to import base.scss (once per page) and the corresponding styles of the component and possible sub-components.

tsx
import '@zurich/css-components/base.css';

import '@zurich/css-components/Icon.css';
import { ReactIcon } from '@zurich/css-components/cjs/Icon';

export default function Home () {

  return (
    <ReactIcon icon="close" />
  );
}

You can wrap everything in your own component too:

tsx
import '@zurich/css-components/Icon.css';
import { ReactIcon, type ReactIcon_Props } from '@zurich/css-components/cjs/Icon';

/**  ## ZDS Icon
 * 
 * A lovely icon component 💚 */
export const ZDSIcon = (props: ReactIcon_Props) => {
  return (
    <ReactIcon {...props} />
  );
};

export default ZDSIcon;
tsx
import '@zurich/css-components/base.css';

import { ZDSIcon } from '@/components/Icon';

export default function Home () {

  return (
    <ZDSIcon icon="close" />
  );
}