-
Notifications
You must be signed in to change notification settings - Fork 63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC] Format specification #1
Comments
Our mileage varies across projects / companies / tools, so I would like to hear thoughts and feedback on where this draft format works / doesn't work, with use cases showing where it breaks 🧐 |
One interesting scenario that's come up in Thumbprint is that some of our tokens have different values depending on the platform. For example, our spacing system on web versus native is:
(Notice that Here's what our JSON file for this looks like: Not sure if this should be supported, but it's something to consider. 🤷♂ |
Thank you @danoc – do you know if any design tool supports this kind of theming/ platform-specific variants so far? |
I think this is a great start! We might want to focus on the token interface to start, so we don't "boil the ocean". @danoc brings up an interesting issue, where is the platform-specific information, and do we even include it in the core token interface? Theo and Style Dictionary keep that out of the tokens themselves by using transforms. Same with names, they could be different per platform as well. Maybe if this is a universal/interchange format each token could have any platform data it wants to provide. For example, in @danoc's example, the space8 token would only have 'web' platform data... interface Token {
name: string;
value: any;
description?: string;
platforms: Platform[];
data?: Data;
}
interface Platform {
platform: string;
name: string;
value: any;
} |
instead of platforms, I think a more generic term could be |
Those are definitely super valid use cases! Theo achieves this with the concept of platform-specific and theming "overrides", or one could also do this by importing a different set of token aliases, specific to the platform or theme.
I've added another principle to the draft above: "The format translates well to existing design tools, in order to facilitate adoption". This means we need to ask ourselves:
|
A easy way to adopt the format without caring about the variants at first would be to specify which one is the default one and the existing design tool just has to care about that one |
I know this conversation focuses on the "shape of the data" rather than the implementation, but FWIW our take on platform-specific overrides in Diez is to use TypeScript decorators on top of property declarations. @override({
ios: 32,
android: 16,
web: 32,
}) spacingTop = 16 Is it worth elevating "cross-platform" as one of the guiding principles? Seems like a pretty big fork in the road. IMHO any spec with a claim to a Design Token Standard should treat platform-specifications(/overrides/variants) as first-class, but can do so without "hard-coding" specific platforms. |
@zackbrown I was also thinking about having a default value and some overrides for variants but with @dabbott we found that it might be safer to specify a value for all the variants so that when you add a new variant, your tool can warn you about the places where you need to look at (eg. the tokens not specifying the value for the new variant)
I think it's necessary too. But I'd say "platform independent" instead "cross-platform". |
@mathieudutour to help me understand:
could you sketch out (or point to) an example/pseudocode? |
{
variants: [
{ name: "web" },
{ name: "ios" }
],
tokens: [
{ name: "token1", value: { web: 1, ios: 2 } },
{ name: "token2", value: 3 }
]
} Let's say you want to add a new variant |
Definitely need some kind of category/grouping system, alias could be useful too.
|
cc @nikolasklein you worked on the styles panel in Figma – do you have thoughts on data structure for grouping/categories? |
IMO a group is just a token which has an array of tokens as value. To reference another token, you can then use an array where each item is the name of the token you need to go through: {
tokens: [
{ name: "token1", value: 1 },
{ name: "group", value: [
{ name: "nestedToken", value: 2 },
{ name: "nestedToken2", value: 3 }
]},
{ name: "refToken", value: ["group", "nestedToken2"] }
]
} |
I do not! We rolled our own a while back: |
@mathieudutour gotcha, I totally agree with this principle (re: variants; few messages above). Implementation-wise (speaking from the perspective of having already implemented this!) Diez leans on the TypeScript compiler [and a subsequent static-analysis pass for our transpiler] as the tool providing a warning, e.g. that you tried to use a platform It would be quite easy to warn also that e.g. "Your overrides are sparse! You might be forgetting Android definitions" without having to contort the data format. In other words, the data is either there or it isn't; IMO it should not be the purview of the data format to make it "extra easy" to perform static analysis, e.g. by duplication; the data format should instead strive to be minimal + ergonomic. Automated tooling can read that data and determine "sparse overrides" or "missing variants" almost regardless of the shape of the data. So keep it human-centered! [I doubt we disagree on this point!] |
I kind of do disagree actually haha. While I do think it should be kept human-readable, I don't think we needs to go out of our way to make it human-writable. I'm sure it will be pretty easy to build tools to edit tokens once we agree on a common format. And so I'm not too worried about introducing duplication as long as it's still readable. I'd even argue that specifying all the variants is more readable than a default value + overrides. So my point was to make sure that nothing weird can happen with the data format and that there is only way way to write one thing. So a token should either be a constant or depends on the variant. Otherwise you have multiple way to write a constant: default value + all the overrides with that value, default value + 1 override with that value, etc. |
Agreed. In my earlier example, which would be the default for |
appears to be at odds with Principle 1 outlined by @kaelig :
Granted, the joy of determining a standard is that of wrangling a variety of viewpoints & needs. And compromising! Maybe @kaelig and I are in the minority here in desiring hand- read/writebility? Design tokens are a promising key to achieving that fabled "single source of truth" for a design language — maybe even, ultimately, to entire applications. To me, hand-editability is important because any "single source of truth" must be accessible to a maximum number of stakeholders [incl. developers and low-code designers.] You can always build tooling on top of hand-editable code [see any IDE ever], but supporting hand-editability of machine-generated or 'machine-first' code is a very different beast. To me this all circles back to prioritizing ergonomics & minimalism in the data format. |
Of course it needs to be human-writable, and if it is readable, it will be writable. But introducing confusion (and multiple ways to write the same thing is def confusing) for the sake of convenience when writing the file by hand isn't something we should lean to IMO. |
Hi! 👋 Co-author of the System UI Theme Specification here. Thanks for bringing everyone together in one place! Based on the Twitter conversations, I originally thought that this sounded very similar to the efforts we're working on in the Theme Specification, but after seeing the examples in the initial comment, I suspect that there might be slightly different goals. If I'm wrong, I'm happy to combine efforts into a single place, but either way I'd love to make sure the two efforts can work together and build on top of one another – or perhaps the two specs can live under the same roof. For background on where we're coming from, some of our high-level goals, which I've written about here are:
Part of the reason the word theme is used here is that this should allow components to be written in a themeable way so that, for example, the same datepicker component can be installed and used at GitHub or Artsy, but match their own brand's "theme". As far as adoption goes, the spec is built into a few OSS libraries, and there is some interest from the following projects:
In my opinion, adoption among the open source community is really key to adoption in proprietary tools. That is, you have to provide something so good that it would be silly not to use, but businesses will rarely have interoperability as a primary goal. As far as the goals set out above, here are my thoughts.
Agreed. This is sort of a definition of code, i.e. human-and-machine-readable language.
This is also one of our principles, and I think it's key for any standard to achieve adoption, which is a very difficult thing to pull off.
This sounds equivalent to what I mean when I say it should be flexible and extensible. By creating a solid foundation, others should be able to build anything they need on top of that foundation.
Any schema can be converted to another shape. I might be reading this the wrong way, but I would argue that accepting translation leads to fragmentation. We already have transformers for parsing data from the Figma API, or converting a theme-spec compliant object to other libraries like Tailwind CSS, but this creates friction and doesn't lead to the level of interoperability that I would like to see tools adopt. So far, this sounds like we're fairly closely aligned with goals, even if they are slightly different. However, the code examples make me suspect that the aim here is more for a documentation format and less about a schema. If that's the case, the Theme Specification and this one could both be adopted and not be mutually-exclusive. Given this example:
The Theme Specification intentionally omits this level of schema definition and does not include documentation or metadata since that would not be desirable in production code and isn't required for interoperability. Things like code comments and type definitions are removed during compilation and more human readable documentation is generally stored in formats like markdown or MDX. I'll try to chime in again with more thoughts later, but we have an initial discussion around the Theme Specification in this issue if anyone in this thread would like to join the discussion. I hope this is helpful, and hopefully there's a way that both efforts can work together and we can stop reinventing the wheel as often. ✌️ |
👋🏻 Lona here! (@mathieudutour is also Lona). I'm excited to see this get off the ground! A couple more meta thoughts:
Sorry I haven't contributed much so far, I have some other priorities this week and next, but hope to hop in more soon |
👋🏻Modulz co-founder here. Thanks for kicking this off, I'm very interested in seeing this discussion evolve. We're a few months away from first-class theme/tokens support in Modulz. We've adopted Theme Specification for Radix (our own design system) and we're working towards adopting it for Modulz theming in general. I'm very keen to see a standard for many aspects of design systems. I'm up for investing time and other resources into it, if people think that might be helpful. |
Hi all. I'm the person behind Universal Design Tokens, which I started with essentially the same goal in mind: Defining a single file format for (source) design token data. So glad to see that others are tackling this too! Thanks @kaelig for kicking off this thread! Reading through the thread so far, I have a few comments / thoughts:
I also have some additional suggestions:
|
I also wonder whether there should be an additional v1 priority:
That might be a validator, some kind of coded test suite or a combination of those. But I feel it's worth having something like that as soon as possible. I believe the main motivation for an effort like this is for better interoperability. I want to one day be able to save out colors from PhotoShop, put them into ColorBox to to generate tints and shades, and then run them through a contrast checker to find accessible pairings and then save the results into my design system's source code without ever needing to convert between file formats. So, the more tools we can provide to let developers ensure their software parses or writes our universal format correctly, the less risk of bugs and incompatibilities creeping in and - ultimately - fragmenting the eco-system and reducing the benefits. |
Hello 👋🏻 Marais here! Human behind Overdrive. Just here dropping my two cents:
{
tokens: [
{
name: 'elevation-1',
value: '0 1px 10px 0 rgba(0, 0, 0, 0.03)',
'@context': [
{
'colour-red-900': '0 1px 10px 0 rgba(0, 0, 0, 0.09)',
},
],
},
{
name: 'colour-red-900',
value: '#780502',
},
];
}
Thanks for all the efforts though guys! |
There's a tension here between us naturally wanting an all-encompassing spec but also not wanting to 'boil the ocean'. I would suggest we start very small and pave the cowpaths before coming up with new things. The cowpaths here being: existing implementations in design tools, and examples used in more than 1 (or any other n) publicly available design system. Paving cowpaths If we zoom in on colors and the way they're used now:
There's a discrepancy between how people want (others) to use colors, namely they want certain colors to be used only for backgrounds, and they want people to choose between named colors blue-400 and blue-500, and what design tools offer, which is mostly 'a list of colors'. Keeping things small Variants, platform-dependent tokens and meta data are all important but what is the least this format should do to be useful? For example, these can be solved by having different token files for different variants. Vendors could choose how to interpret tokens without that having to be in the spec (if we put that in a spec and they ignore it in favor of their own translation of the true value, then what good is the spec?) What do we want a token to be? If we keep most of these things out, then focussing on what an actual token should encompass has us ask questions like:
Still, some of these questions already make things bigger rather than smaller (the nature of exploration). |
Hello, 👋 Co-founder of Interplay here. After reviewing the spec and comments above, here are some thoughts... 1. Overlap with System UI Theme Specification 2. Theming/Platform specific values Another option would be to leave this above the spec for now. i.e. The spec only deals with the values for a specific theme/platform. You can have complete token-sets (with the exact same structure) for each theme/platform/whatever. Obviously, in implementation, they could inherit from a base set. 3. Token Structure 4. Cross-referencing Other than that, I love the idea of having a spec, and happy to help however we can. |
A lot of the (super interesting ❤️) comments mention theming. After talking with @dbanksdesign earlier today, we think it'd make sense for theming to get its own task force. I'd like to start the conversation by laying out the basics of what a simple, low level theming spec could look like and ask y'all to comment on this topic over here: #2 |
👋 I'm Matt, a designer and developer - I've been exploring how design tokens can be stored, transformed, and accessed in ways that maximize their utility. You can read that work here. It might be useful to separate some of the individual aspects being discussed (typing, uniqueness, aliasing, order-dependency) from specific language specs and interpreters (CSS, JSON, SASS) ... it'll help clarify some of the discussion and avoid wrestling with the complexity of the existing implementations. I'll try and kick off some of those topics — though, as we get into some of the more "pure" concepts, my understanding gets a little fuzzier, so please correct me if I'm using these terms incorrectly. High-level structureI personally think of a design token as a key-value pair meaning it consists of two parts: one part is used for reference (looking up the token, talking about the token), and the other is used for application (indicating the color to be used, the font family, the border radius). Is that the mental model that y'all use, too? Might be nice to just put a checkmark in this box :) TypingReading through all the great conversations happening here, it's clear that typing is very important. Not only is it a key to a human-readable and human-writable format, but it's also going to have a big impact on the machines/code that read and write the tokens. The main question around typing: Should tokens be strongly typed, weakly typed, or not typed at all? Strongly typed: this might involve defining types as part of the spec. A token is only properly-formed if its types are declared and validated at compile time. This makes tokens a little harder to write, but has benefits for performance in the programs that utilize them. Weakly typed: this puts the burden of type-checking on the interpreter. Tokens are easier to write, but applications have to do some extra work to check types before utilizing the tokens. Not typed: this is some deep theory stuff that I don't understand very well. Uniqueness
Some analogies here: In JS, I can't define a In CSS, I can define a rule (like What are use cases for defining a token more than once? What kinds of complications would that introduce to the humans that write and maintain the code, and the machines that have to correctly interpret these definitions? AliasingI've found quite a few use cases for aliasing in writing tokens or using tokens — sometimes it's a lot more convenient to think about the However, there are some tradeoffs that come with writing aliases into the spec. For instance, what do we do about circular references? Order dependencySome current implementations of design tokens produce order-independent token files — Theo and Style Dictionary both work with JSON and YAML, which are essentially associative arrays. Earlier in the conversation, folks have mentioned some operations and use cases that might be order-dependent, like overrides and functions. I think that there's a ton of experience we can draw on from the history of other specs and how they were adopted over time — but ultimately it's the answers to these very core questions that will inform the shape and scope of the format specification. |
That’s a fantastic write-up, @ilikescience. I also enjoyed your post about your design API. I found the GraphQL interface quite straightforward. In that post I spotted the TypingI can see how typing might be helpful. I would be interested in seeing this explored more. In a CSS-like markup, I could imagine at-rules and functions accomplishing this. Tho, I like that you are focused on the should we before the how do we. It is harder for me to separate them. 🤷 UniquenessRegarding I would not be in favor of To the point of the prompt; if I interpret a style rule like If AliasingI think aliasing is a must-have, tho most-crucial for design systems over time. Aliasing can happen in the start, as in primitive tokens like you described, and also in higher order components. Like, sometimes things are referred to by how they look; sometimes things are referred to by how they function; and sometimes things are referred to by how they relate to other things. And on and on. Things get referred to multiple ways within a design system, usually based on history or context. Aliasing can seem antithetical to order and consistency, but consistency gets super hard the more components get created and the more time passes. Most design systems that I have seen up-close start out as a state of the union, often combining some new desires of the designers or developers with a larger set of existing patterns in production. The new and old are best paired with aliasing. Then, in the course of putting the design system together, the team makes choices over how to group color tokens along some axis of intensity, or how to group spacing by some multiple. And then later in the course of using the design system, exceptions are made and whole concepts change or get reimagined, and new pattern emerges. The new and old are best transitioned with aliasing. Aliasing for all the things! Order dependencyI probably have more to learn here. I would expect it to resolve a dependency tree like JS imports; e.g. Two JS files can both import from the same third JS file. |
Wow. Lots of great activity going on here! It's sparked a ton of questions in my head... @oscarotero I really like your CSS-like syntax proposals! I'd definitely support exploring that direction more. @mirisuzanne I'm not sure I've fully understood what you meant by "custom groupings". Are you thinking of allowing people to define their own, custom group types for token values? I.e. something similar to interfaces found in some programming languages (e.g. TypeScript)? Or did you have something else in mind? @ManeeshChiba How would you expect tools to interpret your proposed "molecule" tokens? Using your example: typography {
main {
font-family: $font-families.display;
font-size: $sizes.medium;
color: $colors.primary;
}
} Is the nesting...
@jonathantneal Great points about the different ways we might re-use or build upon CSS syntax. I think you've touched on something interesting there: What are the concepts we might want to inherit or copy from CSS? Most design token tools to date treat them as key-value pairs. Taking Styledictionary as an example, you might define a single design token in a JSON input file like so:
...and it can translate that in a range of different output formats. E.g. the SASS output might be: My (possibly incorrect) interpretation of @oscarotero's original proposal was an alternative, CSS-inspired syntax for expressing same kind of design token input data. So, for instance, a future Style-dictionary-like tool might read in such files instead of JSON. However, what's missing is the equivalent of CSS's selectors and properties. There's nothing that specifies what parts of a UI certain token values should be applied to. (That's assumed to be the job of a designer and/or developer who consumes the (potentially translated) tokens into their project) It's a totally valid question to debate whether a design token format should let you assign tokens to properties and thus essentially define the visual appearance of a UI, but so far they mostly don't (though Diez is beginning to blur those boundaries!). If I understood your option 2 correctly, where "we build upon the whole suite of CSS specifications", we'd be making a superset of CSS. I suppose we'd get all of CSS's properties, selectors and other goodness "for free" in that case. But, assuming we'd want to empower people that could write tools that knew how to translate that into something meaningful for completely different platforms (e.g. output native Swift UI code for iOS), I'd expect there to be some substantial challenges. Does native UI code for, say iOS, have an equivalent to the DOM in a web-browser and if not what how would we interpret a CSS selector? Also, would we not be reinventing the likes of SASS and LESS? I suspect I misunderstood the options in your comment though and you meant something else? @ilikescience Thanks for that excellent write-up! The more I think about it, the more I feel we need to capture and name the concepts we're all talking about. Then we can begin to decide which ones are in-scope for a design token format (at least for v1) and which are not. As you already know, there's already been some discussion amongst the editors about how it might make sense to begin by defining the "model" or "mechanisms" of design token data first and then worry about what syntax(es) it can be serialised to / de-serialised from. I feel like your comment is the first step towards being able to define such a model. :-) |
👋 Hello everyone. Just getting some thoughts out here for the group to mull over. High-Level StructureI feel as though adopting or starting from the CSS syntax and looking in to using rules and properties associated with CSS is going to cause a sort "lock-in" and reduce the "platform/tool/language agnostic" ideal of design tokens. CSS by it's own nature is a web technology. It does not need to serve native applications, and as such does not have considerations for how different native platforms handle their data or declarations. Where a language like JSON/YAML/XML is almost purely data storage and key/value pair associations. Using these languages as a point of origin would result in a less restrictive structure and allow for a simpler association between a token's name and it's value. Using something like YAML you can still get nested groupings/associations: font:
size:
small: 8px;
medium: 16px;
large: 32px;
family:
display: fancy-font;
body: normal-font; This could result in tokes like One other consideration I think may be worth mentioning is that unless the CSS Working Group updates the CSS spec, and then browsers adopt it in a timely manner whatever format we choose will have to be compiled into native CSS (same logic for your pre-processor of choice) anyway. If we're going to have to compile from "token syntax" to "platform syntax" (this could be UniquenessIn my experience we typically only define our tokens once, however I could see a world where at a larger org, or for something like a "bootstrap of design tokens" a team may want to take a "master" tokens file and suppliment or modify it with new definitions for existing tokens. Example: color:
primary: #7F0000;
secondary: #320000; The tokens fit most of our needs, but my team wants to change the colors. Rather than create new tokens, it would be nice if we could simply override the existing token definitions. color:
primary: #6666FF;
secondary: #33337F; In this example the format would need to function similar to @import tokens-master
@import custom-token-definitions
color: $color.primary; This would be expected to output to color: #6666FF; AliasingI would agree with this being a must-have. If only for the ability to define specific component/state/relational values based on an existing token's value. The biggest use case that our team uses this for is for branding and state values. All of our system's colors have generic names, they are then aliased to product specific values based on that product's branding. The same logic applies to states. It makes more sense to define |
Thanks for the thoughtful question @c1rrus I may be incorrect about this, but I am thinking about Design Tokens as way to codify design decisions, so I view the "selectors" as keys rather than css selectors per se. In my mind, the nesting implies a relationship. For instance in my example: typography {
main {
font-family: $font-families.display;
font-size: $sizes.medium;
color: $colors.primary;
}
} There is a token named main which defines a set of design decisions about how text should be rendered. This token is grouped into a super set of typography. So if I were to build a interpreter, I may look for the specific super set (perhaps because its reserved) of typography, within it I would expect to find collections of decisions to render a particular typographic element. In case of my example, the main text element. If I were writing a Design Token to CSS transpiler; It might create a css class of If I were writing a transpiler for some design software, perhaps it would be presented like this: I fear I may have missed my mark with my initial example. What I was trying to express is that Tokens will need two parts, no matter which syntax or language we choose. One part to define a property, Both are design decisions we need to codify. |
Hi again. What a lot of great thoughts! Why a CSS-like syntax?I'm agree with many of you that design tokens are key-value pairs, with nested groups, so they could be represented with JSON. Example: {
"typography": {
"font-family": "Arial",
"font-size": "24px"
}
} But the problems I see with JSON are:
{
"typography": {
"comments": [
"First comment",
"Second comment"
],
"value": {
"font-family": {"value": "Arial"},
"font-size": {"value": "24px"}
}
}
} Other option is using YAML, a more human format, that allows to add comments: # This is a comment
# Another comment
typography:
font-family: Arial
font-size: 24px That's a good option but has some drawbacks:
Other drawback of JSON and YAML is not about the structure of the tokens but how express the values. Colors are one of the most clear examples. Sketch, Figma, CSS, Swift, Java... all have different methods to represent colors. So we need a standard way to represent them as tokens. And the same for other values like dimmensions, gradients, different units, animations, etc. CSS is a language that have support and documentation for all these stuff and have additional features:
@c1rrus says:
Yes, exactly! My proposal is not about using the CSS format as is to store tokens, but creating a new format, inspired in CSS and taking advantage of all its standards. So when a tool import this new format, it nows how the colors, units, fonts, etc are expresed and how transform these values to use them in other platform (CSS, SASS, LESS, iOS, Android, CSS-in-JS, etc). @c1rrus also says:
In my opinion, is the first case, illustrated with this example: typography {
main {
font-size: $sizes.medium
}
}
/* It's equivalent to: */
typography {
main.font-size: $sizes.medium;
}
/* And to: */
typography.main.font-size: $sizes.medium; Anyway, this is just sugar syntax, so I don't have a strong opinion about adding support for this or not. Just want to illustrate that in this format there are no selectors. Only key-value pairs. UniquenessIn my company, we have a white-label product, so we have basic styles and them multiple themes, created by overriding the tokens (mainly colors and fonts). So this new format should allow to override these values at any point, in the same way that CSS. AliasingFrom a designer perspective, aliasing is a must. Design systems are recursive, and one clear example is the atomic design system, in which a value (atom) is used to generate a more big value (molecula) and this value will generate a even bigger value (organism). So we need a way to create aliases between values, in order to avoid repetition. Practical exampleFor designersI imagine design sofware like Sketch, Figma or Adobe XD with support for this new format, so you could have a panel to import and edit tokens in order to use them later in the elements. Maybe a simple text editor where you could include some An example using Sketch: For developersThe developers could use any tool (like Style-dictionary, Diez etc) to load these tokens and convert them to values that can be used in each platform (css, swift, android, etc). In CSS, the tokens could be converted to css variables, but also there could be a postcss plugin to use them directly, for example: .button {
background-color: $colors.primary;
} Other example: In my company, we are using mjml to create emails, and you must assign style values as attributes (see, for example, the button component). We could use the tokens here too: <mj-button background-color="$colors.primary">Click me</mj-button> TypingCSS has not typings and in most of cases it's not necessary. If we use the CSS way to represent values, we can detect that But typing could be a nice feature anyway. I've proposed a simple syntax here: #1 (comment) but open to other proposals, for example, using something similar to the |
On Value TypesI agree with @kevinmpowell that this is an important issue to be dealt with. With a missing unit value the only option is to supply many values as strings which makes them potentially harder to work with. Think about something like The same goes when specifying To come back to @kaelig original proposal I would suggest to add either an (optional) unit property or an optional sub-object with Another approach would be to do something like
TypingsI am strongly in favour of typing. This may not be important for the design tools, but for implementation of design tokens. Thinking about developers writing transformers, plugins, etc. This would arguably also create a less error toolset around design tokens, as all tools and implementations can refer back to standardised types. Property specificationsI don't know if this should be done in this issue or in a new one, but I think we need to also specify properties in a more detailed level. At least the common ones. If you agree, I would prefer to move this to a new issue, as this one gets pretty crowded. Property naming specificationIt would be important to specify how certain values need to be named. Having a standard makes it much easier to use them in tools. For example are we talking about Property value specificationThe same goes for property values. |
Concerning token namesCurrently the interface defines names as interface Token {
name: string;
value: any;
description?: string;
data?: Data;
// What other properties are needed? (type, category, group…)
} However I am wondering if this should be more strict? Since I guess most of us have worked with tech a lot, the examples "accidentally" seem to all follow conventions. However I have seen names like this:
Also there are many languages with special characters like I think this is something to consider and specify, either by restricting it to a certain format and character set or by explicitly allowing any string. Case 1: restrictedE.g. However it does restrict the user or at least the users output. Case 2: unrestrictedThis would allow very expressive names. However this makes it complex to use references in dot notation or use the names in code. They need to be converted and special attention needs to be put on how the names are converted to be still easily readable. |
Hey @kaelig the In case it is for the tokens, this would be very useful (I am currently looking into how a version could be added to a design tokens file). My use case is that I can not store the tokens in a vcs (I don't have access due to missing vpns), so I need to add a version to the file. |
I believe it was related to the version of the file itself, not of the token spec. However, you bring a very important point that we need to discuss with tooling vendors at large: should the format be shaped in a way that allows for token-level versioning, or any mechanism that potentially helps with cross-tool conflict resolution between versions of a token set? My hunch is that we'll see some tools acting as "design token brokers" in the middle, which are tools that would aggregate tokens and manage them in a way that works for an entire team's ecosystem. Another outcome I foresee will be that a team points all of their tools to a single "token source", which itself handles access management, versioning, and shipping. With that in mind, I'd love to hear more about your use-case and perhaps you could even share what you think might solve what you brought up? |
Hey @kaelig,
That sounds great. I think this is something that is definitely needed! Your "hunch" seems very likely to me. However in any of those cases I think it would be helpful to have some meta data and a version within the token payload. This way it does not matter if you get the token from a broker via an api request, pull it from an npm package or import a json file that the design team stores on a shared drive. Keeping a version tightly coupled with the tokens just makes sense. Like the version number that you have in a package.json. It makes the product (token.json) more resilient as it does not rely on a specific type of storage. It also means that caching the payload (tokens) will always keep the version as well, so it makes it easy to compare if something has changed and a cache needs to be invalidated. Let me know what your thoughts are on this. Just as a last thought, DSP has a |
👋 Hello everyone, I'm Nicolas, I've been working on some projects involving Design Tokens, and hope to do more, so I'm really interested in a standard for these. I've read the whole thread two times to make sure I understand all opinions, and here are some comments: SyntaxI like @oscarotero's suggestion to use a CSS-like syntax, because it's really both "human-editable and human-readable", which is the first principle from @kaelig's first message, it's better than JSON or YAML for some reasons @oscarotero listed here, and it already has many syntaxes and units for colors, dimensions, etc. However, sadly, I think dev tooling to deal with such a format could probably not re-use CSS based tooling, as this syntax would be "inspired by" more than "based on" CSS. And there are already a lot of robust tools to deal with JSON or YAML inputs and outputs. TypesI agree that it would be best having types to help tools manipulate values, and allow for tokens files validation. I use Style Dictionary and the CTI logic (or map it from my own hierarchy) to get typing, which allows for targeted transformations (px to rem, colors, etc.). I see that @oscarotero said that "CSS has not typings and in most of cases it's not necessary", but I think CSS do have (infered?) typings, we can't put a dimension in a NamingI would prefer it to be restricted, even without dashes (but underscores could be used), to prevent any issue, as suggested by @lukasoppermann in this comment AliasingAs most of you already said, aliasing is a must have to deal with token reuse. Tools can deal with circular references and alert the user when there's something wrong. Property naming specificationFrom @lukasoppermann's comment here, I don't understand "are we talking about |
Hey @nhoizey, thanks for all your thoughts on the topic. Concerning the Lets say tools like Figma and Sketch implement design tokens:
border-radius--small: 4px;
border-radius--default: 8px;
spacer--4: 4px;
spacer--8: 8px;
spacer--16: 16px;
It could also be solved by a property on the item that defines the use case (which than would probably have to be standardised). I am not saying this idea was the best solution. But having a way to "understand" values would be very helpful. |
@lukasoppermann ok, I now understand what you want to achieve, and I agree there's a need to filter tokens to those really useful for each use case in a design tool. 👍 |
Hey @kaelig I just thought about another topic: relationships. There are two types:1) Values from a visual group (what DSP of combines as collections)
While one could argue that the font example would be a text-style group, and the tokens make sense on and individual base, this is not true for the shadow example. An 2) Logical pairs (e.g. a background & text font)In css this is apparent by having an element and checking the background color and the text color. For tokens you can not know this at the moment. I personally use the google material approach, where you have a color e.g. Therefore it could be helpful to allow for some kind of pairing. This could be solved via the data properties, but if this use case is bigger, it may make sense to consider it. |
Hi everyone! I wanted to chime in with the approach to tokens we're taking at Vimeo. Everything is in early stages and subject to change, but we have quirks that I'm not sure have been fully represented here, and I hope y'all will find them interesting. I'm still re-reading the entire thread to ensure I understand the many thoughts that have been put forward, but I feel like @danoc, @ventrebleu, @mathieudutour, @mirisuzanne, @NateBaldwinDesign (and others!) have touched on related ideas to our approach. High Level Summary
ContextTokens must specify or inherit default contexts. In the case of color tokens, the note: in the below example export type TokenValue = string | FlattenSimpleInterpolation;
export type TokenProxy = (grade: number) => TokenProxy | TokenPrimitive;
export type TokenPrimitive = (grade: number) => TokenValue;
interface Token {
default?: string;
themes: {
[theme: string]: TokenPrimitive;
};
} // background is a TokenBand
export const background = (grade: number) => readToken(backgrounds, grade);
const backgrounds: Token = {
default: 'light',
themes: { dark, light },
};
function dark(grade: number): TokenValue {
return grayscale(-1 * (grade / 5 - 1000));
}
function light(grade: number): TokenValue {
return grade >= 300 ? white : slate(-1 * (grade / 2 - 150));
} import { core } from '@tokens/vimeo';
import { Button } from '@vimeo/iris/components';
const SpecialDownloadButton = styled(Button)`
display: flex;
color: ${core.color.text(700)};
background: ${core.color.background(400)};
@media screen and ${core.layout.breakpoint(300)} {
display: none
}
`; TaxonomyThis is a very rough draft.
We're trying to avoid hyper-specific tokens and stick to as few tokens as possible to represent all the design concepts and relationships in Vimeo's UI/UX. Eventually though, I could see a need for increased token specificity, such as the component-specific tokens that exist in Adobe Spectrum (and other systems).
Mapping Relationships (and Visualizing TokenBands)
I find this to be so, so, so important. It's the basis behind our more functional approach and use of Given that we view tokens as ways to capture relational meaning in design, we think that:
VersioningFollowing the structure we've set up, there isn't really a need to individually version tokens. |
Hey, I am currently working on a tool to use design tokens in design. I need to work with text-styles, meaning a collection of multiple values that make up a unique text style, e.g. Since the specs do not include collections, how would I best go about it? Would I just use tokens with an object as a value? Is this how such a token should be best defined? {
name: 'font/body',
value: {
fontSize: 16,
textDecoration: 'line-through',
fontFamily: 'Roboto',
fontWeight: 500,
fontStyle: 'italic',
fontStretch: 'normal',
letterSpacing: 0,
lineHeight: 'normal',
paragraphIndent: 0,
paragraphSpacing: 0,
textCase: 'none',
},
description: 'use for danger stuff',
data: {
type: 'fontStylte'
}
} |
If I read the gh-page / w3c specs correctly this would be a Is the idea here a: The value property has named values (like seen below) (and the names can be used to interpret the value, e.g. fontSize is always a px unit) {
name: 'font/body',
value: {
fontSize: 16,
textDecoration: 'line-through',
// ... or b: The value holds tokens: {
name: 'font/body',
value: {
fontSize: {
type: 'dimension',
value: 16
},
// ... |
@lukasoppermann what we've been talking about is composite tokens themselves having a type which would help interpret values, so something like: {
name: 'body-text',
type: 'text-style,
value: {
fontSize: 16,
textDecoration: 'line-through',
// ... A separate composite type definition for |
Hey @kevinmpowell thanks for the quick reply. Since I am currently trying to implement the draft to test it out, my best shot would be to create a group of tokens, right? {
'body-text': {
fontSize: {
value: 16,
type: 'dimension',
},
textDecoration: //...
} |
☝️ We've talked about user-defined (custom) composite tokens, but haven't added it into the current draft. I think your example makes sense. A group is similar to a composite, though with less defined structure. |
Hey @kevinmpowell thanks for the feedback. I reread the section about groups and saw that it is state that:
I want to export tokens from figma, so that I can build a amazon style dictionary transformation to turn them into css, xml and xcassets. To me this feels like "inferring" the purpose (e.g. combining the tokens into a text style). Considering this it would probably be more useful to create "user-defined composite tokens" and update them when the specs are finalised / composite token types are defined. Does that make sense? |
👍 |
Hi everyone, I'm closing this for now as we're looking to publish the first public editor's draft soon. Each important point will be addressed in its own issue, so we can individually track decisions and have focused conversations. You all provided tremendous amounts of inspiration, and I want to thank you all on behalf of the entire DTCG team for being so engaged ❤️ To complement the opinions of the community, we gathered requirements from all major design tool makers (both in a group setting and in smaller focus groups). Design tool makers tell us that their customers have a growing interest toward design tokens, so please keep sharing your feedback and use-cases so we can make the spec better for everyone 🔥 🙏🏻 |
Principles
v1 priorities
Inspiration
Proposal
At the moment, this proposal doesn't advocate for a particular file format (JSON, TypeScript…), it merely discusses what the shape of it should look like.
Example
The text was updated successfully, but these errors were encountered: