Watson in Code

Introduction

Watson provides three libraries:

  • Tokens: a collection of styles that contain the necessary to use Watson Design System in your project. This package contains a /dist folder with:
    • index.css: contains CSS custom properties including our three tiers of design tokens: components, semantic and core.
    • /components, /semantic, /core: contains CSS custom properties and JS variables separately.
  • Components: a set of Vue components ready to use to help developers with their work building high-quality components based on Watson foundations.
  • Web Components: a set of web components that can be used in non-Vue projects. These are converted from Vue components and verified to work as close as possible to the Vue components.

Do we have utility classes?

Watson does not include CSS utility classes as we don't want to break component encapsulation or facilitate their misuse. We aim to create a UI language for you to use and not another vast CSS framework, so instead, we provide components like Grid, Stack, and Spacer to help with distributing items on the screen. Additionally, you can always use the semantic Tokens mentioned above in case you need to build your own solutions.

Note

If you want to know more about tokens tiers structure, please read Design Tokens section


Vue

Installation

All modules are available in DocPlanner private package registry as separate npm packages. In order to use them in your project you need to add .npmrc file to it and configure it as follows:


                                                        
                                                        
                                                            always-auth=true
                                                        registry=https://npm-proxy.docplanner.io
                                                        //npm-proxy.docplanner.io/:_authToken="YOUR_TOKEN_GOES_HERE"
                                                        
                                                            

Please note that both @dp-watson-web/components and @dp-watson-web/web-components are a standalone packages including CSS and compiled JS. You don't need to include @dp-watson-web/tokens as dependency in your Vue project as it is already integrated as part of the package.
Tokens should be used in case you plan to add custom components that are not available in the @dp-watson-web/components package or if you are working into a non Vue ecosystem and you want to include the foundations of Watson Design System.

Components

Import CSS file


                                                        
                                                        
                                                            import "@dp-watson-web/components/dist/watson.css";
                                                        
                                                            

Import JS file

You can import @dp-watson-web/components Watson Components in two ways:

  1. As a plugin

This option makes all Vue componentes available into your project and you don't need to import them all the time you need them, just use them directly in your Vue templates. Don't pick this option if you want to be ** tree-shakeable**.


                                                        
                                                        
                                                            import WatsonComponents from "@dp-watson-web/components";
                                                        import { createApp } from "vue";
                                                        
                                                        const app = createApp(App);
                                                        app.use(WatsonComponents);
                                                        
                                                            
  1. Importing components manually in your views.

                                                        
                                                        
                                                            import { WGrid, WGridItem, WCard, WText } from "@dp-watson-web/components";
                                                        
                                                            

Design Tokens

Design tokens are a set of CSS properties used to build Watson Design System. They store foundational styles on spacing, color, typography, shadows, and border radius.
They are divided into three tiers:

Core tokens

Content-agnostic values. Used only internally as a reference for semantic, and component tokens.

Example: --w-color-red-200

Semantic tokens

Their name describes the intended use of the token — this tier references core tokens.

Example: --w-font-size-page-heading

Component tokens

Tokens are tied to a specific component value — this tier references semantic tokens.

Example: --w-button-background-secondary

Tokens are delivered as CSS and JS variables in @dp-watson-web/tokens package, each tier available as a separate file inside /dist folder. Additionally, there is a JSON object with all tokens in it. This format may come in handy in cases when the developer needs access to the style dictionary that was used to build design tokens. Except for the name and value JSON file contains additional fields used to generate this documentation like description, tokenRefercence or comment.

Examples


Web components

Watson Design System provides a set of web components that can be used in non-Vue projects. Using web components offers several benefits like:

  • Reusability: Web components are self-contained and can be reused across different projects.
  • Encapsulation: Web components are encapsulated, meaning their styles and logic are scoped to the component.
  • Interoperability: Web components can be used in any framework or library.
  • Browser support: Web components are supported by all modern browsers.
  • Future-proof: Web components are part of the web standards and are here to stay.
  • Ease of use: Web components can be used like any other HTML element.

The core concept of web components remains the same across all frameworks, but each framework has different mechanisms for handling component communication, rendering, and reactivity. You'll need to bridge some of these differences when integrating web components into your specific framework.

Installation

Import CSS file


                                                        
                                                        
                                                            import "@dp-watson-web/web-components/dist/watson.css";
                                                        
                                                            

Import components


                                                        
                                                        
                                                            import "@dp-watson-web/web-components/dist/components/WAvatar/WAvatar.js"; 
                                                        
                                                            

Importing components in this way will define the custom element in the global scope, so you can use it in your HTML.
If you want to manually define the component, you can do it like this:


                                                        
                                                        
                                                            import WAvatar from "@dp-watson-web/web-components/dist/components/WAvatar/WAvatar.component.js";
                                                        
                                                        WAvatar.define();
                                                        
                                                            

It may be useful in some scenarios when you do not have all required properties available at the time of the component is defined.

Working with web components

