Skip to content
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

[question] Token referencing an alias gets raw value? #181

Open
eloiseterry opened this issue Jan 16, 2024 · 4 comments
Open

[question] Token referencing an alias gets raw value? #181

eloiseterry opened this issue Jan 16, 2024 · 4 comments

Comments

@eloiseterry
Copy link

eloiseterry commented Jan 16, 2024

Setup:
palette.json -> collection of colors, some containing a custom extension that adjusts the raw value
colors.json -> collection of color tokens, each referencing a palette color

For example's sake, let's say my custom extension sets the opacity of an rgba color value.

// palette.json

{
  "palette": {
    "$type": "color",
    "black": {
      "$value": "rgba(0,0,0,100)",
      "$extensions": { "set-opacity": { "opacity": "0.25" } }
    }
  }
}

// colors.json

{
  "colors": {
    "$type": "color",
    "primary": {
      "$value": "{palette.black}"
    }
  }
}

When a plugin is run, such as @cobalt-ui/plugin-js, the value of token in the transform function references the value of the alias before the extensions are run, instead of the computed value. For example:

// tokens.config.mjs

import pluginCustom from './pluginCustom.mjs'

export default {
  tokens: [
    "./src/palette.json",
    "./src/color.json"
  ],
  plugins: [
    pluginJS({
      transform: (token) => {
        console.log(token.$value); // 'rgba(0,0,0,100)'

        console.log(token._original); // { '$value': '{palette.black}' }

        return token.$value;
      },
    })
}

Is this intended? If so, is there a way to either:

  1. Provide an option to have the plugins transform computed tokens (post-extension)
  2. Expose all properties of __original to include extensions
@drwpow
Copy link
Collaborator

drwpow commented Jan 16, 2024

Thanks for raising! $extensions in the spec is basically arbitrary metadata meant for tools to interpret how they will. There is no standard inside $extensions, so every tool will interpret it differently.

So there is no way for Cobalt to know how to execute set-opacity; it’s merely ignored. And as plugins are concerned with build targets, even if a plugin provided instructions with how to apply $extensions['set-opacity'], that would only apply to that plugin run and no other (i.e. plugin-js wouldn’t affect plugin-css).

So I think of the 2 proposals, #2 is the only one that’s possible—we do need to keep $extensions in the transformer for consumers to control how to execute that code.

I don’t think it’s intentional that’s omitted; it’s probably just a byproduct of how $extensions.mode works in Cobalt currently. We probably need to have better, clearer ways to provide multi-modal transforms in plugins, which means handling $extensions better in general.

@drwpow
Copy link
Collaborator

drwpow commented Feb 17, 2024

A related issue popped up this week with #192. I’ve realized that plugins need 3 things:

  1. The final / resolved value (exists currently)
  2. The original as-authored raw value (exists currently)
  3. (If aliased) The resolved original raw value, including extensions and modes (currently missing)

I think there’s a way to provide the third without a breaking change to the API. But things like these will inform the 2.0 API revision that will likely happen later this year.


On another note, this issue is related to #179

@jbarreiros
Copy link

jbarreiros commented Feb 27, 2024

Style Dictionary added this concept in v3. They call it "transitive transforms". Just wanted to note it as potential inspiration.

@drwpow
Copy link
Collaborator

drwpow commented Feb 27, 2024

@jbarreiros ah that’s very helpful, thank you! I am currently exploring something like that as part of the 2.0 plugin API. That will be a good reference point though

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants