cobalt-ui icon indicating copy to clipboard operation
cobalt-ui copied to clipboard

Enable granular CSS variables output

Open laitine opened this issue 1 year ago • 4 comments

Please enable configuring what tokens to exclude from the output. This would simply make generating CSS variables a lot more flexible and allow optimizing for specific use cases where a token or a token group is not needed. Below is a suggestion how this might work in practice. Adding ignorePatterns into the config would allow setting what tokens or groups to exclude from output.

/** @type {import('@cobalt-ui/core').Config} */
export default {
  tokens: './tokens.yaml',
  ignorePatterns: ['typography.font.*']
};

Currently the only option is to use modes which are intended for a different use case and would result in a lot of unconvenience.

laitine avatar Mar 08 '24 15:03 laitine

If the spec supported a $deprecated property would that be sufficient?

drwpow avatar Mar 08 '24 15:03 drwpow

Or, alternatively, if you read that issue some people have more advanced requirements of organizing their tokens, and they may have additional designations other than “deprecated.” What if we allowed you to specify deprecation based on a token property, e.g.?:

/** @type {import('@cobalt-ui/core').Config} */
export default {
  tokens: './tokens.yaml',
  ignoreToken: (token) => token.$extensions.deprecated || token.$extensions.status === 'deprecated',
};

The ignorePattern works, but I also want to pay attention to a community-surfaced issue to specify this at the token level and am trying to prevent people from configuring anything twice (and if you can set anything on a token, and not in Cobalt, I always want to encourage that)

drwpow avatar Mar 08 '24 15:03 drwpow

$deprecated could be interpreted so that the value is not valid which is not the case. $extensions could be used for this as this is a tool-related issue.

To further add details to the current state, this is possible by using transform but is somewhat hacky.

transform: (token) => {
  if (token.id.includes('typography.content') || token.id.includes('typography.heading')) {
    return true;
  }
},

laitine avatar Mar 08 '24 15:03 laitine

Good point. I guess that just leaves 2 questions:

  1. Does this make sense to ignore tokens globally (i.e. for all outputs?)
  2. Are there cases where you’d want to omit tokens for output A but not B?

Perhaps the answer is “sometimes both” and we could add a global ignore option for the core, and also add some way to remove outputs from individual transforms for each plugin, e.g.:

transform: (token, options) => {
  if (token.id.includes('id-i-do-not-want')) {
    return options.delete;
  }
}

Note: the way transform works, if you return undefined or null you’re saying “I still want this token in the output; I just don’t want to modify its original value” whereas an explicit .delete symbol would mean “I actually want this removed from the output altogether, but just for this plugin.”


$extensions could be used for this as this is a tool-related issue.

And yes just an additional slightly-off-topic thought: yes the original design of $extensions is “arbitrary metadata that a tool can either use or ignore,” it’s also important to view $extensions as “proposals to DTCG that may appear in the official spec someday.” So while $extensions can be used for tooling integrations, they also can be proposals, in a sense. And since I don’t see a clear consensus for $deprecated in that discussion, this seems like a good candidate for “just use $extensions for now that way if something does get added to the spec there’s no conflict.”

drwpow avatar Mar 08 '24 16:03 drwpow