Skip to content

Commit aeb9b03

Browse files
committed
Add ability to configure frames names
Closes #29
1 parent 40ab107 commit aeb9b03

File tree

10 files changed

+79
-38
lines changed

10 files changed

+79
-38
lines changed

CONFIG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,13 @@ common:
2222
# RegExp pattern for color name validation before exporting
2323
nameValidateRegexp: '^[a-zA-Z_]+$' # RegExp pattern for: background, background_primary, widget_primary_background
2424
icons:
25+
# Name of the Figma's frame where icons components are located
26+
figmaFrameName: Colors
2527
# RegExp pattern for icon name validation before exporting
2628
nameValidateRegexp: '^(ic)_(\d\d)_([a-z0-9_]+)$' # RegExp pattern for: ic_24_icon_name, ic_24_icon
2729
images:
30+
# Name of the Figma's frame where image components are located
31+
figmaFrameName: Illustrations
2832
# RegExp pattern for image name validation before exporting
2933
nameValidateRegexp: '^(img)_([a-z0-9_]+)$' # RegExp pattern for: img_image_name
3034

Examples/AndroidExample/figma-export.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@ figma:
33
lightFileId: BEjfU0kCVnPqXdRLfoLvkf
44
darkFileId: QwF30YrucxVwQyBNT0C09i
55

6+
# [optional] Common export parameters
7+
common:
8+
icons:
9+
# Name of the Figma's frame where icons components are located
10+
figmaFrameName: Colors
11+
images:
12+
# Name of the Figma's frame where image components are located
13+
figmaFrameName: Illustrations
14+
615
android:
716
mainRes: ./app/src/main/res
817
images:

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,11 +311,12 @@ File | Styles
311311

312312
For `figma-export icons`
313313

314-
Your Figma file must contains a frame with `Icons` name which contains components for each icon.
314+
By default your Figma file should contains a frame with `Icons` name which contains components for each icon. You may change a frame name in a [config](Config.md) file by setting `common.icons.figmaFrameName` property.
315315

316316
For `figma-export images`
317317

318-
Your Figma file must contains a frame with `Illustrations` name which contains components for each illustration.
318+
Your Figma file should contains a frame with `Illustrations` name which contains components for each illustration. You may change a frame name in a [config](Config.md) file by setting `common.images.figmaFrameName` property.
319+
319320
If you support dark mode you must have two Figma files.
320321

321322
For `figma-export typography`.

Release/figma-export.yaml

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
---
22
figma:
3-
# Identifier of Figma file
3+
# Identifier of the file containing light color palette, icons and light images. To obtain a file id, open the file in the browser. The file id will be present in the URL after the word file and before the file name.
44
lightFileId: shPilWnVdJfo10YF12345
5-
# [optional] Identifier of Figma file for dark mode
5+
# [optional] Identifier of the file containing dark color palette and dark images.
66
darkFileId: KfF6DnJTWHGZzC912345
77

88
# [optional] Common export parameters
@@ -11,24 +11,30 @@ common:
1111
# RegExp pattern for color name validation before exporting
1212
nameValidateRegexp: '^[a-zA-Z_]+$' # RegExp pattern for: background, background_primary, widget_primary_background
1313
icons:
14+
# Name of the Figma's frame where icons components are located
15+
figmaFrameName: Colors
1416
# RegExp pattern for icon name validation before exporting
1517
nameValidateRegexp: '^(ic)_(\d\d)_([a-z0-9_]+)$' # RegExp pattern for: ic_24_icon_name, ic_24_icon
1618
images:
19+
# Name of the Figma's frame where image components are located
20+
figmaFrameName: Illustrations
1721
# RegExp pattern for image name validation before exporting
1822
nameValidateRegexp: '^(img)_([a-z0-9_]+)$' # RegExp pattern for: img_image_name
1923

2024
# [optional] iOS export parameters
2125
ios:
2226
# Path to xcodeproj
2327
xcodeprojPath: "./Example.xcodeproj"
28+
# Xcode Target containing resources and corresponding swift code
29+
target: "UIComponents"
2430
# Absolute or relative path to the Assets.xcassets directory
2531
xcassetsPath: "./Resources/Assets.xcassets"
2632
# Is Assets.xcassets located in the main bundle?
2733
xcassetsInMainBundle: true
2834

2935
# Parameters for exporting colors
3036
colors:
31-
# Should be generate color assets instead of pure swift code
37+
# How to export colors? Use .xcassets and UIColor extension (useColorAssets = true) or extension only (useColorAssets = false)
3238
useColorAssets: True
3339
# [required if useColorAssets: True] Name of the folder inside Assets.xcassets where to place colors (.colorset directories)
3440
assetsFolder: Colors
@@ -47,13 +53,15 @@ ios:
4753
assetsFolder: Icons
4854
# Icon name style: camelCase or snake_case
4955
nameStyle: camelCase
50-
# [optional] Enable Preserve Vector Data for specified icons
56+
# [optional] An array of icon names that will supports Preseve Vecotor Data
5157
preservesVectorRepresentation:
5258
- ic24TabBarMain
5359
- ic24TabBarEvents
5460
- ic24TabBarProfile
5561
# [optional] Absolute or relative path to swift file where to export icons (SwiftUI’s Image) for accessing from the code (e.g. Image.illZeroNoInternet)
5662
swiftUIImageSwift: "./Source/Image+extension_icons.swift"
63+
# [optional] Absolute or relative path to swift file where to generate extension for UIImage for accessing icons from the code (e.g. UIImage.ic24ArrowRight)
64+
imageSwift: "./Example/Source/UIImage+extension_icons.swift"
5765

5866
# Parameters for exporting images
5967
images:
@@ -63,16 +71,31 @@ ios:
6371
nameStyle: camelCase
6472
# [optional] Absolute or relative path to swift file where to export images (SwiftUI’s Image) for accessing from the code (e.g. Image.illZeroNoInternet)
6573
swiftUIImageSwift: "./Source/Image+extension_illustrations.swift"
74+
# [optional] Absolute or relative path to swift file where to generate extension for UIImage for accessing illustrations from the code (e.g. UIImage.illZeroNoInternet)
75+
imageSwift: "./Example/Source/UIImage+extension_illustrations.swift"
6676

6777
# Parameters for exporting typography
6878
typography:
69-
# Path to directory where to place UIFont+extension.swift file
70-
fontExtensionDirectory: "./Source/UIComponents/"
71-
# Will FigmaExport generate UILabel for each text style (font) e.g. HeaderLabel, BodyLabel, CaptionLabel.
79+
# [optional] Absolute or relative path to swift file where to export UIKit fonts (UIFont extension).
80+
fontSwift: "./Source/UIComponents/UIFont+extension.swift"
81+
# [optional] Absolute or relative path to swift file where to export SwiftUI fonts (Font extension).
82+
swiftUIFontSwift: "./Source/View/Common/Font+extension.swift"
83+
# Should FigmaExport generate UILabel for each text style (font)? E.g. HeaderLabel, BodyLabel, CaptionLabel
7284
generateLabels: true
73-
# Path to directory where to place UILabel for each text style (font) (Requred if generateLabels = true)
85+
# Relative or absolute path to directory where to place UILabel for each text style (font) (Requred if generateLabels = true)
7486
labelsDirectory: "./Source/UIComponents/"
7587

7688
# [optional] Android export parameters
7789
android:
90+
# Relative or absolute path to the `main/res` folder including it. The colors/icons/imags will be exported to this folder
7891
mainRes: "./main/res"
92+
# Parameters for exporting images
93+
images:
94+
# Image file format: svg or png
95+
format: webp
96+
# Format options for webp format only
97+
webpOptions:
98+
# Encoding type: lossy or lossless
99+
encoding: lossy
100+
# Encoding quality in percents. Only for lossy encoding.
101+
quality: 90

Sources/FigmaAPI/Endpoint/ComponentsEndpoint.swift

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,3 @@ public struct ContainingFrame: Codable {
4747
public let name: String?
4848
public let pageName: String
4949
}
50-
51-
public enum FrameName: String, Codable {
52-
case components = "Components"
53-
case icons = "Icons"
54-
case illustrations = "Illustrations"
55-
}