General rules

  • Use camelCase for properties and dash-case for attributes: HTML has only two types of values: strings and booleans. Any property that stores other type of value cannot be represented as an attribute. There are multiple ways of approaching booleans. If treated as an attribute boolean is true when the attribute is present and false when it is not.

                                                        
                                                        
                                                            <!--Vue -->
                                                        <!--attribute set to true-->
                                                        <w-checkbox model-value />
                                                        <!--attribute set to false-->
                                                        <w-checkbox />
                                                        <!--property set to false-->
                                                        <w-checkbox :modelValue="true" />
                                                        <!--property set to false-->
                                                        <w-checkbox :modelValue="false" />
                                                        
                                                            
  • All our components emit custom DOM events Use detail property of CustomEvent to obtain payload data from the event. The detail property is an array that contains the data passed to the event.

                                                        
                                                        
                                                            ...
                                                        document.querySelector('w-checkbox').addEventListener('update:modelValue', onUpdateCheckbox);
                                                        
                                                        function onUpdateCheckbox(event) {
                                                        checkboxValue = event.detail[0];
                                                        ...
                                                        };
                                                        
                                                            
  • Slots: Some of our components utilize slots to obtain content. Those with a single slot use the 'default' slot which does not need additional configuration. Those with multiple slots utilize named slots. In order to pass content to the named slot you need to use slot attribute and pass slot's name into it. Please note that Vue slot syntax won't work with web components.

                                                        
                                                        
                                                            <!--Vue-->
                                                        <w-collapse :indent="false" padding="none">
                                                          <div slot="header">
                                                            <w-text type="subSectionHeading">Default slot content</w-text>
                                                          </div>
                                                          <div slot="panel">
                                                            Named slot content
                                                          </div>
                                                        </w-collapse>
                                                        
                                                            
  • Defining web components: We offer two versions of each component in our library:
    • One that auto registers itself when imported (Files withouth the .component suffix). After importing the component it registers itself as custom element in the browser and is ready to use

                                                        
                                                        
                                                            import "@dp-watson-web/web-components/dist/components/WText/WText.js";
                                                        
                                                            
    • One that needs to be registered manually (Files with the .component suffix). It imports the component, but does not register it as custom element. You need to call the define method on the component to register it. This option gives you more flexibility and control over the registration process.

                                                        
                                                        
                                                            import WText from "@dp-watson-web/web-components/dist/components/WText/WText.component.js";
                                                        
                                                        WText.define();
                                                        
                                                            
  • Component dependencies: Some of our components depend on other components. We take care of importing those dependencies for you so you don't have to worry about importing them separately. We also make sure that the component won't be registered twice so if you import the same component in multiple views you're covered.

Vanilla JS

  • Direct Interaction: Without a framework, you can directly manipulate web components using their API. You have full control over attributes, properties, and events using standard JavaScript methods.
  • Manual DOM Updates: Without the help of a framework, you’ll need to manually handle state changes and DOM updates, which might require more boilerplate code compared to using a framework.

                                                        
                                                        
                                                            <w-text id="checkbox-text">Lorem ipsum</w-text>
                                                        <w-checkbox label="Checkbox label"></w-checkbox>
                                                        
                                                            

                                                        
                                                        
                                                            let checkboxValue = false;
                                                        document.querySelector("w-checkbox").modelValue = checkboxValue;
                                                        document
                                                          .querySelector("w-checkbox")
                                                          .addEventListener("update:modelValue", onUpdateCheckbox);
                                                        
                                                        function onUpdateCheckbox(event) {
                                                          checkboxValue = event.detail[0];
                                                          document.querySelector("w-checkbox").modelValue = checkboxValue;
                                                          document.querySelector(
                                                            "#checkbox-text"
                                                          ).innerHTML = `The checkbox value is: ${checkboxValue}`;
                                                        }
                                                        
                                                            

Vue

We do not recommend using web components in Vue projects. In those projects Watson Vue components should be the first choice as they are easier to integrate into existing code and easier to debug. Still, Vue works very well with web components so if you you stick to the general rules listed above you should be able to use web components without any issue.

Angular

When using web components in Angular, you need to remember to add the CUSTOM_ELEMENTS_SCHEMA to the schemas array in the component decorator. This tells Angular to ignore unknown elements and attributes, which is necessary when using web components.


                                                        
                                                        
                                                            <w-button
                                                          label="Push me!"
                                                          [fullWidth]="isFullWidth"
                                                          (click)="onClick()"
                                                        />
                                                        
                                                            

                                                        
                                                        
                                                            import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
                                                        
                                                        import '@dp-watson-web/web-components/dist/components/WButton/WButton.js';
                                                        
                                                        @Component({
                                                          schemas: [CUSTOM_ELEMENTS_SCHEMA]
                                                        })
                                                        
                                                        export class ButtonComponent {
                                                          isFullWidth = false;
                                                        
                                                          onClick() {
                                                          ...
                                                          }
                                                        }
                                                        
                                                            

React

We do not recommend using Watson web components in React projects. We do not provide a reliable wrapper for our web components to make them work with older version of React. We didn’t test our web components in any project that uses latest version of React. Right now we can’t provide you any support in using Watson web-components in React based projects.