style-dictionary icon indicating copy to clipboard operation
style-dictionary copied to clipboard

[Question] Can I generate extensions in iOS Swift?

Open antoniogamiz opened this issue 3 years ago • 7 comments

Hi, I have been using Style Dictionary and it's great! Thanks a lot for the hard work.

I have a question. I have the following configuration file to generate styles sheets on iOS Swift from design tokens hosted on Invision App:

{
  "source": [
    "tokens/**/*.json"
  ],
  "platforms": {
    "ios-swift-separate-enums": {
      "transformGroup": "ios-swift-separate",
      "buildPath": "build/ios-swift/",
      "files": [
        {
          "destination": "StyleDictionaryColor.swift",
          "format": "ios-swift/enum.swift",
          "className": "StyleDictionaryColor",
          "filter": {
            "attributes": {
              "category": "color"
            }
          }
        },
        {
          "destination": "StyleDictionarySize.swift",
          "format": "ios-swift/enum.swift",
          "className": "StyleDictionarySize",
          "type": "float",
          "filter": {
            "attributes": {
              "category": "size"
            }
          }
        }
      ]
    },
  }
}

The result is something like this:

import UIKit

public enum StyleDictionaryColor {
    public static let basicGrayDark = UIColor(red: 0.345, green: 0.345, blue: 0.345, alpha: 1)
    public static let basicGrayDark60 = UIColor(red: 0.000, green: 0.000, blue: 0.000, alpha: 0.6)
}

But, I would like to generate something like this:

extension Color {
    static let oldPrimaryColor = Color(UIColor.systemIndigo)
    static let darkGreyColor = Color("darkGrey")
}

Is that currently possible? Or would I need to create my own transformer? Thanks in advance (if this is not the place for this type of question, please redirect to the correct place if you which is, thanks! :))

antoniogamiz avatar Oct 19 '21 15:10 antoniogamiz

Hi @antoniogamiz!

Unfortunately right now there is no built-in format to generate a Swift extension for iOS. But I think it would be a good idea considering it is pretty common practice and makes using those colors easier. It would be a pretty straight-forward format to add, follow the ios-swift/enum format: https://github.com/amzn/style-dictionary/blob/main/lib/common/templates/ios-swift/enum.swift.template. You could write a custom format, and if you had time I think it would be a good contribution to the built-in formats. If you would like any help with that let me know.

dbanksdesign avatar Oct 19 '21 16:10 dbanksdesign

Okay, I will try to implement it in the near future! Thanks for the fast response :smiley: .

antoniogamiz avatar Oct 19 '21 16:10 antoniogamiz

Hi again @dbanksdesign, I have already created a PR with what I think is the correct way to implement this (I'm still learning all of this). I have found the following problem: when using colors, the default transformer (the one that uses UIColor is used), so If I want to generate an extension of Color:

extension Color {
    static let oldPrimaryColor = Color(UIColor.systemIndigo)
    static let darkGreyColor = Color("darkGrey")
    static let greyColor = Color("grey")
    static let lightGreyColor = Color("lightGrey")
    static let greyBackgroundColor = Color("greyBackground")
    static let blueBackgroundColor = Color("blueBackground")
    static let darkRedColor = Color("darkRed")   
}

I would need to specify another transformer. As I have not found any transformer for Color on Swift, I suppose I would have to implement it too, right?

antoniogamiz avatar Oct 25 '21 13:10 antoniogamiz

That is correct, we will need a SwiftUI Color transformer

dbanksdesign avatar Oct 25 '21 16:10 dbanksdesign

PR made for the SwiftUI Color transformer, let me now if I need change something.

antoniogamizbadger avatar Nov 12 '21 11:11 antoniogamizbadger

In case anyone wants an example on how to create a Swift extension file, on your iOS swift file object in config.json, use ios-swift/any.swift as the format and add a options object, in which you can provide a objectType with a extension value. Here's an example:

{
  "source": [
    "tokens/**/*.json"
  ],
  "platforms": {
    "ios-swift": {
      "transforms": [
        "..."
      ],
      "buildPath": "files/ios-swift/",
      "files": [
        {
          "destination": "MyCustomSpacing.swift",
          "format": "ios-swift/any.swift",
          "className": "CGFloat",
          "filter": "foundation/spacing",
          "options": {
            "objectType": "extension"
          }
        }
      ]
    }
  }
}

tfmart avatar Jul 26 '22 21:07 tfmart

@tfmart I'm doing the same thing and it's working great. Shouldn't need any custom formats or templates for this.

colinhumber avatar Sep 21 '22 14:09 colinhumber