Sources/FigmaExport/Input/Params.swift

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,22 @@ struct Params: Decodable {
99

1010
struct Common: Decodable {
1111
struct Colors: Decodable {
12-
let nameValidateRegexp: String
12+
let nameValidateRegexp: String?
1313
}
1414

1515
struct Icons: Decodable {
16-
let nameValidateRegexp: String
16+
let nameValidateRegexp: String?
17+
let figmaFrameName: String?
1718
}
1819

1920
struct Images: Decodable {
20-
let nameValidateRegexp: String
21+
let nameValidateRegexp: String?
22+
let figmaFrameName: String?
2123
}
2224

23-
let colors: Colors
24-
let icons: Icons
25-
let images: Images
25+
let colors: Colors?
26+
let icons: Icons?
27+
let images: Images?
2628
}
2729

2830
enum NameStyle: String, Decodable {

Sources/FigmaExport/Loaders/ImagesLoader.swift

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ final class ImagesLoader {
88
let params: Params
99
let platform: Platform
1010

11+
private var iconsFrameName: String {
12+
params.common?.icons?.figmaFrameName ?? "Icons"
13+
}
14+
15+
private var imagesFrameName: String {
16+
params.common?.images?.figmaFrameName ?? "Illustrations"
17+
}
18+
1119
init(figmaClient: FigmaClient, params: Params, platform: Platform) {
1220
self.figmaClient = figmaClient
1321
self.params = params
@@ -20,14 +28,14 @@ final class ImagesLoader {
2028
(.ios, .svg):
2129
return try _loadImages(
2230
fileId: params.figma.lightFileId,
23-
frameName: .icons,
31+
frameName: iconsFrameName,
2432
params: SVGParams(),
2533
filter: filter
2634
).map { ImagePack.singleScale($0) }
2735
case (.ios, _):
2836
return try _loadImages(
2937
fileId: params.figma.lightFileId,
30-
frameName: .icons,
38+
frameName: iconsFrameName,
3139
params: PDFParams(),
3240
filter: filter
3341
).map { ImagePack.singleScale($0) }
@@ -39,13 +47,13 @@ final class ImagesLoader {
3947
case (.android, .png), (.android, .webp), (.ios, .none):
4048
let lightImages = try loadPNGImages(
4149
fileId: params.figma.lightFileId,
42-
frameName: .illustrations,
50+
frameName: imagesFrameName,
4351
filter: filter,
4452
platform: platform)
4553
let darkImages = try params.figma.darkFileId.map {
4654
try loadPNGImages(
4755
fileId: $0,
48-
frameName: .illustrations,
56+
frameName: imagesFrameName,
4957
filter: filter,
5058
platform: platform)
5159
}
@@ -56,14 +64,14 @@ final class ImagesLoader {
5664
default:
5765
let light = try _loadImages(
5866
fileId: params.figma.lightFileId,
59-
frameName: .illustrations,
67+
frameName: imagesFrameName,
6068
params: SVGParams(),
6169
filter: filter)
6270

6371
let dark = try params.figma.darkFileId.map {
6472
try _loadImages(
6573
fileId: $0,
66-
frameName: .illustrations,
74+
frameName: imagesFrameName,
6775
params: SVGParams(),
6876
filter: filter)
6977
}
@@ -76,10 +84,10 @@ final class ImagesLoader {
7684

7785
// MARK: - Helpers
7886

79-
private func fetchImageComponents(fileId: String, frameName: FrameName, filter: String? = nil) throws -> [NodeId: Component] {
87+
private func fetchImageComponents(fileId: String, frameName: String, filter: String? = nil) throws -> [NodeId: Component] {
8088
var components = try loadComponents(fileId: fileId)
8189
.filter {
82-
$0.containingFrame.name == frameName.rawValue &&
90+
$0.containingFrame.name == frameName &&
8391
($0.description == platform.rawValue || $0.description == nil || $0.description == "") &&
8492
$0.description?.contains("none") == false
8593
}
@@ -94,7 +102,7 @@ final class ImagesLoader {
94102
return Dictionary(uniqueKeysWithValues: components.map { ($0.nodeId, $0) })
95103
}
96104

97-
private func _loadImages(fileId: String, frameName: FrameName, params: FormatParams, filter: String? = nil) throws -> [Image] {
105+
private func _loadImages(fileId: String, frameName: String, params: FormatParams, filter: String? = nil) throws -> [Image] {
98106
let imagesDict = try fetchImageComponents(fileId: fileId, frameName: frameName, filter: filter)
99107

100108
guard !imagesDict.isEmpty else {
@@ -114,7 +122,7 @@ final class ImagesLoader {
114122
}
115123
}
116124

117-
private func loadPNGImages(fileId: String, frameName: FrameName, filter: String? = nil, platform: Platform) throws -> [ImagePack] {
125+
private func loadPNGImages(fileId: String, frameName: String, filter: String? = nil, platform: Platform) throws -> [ImagePack] {
118126
let imagesDict = try fetchImageComponents(fileId: fileId, frameName: frameName, filter: filter)
119127

120128
guard !imagesDict.isEmpty else {

Sources/FigmaExport/Subcommands/ExportColors.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ extension FigmaExportCommand {
3939
logger.info("Processing colors...")
4040
let processor = ColorsProcessor(
4141
platform: .ios,
42-
nameValidateRegexp: params.common?.colors.nameValidateRegexp,
42+
nameValidateRegexp: params.common?.colors?.nameValidateRegexp,
4343
nameStyle: params.ios?.colors.nameStyle
4444
)
4545
let colorPairs = try processor.process(light: colors.light, dark: colors.dark).get()
@@ -54,7 +54,7 @@ extension FigmaExportCommand {
5454
logger.info("Processing colors...")
5555
let processor = ColorsProcessor(
5656
platform: .android,
57-
nameValidateRegexp: params.common?.colors.nameValidateRegexp,
57+
nameValidateRegexp: params.common?.colors?.nameValidateRegexp,
5858
nameStyle: .snakeCase
5959
)
6060
let colorPairs = try processor.process(light: colors.light, dark: colors.dark).get()

Sources/FigmaExport/Subcommands/ExportIcons.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ extension FigmaExportCommand {
5353
logger.info("Processing icons...")
5454
let processor = ImagesProcessor(
5555
platform: .ios,
56-
nameValidateRegexp: params.common?.icons.nameValidateRegexp,
56+
nameValidateRegexp: params.common?.icons?.nameValidateRegexp,
5757
nameStyle: params.ios?.icons.nameStyle
5858
)
5959
let icons = try processor.process(assets: images).get()
@@ -105,7 +105,7 @@ extension FigmaExportCommand {
105105
logger.info("Processing icons...")
106106
let processor = ImagesProcessor(
107107
platform: .android,
108-
nameValidateRegexp: params.common?.icons.nameValidateRegexp,
108+
nameValidateRegexp: params.common?.icons?.nameValidateRegexp,
109109
nameStyle: .snakeCase
110110
)
111111
let icons = try processor.process(light: images, dark: nil).get()

Sources/FigmaExport/Subcommands/ExportImages.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ extension FigmaExportCommand {
5353
logger.info("Processing images...")
5454
let processor = ImagesProcessor(
5555
platform: .ios,
56-
nameValidateRegexp: params.common?.images.nameValidateRegexp,
56+
nameValidateRegexp: params.common?.images?.nameValidateRegexp,
5757
nameStyle: params.ios?.images.nameStyle
5858
)
5959
let images = try processor.process(light: imagesTuple.light, dark: imagesTuple.dark).get()
@@ -102,7 +102,7 @@ extension FigmaExportCommand {
102102
logger.info("Processing images...")
103103
let processor = ImagesProcessor(
104104
platform: .android,
105-
nameValidateRegexp: params.common?.images.nameValidateRegexp,
105+
nameValidateRegexp: params.common?.images?.nameValidateRegexp,
106106
nameStyle: .snakeCase
107107
)
108108
let images = try processor.process(light: imagesTuple.light, dark: imagesTuple.dark).get()

0 commit comments

Comments
 (0)