Skip to content
This repository has been archived by the owner on May 17, 2023. It is now read-only.

Second level tokens (intro) #176

Closed
wants to merge 7 commits into from
Closed

Conversation

siddharthkp
Copy link
Contributor

@siddharthkp siddharthkp commented Jan 12, 2018

This PR is an attempt at defining our tokens strategy.

I'll use the example of colors because that's the one I understand the most.


Tokens solve 2 purposes for us:

Purpose 1: Serves as an inventory of our brand guidelines.

Check out tokens/values/colors.js

This file stores all the values we have in the application.

const colors = {
  white: {
    base: '#FFF'
  },
  red: {
    lighter: '#FF3E00',
    light: '#FF3434',
    base: '#FF0000',
    dark: '#e50000',
    darker: '#cc0000'
  },
  blue: {
    lighter: '#14AAFF',
    light: '#4e9ee2',
    base: '#2386DB',
    dark: '#1f78c5',
    darker: '#1c6baf'
  }
}

Purpose 2: Hold all the design conventions/guidelines that our applications should follow.

Check out tokens/conventions/colors.js

These are essentially rules that every application should comply with to feel like they are from the same company.

const conventions = {
  destructive: {
    background: {
      default: values.red.base,
      hover: values.red.light,
      focus: values.red.lighter
    },
    foreground: {
      default: values.white.base
    }
  },
  link: {
    background: {
      default: 'transparent'
    },
    foreground: {
      default: values.blue.base,
      hover: values.blue.light,
      focus: values.blue.lighter
    }
  }
}

The point to note here is the conventions are based on meaning or usage.

Check out the implementation of button.js to see changes.

That means, an anchor tag, a button of type link and a tab link should all have the same color (even though they have different UX patterns)

screen shot 2018-01-12 at 5 13 05 pm


What tokens are not: A way to theme our application

Tokens are a way to make repeatable variables that can be used across the application, making it more consistent and easy predictable for change.

When you change a token, you should be able to say which component it effects and which one it doesn't with confidence.

They are not a way to theme our application with variables. We don't have rules specific to components in tokens. It's tempting to do so, but that's doesn't contribute towards our goal and will make the system complex without any rewards.

We don't have component overrides in the tokens. Example: Sidebar links do not conform to conventions of link, they use the values differently to create their own UX pattern. Components are allowed to do that.

The code for that sits inside the Sidebar component.

This brings us to the next section:


What is the criteria for a variable to become a token?

It's useful to repeat:

Tokens are a way to make repeatable variables that can be used across the application, making it more consistent and easy predictable for change.

When you see a pattern emerging, tokenise it. Pure tokenisation is only possible if you start with an inventory of consistent components. Because, our goal is the opposite (starting with inconsistent components and taking them to consistent), we will end up pure tokens eventually rather than starting with them.

Variables that are only used in one use case/component are not worth tokenising (example: Sidebar links)


Beware of early tokenisation

Hot take: Moving variables into tokens early on can make changing design slower and less predictable. Breaking a convention is much harder than creating a new one.

Example: While building forms, it might be tempting to tokenise the height of form elements. After all, buttons and inputs should be perfectly aligned. But, the moment we introduce EmptyState component, buttons have a different behaviour there. (sorry @landitus)

2nd example: If you notice, you'll find that conventions/colors does not talk about border in destructive and link. This is intentional. Most (maybe all) of components with backgrounds (like buttons, switch), have the same background and border-color.

screen shot 2018-01-12 at 5 54 24 pm

This is our convention. Maybe one day in the future, we will break this convention. At that point, we will have to introduce a new variable in conventions and change a bunch of components. This is not a bad thing. predictability > ease


Sounds horrible? Let's talk about it. This implementation is based on what I have learned till now and is still naive.

Sounds good? Here's how we get there:

  1. I've kept the existing tokens untouched, so nothing should break on it's own.
  2. Introduced 2 new directories: values and conventions, they serve the 2 purposes defined above.
  3. All of the values are exported as a flag object under tokens, so how you use them remains the same.
  4. We should slowly move all components to use conventions instead of old tokens
  5. If you are tackling a new component and a convention doesn't exist for it yet, feel free to use values until we find a right home for it 馃彔

@siddharthkp siddharthkp added 鉁媎on't merge PRs that are blocked / paused at the moment and removed wip labels Jan 12, 2018
@landitus landitus mentioned this pull request Jan 12, 2018
@siddharthkp
Copy link
Contributor Author

giphy-downsized

@nkohari @beneliflo @landitus Thoughts?

@landitus landitus mentioned this pull request Jan 29, 2018
@siddharthkp
Copy link
Contributor Author

Closing this because I'm not working on this anymore. Will start over sometime in the future

@landitus landitus mentioned this pull request Feb 15, 2018
@siddharthkp siddharthkp deleted the second-level-tokens branch March 13, 2018 15:14
@siddharthkp siddharthkp mentioned this pull request Apr 6, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
鉁媎on't merge PRs that are blocked / paused at the moment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant