Re: [community-group] Pre-defined composite type for refering color modifications (e.g. rgba) (#88)

Lots of really interesting suggestions here. Thanks everyone for sharing!

I'm not sure if additional types for modified/generated colors is the way to go though. My concern is that might make things more complex downstream if other things that expect color tokens want to reference those tokens. For example, if you wanted to use them in composite tokens like stops on a [gradient](https://design-tokens.github.io/community-group/format/#gradient) or the color of a [border](https://design-tokens.github.io/community-group/format/#border). Granted, we could update the spec for those types to allow their sub-values to be `color`, `color-rgba`, `color-hsla`, etc. but that doesn't feel very maintainable.

Also, thinking ahead a bit, I can imagine other types besides colors also benefitting from some mechanism to manipulate their values. For example dimension tokens being calculated as multiples of other dimension tokens (maybe to generate a spacing scale or something like that). I'm wondering if we can come up with a syntax and mechanism that works for colors today but could be extended to other types too.

I therefore really like the approach @jeromefarnum describes, where you can have an array of `operations`. Also, being able to factor them out as an `operations` token seems pretty neat - though that might raise interesting questions (or possibilities?) if you have a token of type `operations` that itself has `operations`. Maybe the operations should get concatenated, effectively allowing you to chain them together.

Let's imagine we could do something like this:

```jsonc
{
  "some-token": {
    "$value": "#ff0000",
    "$type": "color",

    // list of operations that can modify
    // the color value. They are applied in
    // the order listed here
    "$operations": [
       {
         "hue": -20
       },
       {
         "alpha": 0.3
       } 
    ]
  }
}
```

When a token has `$operations`, its `$value` becomes the input to those operations. The token's _resolved_ value is whatever the calculated value is after the operations have been applied. If other tokens reference this token, they should get the resolved value.

E.g.:

```jsonc
{
  "some-token": {
    "$value": "#ff0000", // input value
    "$type": "color",

    // list of operations that can modify
    // the color value. They are applied in
    // the order listed here
    "$operations": [
       {
         "alpha": 0.5
       }
    ]
    // resolved value is #ff00007f
  },

  "alias-token": {
    "$value": "{some-token}"
    // value is #ff00007f
  }
}
```

Whatever operations we define in our spec would need to be type-specific. The color type might have operations like hue, lighten, darken, alpha, etc., the dimension type might have operations like add, multiply, etc. and some types might have no available operations at all.

The rule would be that only compatible operations can be used. E.g. if your token is of type dimension and you use one fo the color operations, that would be considered invalid and tools should reject that token (and probably report an error to the user).

However, each operation can have parameters and can defined what types those parameters need to be. Furthermore, the parameters can be references to tokens of the required type.

Let's imagine we have a color operation called `alpha` and it takes a single parameter which is of type `number`. The number should be in the range `0` - `1` and will be set as the input color's alpha channel value (if numbers outside of that range are provided, they gets clamped to that range (so `999` would be treated as `1` for example)). The parameter could be a raw number value or a reference to a number token:

```jsonc
{
  "half": {
    "$value": 0.5
  },

  "some-token": {
    "$value": "#ff0000", // input value
    "$type": "color",

    "$operations": [
       {
         "alpha": "{half}"
       }
    ]
    // resolved value is #ff00007f
  }
}
```

So, for each operation we include in the spec, we'd need to define:

* It's name
* _Exactly_ what it does (e.g. there might be more than one way to lighten a color, so we'd need to specify the exact algorithm to ensure that all tools that support our format produce the same results)
* What type(s) it can operate on
* What parameter(s) it has and, for each paramater:
     * What type(s) that parameter needs to be

What do you think?

-- 
GitHub Notification of comment by c1rrus
Please view or discuss this issue at https://github.com/design-tokens/community-group/issues/88#issuecomment-1073374383 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Sunday, 20 March 2022 23:37:56 UTC