design-tokens / community-group

This is the official DTCG repository for the design tokens specification.
https://tr.designtokens.org
Other
1.56k stars 63 forks source link

Optional "tags" property on tokens #109

Open WardMe opened 2 years ago

WardMe commented 2 years ago

Hello,

I was wondering if an optional "tags" property containing an array of strings could be added to the tokens? This way we would be able to filter or group certain tokens using these tags in our tools ie. Figma Tokens, instead of adding metadata to our naming. It allows more flexibility for future updates and changes.

{
  "color": {
    "brand": {
      "primary": {
        "400": {
          "value": "#7cf88b",
          "type": "color",
          "tags": ["brand", "global", "…"]
        }
      }
    }
  }
}

What do you think?

Ward

drwpow commented 2 years ago

I like this idea, and this is something my team could use as well! Our color palette is broken down into a few related subgroups (brand, brand-secondary, etc.). While one opinion would be to just make each subgroup a different group in tokens (color.brand, color.brand-secondary), that seems a little unnecessary because there are no conflicts with color names, and in our code using color.teal is more intuitive/more efficient than color.brand-secondary.teal. This is an area where the subgroups feel more like a tag because they’re not necessarily a hard categorization. And to your point it’d futureproof the schema, being able to change a tag not affecting the token ID and cascading into code changes just because you wanted to associate a few colors together in a new way.

TravisSpomer commented 2 years ago

Would the $metadata node be sufficient for this, or is it important for what you want that there be a standardized place for specifically an array of tag names as strings that multiple third-party tools all understood?

[Oops, I meant $extensions, not $metadata!]

WardMe commented 2 years ago

I would love to see a standardised way for these tags, and isn't $metadata a group property? With tags you could add versioning, status, aliases, theming, … anything you could imagine to improve collaboration without forcing teams into structured data.

TravisSpomer commented 2 years ago

$extensions can go on tokens—I'd say probably 95% of its use case would be on tokens.

To me, all of those things you mentioned make a lot more sense as structured key/value pairs instead of simple string tags, but also I'm an obsessive organizer so I'm biased. 🙂 I can see how an unstructured list of strings could be more useful to some people. Worst-case, if the format didn't support it, you could just use a tags node inside of $extensions:

{
  "color": {
    "brand": {
      "primary": {
        "400": {
          "value": "#7cf88b",
          "type": "color",
+         "$extensions": { "tags": ["brand", "global", "…"] }
        }
      }
    }
  }
}
c1rrus commented 2 years ago

I like the idea of a tags property (in light of the recent decision to prefix format properties with $, it would need to be $tags though).

Just to make sure I've understood the original intent correctly, I'm assuming that $tags would be a means of tagging tokens with keywords (similar to how you might tag a blog post). Presumably tools could use that in a variety of ways:

@WardMe is that a fair summary of how you'd envisaged $tags being used? If not, then please do correct me.

My next question then would be: Should the $tags only be allowed on tokens, or on groups as well? And, if it is allowed on groups, does it apply to the group itself (i.e. you're tagging a group, not things within the group) or is it inherited by tokens within that group (just like $type, when applied to a group)?

I can imagine the latter being useful. It would basically be a handy way to apply the same set of tags to several tokens at once. However, given that the value of $tags is an array, what should the behaviour be for when a token that is inherting $tags from a parent group also has its own $tags property. Do the token's tags replace the inherited ones, or do they get merged?

{
  "color": {
    "brand": {
      // Tags on the "brand" group, which are inherited by
      // tokens within this group
      "$tags": ["global", "marketing", "company"],      

      "primary": {
        "400": {
          "$value": "#7cf88b",
          "$type": "color",
          // Tags on the "400" token
          "$tags": ["green", "logo"]

          // Are the resolved tags for this token:
          // a) ["green", "logo"] (replaced)
          // b) ["green", "logo", "global", "marketing", "company"] (merged)
        }
      }
    }
  }
} 

I'm thinking merged would be more useful. What do you think?

c1rrus commented 2 years ago

@TravisSpomer I think there may be some confusion. There is no $metadata property in the draft DTCG spec.

We were nearly added one to groups only in order to avoid group properties clashing with the names of items in the group. However, we've since decided not to do that and instead prefix all format properties (on groups and tokens) with $.

TravisSpomer commented 2 years ago

Yep, I mixed up $metadata with $extensions!

WardMe commented 2 years ago

@c1rrus correct summary! Concerning the groups, I would prefer merging the $tags as well.

CITguy commented 2 years ago

I agree with concatenating $tags as you walk down the JSON tree.

This definition...

{
  "color": {
    "$tags": ["global"],

    "brand": {
      "$tags": ["marketing", "company"],      

      "primary": {
        "400": {
          "$value": "#7cf88b",
          "$type": "color",
          "$tags": ["green", "logo"]
        }
      }
    }
  }
} 

Would resolve as...

{
  "color.brand.primary.400": {
    "$value": "#7cf88b",
    "$type": "color",
    /*
      resolved = [ 
        ...color.$tags, 
        ...color.brand.$tags, 
        ...color.brand.primary.400.$tags 
      ]
    */
    "$tags": ["global", "marketing", "company", "green", "logo"]
  }
}