Re: [community-group] Alias $type inheritance? (#236)

In addition to this comprehensive explanation, I would like to address an issue we face when parsing the Token Studio dynamic JSON that is based on this spec into a type-safe system in Swift. Type safety ensures that our code adheres to the specification. Below, you can see how we define the specification related to the types in Swift.

Note: To understand the Swift code, familiarity with the concept of enums with associated values is required. You can find more information [here](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/enumerations/). Additionally, understanding [Codable](https://developer.apple.com/documentation/swift/codable) might be necessary.

```swift
public enum Token: Codable, Hashable, Sendable {
    case assetLink(RefOrValue<Asset>)
    case boolean(RefOrValue<Boolean>)
    case boxshadow(RefOrValue<BoxShadow>)
    case border(RefOrValue<Border>)
    case color(RefOrValue<ColorResult>)
    case dimension(RefOrValue<Math>)
    case fontFamily(RefOrValue<FontFamily>)
    case fontSize(RefOrValue<Pixel>)
    case fontWeight(RefOrValue<FontWeight>)
    case format(RefOrValue<Format>)
    case lineHeight(RefOrValue<LineHeight>)
    case number(RefOrValue<Math>)
    case size(RefOrValue<Pixel>)
    case textDecoration(RefOrValue<TextDecoration>)
    case typography(RefOrValue<Typography>)
    case composition(RefOrValue<Composition>)

    public enum RawType: String, Codable, CaseIterable, Sendable {
        case assetLink = "asset"
        case boolean
        case border
        case boxshadow = "boxShadow"
        case color
        case composition
        case dimension
        case fontFamily = "fontFamilies"
        case fontSize = "fontSizes"
        case fontWeight = "fontWeights"
        case format
        case lineHeight = "lineHeights"
        case number
        case size = "sizing"
        case textDecoration
        case typography
    }
}
```
The types in the enum `Token.RawType` are based on the Token Studio specification. The challenge arises when we try to transform this specification into Swift/Kotlin/web code. We need to convert these types into a format that can be displayed on the screen. This transformation groups the types into a `UIType`, which represents something that can actually be rendered.

The specification poses a problem in determining which file to write the code to, as we can only identify the type if it is resolved. However, we do not want to resolve every alias at the moment we define the file to write to (this is an optimization to parse asynchronously). Hence, we have this mapping:

```swift
extension Token {
    var uiType: UIType {
        switch self {
        case .assetLink:
            return .assetLink
        case .boolean:
            return .uiBoolean
        case .boxshadow:
            return .boxShadow
        case .border:
            return .border
        case .color(.value(.color)):
            return .color
        case .color(.value(.gradient)):
            return .gradient
        case .color(.value(.modified)):
            return .color
        case .color(.reference(_)):
            // TODO: what to do here?
            return .color
        case .dimension:
            return .dimension
        case .fontFamily:
            return .fontFamily
        case .fontSize:
            return .fontSize
        case .fontWeight:
            return .fontWeight
        case .format:
            return .format
        case .lineHeight:
            return .assetLink
        case .number:
            return .number
        case .size:
            return .sizing
        case .textDecoration:
            return .textDecoration
        case .typography:
            return .typography
        case .composition:
            return .composition
        }
    }
}
```

The code includes a `TODO` because, according to the specification, a color can also be a gradient. However, to display them, the schema for a gradient differs significantly from a single color. For example, a single color might be represented as `color=hex`, while a gradient could be represented as `colors=[(hex, 50%),(hex, 10%),(hex, 30%)]`.

In XML, each node with a value or reference has a class that describes its type. We propose a similar approach here by adding the type reference.

Might I suggest that a reference is simply another JSON node, like color, with a type and a value. If the type is a reference, then the value is also a JSON node with a path and a type describing the destination type.

```json
{
  "background": {
    "gradient": {
      "value": {
        "path": "gradient.default.1",
        "type": "gradient"
      },
      "type": "reference"
    }
  }
}
```
This approach provides a clear and structured way to handle dynamic JSON parsing in a type-safe manner, ensuring that our code adheres to the specification and can be rendered appropriately on the screen.

We face this issue in projects for a media group based in Belgium called Mediahuis.

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


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

Received on Friday, 26 July 2024 09:04:53 UTC