Skip to content

Working with the System

Viljami Salminen edited this page Feb 22, 2018 · 15 revisions

Tokens

Tokens are the visual design atoms of the design system. Specifically, they are named entities that store visual design attributes.

Creating a new Token

Creating a new design token is as simple as navigating to /src/tokens/ and editing any of the YAML files. I strongly recommend you to see what kind of example tokens spacing.yml or color.yml already have inside of them.

If you need to add a new category in addition to the existing ones, you’ll have to create a new YAML file inside the same directory. Once done, you can import the new partial inside /src/tokens/tokens.yml:

#
# GLOBAL: DESIGN TOKENS
#

imports:
  - color.yml
  - font-size.yml
  - font-family.yml
  - opacity.yml
  - size.yml
  - timing.yml
  - z-index.yml
  - media-query.yml
  - box-shadow.yml
  - border-radius.yml
  - spacing.yml
  - line-height.yml
global:
  type: global
  category: all

Token partials themselves will look somewhat like this, depending on the complexity of your system:

#
# SPACING TOKENS
# Use these tokens to set padding, margin and position coordinates.
#

props:
  space_xx_large:
    value: "128px"
  space_x_large:
    value: "64px"
  space_large:
    value: "48px"
  space_base:
    value: "24px"
  space_small:
    value: "16px"
  space_tiny:
    value: "8px"
global:
  type: number
  category: space

Using a Token in SCSS

Since tokens are imported globally, you can use them inside any Element, Pattern or Template without extra work. Using a token is as simple as:

<style lang="scss" scoped>
  a {
    font-family: $font-family-primary;
  }
</style>

Vue Design System uses Theo to transform and format the design tokens from YAML to both JSON and SCSS formats. To learn more about using and formatting Tokens, see Theo’s documentation.

Using a Token in JS

Elements

Elements are the smallest basic structures of a UI. They can not be broken down any further. Buttons, links, and inputs are good examples. Elements utilize Tokens.

Creating a new Element

To create a new element, you will first want to navigate to /src/elements/ and create a new .vue file. Element names don’t have a prefix, but it’s recommended that they are multiword or otherwise compatible with existing and future HTML elements (to learn more, see Naming of Things).

For the sake of simplicity, let’s imagine you’re creating a button:

First, name your file for example VueButton.vue.

After you’ve created the file, it’s time to get yourself familiar with Vue’s templates and how they work. The basic structure is following:

<template>
  <!-- Your element’s HTML -->
</template>

<script>
  // Your element’s JS
</script>

<style>
  /* Your element’s CSS */
</style>

Looks quite simple, right?

Now, let’s add a little bit of template markup. It’s a button, so we’ll add a basic html <button> and a <slot/> inside of it. Slot is used to allow a parent Pattern to pass DOM elements into a child Element.

<template>
  <button class="button">
    <slot/>
  </button>
</template>

Moving further, we can also add default content for the <slot/> that will be shown if nothing gets passed:

<template>
  <button class="button">
    <slot>I’m a Button!</slot>
  </button>
</template>

<script>
  export default {
    name: 'VueButton',
  };
</script>

<style lang="scss" scoped>
  .button {
    font-family: $font-family-primary;
    background: $color-primary-rich-black;
    color: $color-primary-white;
  }
</style>

In the above example, I’ve also added some basic style properties which utilize design system’s Tokens. The scoped attribute in <style> means that this SCSS will apply to the current Element only, which is similar to the style encapsulation found in Shadow DOM.

See below for additional examples about passing props to Elements and Patterns.

Example Element with a custom props:

<template>
  <a :href="href">
    <slot/>
  </a>
</template>

<script>
  export default {
    name: 'VueLink',
    props: ['href'],
  };
</script>

Example of a Template utilizing the above Element and props:

<template>
  <vue-link href="https://viljamis.com/">
    This is a label!
  </vue-link>
</template>

<script>
  export default {
    name: 'MyTemplate',
  };
</script>

As you can see, we’ve also added some basic text content inside our Element to override the default <slot/> contents. If wanted, we could also use the element as is, with the default slot contents shown:

<template>
  <vue-link/>
</template>

Patterns

Patterns are UI patterns that fall on the more complex side of the spectrum. Patterns can consist of both Elements and Tokens.

The exact same rules apply to both Patterns and Elements. From Vue.js’s perspective these are all Vue Components, but for the sake of communication between different teams, diciplines and stakeholders we need a set of unified terms and hierarchy for a system.

To better understand the hierarchy and terms used in this project, see System Hierarchy section.

Templates

Templates exist to document the layout and structure of a section or the entirety of an interface. Templates can consist of Patterns, Elements and Tokens.