-
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
$type should be a required property #139
Comments
I fully agree with this. Composite types should be typed groups.
This I do not see the purpose of, but I might be missing the point :) Tools would be unable to use this token as they do not know its type. So a |
I agree with you. I'm always thinking as "when things go wrong". But in this case, ony if "type" becomes required, maybe it makes no sense to have also a defult type. |
I agree with this; I don't see the point to having |
Perhaps the spec can be worded more clearly but: Every token has an unambiguous type and tools are expressly forbidden from trying to guess the token's type (e.g. from the value or name). However, the As it stands, the order of precedence is (from highest to lowest):
If we mandated that every token object must have Personally, I prefer to retain the ability to set a default type at the group level (yes, I'm a lazy typist! 😛) but that only makes sense if the Btw, the last fallback case (4.) is a bit like the "default" type idea proposed in @reblim's OP. Admittedly, most of those basic types are unlikely to be useful in the context of a design system (though
Note that I think it's perfectly acceptable for tools to ignore tokens that have a type that's not relevant to them. For example, imagine I wrote a tokens file that contained a In my view, what every tool MUST be capable of is to parse the entire file and implement that type resolution algorithm in order to determine what kinds of tokens there are. Whether it subsequently does stuff with all or just a sub-set of the tokens is entirely up to the tool though. Footnotes
|
In the case of parsing or linting, I think it is much simpler for each token to carry a Using For example, I would want an error if I tried to do this:
With "$type" present, I can get an error when I author this mistake. Without "$type", this error may not surface until I try to build CSS from the tokens. I think we're also seeing a trend in developer tooling toward stronger type safety (e.g. Python type annotations, Typescript, etc). For all those reasons, I would like to see "$type" be required. |
Hehe, this is the one exception where I think A background color and a background image will have different types as tokens but might be able to be assigned to the same property by consumers. If tokens with references as values have a type, it will no longer be possible to change the type at all for the source token. Each attempt will just be an error. It might be interesting to have a specialised |
@KyleWpppd Perhaps the spec's wording doesn't make this clear, but what you've described is how things should work. As per my earlier comment, a Therefore, if that token happens to reference another token which has a different type, then that is an error since the value will be incompatible. By having {
"token-a": {
"$type": "dimension",
"$value": "1rem"
},
// token-b's resolved type is "dimension"
// If the author's intent is: token-b is just another name for token-a, regardless of what
// token-a's type is, then they can express that by not setting $type and thus having the
// the resolved type be determined by the other token they are referencing.
"token-b": {
"$value": "{token-a}"
},
// This token's resolved type is color. However, it is invalid
// as its value references a non-color token. Tools are therefore
// required to reject this token and should show an appropriate
// warning or error message to the user.
// If the author's intent is: token-c must be a color, so I want tools to warn
// me if I accidentally reference a non-color token, then this is the way to
// achieve that.
"token-c": {
"$type": "color",
"$value": "{token-a}"
}
} |
This goes both ways right? If you do need to change the type you would first need to remove the type constraint everywhere the token is referenced or remove all references and add them back later. correct? |
@romainmenke Yes, I think you're right. I had so far mainly been focussing on what the expectations are for tools when they read or write tokens files, not so much what they do with the parsed data inbetween. My assumption is that different tools will have different internal representations and usages of the token data. That being said, tools must only write out valid token files. So, one way or another, they'll need to do something along the lines of what you described in order to meet that requirement. Perhaps the requirements could be specified something like this:
In both cases, one can argue that the intent of the referencing tokens is being altered in some way, so tools should warn the user or, better yet, give them a choice of what to do. |
But I do agree that |
Over the weekend I did some thinking. One place I got stuck is how to process |
Why do you see it being different in Java? Per c1rrus's comments above, every token already has an unambiguous type in the current format. |
@TravisSpomer apologies I did not understand that part of the spec. I was worried about parsing the |
No need to apologize. 🙂 And I think I misunderstood things a bit myself: it looks like it's in fact always optional, but if you don't specify |
Related to #149 |
This algorithm makes it much harder to describe the shape of the documents with TypeScript, JSON Schema or other tools for describing JSON. With a simpler model, for example making "$type" required with every "$value", we can create simple schemas for the document. With a simple JSON Schema we can get autocomplete and linting in Visual Studio Code almost for free. |
@KyleWpppd & @romainmenke, I used to think that manipulating the tree would get difficult without a mandatory To put my head around this issue I'm building a parser that reveal how |
That is not true currently :) It however has been mentioned many times in comments. Even when a parser for the current spec can be implemented, doesn't mean that it will age gracefully. My concern is the long term. I would like to see a transfer format that can easily be used in older and newer versions of tools and where older and newer files can easily be opened in all tools. I also want new additions and expansions to be simple and I never want them to be breaking changes for any and all users. These properties reduce friction between spec editors, tools and users, in turn these drive adoption. |
I do share your claims around making the format future proof being careful on architectural choices. Yet, I do see the IMO, what is actually at stake here is performance. Any loose schema with implicit resolutions like These are definitely design decisions that will impact any future tools, UX and performance. |
{
"$value": "foo"
} This token has the JSON type
1 is problematic because there is no context and this can be ambiguous. 2 is the only option that makes sense. But then why not 3 If it is undefined and should be ignored, then why even include it in the specification? It needs to be defined now what the JSON type
{
"$value": "foo",
"$type": "string"
} vs. {
"$value": "foo",
"$type": "keyword"
} It is highly unusual for specification to have these large gaps in their definitions. Especially for fundamental things like basic value types. |
Another good reason to make it required is because it doesn't make sense to omit After first going through the algorithm to assign types to every token it doesn't make sense to remove them again when writing out back to json. This is just more consistent |
Thanks all for your comments and feedback. The spec editors reviewed this and have decided to update the spec to make
The intent is to preserve the (human) authoring convenience that inheriting I'll leave this issue open until we've created and merged a PR that updates the spec to reflect this change. |
@c1rrus That's great news! Do you have a link to the PR? Thank you! Also, what about the |
I've just opened a PR to make the required changes: #201 :-) It'll need to be approved by other editors before it can be merged. But you're all very welcome to take a look and add review comments. Thanks! |
Just realised this issue never got closed even though PR #201 has been merged for a while now. Therefore go ahead and closing this. |
3.2 (Design) Token Properties
A concern I have with the current specification is that we are not making the "$type" property required. I believe that both the "$type" and "$value" properties should always be required to avoid tools from having to guess a type based on the group type, or even higher scopes.
Nevertheless, in order for this to work well, we must define our core types more precisely and create a complete list of all possible "primitive" token types. In addition, we could have a "default" type that acts like "any" in TypeScript, to be used if a defined type does not provide enough context for a token.
The text was updated successfully, but these errors were encountered: