terrazzoapp / terrazzo

Use DTCG tokens in CI and code

Home Page:https://terrazzo.app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support for boolean and string types?

torstendaeges opened this issue · comments

Hey there,

I'd like to start a discussion on the topic of boolean and string type tokens and if it would be beneficial for Cobalt to support them.

Why to support a boolean type?

First and foremost: It would bridge the gap between Figma and the dev world. While there may be other creative uses, I think boolean variables in Figma are mainly used to hide or show layers. This also alleviates the need for hacks to story visibility information (like fully transparent color tokens) and therefore stays closer to what is done in development.

If we're talking about only storing visibility information however, one could argue that a token type based on CSS properties might be a more specific way to go. You could have a "visibility" type with values "visible" and "hidden" (which is what Supernova seems to be doing). However having "visibility" on "hidden" does not behave like hidden layers in Figma do - for that you'd need a "display: none".

But since we can't be entirely sure if a boolean coming from Figma would indeed be used for visibility purposes, here are some thoughts on how to handle boolean in Cobalt:

  • JSON: type "boolean" as in the JSON standard type, value true or false. "true" and "false" as strings would throw an error. Common Figma plugins that export JSON also export boolean variables as JSON standard booleans.
  • CSS: Since it's hard to do anything with true or false in CSS, the values 1 and 0 could be used for CSS and custom properties: This would make it easier to do logical operations even in CSS (see here or here).
  • JS/SASS: For JS and SASS, standard boolean true and false should be used. I realize this could be problematic in combination with the 1 and 0 CSS solution, since Cobalt also allows for CSS custom properties to be assigned to SCSS variables...

Why to support a string type?

It would be great if you could use tokens to store default labels/texts/prefixes, placeholder text, current mode names, default error messages and so on. Also, it would again be on par with Figma to enable import and not lose half of the variables / tokens on the way.

In contrast with boolean, this seems to be rather straightforward:

  • JSON: type "string" as in the JSON standard type.
  • String value can also be empty (""), as it could be filled later. For example: prefixes for accessibility.
  • CSS/JS/SASS could all use the string equally.

Especially for boolean, this isn't as straightforward as I initially thought, so I'd love to hear your thoughts. Thanks and all the best!

Thanks for putting this together! Overall I’m (still) in favor of supporting these, even if for no other reasons to support parity with Figma, which is one of the most popular sources of truths of tokens (until the DTCG 1.0 spec is finalized)

To give a little context as to why these weren’t supported originally in the DTCG spec, the design was largely a reaction to Style Dictionary’s patterns where there aren’t hard types in a sense; it’s just up to you to define your schema and what it means for every platform. What resulted was many people “reinventing the wheel” for basic things. So a major goal of DTCG was force people into identifying token types from the start, for the sake of tooling being able to translate better. And in addition to this, the whole idea of universal design tokens was to define tokens in a truly platform-agnostic way. Practically, people tend to favor one platform over another, and if tokens are stored in that platform’s constraints, it begs the question “is the token that way because it’s meant to be universally, or bound by platform restrictions?” The thinking was translating from “universal” tokens → every platform would solve many problems imposed by the common pattern of translating from Platform A → every other platform.

String and boolean types are a partial return to that “hands-off” previous world, where you have to do more work to define meaning for the token itself, and probably do the work of translating it to every platform (even in your example, having string tokens just being output straight to CSS means you have platform-aware tokens that will have to be translated for native, or ignored).

But now that the types have been established, and users of the specs know to reach for off-the-shelf types, I do think adding these would help. For string especially, the “punishment” is having to do all the work of configuring it per-platform, so I think users wouldn’t reach for this type unless they really needed to. And good designs always need escape hatches!

Agree with the proposal as-written and don’t have any changes; just wanted to fill in more context in case it affects a decision later. I only had a couple additional thoughts:

Boolean types

👍 Agree totally with the proposal. 0 and 1 for CSS is smart! (also to your point of interop between true/false ←→ 0/1, that’s a great callout but I don’t think that would be a major problem once people get used to it)

String types

  • If the strings are platform-specific, user will have to manually ignore in outputs they’re not used (🤔 I think others have proposed ignoring tokens; this should be easier to do globally and per-plugin, including ignoring by default and overriding it for one plugin)
  • Can support microcopy as well (especially with $extensions you could even support i18n)
  • Agreed with not validating it and allowing empty strings (other than throwing an error for obvious errors like $value: null)

Minor update: still pushing forward on this with DTCG 🙂 (it’s just behind other decisions / proposals in the queue, but we’re trying to work through everything!). There’s already support for string and boolean types in Cobalt 2.0 (“Terrazzo”).

Realistically though there’s nothing stopping Cobalt 1.0 from adding this, I just don’t have time at the moment and am trying to get 2.0 stable and ready for release. But again, it supports both of these types natively (though I think each plugin may or may not support it—depends).