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

Added possibility of separate text styles extension generation #113

Merged
merged 7 commits into from
Aug 17, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CONFIG.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ ios:
typography:
# [optional] Absolute or relative path to swift file where to export UIKit fonts (UIFont extension).
fontSwift: "./Source/UIComponents/UIFont+extension.swift"
# [optional] Absolute or relative path to swift file where to generate LabelStyle extensions for each style (LabelStyle extension).
labelStyleSwift: "./Source/UIComponents/LabelStyle+Extension.swift"
# [optional] Absolute or relative path to swift file where to export SwiftUI fonts (Font extension).
swiftUIFontSwift: "./Source/View/Common/Font+extension.swift"
# Should FigmaExport generate UILabel for each text style (font)? E.g. HeaderLabel, BodyLabel, CaptionLabel
Expand Down
1 change: 1 addition & 0 deletions Sources/FigmaExport/Input/Params.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ struct Params: Decodable {

struct Typography: Decodable {
let fontSwift: URL?
let labelStyleSwift: URL?
let swiftUIFontSwift: URL?
let generateLabels: Bool
let labelsDirectory: URL?
Expand Down
22 changes: 18 additions & 4 deletions Sources/FigmaExport/Subcommands/ExportTypography.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,28 @@ extension FigmaExportCommand {
}
}

private func exportXcodeTextStyles(textStyles: [TextStyle], iosParams: Params.iOS, logger: Logger) throws {
let output = XcodeTypographyOutput(
private func createXcodeOutput(from iosParams: Params.iOS) -> XcodeTypographyOutput {
let fontUrls = XcodeTypographyOutput.FontURLs(
fontExtensionURL: iosParams.typography?.fontSwift,
swiftUIFontExtensionURL: iosParams.typography?.swiftUIFontSwift,
generateLabels: iosParams.typography?.generateLabels,
swiftUIFontExtensionURL: iosParams.typography?.swiftUIFontSwift
)
let labelUrls = XcodeTypographyOutput.LabelURLs(
labelsDirectory: iosParams.typography?.labelsDirectory,
labelStyleExtensionsURL: iosParams.typography?.labelStyleSwift
)
let urls = XcodeTypographyOutput.URLs(
fonts: fontUrls,
labels: labelUrls
)
return XcodeTypographyOutput(
urls: urls,
generateLabels: iosParams.typography?.generateLabels,
addObjcAttribute: iosParams.addObjcAttribute
)
}

private func exportXcodeTextStyles(textStyles: [TextStyle], iosParams: Params.iOS, logger: Logger) throws {
let output = createXcodeOutput(from: iosParams)
let exporter = XcodeTypographyExporter(output: output)
let files = try exporter.export(textStyles: textStyles)

Expand Down
51 changes: 41 additions & 10 deletions Sources/XcodeExport/Model/XcodeTypographyOutput.swift
Original file line number Diff line number Diff line change
@@ -1,24 +1,55 @@
import Foundation

public struct XcodeTypographyOutput {

let fontExtensionURL: URL?
let swiftUIFontExtensionURL: URL?
let urls: URLs
let generateLabels: Bool
let labelsDirectory: URL?
let addObjcAttribute: Bool

public struct FontURLs {
let fontExtensionURL: URL?
let swiftUIFontExtensionURL: URL?
public init(
fontExtensionURL: URL? = nil,
swiftUIFontExtensionURL: URL? = nil
) {
self.swiftUIFontExtensionURL = swiftUIFontExtensionURL
self.fontExtensionURL = fontExtensionURL
}
}

public struct LabelURLs {
let labelsDirectory: URL?
let labelStyleExtensionsURL: URL?

public init(
labelsDirectory: URL? = nil,
labelStyleExtensionsURL: URL? = nil
) {
self.labelsDirectory = labelsDirectory
self.labelStyleExtensionsURL = labelStyleExtensionsURL
}
}

public struct URLs {
public let fonts: FontURLs
public let labels: LabelURLs

public init(
fonts: FontURLs,
labels: LabelURLs
) {
self.fonts = fonts
self.labels = labels
}
}

public init(
fontExtensionURL: URL? = nil,
swiftUIFontExtensionURL: URL? = nil,
urls: URLs,
generateLabels: Bool? = false,
labelsDirectory: URL? = nil,
addObjcAttribute: Bool? = false
) {
self.fontExtensionURL = fontExtensionURL
self.swiftUIFontExtensionURL = swiftUIFontExtensionURL
self.urls = urls
self.generateLabels = generateLabels ?? false
self.labelsDirectory = labelsDirectory
self.addObjcAttribute = addObjcAttribute ?? false
}
}
58 changes: 53 additions & 5 deletions Sources/XcodeExport/XcodeTypographyExporter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ final public class XcodeTypographyExporter {
var files: [FileContents] = []

// UIKit UIFont extension
if let fontExtensionURL = output.fontExtensionURL {
if let fontExtensionURL = output.urls.fonts.fontExtensionURL {
files.append(contentsOf: try exportFonts(
textStyles: textStyles,
fontExtensionURL: fontExtensionURL,
Expand All @@ -22,21 +22,29 @@ final public class XcodeTypographyExporter {
}

// SwiftUI Font extension
if let swiftUIFontExtensionURL = output.swiftUIFontExtensionURL {
if let swiftUIFontExtensionURL = output.urls.fonts.swiftUIFontExtensionURL {
files.append(contentsOf: try exportFonts(
textStyles: textStyles,
swiftUIFontExtensionURL: swiftUIFontExtensionURL
))
}

// UIKit Labels
if output.generateLabels, let labelsDirectory = output.labelsDirectory {
if output.generateLabels, let labelsDirectory = output.urls.labels.labelsDirectory {
// Label.swift
// LabelStyle.swift
files.append(contentsOf: try exportLabels(
textStyles: textStyles,
labelsDirectory: labelsDirectory
))

// LabelStyle extensions
if let labelStyleExtensionsURL = output.urls.labels.labelStyleExtensionsURL {
files.append(contentsOf: try exportLabelStylesExtensions(
textStyles: textStyles,
labelStyleExtensionURL: labelStyleExtensionsURL
))
}
}

return files
Expand Down Expand Up @@ -121,6 +129,27 @@ final public class XcodeTypographyExporter {
return [FileContents(destination: destination, data: data)]
}

private func exportLabelStylesExtensions(textStyles: [TextStyle], labelStyleExtensionURL: URL) throws -> [FileContents] {
let dict = textStyles.map { style -> [String: Any] in
let type: String = style.fontStyle?.textStyleName ?? ""
return [
"className": style.name.first!.uppercased() + style.name.dropFirst(),
"varName": style.name,
"size": style.fontSize,
"supportsDynamicType": style.fontStyle != nil,
"type": type,
"tracking": style.letterSpacing.floatingPointFixed,
"lineHeight": style.lineHeight ?? 0
]}
let contents = try labelStyleExtensionSwiftContents.render(["styles": dict])

let fileName = labelStyleExtensionURL.lastPathComponent
let directoryURL = labelStyleExtensionURL.deletingLastPathComponent()
let labelStylesSwiftExtension = try makeFileContents(data: contents, directoryURL: directoryURL, fileName: fileName)

return [labelStylesSwiftExtension]
}

private func exportLabels(textStyles: [TextStyle], labelsDirectory: URL) throws -> [FileContents] {
let dict = textStyles.map { style -> [String: Any] in
let type: String = style.fontStyle?.textStyleName ?? ""
Expand Down Expand Up @@ -233,12 +262,31 @@ public final class {{ style.className }}Label: Label {
{% endfor %}
""")

private let labelStyleExtensionSwiftContents = Template(templateString: """
\(header)

import UIKit

public extension LabelStyle {
{% for style in styles %}
static func {{ style.varName }}() -> LabelStyle {
LabelStyle(
font: UIFont.{{ style.varName }}(){% if style.supportsDynamicType %},
fontMetrics: UIFontMetrics(forTextStyle: .{{ style.type }}){% endif %}{% if style.lineHeight != 0 %},
lineHeight: {{ style.lineHeight }}{% endif %}{% if style.tracking != 0 %},
tracking: {{ style.tracking}}{% endif %}
)
}
{% endfor %}
}
""")

private let labelStyleSwiftContents = """
\(header)

import UIKit

struct LabelStyle {
public struct LabelStyle {

let font: UIFont
let fontMetrics: UIFontMetrics?
Expand All @@ -252,7 +300,7 @@ struct LabelStyle {
self.tracking = tracking
}

func attributes(for alignment: NSTextAlignment, lineBreakMode: NSLineBreakMode) -> [NSAttributedString.Key: Any] {
public func attributes(for alignment: NSTextAlignment, lineBreakMode: NSLineBreakMode) -> [NSAttributedString.Key: Any] {

let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = alignment
Expand Down