Skip to content

Commit

Permalink
BREAKING CHANGE(design-tokens): Introduce new design tokens structure…
Browse files Browse the repository at this point in the history
… #DS-1430
  • Loading branch information
crishpeen committed Aug 16, 2024
1 parent 77a5ec5 commit 15a406f
Show file tree
Hide file tree
Showing 25 changed files with 1,855 additions and 758 deletions.
266 changes: 134 additions & 132 deletions packages/design-tokens/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,142 +2,94 @@

> Design tokens for Spirit Design System.
⚠️ Spirit design tokens are managed with and generated by [Supernova]. DO NOT EDIT MANUALLY!
⚠️ Spirit design tokens are managed with and generated by [Supernova][supernova]. DO NOT EDIT MANUALLY!

## Table of Contents

1. [Available Design Tokens](#available-design-tokens)
1. [Global Tokens](#global-tokens)
2. [Theme Tokens](#theme-tokens)
2. [Install](#install)
3. [Basic Usage](#basic-usage)
4. [`@tokens` API](#tokens-api)
1. [In JavaScript](#in-javascript)
4. [Rebranding Spirit](#rebranding-spirit)
5. [FAQ](#faq)
6. [License](#license)

## Available Design Tokens

| Category | Supernova | Figma | Sass |
| ------------- | --------- | ----- | -------------------- |
| 🖼 Borders ||| [`_borders.sass`] |
| 🎨 Colors ||| [`_colors.sass`] |
| 🖌️ Gradients ||| [`_gradients.sass`] |
| 📏️ Measures ||| [`_measures.sass`] |
| ⚙️ Other ||| [`_other.sass`] |
| 🎱 Radii ||| [`_radii.sass`] |
| ⛱ Shadows ||| [`_shadows.sass`] |
| 🔠 Typography ||| [`_typography.sass`] |
Tokens are split into two categories: Global and Themes. Global tokens are
shared across all themes, while theme tokens are specific to a particular theme.

## Install
They are managed in Figma and exported to Supernova.

🙋🏻‍♂️ **Hold on! Do you already use [`spirit-web`]?** Then you don't need to
install this package because `spirit-design-tokens` is installed automatically
as a dependency of [`spirit-web`].
All content in `src` is generated by Supernova and should not be edited manually.

If you want to use just `spirit-design-tokens` alone in your project, run:
In `scss` directory are files `@global.scss` and `@themes.scss` which contain links to all available tokens.

```shell
yarn add @lmc-eu/spirit-design-tokens
```
### Global Tokens

or
The category consist of these groups:

```shell
npm install --save @lmc-eu/spirit-design-tokens
```
- Borders
- Gradients
- Other
- Radii
- Shadows
- Typography

## Basic Usage
These tokens does not depend on any theme and are shared across all themes.

The recommended approach in Sass is to import all Spirit design tokens at once
via the [`@tokens` API](#tokens-api):
### Theme Tokens

```scss
@use 'sass:map';
@use 'node_modules/@lmc-eu/spirit-design-tokens/scss/@tokens' as tokens;

.MyComponentThatMightGoToSpiritInFuture {
font-family: map.get(tokens.$body-medium-text-regular, font-family);
color: tokens.$text-primary-default;
}
```
You can find the list of themes in the `src/themes` directory. Each theme has
its own directory and set of design tokens.

This makes it easier to [migrate your code to Spirit][migrate-to-spirit] in the
future.
The category currently consist only of this group:

<details>
<summary>Optional: import by categories</summary>
- Colors

You can also import individual design token files by categories, e.g.:
Each theme consists of the same set of tokens, but with different values.

```scss
@use 'sass:map';
@use 'node_modules/@lmc-eu/spirit-design-tokens/scss/colors';
@use 'node_modules/@lmc-eu/spirit-design-tokens/scss/typography';

.MyComponent {
font-family: map.get(typography.$body-medium-text-regular, font-family);
color: colors.$text-primary-default;
}
```
We currently support two themes:

This approach is a bit more descriptive and thus provides slightly better
developer experience. You may find it more convenient in situations you
**don't** suppose your code will make its way to Spirit as this approach is
incompatible with `@tokens` API that makes rebranding possible.
- Light
- Light Inverted

</details>
Where the former is the default.

### In JavaScript
## Install

Additionally the design tokens are also provided as a JavaScript object.
🙋🏻‍♂️ **Hold on! Do you already use [`spirit-web`][web-docs]?** Then you don't need to
install this package because `spirit-design-tokens` is installed automatically
as a dependency of `spirit-web`.

```js
import * as SpiritDesignTokens from '@lmc-eu/spirit-design-tokens';
If you want to use just `spirit-design-tokens` alone in your project, run:

const desktopBreakpoint = SpiritDesignTokens.breakpoints.desktop;
```shell
yarn add @lmc-eu/spirit-design-tokens
```

The structure is the same as in the SASS.

## `@tokens` API

`@tokens` API enables quick and easy rebranding of Spirit Sass styles by
[replacing the path](#b-via-load-path) to design tokens. You need to be familiar
with it if you are building your custom design system based on Spirit or you are
going to contribute to Spirit.

### Accessing `@tokens`

#### a) via full path

Access Spirit design tokens via the `@tokens` API without having to configure
load path, just like shown in the [basic example](#basic-usage). This is a good
choice for starting off quickly. However, it **doesn't enable rebranding**.

#### b) via load path

To get ready for rebranding, access Spirit design tokens via the `@tokens` API
while keeping them open to be replaced by another set of design tokens:

```scss
@use 'sass:map';
@use '@tokens' as tokens;
or

.MyComponentThatIsReadyForSpirit {
font-family: map.get(tokens.$body-medium-text-regular, font-family);
color: tokens.$text-primary-default;
}
```shell
npm install --save @lmc-eu/spirit-design-tokens
```

##### Configuring Load Path
## Basic Usage

SCSS is the primary language for styling Spirit components.

Because the `@tokens` file doesn't exist locally, tell Sass where it should
look for unreachable files. This is also a required step if you are importing
Spirit components from their Sass source.
The best way to use the design tokens is to load their path in SASS:

```shell
sass --load-path=node_modules/@lmc-eu/spirit-design-tokens/scss my-styles.scss
```

Or integrate them into your build system:

<details>
<summary>Or with Webpack and <code>sass-loader</code>:</summary>
<summary>Webpack example with <code>sass-loader</code>:</summary>

```javascript
// webpack.config.js
Expand Down Expand Up @@ -169,39 +121,88 @@ module: {

</details>

### Exposing Your Custom Design Tokens
<details>
<summary>Vite example:</summary>

```javascript
// vite.config.js

//
import { defineConfig } from 'vite';

export default defineConfig({
css: {
preprocessorOptions: {
scss: {
includePaths: [path.resolve(__dirname, 'node_modules/@lmc-eu/spirit-design-tokens/scss')],
},
},
},
});
//
```

</details>

This way the [`spirit-web`][web-docs] package or your own components can simply reach token values like this:

```scss
@use 'sass:map';
@use '@global' as global-tokens;

.MyComponentThatMightGoToSpiritInFuture {
font-family: map.get(global-tokens.$body-1-regular, font-family);
margin-bottom: global-tokens.$space-300;
}
```

In Spirit, the [`@tokens.scss`] file simply @forwards all design tokens exposed
by [`index.scss`] which in turn @forwards all design token categories. To make
your design tokens compatible with Spirit, just create a `@tokens.scss` file and
@forward all your design tokens through it, e.g.:
For your components you can also load the token files directly:

```scss
// @tokens.scss

@forward 'borders';
@forward 'colors';
@forward 'gradients';
@forward 'measures';
@forward 'other';
@forward 'radii';
@forward 'shadows';
@forward 'typography';
@use 'node_modules/@lmc-eu/spirit-design-tokens/scss/@global' as global-tokens;
```

As mentioned, all themes contain the same set of tokens, so to use them you need to either
choose which theme you want to use and load it directly or use the `@themes` file to
generate CSS variables and use them in your components. The [`spirit-web`][web-docs] package does
this for you.

### In JavaScript

Additionally the design tokens are also provided as a JavaScript object.

```js
import * as SpiritDesignTokens from '@lmc-eu/spirit-design-tokens';

const desktopBreakpoint = SpiritDesignTokens.breakpoints.desktop;
```

The structure is the same as in the SASS.

## Rebranding Spirit

The system is designed to be easily rebranded. To do so, you need to provide
your own design tokens and use `@global` and `@themes` files. Then forward your tokens
to these files and set the correct load path for your project.

Your tokens should contain the same structure as the Spirit tokens. The simplest
way to do this is to have the same structure in your Figma file and export it
using Supernova. If that's not possible, you can copy our tokens and adjust their values
to your needs. You can also add new tokens required by your design system.

## FAQ

<details>
<summary>
Why do I need to rename <code>@tokens</code> to <code>tokens</code> when @using?
Why do I need to rename <code>@global</code> to <code>global-tokens</code> when @using?
</summary>

Because @using the `@tokens` module without renaming would produce an error:
Because @using the `@global` module without renaming would produce an error:

```log
Error: Invalid Sass identifier "@tokens"
Error: Invalid Sass identifier "@global"
1 │ @use '@tokens';
1 │ @use '@global';
│ ^^^^^^^^^^^^^^
```

Expand All @@ -210,18 +211,18 @@ Error: Invalid Sass identifier "@tokens"
<details>
<summary>Why is there the <code>@</code> prefix?</summary>

We prefix the `@tokens.scss` file with `@` to differentiate it from other Sass
We prefix the `@global.scss` file with `@` to differentiate it from other Sass
files in the directory.

In order for developers to know the file behaves differently than usual Sass
partials, a `@` prefix is added to mark this behavior both in filesystem and
inside Sass files. As a result, it's clear why e.g. `@use 'tools'` refers to
a local file and `@use '@tokens'` does not. However, **it's only a naming
a local file and `@use '@global'` does not. However, **it's only a naming
convention,** there is no special tooling or configuration for Sass partials
starting with `@`.

Imported module **needs to be renamed to be compatible with SCSS** syntax
when it's used later on. That's why `@use '@tokens' as tokens`.
when it's used later on. That's why `@use '@global' as global-tokens`.

Look at the following snippets and compare which one offers better
comprehensibility.
Expand All @@ -232,7 +233,7 @@ Without `@` prefix:
// _Button.scss

@use 'tools'; // Calls './_tools.scss'. You don't have to explain this to me.
@use 'tokens'; // Wait, this file doesn't exist… What's going on here? Is it
@use 'global'; // Wait, this file doesn't exist… What's going on here? Is it
// an error?
```

Expand All @@ -242,7 +243,7 @@ With `@` prefix:
// _Button.scss

@use 'tools'; // Calls './_tools.scss'.
@use '@tokens' as tokens; // OK, './_@tokens.scss' is not here, but the at-sign
@use '@global' as global-tokens; // OK, './_@global.scss' is not here, but the at-sign
// prefix suggests a special behavior. Maybe I'll learn more in the docs?
```

Expand All @@ -266,7 +267,19 @@ Simply put, if you are going to build a design system based on Spirit:
4. use your design tokens in your code (and compile Spirit with them).

To make your Sass design tokens compatible with Spirit, don't forget to expose
them via your custom [`@tokens` API](#tokens-api).
them via SASS load path.

</details>

<details>
<summary>Do I need themes? And if so, how many?</summary>

You need at least one theme to define the default values for your design tokens.
If you want to support multiple themes, you can add more. The number of themes
is up to you and your design system requirements.

But remember, each theme should contain the same set of tokens, just with different
values. This way, you can switch between themes without changing your components.

</details>

Expand All @@ -275,15 +288,4 @@ them via your custom [`@tokens` API](#tokens-api).
See the [LICENSE](LICENSE.md) file for information.

[supernova]: https://spirit.supernova-docs.io
[`@tokens.scss`]: src/scss/@tokens.scss
[`index.scss`]: src/scss/index.scss
[`_borders.sass`]: src/scss/generated/_borders.scss
[`_colors.sass`]: src/scss/generated/_colors.scss
[`_gradients.sass`]: src/scss/generated/_gradients.scss
[`_measures.sass`]: src/scss/generated/_measures.scss
[`_other.sass`]: src/scss/generated/_other.scss
[`_radii.sass`]: src/scss/generated/_radii.scss
[`_shadows.sass`]: src/scss/generated/_shadows.scss
[`_typography.sass`]: src/scss/generated/_typography.scss
[`spirit-web`]: https://github.com/lmc-eu/spirit-design-system/tree/main/packages/web
[migrate-to-spirit]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web/CONTRIBUTING.md#migrating-your-components-to-spirit
[web-docs]: https://github.com/lmc-eu/spirit-design-system/tree/main/packages/web#readme
2 changes: 1 addition & 1 deletion packages/design-tokens/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"build": "npm-run-all --serial build:prepare build:scss build:js",
"build:prepare": "yarn clean",
"build:js": "vite build",
"build:scss": "shx mkdir -p scss && shx cp -r src/scss/generated/* src/scss/@tokens.scss scss/",
"build:scss": "shx mkdir -p scss && shx cp -r src/scss/* scss/",
"clean": "rimraf esm cjs umd scss types",
"lint": "stylelint ./src/**/*.scss",
"test": "yarn lint",
Expand Down
1 change: 1 addition & 0 deletions packages/design-tokens/src/scss/@global.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@forward 'global';
Loading

0 comments on commit 15a406f

Please sign in to comment.