Re: [community-group] How to do tokens that share a name with a group (#97)

To get the ball rolling, I'll outline a workaround and some potential approaches:

**Work around**
Authors can side-step the issue by not using a group. The example in the issue description could just put all 3 tokens into the "color" group and not have an "accent" group at all:

```json
{
  "color": {
    "accent": {
      "type": "color",
      "value": "#dd0000"
    },
    "accent-light": {
      "type": "color",
      "value": "#ff2222"
    },
    "accent-dark": {
      "type": "color",
      "value": "#aa0000"
    }
  }
}
```

While this works, it's not ideal. Part of the benefit of groups is that avoids having to repeat common prefixes in names, such as "accent" in this example. By using this work-around authors miss out on that benefit.

Also, groups can have their own descriptions (and potentially other properties future spec versions may add), so by using this work-around authors lose the ability to add such descriptive information to all the "accent*" tokens as there is no "accent" group anymore.

-----

Suggestion 1: **Empty name token**

It turns out that an empty string `""` is a valid name in JSON. Authors could therefore do the following:

```json
{
  "color": {
    "accent": {
      "": {
        "type": "color",
        "value": "#dd0000"
      },
      "light": {
        "type": "color",
        "value": "#ff2222"
      },
      "dark": {
        "type": "color",
        "value": "#aa0000"
      }
    }
  }
}
```

Since this apprach retains the "accent" group, authors can add things like a description to that group and that would be indendent of any description they give the "" token itself. For example:

```jsonc
{
  "color": {
    "accent": {
      "description": "Our brand's accent color and its tints & shades",
      "": {
        "type": "color",
        "value": "#dd0000",
        "description": "Our brand's accent color"
      },
      "light": {
        "type": "color",
        "value": "#ff2222",
        "description": "Tinted version of our brand's accent color"
      },
      // ...
    }
  }
}
```

There is actually nothing in the current spec draft that forbids this. However, if you wanted to alias the "color" / "accent" / "" token, the reference would need to be `{color.accent.}` (note the trailing period `.`). Without the period at the end, the reference would be pointing to the group, but we don't allow that (reference must always point to tokens).

Such reference might look a bit odd and are perhaps unintuitive. For convenience we may therefore want to modify our spec to have a rule stating that a reference that points to a group should be interpreted a pointing to a token with an empty name (`""`) within that group. So, if such a token exists the reference is valid and otherwise it is not. That way `{color.accent}` would be a valid reference.

-----

Suggestion 2: **Token and group hybrid**

In the current spec draft, groups and tokens are two very distinct concepts. Only tokens have values and only groups can contain tokens and other groups.

What if we allowed hybrids that are both token and group at the same time. They'd have a value (like a token), but could also contain other tokens or groups.

Our example might then become something like this:

```json
{
  "color": {
    "accent": {
      "type": "color",
      "value": "#dd0000",

      "light": {
        "type": "color",
        "value": "#ff2222"
      },
      "dark": {
        "type": "color",
        "value": "#aa0000"
      }
    }
  }
}
```

While this may seem quite elegant, it does introduce some challenges:

- How do we allow separate descriptions (or other "special" properties) for the group and token that make up the hybrid?
- Currently the `type` property on a _group_ acts as a default type for any tokens within that group - the group itself doesn't actually have a type. Therefore, how do we allow authors to specify a separate group (default) type and token type for the hybrid?
- This potentially increases the number of reserved words that cannot be used as group or token names. Every property that is allowed for tokens (`value`, `type`, `description`, `extensions` and whatever else we may add in future) must necessarily also be a reserved word within groups, since every group has the potential to be a hybrid.

You could resolve the first 2 challenges by have group-specific property names that don't clash with their token equivalents (e.g. `group-description`, `group-type` etc.), but that then means there even more reserved words.

For example, you might end up with something like this:
```jsonc
{
  "color": {
    // "accent" is a group & token hybrid
    "accent": {
      // "accent" group special props
      "group-description": "Our brand's accent color and its tints & shades",

      // "accent" token special props
      "type": "color",
      "value": "#dd0000",
      "description": "Our brand's accent color"

      // "light", "dark" etc. are items in the "accent" group as per usual
      "light": {
        "type": "color",
        "value": "#ff2222",
        "description": "Tinted version of our brand's accent color"
      },
      // ...
    }
  }
}
```

-----

I'm sure there's other pros/cons and approaches too. So, let's hear 'em! :-)

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


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

Received on Wednesday, 12 January 2022 23:08:25 UTC