From bf78fd7da1f961e5ddadcbdc270d66af66f294e6 Mon Sep 17 00:00:00 2001 From: nschpy Date: Sun, 16 Mar 2025 23:31:17 +0300 Subject: [PATCH 01/23] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B3=D0=B5=D0=BD=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D1=8E?= =?UTF-8?q?=20border=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/FigmaGen/Commands/TokensCommand.swift | 32 ++++++++++ Sources/FigmaGen/Dependencies.swift | 8 ++- .../Tokens/Contexts/BorderToken.swift | 8 +++ .../Tokens/DefaultTokensGenerator.swift | 15 ++++- ...ltTokensGenerationParametersResolver.swift | 9 ++- .../Borders/BorderTokensGenerator.swift | 3 + .../DefaultBorderTokensGenerator.swift | 58 +++++++++++++++++++ .../Tokens/TokensTemplateConfiguration.swift | 5 ++ .../TokensGenerationParameters.swift | 1 + Templates/BorderTokens.stencil | 39 +++++++++++++ 10 files changed, 175 insertions(+), 3 deletions(-) create mode 100644 Sources/FigmaGen/Generators/Tokens/Contexts/BorderToken.swift create mode 100644 Sources/FigmaGen/Generators/Tokens/Generators/Borders/BorderTokensGenerator.swift create mode 100644 Sources/FigmaGen/Generators/Tokens/Generators/Borders/DefaultBorderTokensGenerator.swift create mode 100644 Templates/BorderTokens.stencil diff --git a/Sources/FigmaGen/Commands/TokensCommand.swift b/Sources/FigmaGen/Commands/TokensCommand.swift index d2ba276..b2dc96d 100644 --- a/Sources/FigmaGen/Commands/TokensCommand.swift +++ b/Sources/FigmaGen/Commands/TokensCommand.swift @@ -236,6 +236,31 @@ final class TokensCommand: AsyncExecutableCommand { """ ) + let bordersTemplate = Key( + "--borders-template", + description: """ + Path to the template file. + If no template is passed a default template will be used. + """ + ) + + // TODO: - @nschpy Обновить description ??? + let bordersTemplateOptions = VariadicKey( + "--borders-options", + description: """ + An option that will be merged with template context, and overwrite any values of the same name. + Can be repeated multiple times and must be in the format: -o "name:value". + """ + ) + + let bordersDestination = Key( + "--borders-destination", + description: """ + The path to the file to generate. + By default, generated code will be printed on stdout. + """ + ) + // MARK: - Initializers init(generator: TokensGenerator) { @@ -314,6 +339,13 @@ extension TokensCommand { templateOptions: resolveTemplateOptions(spacingTemplateOptions.value), destination: spacingDestination.value ) + ], + borders: [ + TemplateConfiguration( + template: bordersTemplate.value, + templateOptions: resolveTemplateOptions(bordersTemplateOptions.value), + destination: bordersDestination.value + ) ] ) ) diff --git a/Sources/FigmaGen/Dependencies.swift b/Sources/FigmaGen/Dependencies.swift index 502aea2..25658fc 100644 --- a/Sources/FigmaGen/Dependencies.swift +++ b/Sources/FigmaGen/Dependencies.swift @@ -179,6 +179,11 @@ enum Dependencies { templateRenderer: templateRenderer ) + static let borderTokensGenerator: BorderTokensGenerator = DefaultBorderTokensGenerator( + tokensResolver: tokensResolver, + templateRenderer: templateRenderer + ) + static let tokensGenerator: TokensGenerator = DefaultTokensGenerator( tokensProvider: tokensProvider, tokensGenerationParametersResolver: tokensGenerationParametersResolver, @@ -188,7 +193,8 @@ enum Dependencies { typographyTokensGenerator: typographyTokensGenerator, boxShadowTokensGenerator: boxShadowTokensGenerator, themeTokensGenerator: themeTokensGenerator, - spacingTokensGenerator: spacingTokensGenerator + spacingTokensGenerator: spacingTokensGenerator, + bordersTokensGenerator: borderTokensGenerator ) static let libraryGenerator: LibraryGenerator = DefaultLibraryGenerator( diff --git a/Sources/FigmaGen/Generators/Tokens/Contexts/BorderToken.swift b/Sources/FigmaGen/Generators/Tokens/Contexts/BorderToken.swift new file mode 100644 index 0000000..bf16663 --- /dev/null +++ b/Sources/FigmaGen/Generators/Tokens/Contexts/BorderToken.swift @@ -0,0 +1,8 @@ +import Foundation + +struct BorderToken { + + let path: [String] + let width: String + let style: String +} diff --git a/Sources/FigmaGen/Generators/Tokens/DefaultTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/DefaultTokensGenerator.swift index 6f6f45c..5cce8aa 100644 --- a/Sources/FigmaGen/Generators/Tokens/DefaultTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/DefaultTokensGenerator.swift @@ -15,6 +15,8 @@ final class DefaultTokensGenerator: TokensGenerator { let boxShadowTokensGenerator: BoxShadowTokensGenerator let themeTokensGenerator: ThemeTokensGenerator let spacingTokensGenerator: SpacingTokensGenerator + let bordersTokensGenerator: BorderTokensGenerator + // MARK: - Initializers @@ -27,7 +29,8 @@ final class DefaultTokensGenerator: TokensGenerator { typographyTokensGenerator: TypographyTokensGenerator, boxShadowTokensGenerator: BoxShadowTokensGenerator, themeTokensGenerator: ThemeTokensGenerator, - spacingTokensGenerator: SpacingTokensGenerator + spacingTokensGenerator: SpacingTokensGenerator, + bordersTokensGenerator: BorderTokensGenerator ) { self.tokensProvider = tokensProvider self.tokensGenerationParametersResolver = tokensGenerationParametersResolver @@ -38,6 +41,7 @@ final class DefaultTokensGenerator: TokensGenerator { self.boxShadowTokensGenerator = boxShadowTokensGenerator self.themeTokensGenerator = themeTokensGenerator self.spacingTokensGenerator = spacingTokensGenerator + self.bordersTokensGenerator = bordersTokensGenerator } // MARK: - Instance Methods @@ -52,6 +56,7 @@ final class DefaultTokensGenerator: TokensGenerator { try generateBoxShadowTokens(parameters: parameters, tokenValues: tokenValues) try generateThemeTokens(parameters: parameters, tokenValues: tokenValues) try generateSpacingTokens(parameters: parameters, tokenValues: tokenValues) + try generateBorderTokens(parameters: parameters, tokenValues: tokenValues) } private func fetchTokens(from parameters: TokensGenerationParameters) async throws -> TokenValues { @@ -120,6 +125,14 @@ final class DefaultTokensGenerator: TokensGenerator { ) } + private func generateBorderTokens(parameters: TokensGenerationParameters, tokenValues: TokenValues) throws { + try generateTokens( + bordersTokensGenerator, + renderParameters: parameters.tokens.bordersRenderParameters, + tokenValues: tokenValues + ) + } + private func generateTokens( _ generator: BaseTokenGenerator, renderParameters: [RenderParameters]?, diff --git a/Sources/FigmaGen/Generators/Tokens/GenerationParametersResolver/DefaultTokensGenerationParametersResolver.swift b/Sources/FigmaGen/Generators/Tokens/GenerationParametersResolver/DefaultTokensGenerationParametersResolver.swift index 5f4c646..aa468b3 100644 --- a/Sources/FigmaGen/Generators/Tokens/GenerationParametersResolver/DefaultTokensGenerationParametersResolver.swift +++ b/Sources/FigmaGen/Generators/Tokens/GenerationParametersResolver/DefaultTokensGenerationParametersResolver.swift @@ -89,6 +89,12 @@ final class DefaultTokensGenerationParametersResolver: TokensGenerationParameter defaultTemplateType: .native(name: "SpacingTokens") ) + // TODO: Borders + let borderRenderParameters = renderParametersResolver.resolveRenderParameters( + templates: configuration.templates?.borders, + defaultTemplateType: .native(name: "Borders") + ) + return TokensGenerationParameters( file: file, remoteFile: remoteFile, @@ -99,7 +105,8 @@ final class DefaultTokensGenerationParametersResolver: TokensGenerationParameter typographyRenderParameters: typographyRenderParameters, boxShadowRenderParameters: boxShadowRenderParameters, themeRenderParameters: themeRenderParameters, - spacingRenderParameters: spacingRenderParameters + spacingRenderParameters: spacingRenderParameters, + bordersRenderParameters: borderRenderParameters ) ) } diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/Borders/BorderTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/Borders/BorderTokensGenerator.swift new file mode 100644 index 0000000..f142449 --- /dev/null +++ b/Sources/FigmaGen/Generators/Tokens/Generators/Borders/BorderTokensGenerator.swift @@ -0,0 +1,3 @@ +import Foundation + +protocol BorderTokensGenerator: BaseTokenGenerator { } diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/Borders/DefaultBorderTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/Borders/DefaultBorderTokensGenerator.swift new file mode 100644 index 0000000..f6a1db5 --- /dev/null +++ b/Sources/FigmaGen/Generators/Tokens/Generators/Borders/DefaultBorderTokensGenerator.swift @@ -0,0 +1,58 @@ +import Foundation + +struct DefaultBorderTokensGenerator: BorderTokensGenerator { + + // MARK: - Instance properties + + private let tokensResolver: TokensResolver + private let templateRenderer: TemplateRenderer + + // MARK: - Initializers + + init(tokensResolver: TokensResolver, templateRenderer: TemplateRenderer) { + self.tokensResolver = tokensResolver + self.templateRenderer = templateRenderer + } + + // MARK: - Private instance methods + + private func getBorderToken( + from token: TokenValue, + tokens: TokenValues + ) throws -> BorderToken? { + guard case .border(let value) = token.type else { + return nil + } + + return BorderToken( + path: token.name.components(separatedBy: "."), + width: try tokensResolver.resolveValue( + value.width, + tokenValues: tokens, + theme: .undefined + ), + style: value.style + ) + } + + // MARK: - BorderTokensGenerator + + func generate(renderParameters: RenderParameters, tokenValues: TokenValues) throws { + let semanticBorders = try tokenValues.semantic.map { tokenValue in + try getBorderToken(from: tokenValue, tokens: tokenValues) + } + + let coreBorders = try tokenValues.core.map { tokenValue in + try getBorderToken(from: tokenValue, tokens: tokenValues) + } + + try templateRenderer.renderTemplate( + renderParameters.template, + to: renderParameters.destination, + context: [ + "coreBorders": coreBorders, + "semanticBorders": semanticBorders + ] + ) + } +} diff --git a/Sources/FigmaGen/Models/Configuration/Tokens/TokensTemplateConfiguration.swift b/Sources/FigmaGen/Models/Configuration/Tokens/TokensTemplateConfiguration.swift index a267946..6de0207 100644 --- a/Sources/FigmaGen/Models/Configuration/Tokens/TokensTemplateConfiguration.swift +++ b/Sources/FigmaGen/Models/Configuration/Tokens/TokensTemplateConfiguration.swift @@ -12,6 +12,7 @@ struct TokensTemplateConfiguration { let boxShadows: [TemplateConfiguration]? let theme: [TemplateConfiguration]? let spacing: [TemplateConfiguration]? + let borders: [TemplateConfiguration]? } // MARK: - Decodable @@ -28,6 +29,7 @@ extension TokensTemplateConfiguration: Decodable { case boxShadows case theme case spacing + case borders } // MARK: - Initializers @@ -48,5 +50,8 @@ extension TokensTemplateConfiguration: Decodable { boxShadows = try container.decodeIfPresent(TemplateConfigurationWrapper.self, forKey: .boxShadows)?.templates theme = try container.decodeIfPresent(TemplateConfigurationWrapper.self, forKey: .theme)?.templates spacing = try container.decodeIfPresent(TemplateConfigurationWrapper.self, forKey: .spacing)?.templates + + // Borders, value + borders = try container.decodeIfPresent(TemplateConfigurationWrapper.self, forKey: .borders)?.templates } } diff --git a/Sources/FigmaGen/Models/Parameters/TokensGenerationParameters.swift b/Sources/FigmaGen/Models/Parameters/TokensGenerationParameters.swift index 224cef9..6c4a7b0 100644 --- a/Sources/FigmaGen/Models/Parameters/TokensGenerationParameters.swift +++ b/Sources/FigmaGen/Models/Parameters/TokensGenerationParameters.swift @@ -15,6 +15,7 @@ struct TokensGenerationParameters { let boxShadowRenderParameters: [RenderParameters]? let themeRenderParameters: [RenderParameters]? let spacingRenderParameters: [RenderParameters]? + let bordersRenderParameters: [RenderParameters]? } // MARK: - Instance Properties diff --git a/Templates/BorderTokens.stencil b/Templates/BorderTokens.stencil new file mode 100644 index 0000000..3d25e52 --- /dev/null +++ b/Templates/BorderTokens.stencil @@ -0,0 +1,39 @@ +{% include "FileHeader.stencil" %} +{% if semanticBorders or coreBorders %} +{% set accessModifier %}{% if options.publicAccess %}public{% else %}internal{% endif %}{% endset %} +{% set tokenTypeName %}{{ options.tokenTypeName|default:"BorderTokens" }}{% endset %} +{% macro propertyName name %}{{ name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords }}{% endmacro %} +{% macro borderProperty border %} + /// {{ border.path|join:"." }} + /// + /// Width: {{ border.width }} + /// Style: {{ border.style|default:"solid" }} + {{ accessModifier }} var {% call propertyName border.path|join:"_" %}: BorderToken { + BorderToken( + width: {{ border.width }}, + style: "{{ border.style|default:"solid" }}" + ) + } +{% endmacro %} + +#if canImport(UIKit) +import UIKit +#else +import AppKit +#endif + +{{ accessModifier }} struct {{ tokenTypeName }} { + + // MARK: - Instance Properties + {% for border in semanticBorders %} + {% call borderProperty border %} + {% endfor %} + + {% for border in coreBorders %} + {% call borderProperty border %} + {% endfor %} +} +{% else %} +// No border tokens found +{% endif %} + From c98c15afac81b68e89ce39e18b72c19e6f08b220 Mon Sep 17 00:00:00 2001 From: nschpy Date: Mon, 17 Mar 2025 16:18:12 +0300 Subject: [PATCH 02/23] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D1=88=D0=B0?= =?UTF-8?q?=D0=B1=D0=BB=D0=BE=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FigmaGenDemo/Generated/BorderTokens.swift | 135 ++++++++++++++++++ ...ltTokensGenerationParametersResolver.swift | 3 +- .../Tokens/TokensTemplateConfiguration.swift | 4 +- Templates/BorderTokens.stencil | 10 ++ 4 files changed, 147 insertions(+), 5 deletions(-) create mode 100644 Demo/FigmaGenDemo/Generated/BorderTokens.swift diff --git a/Demo/FigmaGenDemo/Generated/BorderTokens.swift b/Demo/FigmaGenDemo/Generated/BorderTokens.swift new file mode 100644 index 0000000..02f31cb --- /dev/null +++ b/Demo/FigmaGenDemo/Generated/BorderTokens.swift @@ -0,0 +1,135 @@ +// swiftlint:disable all +// Generated using FigmaGen - https://github.com/hhru/FigmaGen + +#if canImport(UIKit) +import UIKit +#else +import AppKit +#endif + +public struct BorderToken: Hashable { + public let width: CGFloat + public let style: String + + public init(width: CGFloat, style: String) { + self.width = width + self.style = style + } +} + +internal struct BorderTokens { + + // MARK: - Instance Properties + /// semantic.border.applied + /// + /// Width: 2 + /// Style: solid + internal var semanticBorderApplied: BorderToken { + BorderToken( + width: 2, + style: "solid" + ) + } + /// semantic.border.checkable + /// + /// Width: 1.5 + /// Style: solid + internal var semanticBorderCheckable: BorderToken { + BorderToken( + width: 1.5, + style: "solid" + ) + } + /// semantic.border.dashed-default + /// + /// Width: 2 + /// Style: dashed + internal var semanticBorderDashedDefault: BorderToken { + BorderToken( + width: 2, + style: "dashed" + ) + } + /// semantic.border.dashed-focused + /// + /// Width: 2 + /// Style: dashed + internal var semanticBorderDashedFocused: BorderToken { + BorderToken( + width: 2, + style: "dashed" + ) + } + /// semantic.border.default + /// + /// Width: 1 + /// Style: solid + internal var semanticBorderDefault: BorderToken { + BorderToken( + width: 1, + style: "solid" + ) + } + /// semantic.border.disabled + /// + /// Width: 1 + /// Style: solid + internal var semanticBorderDisabled: BorderToken { + BorderToken( + width: 1, + style: "solid" + ) + } + /// semantic.border.focused + /// + /// Width: 2 + /// Style: solid + internal var semanticBorderFocused: BorderToken { + BorderToken( + width: 2, + style: "solid" + ) + } + /// semantic.border.hovered + /// + /// Width: 1 + /// Style: solid + internal var semanticBorderHovered: BorderToken { + BorderToken( + width: 1, + style: "solid" + ) + } + /// semantic.border.invalid + /// + /// Width: 1 + /// Style: solid + internal var semanticBorderInvalid: BorderToken { + BorderToken( + width: 1, + style: "solid" + ) + } + /// semantic.border.selected + /// + /// Width: 2 + /// Style: solid + internal var semanticBorderSelected: BorderToken { + BorderToken( + width: 2, + style: "solid" + ) + } + /// semantic.border.tab-focused + /// + /// Width: 4 + /// Style: solid + internal var semanticBorderTabFocused: BorderToken { + BorderToken( + width: 4, + style: "solid" + ) + } + +} + diff --git a/Sources/FigmaGen/Generators/Tokens/GenerationParametersResolver/DefaultTokensGenerationParametersResolver.swift b/Sources/FigmaGen/Generators/Tokens/GenerationParametersResolver/DefaultTokensGenerationParametersResolver.swift index aa468b3..8add0c3 100644 --- a/Sources/FigmaGen/Generators/Tokens/GenerationParametersResolver/DefaultTokensGenerationParametersResolver.swift +++ b/Sources/FigmaGen/Generators/Tokens/GenerationParametersResolver/DefaultTokensGenerationParametersResolver.swift @@ -89,10 +89,9 @@ final class DefaultTokensGenerationParametersResolver: TokensGenerationParameter defaultTemplateType: .native(name: "SpacingTokens") ) - // TODO: Borders let borderRenderParameters = renderParametersResolver.resolveRenderParameters( templates: configuration.templates?.borders, - defaultTemplateType: .native(name: "Borders") + defaultTemplateType: .native(name: "BorderTokens") ) return TokensGenerationParameters( diff --git a/Sources/FigmaGen/Models/Configuration/Tokens/TokensTemplateConfiguration.swift b/Sources/FigmaGen/Models/Configuration/Tokens/TokensTemplateConfiguration.swift index 6de0207..bf165db 100644 --- a/Sources/FigmaGen/Models/Configuration/Tokens/TokensTemplateConfiguration.swift +++ b/Sources/FigmaGen/Models/Configuration/Tokens/TokensTemplateConfiguration.swift @@ -50,8 +50,6 @@ extension TokensTemplateConfiguration: Decodable { boxShadows = try container.decodeIfPresent(TemplateConfigurationWrapper.self, forKey: .boxShadows)?.templates theme = try container.decodeIfPresent(TemplateConfigurationWrapper.self, forKey: .theme)?.templates spacing = try container.decodeIfPresent(TemplateConfigurationWrapper.self, forKey: .spacing)?.templates - - // Borders, value - borders = try container.decodeIfPresent(TemplateConfigurationWrapper.self, forKey: .borders)?.templates + borders = try? container.decodeIfPresent(TemplateConfigurationWrapper.self, forKey: .borders)?.templates } } diff --git a/Templates/BorderTokens.stencil b/Templates/BorderTokens.stencil index 3d25e52..0d46d98 100644 --- a/Templates/BorderTokens.stencil +++ b/Templates/BorderTokens.stencil @@ -22,6 +22,16 @@ import UIKit import AppKit #endif +public struct BorderToken: Hashable { + public let width: CGFloat + public let style: String + + public init(width: CGFloat, style: String) { + self.width = width + self.style = style + } +} + {{ accessModifier }} struct {{ tokenTypeName }} { // MARK: - Instance Properties From ca1cd8970dc2975ccdf2eaa2cc2fd58d3c2c5f52 Mon Sep 17 00:00:00 2001 From: nschpy Date: Mon, 17 Mar 2025 18:09:33 +0300 Subject: [PATCH 03/23] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D0=B3=D0=B5=D0=BD=D0=B5=D1=80=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D1=8E=20=D1=88=D0=B0=D0=B1=D0=BB=D0=BE=D0=BD=D0=B0=20border?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Demo/.figmagen.yml | 4 ++++ Demo/FigmaGenDemo/Generated/BorderTokens.swift | 14 +++++++++++--- .../Borders/DefaultBorderTokensGenerator.swift | 4 ++-- Templates/BorderTokens.stencil | 14 +++++++------- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/Demo/.figmagen.yml b/Demo/.figmagen.yml index ecf3b1c..40c3d07 100644 --- a/Demo/.figmagen.yml +++ b/Demo/.figmagen.yml @@ -66,6 +66,10 @@ tokens: destination: FigmaGenDemo/Generated/SpacingTokens.swift templateOptions: publicAccess: true + borders: + destination: FigmaGenDemo/Generated/BorderTokens.swift + templateOptions: + publicAccess: true theme: destination: FigmaGenDemo/Generated/Theme.swift templateOptions: diff --git a/Demo/FigmaGenDemo/Generated/BorderTokens.swift b/Demo/FigmaGenDemo/Generated/BorderTokens.swift index 02f31cb..54f1d0c 100644 --- a/Demo/FigmaGenDemo/Generated/BorderTokens.swift +++ b/Demo/FigmaGenDemo/Generated/BorderTokens.swift @@ -18,8 +18,8 @@ public struct BorderToken: Hashable { } internal struct BorderTokens { - // MARK: - Instance Properties + /// semantic.border.applied /// /// Width: 2 @@ -30,6 +30,7 @@ internal struct BorderTokens { style: "solid" ) } + /// semantic.border.checkable /// /// Width: 1.5 @@ -40,6 +41,7 @@ internal struct BorderTokens { style: "solid" ) } + /// semantic.border.dashed-default /// /// Width: 2 @@ -50,6 +52,7 @@ internal struct BorderTokens { style: "dashed" ) } + /// semantic.border.dashed-focused /// /// Width: 2 @@ -60,6 +63,7 @@ internal struct BorderTokens { style: "dashed" ) } + /// semantic.border.default /// /// Width: 1 @@ -70,6 +74,7 @@ internal struct BorderTokens { style: "solid" ) } + /// semantic.border.disabled /// /// Width: 1 @@ -80,6 +85,7 @@ internal struct BorderTokens { style: "solid" ) } + /// semantic.border.focused /// /// Width: 2 @@ -90,6 +96,7 @@ internal struct BorderTokens { style: "solid" ) } + /// semantic.border.hovered /// /// Width: 1 @@ -100,6 +107,7 @@ internal struct BorderTokens { style: "solid" ) } + /// semantic.border.invalid /// /// Width: 1 @@ -110,6 +118,7 @@ internal struct BorderTokens { style: "solid" ) } + /// semantic.border.selected /// /// Width: 2 @@ -120,6 +129,7 @@ internal struct BorderTokens { style: "solid" ) } + /// semantic.border.tab-focused /// /// Width: 4 @@ -130,6 +140,4 @@ internal struct BorderTokens { style: "solid" ) } - } - diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/Borders/DefaultBorderTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/Borders/DefaultBorderTokensGenerator.swift index f6a1db5..85d2165 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/Borders/DefaultBorderTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/Borders/DefaultBorderTokensGenerator.swift @@ -38,11 +38,11 @@ struct DefaultBorderTokensGenerator: BorderTokensGenerator { // MARK: - BorderTokensGenerator func generate(renderParameters: RenderParameters, tokenValues: TokenValues) throws { - let semanticBorders = try tokenValues.semantic.map { tokenValue in + let semanticBorders = try tokenValues.semantic.compactMap { tokenValue in try getBorderToken(from: tokenValue, tokens: tokenValues) } - let coreBorders = try tokenValues.core.map { tokenValue in + let coreBorders = try tokenValues.core.compactMap { tokenValue in try getBorderToken(from: tokenValue, tokens: tokenValues) } diff --git a/Templates/BorderTokens.stencil b/Templates/BorderTokens.stencil index 0d46d98..40c2203 100644 --- a/Templates/BorderTokens.stencil +++ b/Templates/BorderTokens.stencil @@ -1,9 +1,9 @@ {% include "FileHeader.stencil" %} -{% if semanticBorders or coreBorders %} +{% if semanticBorders or coreBorders -%} {% set accessModifier %}{% if options.publicAccess %}public{% else %}internal{% endif %}{% endset %} {% set tokenTypeName %}{{ options.tokenTypeName|default:"BorderTokens" }}{% endset %} {% macro propertyName name %}{{ name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords }}{% endmacro %} -{% macro borderProperty border %} +{% macro borderProperty border -%} /// {{ border.path|join:"." }} /// /// Width: {{ border.width }} @@ -14,7 +14,7 @@ style: "{{ border.style|default:"solid" }}" ) } -{% endmacro %} +{%- endmacro %} #if canImport(UIKit) import UIKit @@ -36,14 +36,14 @@ public struct BorderToken: Hashable { // MARK: - Instance Properties {% for border in semanticBorders %} + {% call borderProperty border %} {% endfor %} - {% for border in coreBorders %} + {% call borderProperty border %} {% endfor %} } -{% else %} +{%- else -%} // No border tokens found -{% endif %} - +{%- endif %} From b7d7f8af40cef00b818321bbaf1dcb262d8d26a4 Mon Sep 17 00:00:00 2001 From: nschpy Date: Mon, 17 Mar 2025 22:22:26 +0300 Subject: [PATCH 04/23] =?UTF-8?q?=D0=93=D0=B5=D0=BD=D0=B5=D1=80=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=20=D0=BD=D0=BE=D0=B2=D1=8B=D1=85=20=D1=80?= =?UTF-8?q?=D0=B5=D1=81=D1=83=D1=80=D1=81=D0=BE=D0=B2=20=D0=B2=20Demo=20?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Resources/Colors.xcassets/Contents.json | 4 ++-- .../DaisyBush.colorset/Contents.json | 14 +++++++------- .../Eclipse.colorset/Contents.json | 14 +++++++------- .../JellyBean.colorset/Contents.json | 14 +++++++------- .../Lochinvar.colorset/Contents.json | 14 +++++++------- .../Razzmatazz.colorset/Contents.json | 14 +++++++------- .../SnowDrift.colorset/Contents.json | 14 +++++++------- .../Submarine.colorset/Contents.json | 14 +++++++------- .../Whisper.colorset/Contents.json | 14 +++++++------- .../Generated/Icon/Cloud.imageset/Cloud.pdf | Bin 1760 -> 3924 bytes .../Icon/Cloud.imageset/Contents.json | 8 ++++---- .../Generated/Icon/Contents.json | 4 ++-- .../Generated/Icon/Geo.imageset/Contents.json | 8 ++++---- .../Generated/Icon/Geo.imageset/Geo.pdf | Bin 1835 -> 3914 bytes .../Icon/Phone.imageset/Contents.json | 8 ++++---- .../Generated/Icon/Phone.imageset/Phone.pdf | Bin 3151 -> 4691 bytes .../Icon/Share.imageset/Contents.json | 8 ++++---- .../Generated/Icon/Share.imageset/Share.pdf | Bin 2210 -> 4062 bytes .../Icon/Snapchat.imageset/Contents.json | 8 ++++---- .../Icon/Snapchat.imageset/Snapchat.pdf | Bin 5114 -> 5571 bytes .../Icon/Star.imageset/Contents.json | 8 ++++---- .../Generated/Icon/Star.imageset/Star.pdf | Bin 1360 -> 4181 bytes .../Icon/Telegram.imageset/Contents.json | 8 ++++---- .../Icon/Telegram.imageset/Telegram.pdf | Bin 4298 -> 6416 bytes .../Icon/Viber.imageset/Contents.json | 8 ++++---- .../Generated/Icon/Viber.imageset/Viber.pdf | Bin 5261 -> 5666 bytes .../Icon/WeChat.imageset/Contents.json | 8 ++++---- .../Generated/Icon/WeChat.imageset/WeChat.pdf | Bin 3396 -> 4443 bytes .../Icon/WhatsApp.imageset/Contents.json | 8 ++++---- .../Icon/WhatsApp.imageset/WhatsApp.pdf | Bin 3446 -> 4788 bytes .../InterfaceEssentialBehance/Contents.json | 4 ++-- .../Contents.json | 8 ++++---- .../InterfaceEssentialBehanceStyleFilled.pdf | Bin 3440 -> 4559 bytes .../Contents.json | 8 ++++---- ...InterfaceEssentialBehanceStyleOutlined.pdf | Bin 3836 -> 4698 bytes .../InterfaceEssentialDribbble/Contents.json | 4 ++-- .../Contents.json | 8 ++++---- .../InterfaceEssentialDribbbleStyleFilled.pdf | Bin 2926 -> 4441 bytes .../Contents.json | 8 ++++---- ...nterfaceEssentialDribbbleStyleOutlined.pdf | Bin 3203 -> 4689 bytes .../InterfaceEssentialFacebook/Contents.json | 4 ++-- .../Contents.json | 8 ++++---- .../InterfaceEssentialFacebookOutlined.pdf | Bin 2484 -> 4220 bytes .../Contents.json | 8 ++++---- .../InterfaceEssentialFacebookStyleFilled.pdf | Bin 1938 -> 4051 bytes .../InterfaceEssentialFigma/Contents.json | 4 ++-- .../Contents.json | 8 ++++---- .../InterfaceEssentialFigmaStyleFilled.pdf | Bin 1628 -> 4449 bytes .../Contents.json | 8 ++++---- .../InterfaceEssentialFigmaStyleOutlined.pdf | Bin 2660 -> 4239 bytes .../InterfaceEssentialGoogle/Contents.json | 4 ++-- .../Contents.json | 8 ++++---- .../InterfaceEssentialGoogleStyleFilled.pdf | Bin 2018 -> 4022 bytes .../Contents.json | 8 ++++---- .../InterfaceEssentialGoogleStyleOutlined.pdf | Bin 1715 -> 3927 bytes .../InterfaceEssentialInstagram/Contents.json | 4 ++-- .../Contents.json | 8 ++++---- ...InterfaceEssentialInstagramStyleFilled.pdf | Bin 2185 -> 4105 bytes .../Contents.json | 8 ++++---- ...terfaceEssentialInstagramStyleOutlined.pdf | Bin 2446 -> 4078 bytes .../InterfaceEssentialLinkedin/Contents.json | 4 ++-- .../Contents.json | 8 ++++---- .../InterfaceEssentialLinkedinStyleFilled.pdf | Bin 3647 -> 4829 bytes .../Contents.json | 8 ++++---- ...nterfaceEssentialLinkedinStyleOutlined.pdf | Bin 3013 -> 4557 bytes .../InterfaceEssentialTwitter/Contents.json | 4 ++-- .../Contents.json | 8 ++++---- .../InterfaceEssentialTwitterStyleFilled.pdf | Bin 2732 -> 4472 bytes .../Contents.json | 8 ++++---- ...InterfaceEssentialTwitterStyleOutlined.pdf | Bin 5652 -> 5541 bytes 70 files changed, 180 insertions(+), 180 deletions(-) diff --git a/Demo/FigmaGenDemo/Resources/Colors.xcassets/Contents.json b/Demo/FigmaGenDemo/Resources/Colors.xcassets/Contents.json index 2fa43f1..a274db6 100644 --- a/Demo/FigmaGenDemo/Resources/Colors.xcassets/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Colors.xcassets/Contents.json @@ -1,6 +1,6 @@ { "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 } } \ No newline at end of file diff --git a/Demo/FigmaGenDemo/Resources/Colors.xcassets/DaisyBush.colorset/Contents.json b/Demo/FigmaGenDemo/Resources/Colors.xcassets/DaisyBush.colorset/Contents.json index f8733e3..023f364 100644 --- a/Demo/FigmaGenDemo/Resources/Colors.xcassets/DaisyBush.colorset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Colors.xcassets/DaisyBush.colorset/Contents.json @@ -1,20 +1,20 @@ { - "info" : { - "version" : 1, - "author" : "FigmaGen" - }, "colors" : [ { "color" : { "color-space" : "srgb", "components" : { - "red" : "0.35686275362968445", "alpha" : "0.75", "blue" : "0.5882353186607361", - "green" : "0.25882354378700256" + "green" : "0.25882354378700256", + "red" : "0.35686275362968445" } }, "idiom" : "universal" } - ] + ], + "info" : { + "author" : "FigmaGen", + "version" : 1 + } } \ No newline at end of file diff --git a/Demo/FigmaGenDemo/Resources/Colors.xcassets/Eclipse.colorset/Contents.json b/Demo/FigmaGenDemo/Resources/Colors.xcassets/Eclipse.colorset/Contents.json index 99772d6..4e15a0f 100644 --- a/Demo/FigmaGenDemo/Resources/Colors.xcassets/Eclipse.colorset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Colors.xcassets/Eclipse.colorset/Contents.json @@ -1,20 +1,20 @@ { - "info" : { - "version" : 1, - "author" : "FigmaGen" - }, "colors" : [ { "color" : { "color-space" : "srgb", "components" : { - "red" : "0.2235294133424759", "alpha" : "1.0", "blue" : "0.2235294133424759", - "green" : "0.2235294133424759" + "green" : "0.2235294133424759", + "red" : "0.2235294133424759" } }, "idiom" : "universal" } - ] + ], + "info" : { + "author" : "FigmaGen", + "version" : 1 + } } \ No newline at end of file diff --git a/Demo/FigmaGenDemo/Resources/Colors.xcassets/JellyBean.colorset/Contents.json b/Demo/FigmaGenDemo/Resources/Colors.xcassets/JellyBean.colorset/Contents.json index e9f6133..ede2d36 100644 --- a/Demo/FigmaGenDemo/Resources/Colors.xcassets/JellyBean.colorset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Colors.xcassets/JellyBean.colorset/Contents.json @@ -1,20 +1,20 @@ { - "info" : { - "version" : 1, - "author" : "FigmaGen" - }, "colors" : [ { "color" : { "color-space" : "srgb", "components" : { - "red" : "0.25882354378700256", "alpha" : "1.0", "blue" : "0.5882353186607361", - "green" : "0.4901960790157318" + "green" : "0.4901960790157318", + "red" : "0.25882354378700256" } }, "idiom" : "universal" } - ] + ], + "info" : { + "author" : "FigmaGen", + "version" : 1 + } } \ No newline at end of file diff --git a/Demo/FigmaGenDemo/Resources/Colors.xcassets/Lochinvar.colorset/Contents.json b/Demo/FigmaGenDemo/Resources/Colors.xcassets/Lochinvar.colorset/Contents.json index a245923..ed5f229 100644 --- a/Demo/FigmaGenDemo/Resources/Colors.xcassets/Lochinvar.colorset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Colors.xcassets/Lochinvar.colorset/Contents.json @@ -1,20 +1,20 @@ { - "info" : { - "version" : 1, - "author" : "FigmaGen" - }, "colors" : [ { "color" : { "color-space" : "srgb", "components" : { - "red" : "0.25882354378700256", "alpha" : "1.0", "blue" : "0.4901960790157318", - "green" : "0.5882353186607361" + "green" : "0.5882353186607361", + "red" : "0.25882354378700256" } }, "idiom" : "universal" } - ] + ], + "info" : { + "author" : "FigmaGen", + "version" : 1 + } } \ No newline at end of file diff --git a/Demo/FigmaGenDemo/Resources/Colors.xcassets/Razzmatazz.colorset/Contents.json b/Demo/FigmaGenDemo/Resources/Colors.xcassets/Razzmatazz.colorset/Contents.json index 105793d..89cf210 100644 --- a/Demo/FigmaGenDemo/Resources/Colors.xcassets/Razzmatazz.colorset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Colors.xcassets/Razzmatazz.colorset/Contents.json @@ -1,20 +1,20 @@ { - "info" : { - "version" : 1, - "author" : "FigmaGen" - }, "colors" : [ { "color" : { "color-space" : "srgb", "components" : { - "red" : "0.8901960849761963", "alpha" : "1.0", "blue" : "0.3607843220233917", - "green" : "0.04313725605607033" + "green" : "0.04313725605607033", + "red" : "0.8901960849761963" } }, "idiom" : "universal" } - ] + ], + "info" : { + "author" : "FigmaGen", + "version" : 1 + } } \ No newline at end of file diff --git a/Demo/FigmaGenDemo/Resources/Colors.xcassets/SnowDrift.colorset/Contents.json b/Demo/FigmaGenDemo/Resources/Colors.xcassets/SnowDrift.colorset/Contents.json index 996ea25..92e03d7 100644 --- a/Demo/FigmaGenDemo/Resources/Colors.xcassets/SnowDrift.colorset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Colors.xcassets/SnowDrift.colorset/Contents.json @@ -1,20 +1,20 @@ { - "info" : { - "version" : 1, - "author" : "FigmaGen" - }, "colors" : [ { "color" : { "color-space" : "srgb", "components" : { - "red" : "0.8549019694328308", "alpha" : "1.0", "blue" : "0.8509804010391235", - "green" : "0.8549019694328308" + "green" : "0.8549019694328308", + "red" : "0.8549019694328308" } }, "idiom" : "universal" } - ] + ], + "info" : { + "author" : "FigmaGen", + "version" : 1 + } } \ No newline at end of file diff --git a/Demo/FigmaGenDemo/Resources/Colors.xcassets/Submarine.colorset/Contents.json b/Demo/FigmaGenDemo/Resources/Colors.xcassets/Submarine.colorset/Contents.json index 08104a1..caa4f87 100644 --- a/Demo/FigmaGenDemo/Resources/Colors.xcassets/Submarine.colorset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Colors.xcassets/Submarine.colorset/Contents.json @@ -1,20 +1,20 @@ { - "info" : { - "version" : 1, - "author" : "FigmaGen" - }, "colors" : [ { "color" : { "color-space" : "srgb", "components" : { - "red" : "0.5803921818733215", "alpha" : "1.0", "blue" : "0.5960784554481506", - "green" : "0.5921568870544434" + "green" : "0.5921568870544434", + "red" : "0.5803921818733215" } }, "idiom" : "universal" } - ] + ], + "info" : { + "author" : "FigmaGen", + "version" : 1 + } } \ No newline at end of file diff --git a/Demo/FigmaGenDemo/Resources/Colors.xcassets/Whisper.colorset/Contents.json b/Demo/FigmaGenDemo/Resources/Colors.xcassets/Whisper.colorset/Contents.json index ebd40e9..bd3b527 100644 --- a/Demo/FigmaGenDemo/Resources/Colors.xcassets/Whisper.colorset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Colors.xcassets/Whisper.colorset/Contents.json @@ -1,20 +1,20 @@ { - "info" : { - "version" : 1, - "author" : "FigmaGen" - }, "colors" : [ { "color" : { "color-space" : "srgb", "components" : { - "red" : "0.9137254953384399", "alpha" : "1.0", "blue" : "0.9137254953384399", - "green" : "0.9137254953384399" + "green" : "0.9137254953384399", + "red" : "0.9137254953384399" } }, "idiom" : "universal" } - ] + ], + "info" : { + "author" : "FigmaGen", + "version" : 1 + } } \ No newline at end of file diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Cloud.imageset/Cloud.pdf b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Cloud.imageset/Cloud.pdf index cc48f85932d0d89fd5d44d9c5b12e329b3baf4bf..407cae71d25c79029acfa22c69d61cae8fca235e 100644 GIT binary patch literal 3924 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 a4@-;tXJ3o)BL2(-9H{_@h>2+%o%#<^DZq39 literal 1760 zcma)7OK;Oa5WerPm`kM=347lUsj5U%iVz@5%B|uM9JdW>ZHQe|`1O1n+q+KN1ACf$ z^ZsTsKDanLe=Q2fm>^E=_aBVt_?S*kSlz7SPbTMh`LS+p`dd-}m(i;0xAp3tm1p(u zO;s=7ozmiR{;TTPFD44Ud&DQt%u;fk;YM1HBmhTmU5DI zJ_D$9AqRV+CqED6t5^PIQr z`W0)~m;a^N7e2D1NT|X|%bh0hoTl(xh&&^q@y0m?CWVk(1iFu)l_qEpP-!VJlL(op z2V|V*V0;dF5xDbI?OX>tfx$T`tt5%bO0AWRmHFVcL5&_^gqLoHRSYQiLMSmqg)6KO zJPeiy$vFWNPB~|yoz>1FBD@Wj!8i@QDIB*x=23-F)_Zt6)T4sXBzO_HR%kC{6|;r& z${INXRe`EC`ihJy6(c7open_+LEagrMX=}-2uP9^WJwvU6A^LJ?HJ`MI3E23Ft5=L zxKKf&+O!!c1`3dz5M7vngwZcyVAvREJdJ{z%q5NHIwP2kz=n7WCdUYp?wHgVvBr2Z zC~bk{oMUn+L4sy=WIJ1U%m`ycG-o(wfS#Nd7)M-_ryEwWwA=9*jhALROYs5?=Sm0> z(zQZ?`HGcqnx^eLy84EzhF4y!wsq4J2&3f)eX7@+)oJ@kS5s>|3;7S7r7703?%IcK zRd*CG=M-+yHa${w6wl@ae*N>aj>&IoB%PhsSVua!<%i80rBdu*NmG_Z`+$PQSZof| z?MJeEkz%H9ugk%4vFcZM?ajXHwLoE(e893EL?uvLJ^C%{R3gp)fyg*xL)5dQW! z(@!7;8ulTL<$Mac?AUKto4b0;@C_>8pMj3UuD!31=y0<>8b~RZZQE09ct>w}x%pe8 V`rWr^we5H92%|hZIC%T{{2ywHaESl_ diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Cloud.imageset/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Cloud.imageset/Contents.json index 540d7c3..30f7efc 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Cloud.imageset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Cloud.imageset/Contents.json @@ -1,13 +1,13 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "Cloud.pdf" + "filename" : "Cloud.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 }, "properties" : { "preserves-vector-representation" : false diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Contents.json index 2fa43f1..a274db6 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Contents.json @@ -1,6 +1,6 @@ { "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 } } \ No newline at end of file diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Geo.imageset/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Geo.imageset/Contents.json index 870c4d1..4019aa5 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Geo.imageset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Geo.imageset/Contents.json @@ -1,13 +1,13 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "Geo.pdf" + "filename" : "Geo.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 }, "properties" : { "preserves-vector-representation" : false diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Geo.imageset/Geo.pdf b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Geo.imageset/Geo.pdf index 96ec68b8215f309a18916adf1428f7669338e655..74c668e530e090e3d6a23685c5f0482863fbb9d3 100644 GIT binary patch literal 3914 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 QtOOhhheM7WL7&$7AIl}b4*&oF literal 1835 zcma)7O-~y!5WV|X%moQ5;rQEL2_cnGs;aF@LvN^u?Z!Z=WVg*O73J4=W=p7eD$Pg#(4r)Qh2B2Eq(gO!ER0 z7G~#O8cwE55LS@#X3%lztTv<@YAda!?n3ZZ6LcUwy_N%TjW1!W5W}$%hmr~$la$

)Vk| LYIbz=?#tCb$e@20 diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Phone.imageset/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Phone.imageset/Contents.json index 75988d7..548d826 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Phone.imageset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Phone.imageset/Contents.json @@ -1,13 +1,13 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "Phone.pdf" + "filename" : "Phone.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 }, "properties" : { "preserves-vector-representation" : false diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Phone.imageset/Phone.pdf b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Phone.imageset/Phone.pdf index b3450cce68e0be0bfad062eb0217c02a2c4205c9..315cf7bfc1d97cf8809ae1d5998852cc802974b1 100644 GIT binary patch literal 4691 zcmZ`-c|4Tg+cqJZtl0@8*~&H;dvzw<3KA-!!&dmi=Q4;_QN&taikT3{o?Fa;cWMx4@ ziq0swhpQC|4iZv_{HXWo=F z1O|M`m|V;{%snB9cO_I2_9!52&$G19_EoW^W!)pX&>bq}Udx1-{XiUm^$FcV`Y={D zL{Fu5k{?o_^xIf==`R^Koxl#8XwgSxf|VHzty4w|^Q74d7wj8f%ZqH0^nPQ>HJV?P;a6;Fgr2WO}zD>0*bH>yAF59`yV5iqQ6fOg*8xf z+uz>5#i}Eo!fI@7EXSvmjMb#+mSnObaXm-U%`pOUmius$LCVxc;8I%Za)Qk|aq8~3 z&Dwr+4wQXSVN2kJ$`dJeWt=Ocf{Iqm`FBC|gM=MH0Oue=xASW)Ec>AfRKP259b1Sm zfQX|M=*I|ZLS$hCyFov4E?)*fawx=tM01E=g+|W;YXPpI0AaGHmSl}Ydb6yUU=S&Z z4(Qs`^9beh@l3XaV2(RoEO*ZlD?f&j(NbRExbO-vah^`09VVquJfbMCyqFU`2q~hh zr;Jsg8MGMWVI)qpVlKVF(wZzxvl~P>3q#XgrYyv+%$lMlOwZrJ7S7u3U-2ho3o2Mw zM>7+{u08?YCTUjy>+tJ?t^w&HFXf8oZt4^iIqDOZkdK7chbH84>#*aE#OO3{iVpTW z$ZrG17&7B#!UR=P^0jl)@zYB(OVr!62iGG)@GTgt3}I&tB5tu1}y@8Y$&~LT!t)>Ki;8to!$mJdel}gDn-@t`J>9hgFANQ6kTcb&D2O z!*E=?6dNVj2D856e!U`QOrcT3|CYbvmF{m_Dl9p2Bk7w5)Df-F;l*P{vq<$ulZK>u#idti7bw z4eK^}Q269IN@F=;h?h=vB)_uA^ozJ7`HqNJOhf?_e(aUXUBD{OT_Km-#?Wy?DGe!; zI;HQ8mHNa5)YRX=O*;Wrp#1~7pfe#^4_bKyYxAKuZeW|Hmq1ejKxxs8#0+ieM?&Iv zdo4_>(C<`7!{>EBUGXYt=%{7$N~&M3b)PDk&Z=Lj+nREk&i2Eguli+Ly_P4GfarDDP#6@T z4iiLYE~TKaZUpFB4sARgUszx0p!L74(Ib_cAPgPLEJ;esoJg@tPEO(0^tt^ZTaF7z zHDag0^jzd_yV$}_4?S!CaY3eTR9|V=Q9NC;m$(Vo1QXy{wmf0xlwH1Myf^Q=?YnmH zf?S%V#+7k=siMM><`ti}-l$zuUtM}<&AzKtMN%yUv4WH`lxmkkz79t^;YNC=6J+YA zef$ElOtW~A4v|}NoHBSBVi`XlfeA0S(NTZ%Pk|oZ8jZboOxoCE&>Dq^q&yLtHLpEbJshwFP zVI$i|T}Kr!44Z0lc5&`=?#mBmX{Nm>yu5fITJ$5>orHr2diX-ulZ72UC&K*P5}ksI zSusfgsUIH~G1(*oL>bG{IN8bd=(j>in(v++*%jS$+0s{6ihc#Dtp1j9Quji9vF4eD z!2KIDFNV$C&A5s8hfBvKk3YBT8>8>mU*QwD)b2)k z+LI!G_|caX`RS8JDLOD@_wKguZh5POBQowyb-*NqRqV&USx-ai-gowQavA$wM`K%j zN5fmGr31ACa0`v*R{`Yv2X5kU?_C*6>$kgh_|-Dj)m0{OGN*b5`8ZA}{V=>gE-5YJ z8Z};dNYYd;Q!ynq=_FnI!3|OcoHv0!yMHtXFfFjxuTn~JHk&x`jt^sSp zK`(*;<|jh5;R!Z$hI-JjYb${C{3GH{7>{_&5C_s&&-3~n)yE(fvgqPto`r7X24C0SQ5sm6fbK;kKYNt*Q$$JEQsOEcWlJGwrI3bVhpUxmnr3e@a

`ocKMVquSeR}Q?haWmp(Ax-zgbJ+|S%votOC- zdxQO3yu^X|j}N1JQUjeV0bKr(jXl0M8*>)t>DF7#quJ$~w9#_M{zn_QdEET#>;mJN z>ylp4Ya9o$$1fT420XN-z{POfI1q22#OBhVSnbi|?;_E6*}?A%+NwhO>EbU~9xrjR)Iv#^A5-*YiRCU3X5ZbR``A%lGS z(465;9@+yLI`;_fxe&svr0%|mIb+GfOs~dyQYyYe4-m(y*-M*o3_T5}6DlsMA@4Co z7o{3wagy?3#M3IMaITgB%Q@QCc&}Z$2u3cq?m0WXmy8E`>7~L4(xj{%vesS8!j7;h2`C@B!)PAY|IHE6Lz}4LWPp z@+vA>sC+{`Mp}VdY7SgZZ-<(c^o5!kNWM&#SB_J_ZxIPa$-kc*>FYL=(K33Vl|X_>4grD%~F`Z_i8P zEBRd*GS->DE@Tk$$d7j#okK<0Q2dpRvi~|Jxa^y`PI-Xm!@?M&g{2}Bj`U?HS3B%k z{$h!!+ZaiqX1PN5LXn-^M>Ps7>7kg{7oK#GSfe3#`{0SsSVuor(KOKNIxurDE97V(OvLbD}RU?B^lWBKjJ51{o z7+;)Z4fQA42n*QDI$5-M5J=E%H_!in)Y-E-_RlpR43?Dmw;D?P3;(?RySgG#o*)ym zU)On!nJmoD5B>E&Sq_XM3) z?X!}4MyHH)MV)Tp2|6pwzd`+bZm0bRn3ermgW-Ra?z40JX;r8rY)_90I*Z`!oA8^@ z>-50jUr&FCJpX2r`itpoC(pm4{Krw*3T5StwEx=`?E$v~3WLDHz<;7Y`vr+ZAfgb^ zDgJAKg+V_pkn1l0W- z;(zZbCJOoEi1M&PIKw@FXYU=Va+*k9PoxW+55$YG<@+a{Lb^yK3UrpLpD#v858(?x Yi~DC=$I1isGZSK`TLZbcRJGOq1N3e|5dZ)H literal 3151 zcma);UvFDQ5XIl`r`VTDEmGIJv%9l9QdNnj6d^#Al(&k9;J9s2V?*qs!l&mq*Rh?X zJm5;z&AB`O&YYRMk6yog^)$ymO*y2n`R(^9glEsf^XJoQed&Krau;9xuv)+0eFz2c z+)r(HH>->5Y4LLP*VS@${_Tr!_U7(i%kA{%lw+EIAsrr`9-qE^cYL+Ho>Hu(=S;Xb zifC3Iidd^PY?o_Z-#QjKJh{y+SZd5IiMC*IRO_XMS`RNz7AI^uolH*X>FK}Tp8PDQ z)5&ANlgTlylf@BQPDg_yc6|8q)yczh`Y^rwYFbY}|6iK(k?;(st*BXm=o5M%=!iJc zHMZ7s)j;T+a!nGh0f$tvGJ{e^lh9&nMS6EAwbAPU5)3M*avWH;9F|jytq^(!r8m*e zxuGME5hTT4w2mA!=25#;hjDi)z)W-C){A# zV<|&L{9NkA2-YJm+9)CSXqj^Y)Osy7In-O~d2gz{WF7&V70BRR*G@eS)sn3!&}deP z1th(8OGG7B9Z7P?N{H^M02NEb0%~oLsC#Qf$D3kW8qCcJw=qORc6N}kb7GK`heLJH zl@3&`HaCTS>q2v!rc8kj*4R6hIm7WEJY~2Vj_mx}{1W43QTm9TX5Z(!-Q>n}o&V~MyTaH?oYn^LF2we-q z3ezJgEOoR*(?`s?QDH!`%{|O5_k0S5IFTXND}HJ3@GMcE$f;dgq)nF5Q|#-Mx|sESWJ?K=9m4byIphP@=2yy0c@0%eB@k`Qd0L+aEpbXEBJs4LReR$RpDos~Z#W1z~kY-B>h;2Y4FlBPJk5pU-l;;!49>|*19AeB-kwaRU3@5!bt<->N zhNjd=eqJFiaNjD}W(hUY@J@I?WrM8)q{`5Ftq#Hyx}uxD`t!VfAc+tX=^(T25ZlYQ z1EuR>HlOzcB%6PoLVvY^SLA|eJ11LHlN7*UZ- z89-I`<3iI>7&DUCjO*R@{>k550+fPm!XbrAo=}FaTA~_Rg4VGwbo7D&R9+P!2j1BI+WIkAYbcRBb zhxCn-*aF`BEM=zIrwmDS{{!MBBCeFnGzsrRVx z-D4U0N4aX5O?|aPEdDrWeB3(cT51h}+=Cu|&+l9%{O)&qu{+!X{ld4u9is4byc|O0 z>C(9PdcEH4w&CrsTq5}`USHg-*1JGQ!}%@rG53c$ET4{||_X{Rw>gqs#MC z;D&qqV+QU+q8L7egf{u_XefN69zuh?a5%NQxw!hcx|z80FTQ&T9gnx0>(!I+`0Db> mo|MJ;X0r=k@J#RG&DB3EvY)U17dN}P95J!!(W7sEdi5^~B7dm> diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Share.imageset/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Share.imageset/Contents.json index da64a08..6104ffb 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Share.imageset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Share.imageset/Contents.json @@ -1,13 +1,13 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "Share.pdf" + "filename" : "Share.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 }, "properties" : { "preserves-vector-representation" : false diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Share.imageset/Share.pdf b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Share.imageset/Share.pdf index 6c123b52719d40465e92f1bd34c7632786be0f5f..832da6cf2b88e72c8a690579fa5e74f6d4651f05 100644 GIT binary patch literal 4062 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 R&z%sLl!5?xc~x$z{s$5y3tRvI literal 2210 zcma);OOG2x5XbNRDeAIPf|Pc@A5s*F>=J|k5uDs24rX?;G4guAM_Y7 zeQN)vyWU;po7Z=*o>`rhvSeuZ{SQU-{5idNq59)J|5R?xH$U~qhw}&WfLlH_o=^Sm zQEl$}zxQ3g{r)B0zFGh3M)jAn+DwbgvUw)E&%ep1?okn6u8Y#OlZCxV2cyE zjB4;cIhI|mGX`3Ob;he8Jo+U1aPLMQ=a_7=BMy#Zbn z?pL4CDfdJ{Qiacv5uA z#XBTj9Ik9#$cVaRMbJ7a0$ZfBHntXntCFUmqjN5BH8hB4?gAG>OUUI3upy#V(B#Ej zGy+#uxJYYgrF9K!u7y)7MIBMeHm0ej=jxBTAV@&n>YW%3b1O1-P)S!`D>_%zctQc5 zMV)gFHG#~L3p$j-c@+Zh(Ge<_y)b$87SA+QeliVtE!l4{;T)bGg0u*0)hRj~>Xew) zpxBQn!~l~jeW4$$otGwYXx)j&$vi8T!NN1-GH?*lD)S}?#vIywdpr*3k>34=xrDWO zy*u^CGoiQBc1Az<_xs(;;S;@U;gArt_S|-htZhFIA5UFB63@Ox-0g5YL&Zou_!ju~ zpFew6{?J3|YB;hTGBh_o?(bnLu?JgPwA>CKVX&QzZGy&YN$E-wYZ|Y-yj;B9op*=f z;ri;QQ~zEW%8DD^Wl=&ujs!d}w3%r~M?oHT@)BfIL`D4%6@=j$l?bn|QN=r4(D}66 zANrHx?EP?ua6B1@$Nnij+223C1ZA@whBL9lQ+PLT_W$;1DJDn$Y&=!iix%uvw GSN{QDXvkCm diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Snapchat.imageset/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Snapchat.imageset/Contents.json index 9de5ea2..b638a4d 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Snapchat.imageset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Snapchat.imageset/Contents.json @@ -1,13 +1,13 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "Snapchat.pdf" + "filename" : "Snapchat.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 }, "properties" : { "preserves-vector-representation" : false diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Snapchat.imageset/Snapchat.pdf b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Snapchat.imageset/Snapchat.pdf index 68ea315bdb50339df673c0e31ff78f27943f7ef6..867bfbe458239fc36e28b18e51fd8e020ef77af1 100644 GIT binary patch literal 5571 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 V)fn#d^Cm!C0-V^4jFQSy{{e!G0KfnM literal 5114 zcma)=OOG7a4TbmhD{3Ra4&a)5dEbCxAeQ1FNP;+Wc19MHR$HDxnog$2f#YAF@36Y7 zT9Ox;Rn2MM2g$=jR=xQ4)i+F(9>KM#lF>)(Gpzx?j@zr%U@_Y{}le{;A#e6c-!`rG!?;r;E( zK5~qG-{O3DoHkRl>(1|YFy$qdV71I+>3OtN=A5r~`-&YqO#6}@-JgE#*L|PEv|DZm z?n{25RZUXxN^WwyV(l$K%{_5YoQSntX4=%Qw~X9 zY#?W`FO@DRM)E$}(p$FVu?s!tCSPr-0ZOqSURWOF!k|LocR_WG8Xzz}^squ%bPK)| zMihn9xQcs?9fToI;(2M6B-+xVVkf8?3{$cdF*BVC?{b28IA%~HbKywZp|QeLdKo+b z!LR6bk(Sy^sZAge2{4ezh18U4pgby1L>LAs4?r=5A)b(lno8o-Kqx4H>PbXR*)1$p zln?}KI71MJcIsD@utvSHA97S$cj{O+ex|PAO0uTSdhBt4-thcNR&Q)Q_fJak;Fj^SeH1)fW1Cb zB6!5QLFY;(qD5geC76ARYBNzpsj)878DM9@iBUp?2E?3*P}Yp~&m1rlN+ z{)8oVj!}gaSl-I4mKHHoalz1p?=In;+!Bota?^pr3Q~$+BaRNqK`a-jke8lDHXTT; z2_*<(rYQP4uYeVcTwYc^AUd)NwfK3ZTUplyBW8Zl782$ez3fDpbvfawZh($Rb)f}L zAcu5EYRgFzAq_28#fY9X%nhZAfs8=K9MnOm;!Le&9x~AgI!~1i7YZ0e>&{6lq-izJ zg=18$O@vgAI=brXl0h&U46HT;TN~8kZG-}n=;|25J>?d4kfM3wi5kL8F-Gl%6@(^$ zWO7g^Sm9QQBi}OE78NJCwbEO?grQBOJjFr%NhP3SfG8W}9k^OY0d^3( zii?REk)_cn3Lx~jaF(DP;Qgg}mjY|tPPK*|t_A1aerj*}+YewV=}y{c2O~M6a;Z1> zfj;FO5x>-F<*MSsQltw$!%TswQ>PCCR%C~Bb$1+M2|4JTtcYJ?3DnTWHJ#Uxs}t8q zkk`yK2o97eHaNef6sRKp8bJ0e)7e4#ZJL27E_F`q%lBUE>1XXU5R|T_1>{!Yy zfH=W?30;H0GZ5WH{ZVQNW4I=Vsa3g*QijfBfjKfDVb>V}kZ?hq!PO<)2nS9JLX^Af zJLMhMQ!^@?r2^!dF7KyOJQS*$MPnut6ao{-+EW;NeDr0~uMjkAc%=WT7k9N!`ltFK z!I!F0?Mx!D-P>kcOF$qh?>#vC03y4taYJ^cR@$UPxpF>G)%d)jP7Q`trj*eG;!iZRdawq1 zyGo#iaviMEKej<9H|mAJ^q_f})l5XFjUpWgi3S0ojO5Igq7?$jOM@^PE_0MH5<;UB zrXkA94PwzF+B$ft#<-gXe+DZO#b_7NVzTHMVnA&%7K^VpImkw$!G8PdbCuyS#%WvMKG;42|M~$Q>^1h>3 zGCI@I9AgASfxvimU}_eIKGKoajPVBL{eWA-P_@M_i5%h^9XT%w z`n&m%vVZir?)Cb3KK=A`IG$&HQ@U>V^7Q!35$9PSl&;|4{`;?^4u5;((3_7=y2ti0 z>h6yZZ@B6#4_?pLQ(m5a;==KA*?pt)hdVI<-Rz{3&L4QWE_`|aeE;tB_QRz=KOKLV zn75|YXZM?T5yTMq@<%K2r_mT#}LK;5u|D9BS?h0LeEe45ATjold|`R zSA^rU^XdKZ^ZB!fH=nOTxqE#&JF44bDHFMjuzZ~g~9 CZ~7Ae diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Star.imageset/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Star.imageset/Contents.json index 55e412b..a25926c 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Star.imageset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Star.imageset/Contents.json @@ -1,13 +1,13 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "Star.pdf" + "filename" : "Star.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 }, "properties" : { "preserves-vector-representation" : false diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Star.imageset/Star.pdf b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Star.imageset/Star.pdf index 19d3c567d20e842915e1add0b4af36369d07219a..874d71cac196a6448946255f7f49786c5a4fa80c 100644 GIT binary patch delta 3137 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 W?TZic#kfG^q!0>_3m3GEuKpkC5#ILz literal 4298 zcmeHKOK;mo5WerP*h_$}TF7+Hlyx)N2m3G(0j4IfL& zRvo+Op#{o=v>eXN&g0wR$7koS-=63!2%)8t&HG=4lrLY(#rIXcYOf?gcmWZv#p`BM ztZVtRRGI27smH}HgUUrwud1UO_igS=MlWyob=j_)`lml`Drw>R^i=HHZB=Z@NBuinPOeF@>8#L)7%_c94PPh@7WT5t&^Mm^|WcRT=vGt z^o=&bjQV|859(_jeDdE1p7cM<^#{qDq#}PQgQVCM=ApaJH<#hFsOsfVTCBMJf?M9> zz!=ZZJE=+189MC05gnu*N zU=JE-rK8t_!4P{gcsf8-#(=Zwthm`(QCY~X(YCMDg8<>Kj{u1YATCK6Am>HfR@=H8 zCFj)ry(`-7`WC~1GUJqYQJ#d%E90Y=X_1~e#EMXj)IOtJIUnRO9=c(4__MgYDwgYd z)$McETsPaxo1&~RvZ~+LWp(k*tA0KmTHU)_oHfmMxtq_g`$H;8{yLnwta&25Xrj^x|zzUqG-ks?O(eB=3g1i=@ASai=v<>TIt z?Xo!6hqyY?Y37}f%e;3wMmenxo|`Q2fHu;_%#zbu{nzou6Z(IA%>mf2{}#SZPnmR# zFF$`U+XiYBxZX2rG7TGfb}43e&k=67W+h(_C_ zxe>-@+9?8~NJ48zy_n@T1~8*ZG&w27B%QoWtLf=vGs#ME#CZx~@{&Z8lTsvM@{tzl z(WIY5rMMCwz7np%Bt0cxm)ZUYqsBU`isVsLkDzG0s?cS1Ip+PqJ8cIrd z84JpYlvn6~S6s;O*0MTimXMFyct})qQL$aLA$TKasRs1IdFAD`z}rpt8|aW(M3o0f zpO{$y2lgJk=1ykFk@+j9*pXtS2tB+>IkQyC0f!pI6+-72lX4QmIvS;N&dq5@s9&ag z+(O&Nh=_rouDGa^$*dykvQU``)?ho#VwDGFpPX6Fa8V2U~<}WiY~f<&JvO}pmY(*=E}k| zawLPkX%)PL=NyZm;E-%a8vF!3hfySLfd`WjdL9+aqDMur0!UQu020U?Sq4yvu>eX2 zmM1kcA487YkK!AOh>{x`0>UJ22m(UDTnn^YfyOapfoP~HRM=Y>mjZMtf&qJp;;E9J}%(H26{g8q>a|tXTa!@ z4+tKNJwMbGR2rfv@9g{X>$+}QP_6Ns@4VPnbt@we)t&<^-c`$W@v33Un82DA)A*TI zqpyo<*X*}twUbOrM|WpU4T6I`d76*Hk$bEvY&x6x97mr6v)S*~9V_GvE=HOFvbaaU zdI)xMv^(?!Vlj7hUaSz;Jk8$ntZ0ktW_4(LyRAM59$2C~aQ&(C&S8v0K3u#3UlM1! zzZ~G-t!5&0^iTx+qB?vfEgUiQ?m$EsY$B`4u5w?lVj%H(ZY9o61Cf6eO+w@ zm-pM(Xz}x1v#DOl=j-K*zQl`*ra^tVd|kH|m+Oxe*8*+YwZ*pWs$*gd;@Pt|KfL`D DBRrxl diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Viber.imageset/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Viber.imageset/Contents.json index ea5af11..797325b 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Viber.imageset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Viber.imageset/Contents.json @@ -1,13 +1,13 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "Viber.pdf" + "filename" : "Viber.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 }, "properties" : { "preserves-vector-representation" : false diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Viber.imageset/Viber.pdf b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/Viber.imageset/Viber.pdf index f74957149e6e7d7099d360a4020156886f8e3417..5944614f7d100d3f2dc32a928a1e009434e05e38 100644 GIT binary patch literal 5666 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 literal 3396 zcmb7HO>Y}F5WVwP@Dd;?5Nh~M0zrVrX^NsPnmWA&J*ewV;v$w>Nh#9&`o5udhZO8X zx(AznJD-m;v*SmvU%q;3O;*Zk()&ODR9ZiKrk_7o^X`WKRBpsKKh3-Mrw`f#yk@E6 z=`e5a)aK><&+Rl{fB!;Xy&3JZkKU87@@>M9-Wr-$BlJCo{?;;^eoSY1P) zNr{4Ba=8DhTbR@b_3j(BQ@?&K&DnVGN=e!VlZ&O4HF%a=xPM@tlPR7kLkXo)eDz7+ z0VJDaa03{PkCmuu>r8MirJ_6JadV}R(~}y(S|iJKYr!P%9OSxJfhLtr3NEn=0gLgt zWh&ZwvsfD;@!CO&u3MADx>tcF1!vaT8p7ZftOZkj2pOIw7#mHj&M_v@TwoH;fJ!`r zMe#oP77P)2WL*;b5frSaXp^-A{{uE$zy-Q+HdyT0JdpRK92s9wL#-ZSppXgm05tkc z1n<@?D6mv~S|mMc!)sv0)mU+bkn>bMN|3eD=+=YbXwa$_D4%R1)-I+-unOB`LPo{l ztzhUpxT%+*^bf3%s|mUtB4ev%7gHY>=#1zKQn3aUf?6F=_Ljo~3qXi8DD;+Kie1_e zxP5?GLgtX-(bN!|$syJI2u2KCN0wTm3Hl>isTRlft*H*Y)(5d{EP)P|Dm8Eu0!bFr zj**;w%cmfUMJkrewyNp1KSy6H z7>db(k%W2S%2$lOU?Q5?w<*W9XnFLFU~xW%iaAFGy$7b8@yVT`oT;e_G~ud41b=am z%NV2~GK6b9TN|OpE04Za4n0sqhF7sx(I1g)L>!A#L3rFQu?f}_5K|q(4WAQj7n@3M zT`4H$9(VPME)gSkhw9>5lx%@jSHlGco0w8IMXtv#iLS`5NeTy;M;+@CbyPy{7A3*% zS|E6q7zG?s>E_1t#IX#Ig767fh&m9A$#Wrj41=05?@+}2wTrImV(^RSgdpu}kBQX! zc9B9HIpc%LVm{ak^N1GH9Bl%qb#m)840~#$2yY1=0CXA{BYbRGHDR2>=K~P3M;V}9 z!TY*>@#x{N3;Gz^xR#8uoE`>Q4j&4S`HeAw9in}K`5TX#2jts!1}_NC%$p4Z+5m2Sx?rvAPm3pxjP3C(z(_*`Ijf zUAEbE_2n)1yb`+{qin=MU~I~pZ+E->>8RiSj?Ed*=Job4?@l`MhP*&O&o{T*7yHlp z?KJn?a|YLX^>VfUgn;c5Y&Uegw1nMzu*9B@7g?SauePV{$Nl?D)z63dog$spc{Asq zI>m^E9Psj3aKewqTE9Ff)piodm4JNs86Yf=myo9bx-O(VDo3ExVSD>=J}ADuA6|lv x$H)EM{6s&#y?JsbWplmXpEM`j=-s@z{W2r^_W#cIaBAt`n;O)kN8kPO>Ob5*tnvT= diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/WhatsApp.imageset/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/WhatsApp.imageset/Contents.json index 6fefb11..7fc8745 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/WhatsApp.imageset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/WhatsApp.imageset/Contents.json @@ -1,13 +1,13 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "WhatsApp.pdf" + "filename" : "WhatsApp.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 }, "properties" : { "preserves-vector-representation" : false diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/WhatsApp.imageset/WhatsApp.pdf b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Icon/WhatsApp.imageset/WhatsApp.pdf index 9f5be910b7bc7b5eb70a0d64f2f2ed47965ff2e4..726c054fc3646cc03d82570946b5865bb845dcf8 100644 GIT binary patch literal 4788 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 PP?)$B@X{q^U6ua;zrk`p literal 3446 zcma)mSM(-Qf|Pbw^;?P}k%S-wh~Th`SeWr7F|udCGeLo0&sRM&_u4TF zyolPzx8A2tcOJcY_4=v!I!)q&+y3_Z#dU7}$-Aplg$w5nA!liWjuKSjHjoB^G;$$@~=;CELEq`5X7Hl>Bhx0kF z#mfvWPF56pY|-pvKFohwzMrAh^l^Is)wG#@{=aSRKF1g}yZJEM+`DQBbnMH6wOOK< zE=_COYjG z(c#RuoLjFL)Y`gKu;8mmXdSn;Xd8j}z3`PlC84xVYze*8?npdJ<2WLSXinW}pas%G zcG>rau{te-RhrC#luEygttKhHbgTy&d&|O?-S?VX1j|0eBB?nhlqj~1Q!X*~LS#+8 zOU@};=+Hy0oQl_)gJg&A7E(C))*4F;BX5dI!`i+KM%jXK#lN{pA!R;%v}smfa?~O&`ktjy!8LS_OuH7Rz89KD6!A)e8h}zPJ<@ez z;6&vB3Ei9nYh6Ib+4(Xt$pxe{p=iQQWl*ta8e>puOwooH2w@HfntOpWv_n!=+D=-r zghE=)_f&Ei4Thb{Y}JHCYVMW}9E>3*a*RIY3Qf$9gb*PbzTrsXH2PHpN*mTgqQfg% zBTU=^&Y;qn(AXDhBJVMJW16+W(zab0X>+WZimh=amTa}RPQ`)!QwYo!(D4>p4)g$C zmXe5>=rg4^Fwvm&;CiCbDKH!iBvj}K_HdLoV6v)BV`Vz5Lgy^Du%IEpV?!g|sGPc| z*KDC-NpdF=7;NonSm)Xcr$Y}F?$RZ8Fhzx&LU?2YF`+(Wg6{e#EER^TC=$1&l-#a?@yS&ORnBO!}1hz$BYe z8Fs9j*sNa>jA(hUh(EiVP?V4<0SJFqYhrcdm?^eW0s|kmoI6Cuqtc7RfCIB^1B1N` zcvL`W7-sdwmS7mx+**l7Q?+_hl{T`qeKGDtU+Rzrl0c&@h}~0!vC!y$z=nP&rWGLL z$iKu+bCS;xzflRv;>;E?`GWGIdLyv5YWF5+6J(gyFd`B9JP&K+CPGUvO~`^N z4qsLy-)JcEU_2b9G(NB|GjU{i?71qs3|1Qk*{oT-QsA)-6TSs5V#7pgAR+_q^bQ-Y z3Z-s*7tbDZWglWU7-?~e&zgqn*f5hxH;atIqYu^!Rp9_cXtWmNj))b@!f34tP2juO z&`!F|i8j!8lOei&fD%W+6a`_p#%{jLEKji;hLY?~0D=!VX_Ow=%sY^oLc~G%`Mb(W zvsA+ytWQ`Vu&r@j46(`r2Z)O5H7>XT7TfrS$Y&(p>aU1a6t(;E1fhLs2d!UC3&`9h zN9JC+8#7X3%nBxB20;ilf}%S~dopopKCn5qi?EVC?t=)Z7jCR!if9dbCRUP+sU}oL zg(-A0@nU-sE9S}lW(+fC8#JzjK?m-Vf*K$YR0`8DHNmwWQxDtRQCXmdfIx-{Qy>6Q zttHtw4un$DeoV<&BJ2eup}>u0GoisF1SK}3Ixm{TE2Ww6*xF&r8rdVo3QK`|bm-fF z#xByQ%+<fVd&hg#ogbke*OylpFSeiEJFfUIAJ5B^b2*)Sov(M>Pq(Y}&e?nZM2kHFdYSC^#ftb%iQit=*%iG<~t?BZy5-xE*6 zJDx1k?p~D#!crktH`w|i#=kM^Fu bz4~WO_Tzs@7q|OS4zH;+J$m%bPp|(4A5ggb diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialBehance/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialBehance/Contents.json index 2fa43f1..a274db6 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialBehance/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialBehance/Contents.json @@ -1,6 +1,6 @@ { "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 } } \ No newline at end of file diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialBehance/InterfaceEssentialBehanceStyleFilled.imageset/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialBehance/InterfaceEssentialBehanceStyleFilled.imageset/Contents.json index 010ab1c..5346105 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialBehance/InterfaceEssentialBehanceStyleFilled.imageset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialBehance/InterfaceEssentialBehanceStyleFilled.imageset/Contents.json @@ -1,13 +1,13 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "InterfaceEssentialBehanceStyleFilled.pdf" + "filename" : "InterfaceEssentialBehanceStyleFilled.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 }, "properties" : { "preserves-vector-representation" : false diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialBehance/InterfaceEssentialBehanceStyleFilled.imageset/InterfaceEssentialBehanceStyleFilled.pdf b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialBehance/InterfaceEssentialBehanceStyleFilled.imageset/InterfaceEssentialBehanceStyleFilled.pdf index 6189715e9c38e6c2c6c02d01e64d46b89d00a38a..b204451dc330d1622f7450186382e668d1c06de4 100644 GIT binary patch literal 4559 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 diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialBehance/InterfaceEssentialBehanceStyleOutlined.imageset/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialBehance/InterfaceEssentialBehanceStyleOutlined.imageset/Contents.json index a411805..bd0f26f 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialBehance/InterfaceEssentialBehanceStyleOutlined.imageset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialBehance/InterfaceEssentialBehanceStyleOutlined.imageset/Contents.json @@ -1,13 +1,13 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "InterfaceEssentialBehanceStyleOutlined.pdf" + "filename" : "InterfaceEssentialBehanceStyleOutlined.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 }, "properties" : { "preserves-vector-representation" : false diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialBehance/InterfaceEssentialBehanceStyleOutlined.imageset/InterfaceEssentialBehanceStyleOutlined.pdf b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialBehance/InterfaceEssentialBehanceStyleOutlined.imageset/InterfaceEssentialBehanceStyleOutlined.pdf index b02118322f2ee271a1b45765fab2f89329dfc8e8..ebc0ff1e997809a075d914d882c55ca25d8bb7bc 100644 GIT binary patch literal 4698 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 tuEKw%6J&xyp@GCy{rWH@B* zA@g93&vw`4)T!#}N3UMIJTrajI-|7O|Mq*Q)YGTx*|TogUCY0nUE}9J47+#7_sRiY z%BsWhZn(Pb&R-0F-E4--Z=b7+*X#c_hwjhL^twJu&o5`~?cs06_CAzSjN06GZQa9{ z!)Di&K1P;ig~6P8^XgW>T#N=Zeek?{ReGCa$VHvm-gq0WRk>}oy%Qr|ZP@CQvo^}Q zkdt;v89W;s66Rd*T#>z{FA`x=XTCSf-WiNDnEEt@7kg`~kJNk53)UL6={zn*dkx$! zAgLwzOKRJt-m#9|E36RdDYjpgMLP%m86I3BT)-Hjc7-w-#}7lU`!LM))^qs=~F)Ms$0M=2F*! zt}T2To$S_>zAPgzU7uY3oQ%+UNLmz6y-bKk6h%hG28a4VEmJ5s#h?tyGGV0C3hjhE zO#QWXG}_T6d5yviGL%YISxhLH%&>8Y1zT4NCLmsdbmg>LW+o_lY$&{e>gWS{VcwxM zVsM^BwdO;VBT7DjVdAtSA7(VXXD|D$v)< z-Bw(b9BDu{3vXbun}bT&2rg(dqMoMWkJF2WjW*o#y-!i?~h|GsQ5?s_*;Ck`YGi zMotjo^m24c)lnR1uu(>i?^A(=syO4U%kbfQ8Yql4H*y}Z87?}oP>U&CEh(kQ1GIOr7c^l&(i zKkORhh*KUlLwx&_&ne`%pxuK!mxg;#U}nzH@$TwoJKS|rz3*N?$K%8Pc6g#5-&{W# mNjbmV?~h6nuJoS2zWHY$`g%{jx;xf%IK+MT=+QSnz5ExI`3NWg diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialDribbble/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialDribbble/Contents.json index 2fa43f1..a274db6 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialDribbble/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialDribbble/Contents.json @@ -1,6 +1,6 @@ { "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 } } \ No newline at end of file diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialDribbble/InterfaceEssentialDribbbleStyleFilled.imageset/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialDribbble/InterfaceEssentialDribbbleStyleFilled.imageset/Contents.json index f76e387..8faeda0 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialDribbble/InterfaceEssentialDribbbleStyleFilled.imageset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialDribbble/InterfaceEssentialDribbbleStyleFilled.imageset/Contents.json @@ -1,13 +1,13 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "InterfaceEssentialDribbbleStyleFilled.pdf" + "filename" : "InterfaceEssentialDribbbleStyleFilled.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 }, "properties" : { "preserves-vector-representation" : false diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialDribbble/InterfaceEssentialDribbbleStyleFilled.imageset/InterfaceEssentialDribbbleStyleFilled.pdf b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialDribbble/InterfaceEssentialDribbbleStyleFilled.imageset/InterfaceEssentialDribbbleStyleFilled.pdf index d89ec073e09d20dd10298918cab13117cad11097..029d1a657938ae6af763f61f3c4777307fed842c 100644 GIT binary patch literal 4441 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 literal 2926 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 literal 3203 zcmZvf$&MUF5Qgvd6nU{^BRM-Wa+fSic#IJOgc)G>jSnay<= zRYzsU^2Z;`JbC;2&2w+dFnHt4;g3HDV_v*4FJBJh{z88aa#z0jY21H2eKG;zxt=i$yT1z<^A8ZS$rfPh&&2c#ypO)LZ0cmYr zCDIhp8O&9e`Xsy~&C!+S^?va&J5gEj&KK-Nn^h-vkm+s07`)iVBiJm~)hwBl&bCrg z;$*Sar&`3+)ife(U~V^58)l8G@MB>?jSq@faPpSU5F^g2~lSQMo2HR`L5!m zGR+zqeFGy9^)}Vo3jTqpok_|DZ*fmw3sTU=- zOFq`7b|m`@?8s)F4K{WsJFk<76CuP>#aC>TF-d`%<6MB1V2qN<9e|kP>#;mU=L*p3 zR6dhEExur`5k|jIP9~wUwX{&-k9rnr1r;T50#p@w9%z%N(&;6(vb6wSb{Zb6N>Kn&@+fK|*IDHg0djEevZV z(87rB9JAFBJ6RC<~q`FI#5l? z4gqp&)hlE%_5vqwDP$iIHT4mFkZeg;wv>N}1ncN0IguB|&Q;Y0fs-;vOGmF_m7-oD zTT`H3B&j~YE&6a-id5}2k%&TT+H3BFHeKC)EnZ~~&T6_8Ci+FVh$}~Zt^;ng0cVt?Q zp#MAaG4h>Yb&uWGL?n!*_t=6DQ(388uM75FsgqzAQ3kkqxU zv3gx%L?_x~0F-nez8UtzuY>N3^D?+>j=CgH8>OTy>q5y|aJy)3zTNK+r=xlQJBugJ z=I!=o+@DO+1#=etJYHOGUmd=f_qPkA?hN`EPZo#FV8` zmXcjWB4uB)|4iSOxA*tH=a1*PpX;3aI_Ey;xzFdid65VOL5Pqz5C{PYgK!qMKoCeu z3Ivw1$75U^(Rd69jKH{IEiqb(vIkuU4Xl8r_8q+K54sT;OPm$vXO9L*^rxkUalC`K z0f|6i;s?mhn?P5*3kK}~B&JryW09u^S=(^#>*0a`fI&;+ef4;niu;0@_x$X$PsPxn zkDNI5+~g$6|D-&E&RCj3{=5@j-|ECk)CdDTy^ircCg3XxiH96l%V;m+zo_>W>y?c) z71jHCe@PwwoW7m4PZQ-xix76nV|vhuwvodpgYnL0C%oo$BuuX_a?gstl-?) zD(XW=lG=`KAIIyw;82~Y(Tm}%}dEkjyoE!9FhC!5&(O&FbtoJj}w#KQqtv4 zi7}Y6sR(RH@k$+0Zq)RV%R(~o&p*2IFtH*FlCm@fqug$XQr0M> z7`}FncF*>*cr!k;tG>E>@jJPPWSWuwdCyS;xyURh4YU&4FuKU5l&v5!Tfcy)wUqp^ z=9ESUvcu>>{-a{N+H6ekl{4~vITZ!QUtqS!)cC(>Ehd$4uphZ_%mtPB>BT}%8^`AZzNxws1&nhM`W435Y$SSJ8Y6dl{LJ_3b zV$YepHWE~JC^HNl;vrPl6>hn#39OO7B=qr}?Pa|Vo)YRbBU(?;9@8i5@aS8TS|Q;n z=iVk8CO0NylMh3|SPk1kn_4?w+c+D7jk=9?l}Q!-5bx00O0({`*$b;y9_*x)n|V1| zlleS7g}t+VNj=bBldP1S;eu_Y$bzMDC%=M=9_P;kPYLaO(-S-DH`(dNZot|g5 zjgzvX(KQpt$*g2&p4&XtJ=b$Qa)Mh~EX61BleUxfm-SCSR*vc5iXDFZPhlGN9yVxJ zP;{VkOwHV_y`<~B<-CoMSQ+f1MHKsmFg1l6mM>&qT0D@CkPm%%P1T!ng+hwI5pP!d zwIrt0w&Z?kT*+>!YsqlQeg&jzVn}CT!~|h5_0(o1`@MXb!)yD^>R^Y3LDaYSp>O}p zRcu=XIVx4E@NYOHHm} z35FSVni)SOzLW0{n$-HlO~|Wnt+_ymtDCKH9w{14ubZn~8L=D9@Ju9L@TU%a<+ z9VC3^_dUEHzBdY(@{96Y_RCjQO9+Xt6bwq(0*^jhoe&AYv|t4NK~bDF;6+pv3hB{Z zMk%KR#On$8vf6VtaMkbyo~yV#Wz}Af?CQ?$o;cHb?b5ZnmML;J`Af@KuxHTOU{xLg z9+<*Nh)yI6qFP}hyCvH;=dqqg*+`R%z>v^&u!mDzPtn)g{kp|v8m8Vp;XCKvBtL~D zCN3t%LNeg~skU$M0+Q7tZVxFRFN`-%)vl-zPkWv9f$ZN+RW)`VAvUP)G=6_T_bjkC zP#K_#6e6b0BoHqxd25;XF69nREl#zvc&Vtpf@j4DD-Wa<#U-Z=C0NJDCtOx{SNV`} zlNWfR&sv(jSj6z9*p#A+wuQi;5PJvybxHe9)R}k!%m`wX=$DVBzq+3B|Y5*hX_vn{a&VfYln*O_1^0W8flrkrN56{Cx4x< z870ZD%Li|mZ!m5!%@c+_v-Qh~CQCDodE3dVGrXI;xQ((w-_m#0tL=b~fDQn5Fs9;t zz}Df7^E<}r$eYLsgC6}tRBiF{F4tJr9(g{PBf{nazr^xv!T1d6>W89fTk@A)%K^)z zw)DQhzSW)fo$@ETr0UFdit~i??1S;sqlDuG0v}X^wU4|Ov-Lo`C*N^@YE9dYHYckH zl~+D4CLsvl{rEXC<8T*U>g;uj)bL_xGdNED-QykWg1ZhYI;ygvmC%Z+h1C7pC$P`e zkIe*qZj3#7YwB#e>4iF6&hyN2y`}Ex+ca!i?Ab|hgj?zCxkeV}S;vj#`7sJ0q0Drt z)}^p5=X1;LgyL`gsZY}C-!zQ5koOc;)az5!n+A8^zq9)=>_wT-opWd#cJL0}zP>fO z1s+?fbNwW=Js<9mq4f^9#;|Zqo>_TeX+HdeX5;>r%ydA~gdj77dF3L%)K%}2rJAh= z9kB|9q}82}{`S}TT$;g(wK-tluJ5}m`tzc%p7wqo>Y8hHXdUMBy6o7bziIImGek-1 zXt>3)U*Lt=`I2yJbiV<91_E6-T=iHlYZ14_MKo1;4?{V{cE6jvs!!V3y!h^B>i71Y zfffFpw<}2{T{T@8GquJ_?_=M$oM0HYbxCH6=5_0yZ>5~yzOloY?CQ?mir`UZeT#V$ z5tp2L^<`mqcMp|=ZY!N-ob}~+ zyWhCdG-s6Yp`ko6Loj_#6zWi_bRq-v_-T+uqf&b`;e~R#BxiIf+-BERM557GDw7X1wyfxyagadwO z#!nW8??twLUbECz)oNpND=Y-wHyaaw&Acd>xfRvRJkXJ4ie|qTJa{_+DKKEs^4$!{0F1M4fVq*9s+4q{}R(CsI35l$SYf zd1@yx5z(}SFrG2JcE$=z`rh`S;>Sh$?lX1akI2oAOaXkkyf`)=o*;j7#H*JALAQKx zMyjn6jUs2l9}Cp#m%*pIO^gB-^$a_^Nc~!%QiCkYT&tQQ2Wz>l-m_PFBs^t8?_u#v z9}g~duh^XA0y_vggbgxi{#IM7i{&(XpLh_2oGsNgmB4{RkSAQ}-$Ek3k_B z$L)ZS>0Qrcqp!mAvVtyjAz@{xMdy&S({D_X(SVBS_6xekl!kDT&oq`jOg32(jpq$N z+=;`4h+KQo5?rHj0##Yqe%~yV&C_t}mO)^_eMWb(GeT>}Iu7yh5nnSndp<8s*kyt9 zD_00X?uCSQb{9@NvkA~0f_eXcWF+;E|F<9%hlu}98}Z-hk22BG5r=mL8JYa7`;cfC zj3XW-@iSSd<)S*q3X7J-5kW>EVIkok?T-P03rUC^VB(-Z)-NtCj4O`dVu^7DQPZ26 zdsI3(oFo2V3Re&{e}92GcbyIjRV4ZjwG#awIZj>2pPE(`Yjvmdq@oZcwVeL=Q%L#Zg?#x^jQczOE6h2*`f1$XA0MOzxaM8+ z@i1;4#p-taXFH7R?_bHAx99(cS^OGDXuEUx?N>ARpD@6K{~6n)#%#XRf<8Kr&B z*+{Rv#v;i_LG}r_V~|qTF1DRfOF))Phy@Ci$uQ)!$thu1@Q$>V1Dm>RP0j$L3nqKs z=bZ_O0HvsNqypJS1wTxsnEDDv#XJEPD&FZ7tc)soZA>au5W_o}m^*(4ZqioSQ z0@8A31o4uqwVSM0mnFYZ$kH zx{<}OF8o>4;H-6$opnbB(Ua>~uRwhTR~Q>X{aOep3X>7i_ydm#da<)p`XJMzP<(uEV&QSKsdU({YyXe#cFXXZ2=t z823l%`9^Ng&*R;8^J@Ai-<^8Uo3Zp9HSBU*e67cM`fwP=S@PGw;_hbJ9}!}f{3)=2 zzy15y$ieSN1U>s)U>^N5V)f(p4pb#)u$D`do9P1xQzLtFG+%mxfX+N|r1>JtYIw6b zZg$iCrRm4R_+Drk1-Gz1GI)=H0o)$avaIC3LpZoDAsme82|s-oWe;K(kRi+3v=J;O_l!i*h`hr^oTRe73!NUW>9?Pt#Fy!lk^cx7$x6*q86C&EZ(mF(w#s Kb@kmZum1ximjZJD diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialFacebook/InterfaceEssentialFacebookStyleFilled.imageset/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialFacebook/InterfaceEssentialFacebookStyleFilled.imageset/Contents.json index 7f55f7a..2e78276 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialFacebook/InterfaceEssentialFacebookStyleFilled.imageset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialFacebook/InterfaceEssentialFacebookStyleFilled.imageset/Contents.json @@ -1,13 +1,13 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "InterfaceEssentialFacebookStyleFilled.pdf" + "filename" : "InterfaceEssentialFacebookStyleFilled.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 }, "properties" : { "preserves-vector-representation" : false diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialFacebook/InterfaceEssentialFacebookStyleFilled.imageset/InterfaceEssentialFacebookStyleFilled.pdf b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialFacebook/InterfaceEssentialFacebookStyleFilled.imageset/InterfaceEssentialFacebookStyleFilled.pdf index ddfc61fe8be4dad51fbceb63fdaaa65ec3c8d9c6..3515883bf2d4ea7af61222986ba8f4afd897d2f8 100644 GIT binary patch literal 4051 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 PAu1su47zefNn80pBRK(E literal 1938 zcmZWq%Z?OB5WLq{F)=4QQL;dH!6w&kN^x}nTyIc9I>=xhs)^>O2ujByk#cDX8+QWm| z-L(H6n|A-^6rBL&r7Q4rXq3IMCovq0x z5F5=FUXdOq)E7fRvq?4;;;2nBK4oyo*{6_+k-AjhDPf{UtzgteSVX#4Y;_LRatk`R zr{En4XmBES+L^#6Qqr7aEU7}Sx+d*Men{eU7+GhX)0_mLbEO0-=u$~Izz#*kED-xx z{0NyEuV{-P;8)`zM>ZLDE}9%ruLA>TgSdL@*t0-JsKg4*u1gcdZl#Qd5?ZqEasGJIo`!&Y91R3 z<23a#=Tg0$FP>|a0i75l`s9qqTeKFKsKn}MP-PwUih8h^YX_PVjEKGV5xHDtluKav zdmS;ban=mB64UFniTMacPCscBma*oMzF|<4_lPx0M(`7uwUsPUIQUVID}>=d{Z#@B zxEW&{eMbpQ6I8!TmC1k-;G>glf>z;H(!6Rxz=N3T3(A7@{jWu`>}DTh_ z!fM3EX)UX#QD4;;)u|6k*5|Yv=S36MGoX?)~A^ zc4rE*Zzt&Y_V##q)qkf?>poq!qg00hL;g~e$EZEcvG(oIe>*kpK(g!SaMyizMv8%C z(a+!?|NY%c^1BvEHy;Dxv3w+UzaDQvm863GlI6Pp2Esg%T>}l5k>W)p$uwM4IXYe+ z&WHQ{?$Y)9sr{l1B{hCkgtzw GuYUkdt(AKK diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialFigma/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialFigma/Contents.json index 2fa43f1..a274db6 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialFigma/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialFigma/Contents.json @@ -1,6 +1,6 @@ { "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 } } \ No newline at end of file diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialFigma/InterfaceEssentialFigmaStyleFilled.imageset/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialFigma/InterfaceEssentialFigmaStyleFilled.imageset/Contents.json index a439fee..556c5dd 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialFigma/InterfaceEssentialFigmaStyleFilled.imageset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialFigma/InterfaceEssentialFigmaStyleFilled.imageset/Contents.json @@ -1,13 +1,13 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "InterfaceEssentialFigmaStyleFilled.pdf" + "filename" : "InterfaceEssentialFigmaStyleFilled.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 }, "properties" : { "preserves-vector-representation" : false diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialFigma/InterfaceEssentialFigmaStyleFilled.imageset/InterfaceEssentialFigmaStyleFilled.pdf b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialFigma/InterfaceEssentialFigmaStyleFilled.imageset/InterfaceEssentialFigmaStyleFilled.pdf index 7889687ca30244e6f4b2221cf8a19cc193dcb46c..47e423698314cb733dc1f85ba8f93be33102b31d 100644 GIT binary patch delta 3154 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 diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialFigma/InterfaceEssentialFigmaStyleOutlined.imageset/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialFigma/InterfaceEssentialFigmaStyleOutlined.imageset/Contents.json index 30947c8..c8142e0 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialFigma/InterfaceEssentialFigmaStyleOutlined.imageset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialFigma/InterfaceEssentialFigmaStyleOutlined.imageset/Contents.json @@ -1,13 +1,13 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "InterfaceEssentialFigmaStyleOutlined.pdf" + "filename" : "InterfaceEssentialFigmaStyleOutlined.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 }, "properties" : { "preserves-vector-representation" : false diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialFigma/InterfaceEssentialFigmaStyleOutlined.imageset/InterfaceEssentialFigmaStyleOutlined.pdf b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialFigma/InterfaceEssentialFigmaStyleOutlined.imageset/InterfaceEssentialFigmaStyleOutlined.pdf index 83e8da73f1399b03839465ff8107faf400ffd715..bd46b5100e78b5760ef874635b6a8f3791193fe7 100644 GIT binary patch literal 4239 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 literal 2660 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 literal 2018 zcmZ`)O^*~e5WV|X)MX`zgvaG?O9%;eLlh+_WXKJ17=Hv>aqJikGnwDsVL_YR(~tuwp?Q zVb37&21kV|B97;K6=T-yJo`kIimkRDc7FA^LXFC}P|zVXfgB86B{po3y46U-q)bI~ znABh$rOC#s8ttUkqv0Hj=z&}~q2W*^8$4Pj>XL1c*7MrhR8ZfbJzK|s90UobNGY7o z-kOLmve3j@#NsrY82wZRHr_@+k-f7LXLKNrxal=pF32M49E$}Obn+P>HZk}BPqlbJ z7U7U;2?=Ept7vUOrp23tlp$cr9MP0U$KnHip(I+lF;occeMXRo!eqpZOweXFqA$SV zIJ%5~MXbi=Si7iMyJ!Wa;~-9oi?N;B>t1oxM$l1#8AY>KRD6wH0I(7~3L?;I38kf; zMWTNQo?f>Y7Ng~(ATn5Es-*vevJR4!lb^MQ3W**=Pk3+Dr=Qe8{i$Re&$D(J%rb+g zfz2+ZILD3~NtNWTlq? diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialGoogle/InterfaceEssentialGoogleStyleOutlined.imageset/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialGoogle/InterfaceEssentialGoogleStyleOutlined.imageset/Contents.json index ababe39..b5a12f5 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialGoogle/InterfaceEssentialGoogleStyleOutlined.imageset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialGoogle/InterfaceEssentialGoogleStyleOutlined.imageset/Contents.json @@ -1,13 +1,13 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "InterfaceEssentialGoogleStyleOutlined.pdf" + "filename" : "InterfaceEssentialGoogleStyleOutlined.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 }, "properties" : { "preserves-vector-representation" : false diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialGoogle/InterfaceEssentialGoogleStyleOutlined.imageset/InterfaceEssentialGoogleStyleOutlined.pdf b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialGoogle/InterfaceEssentialGoogleStyleOutlined.imageset/InterfaceEssentialGoogleStyleOutlined.pdf index 1305fae3b10ced7f98e6053f0f4a463cc919df40..fc205ce3b5357671c64d811898eca7be7bcf53ad 100644 GIT binary patch literal 3927 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 literal 1715 zcmb7FO>fgc5WVlOm`kPh(9O<%uT)i{Eky_rCFNFe2#(tZr8dMa0)9Pj?bvZ>5n>O~ z`g!*4yqWRK!PUj(G0PwXlcM_b7eRD#LZ_#qtd{vv=qWyXTUK}NJsE)W9M!a&a`7N$ z7v=X=QO;kT(fRfCsc6JE!BTaL)UY`ocawL{smPk}&bbtgqT)e}aZfi*Q3)@dP00j` zQah_S(ZddNGW6J5u#&707-<3~>Agvj$x05&$IQZr!Ny3Hg3_AC3ykERtPoa)x(gfpF07Zx#YzJwpoXZ?ri8!iKSBxSHPkn`OHkl4xiwFgZqbD{p zDd(d@o-Ue{95FN~li2h{@HP=^RLWXhTc9DH*(j59VGYsTHw>*axqg~+{S?~4P9@M9 zR1$?mDpEO!W2m;MiOW^?+BuKO>pHI8uG~QUAVEvylbbw(NE=sY$VuNzMUEkNxElrJ zicu(bqcD!gTHK3UQHc-#J(fY*U^Tk_@2S*iKuF1UrO~;=c`iA~gtdoaGDnnU^bnv3 zAjS@ot)gc^d?8y_gj$SF7y1{J(Yr2#DJ?$v=TL*G9b(74j-N*-3=_T2qmz7x@@Ie9 zn#bTY*;IN5VioLYKz4*-OtTkNRksb@e1cJ7&8`-kvTDg?L)t>`%H?WtR{x-zo#Bl3 zfn2>&!Q%_V_+e0DqJe8(HudACC>zRVIMAKfRf{Vc%1$_dAAf!=^W}FXE}gh#&SP}Z z*_+i8sZv%jA8$FYACWL`lid+D`%He1Dc{uWsq7D)FWSYrzS}?gV^iJ=MM3non}5kW zSQY`^E>_g-s2U*{%s#~IpF;WT&TBl##{bF1*{p`BcC%Qm%Z%7VM{&aPL#N@U;ty(~6uCx>k^;^5%r`^(=H<7=z{ diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialInstagram/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialInstagram/Contents.json index 2fa43f1..a274db6 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialInstagram/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialInstagram/Contents.json @@ -1,6 +1,6 @@ { "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 } } \ No newline at end of file diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialInstagram/InterfaceEssentialInstagramStyleFilled.imageset/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialInstagram/InterfaceEssentialInstagramStyleFilled.imageset/Contents.json index 3ad0337..400c8d1 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialInstagram/InterfaceEssentialInstagramStyleFilled.imageset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialInstagram/InterfaceEssentialInstagramStyleFilled.imageset/Contents.json @@ -1,13 +1,13 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "InterfaceEssentialInstagramStyleFilled.pdf" + "filename" : "InterfaceEssentialInstagramStyleFilled.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 }, "properties" : { "preserves-vector-representation" : false diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialInstagram/InterfaceEssentialInstagramStyleFilled.imageset/InterfaceEssentialInstagramStyleFilled.pdf b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialInstagram/InterfaceEssentialInstagramStyleFilled.imageset/InterfaceEssentialInstagramStyleFilled.pdf index 13ef550a15c69c717d3ed3ae05e0a22bbd137002..d2cc1c7321b624353d672334cff43297f548f6d2 100644 GIT binary patch literal 4105 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 M3V89Ny1vGL0O43F5dZ)H literal 2185 zcmb7GO^+Kl487}D@UlQsU}aI?0)ha|Zc`L((bVZJ=)v_)HZE*W>v4)SzrK%}8I7GS zP;^f6llb^Zk)m(j+`qnMos?oS)c^LoB6{(HUcOY_@j-qndx@`p=#G!)599!@<{F^-c zw@oF_yx{_BI>0wYgSeVv5H4s7ZE-U1!b?-LU~+L&AurAbiJNTP%#(^#tWaZf@|PzG-iWQ!Racy)R+6f| zhAjbAjd6rWhSrles@k~Vz_Vbm5FV-Dih3i#V&B;)euDO#ZXg+PGu>T(Jj2C6GT&zK zm%sn$#Q9?frx!C&bhO#H`hNESsU#7sY4&p0e}rJ3#4bd`HB-D|5>LZbl%wI@=DgYW zkJqN3PThNDC@GZ7^id4K1p+*MjGV|v#|EL?t|3NgJb^;`63Uo6Ul+8UgZlcXVRJgyaJWRLZf?H$>GeNs C`oiY` diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialInstagram/InterfaceEssentialInstagramStyleOutlined.imageset/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialInstagram/InterfaceEssentialInstagramStyleOutlined.imageset/Contents.json index e9f94ae..2f671e1 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialInstagram/InterfaceEssentialInstagramStyleOutlined.imageset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialInstagram/InterfaceEssentialInstagramStyleOutlined.imageset/Contents.json @@ -1,13 +1,13 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "InterfaceEssentialInstagramStyleOutlined.pdf" + "filename" : "InterfaceEssentialInstagramStyleOutlined.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 }, "properties" : { "preserves-vector-representation" : false diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialInstagram/InterfaceEssentialInstagramStyleOutlined.imageset/InterfaceEssentialInstagramStyleOutlined.pdf b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialInstagram/InterfaceEssentialInstagramStyleOutlined.imageset/InterfaceEssentialInstagramStyleOutlined.pdf index e0793148d00b93d9d6fbd4f8ea103eeb196acbd8..7af15fcb74ab9955c8d0f50695a50bec6761ebc2 100644 GIT binary patch literal 4078 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 literal 2446 zcmbVOO^@3)5WVwP%w>TjfN6e8BoG8>cAKC`il$C)K@YB0yK&)_5=#k^{`$U=L{i>e zpdUPqpN4N{9)}!Xyt{g}(XtjolcN5QKLyeA=k(%*XuE6vDa;z*zHPhP@grG)JN6pJ zQ@g(t+pG5Lp=o!oU()6K^{-|SpM{ocTBMS($=1Vf`BQTzvi;B)nof8br$su-imjUN zgtoICR_IaaS}JX8RjtspE7HTSz!sjG8c{r#kTrpF2^z`BDpV${c~XTg^8_kbQ&KPB zQOrD1uRL?%IYvfuDoxR;Bz;_gx%M0&14NLNw^!-^*h z)lXktg!1JK79LiyO2?nbSw$ZbSeqVO5jk^Ugkwl1S$dM zPo7F15>aBT_=HQw2?W^^ADN`RMS&b3RTGnzQ*MvwcZ9At&qODF{m+*|YpJ<@r1~#z zg`dPCTxRvSZ{d~~9 z8CBB6$_6y5mKGMbtYmpmb5itqY6g&h*q+56$v!5 zj+Ik2F_*2BrHz|Et_8>t)XS+A$5O#2^R2Km4gPPZ)zaf${oGz3_AmQy^r6hsJP*p7UaZ8mYlr^Jsc8q|IiKh* z`))*tfq2L#@VD=uS`L2OBIxRm0OyhaAZ*_pu8}Hn1v^SnF8eP?STD&IqT!qgmuAJp zk%qG>=Z%;9aewS@&$oU%wKqahE%>I*iz@G}C&0_XdpB9sWe5+?Iiy2GJ-o7)jyl|f zjKX_x?qzgUHjbzL;nI9xEXsD*_akw^lf2vahre26KmBvs SpT?;iysu7NT>SXUtG@y2;`o~Y diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialLinkedin/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialLinkedin/Contents.json index 2fa43f1..a274db6 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialLinkedin/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialLinkedin/Contents.json @@ -1,6 +1,6 @@ { "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 } } \ No newline at end of file diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialLinkedin/InterfaceEssentialLinkedinStyleFilled.imageset/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialLinkedin/InterfaceEssentialLinkedinStyleFilled.imageset/Contents.json index 600db9f..60af618 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialLinkedin/InterfaceEssentialLinkedinStyleFilled.imageset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialLinkedin/InterfaceEssentialLinkedinStyleFilled.imageset/Contents.json @@ -1,13 +1,13 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "InterfaceEssentialLinkedinStyleFilled.pdf" + "filename" : "InterfaceEssentialLinkedinStyleFilled.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 }, "properties" : { "preserves-vector-representation" : false diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialLinkedin/InterfaceEssentialLinkedinStyleFilled.imageset/InterfaceEssentialLinkedinStyleFilled.pdf b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialLinkedin/InterfaceEssentialLinkedinStyleFilled.imageset/InterfaceEssentialLinkedinStyleFilled.pdf index f4905d7572695192ad286c496173916641074a23..b307d47731d0903424db2c437fcd78c8a8c0a7ab 100644 GIT binary patch literal 4829 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 o=`704?eTbCm9Ulf=DYjC+)(?7oXKh*l+CjbBd diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialLinkedin/InterfaceEssentialLinkedinStyleOutlined.imageset/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialLinkedin/InterfaceEssentialLinkedinStyleOutlined.imageset/Contents.json index 77be0a9..675ae28 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialLinkedin/InterfaceEssentialLinkedinStyleOutlined.imageset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialLinkedin/InterfaceEssentialLinkedinStyleOutlined.imageset/Contents.json @@ -1,13 +1,13 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "InterfaceEssentialLinkedinStyleOutlined.pdf" + "filename" : "InterfaceEssentialLinkedinStyleOutlined.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 }, "properties" : { "preserves-vector-representation" : false diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialLinkedin/InterfaceEssentialLinkedinStyleOutlined.imageset/InterfaceEssentialLinkedinStyleOutlined.pdf b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialLinkedin/InterfaceEssentialLinkedinStyleOutlined.imageset/InterfaceEssentialLinkedinStyleOutlined.pdf index efe7372087d8462a3d1e07ebbd920bf638634156..b14dddf7b0ca3ab8fcc54779d00146e71d5838c9 100644 GIT binary patch literal 4557 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 I^~3YO0d3M`&j0`b diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialTwitter/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialTwitter/Contents.json index 2fa43f1..a274db6 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialTwitter/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialTwitter/Contents.json @@ -1,6 +1,6 @@ { "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 } } \ No newline at end of file diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialTwitter/InterfaceEssentialTwitterStyleFilled.imageset/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialTwitter/InterfaceEssentialTwitterStyleFilled.imageset/Contents.json index f1b277e..977fa91 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialTwitter/InterfaceEssentialTwitterStyleFilled.imageset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialTwitter/InterfaceEssentialTwitterStyleFilled.imageset/Contents.json @@ -1,13 +1,13 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "InterfaceEssentialTwitterStyleFilled.pdf" + "filename" : "InterfaceEssentialTwitterStyleFilled.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 }, "properties" : { "preserves-vector-representation" : false diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialTwitter/InterfaceEssentialTwitterStyleFilled.imageset/InterfaceEssentialTwitterStyleFilled.pdf b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialTwitter/InterfaceEssentialTwitterStyleFilled.imageset/InterfaceEssentialTwitterStyleFilled.pdf index 767bf8d9429a20ef6bd157ddb4868ad4670d4469..7488b13c44cc5edaf373e88e56f27e21c13cfe57 100644 GIT binary patch literal 4472 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 VPxs38{y3Gxpt<46lW%{1^977dErI|5 diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialTwitter/InterfaceEssentialTwitterStyleOutlined.imageset/Contents.json b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialTwitter/InterfaceEssentialTwitterStyleOutlined.imageset/Contents.json index b852483..5e6f3ec 100644 --- a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialTwitter/InterfaceEssentialTwitterStyleOutlined.imageset/Contents.json +++ b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialTwitter/InterfaceEssentialTwitterStyleOutlined.imageset/Contents.json @@ -1,13 +1,13 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "InterfaceEssentialTwitterStyleOutlined.pdf" + "filename" : "InterfaceEssentialTwitterStyleOutlined.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "FigmaGen" + "author" : "FigmaGen", + "version" : 1 }, "properties" : { "preserves-vector-representation" : false diff --git a/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialTwitter/InterfaceEssentialTwitterStyleOutlined.imageset/InterfaceEssentialTwitterStyleOutlined.pdf b/Demo/FigmaGenDemo/Resources/Images.xcassets/Generated/Service/InterfaceEssentialTwitter/InterfaceEssentialTwitterStyleOutlined.imageset/InterfaceEssentialTwitterStyleOutlined.pdf index a6a977b1be8e2c76749011512b5099bb98122e88..a73f3172d2860f0d0c28f00b6e1b97859642f54b 100644 GIT binary patch literal 5541 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 J+$y@N{{i&I-9P{U literal 5652 zcmZvgTaP5g5ryCDSJcZ&V2PT{%43IKE|2wTu@vFZd@83QC zJSV_wtvWwG9BN9_f zG3Kq#hxgNE-OC^6!~L`_rM9hx85g#mw>H0@($ZpdER{`IUbeP55<4e%AzK(bIwcc{xHpt7X32&zktT+pyK)};pn`?5uI6Q~rsH9|+h;5G{z#(~Mz zvAJLsC$e%&W{p;g6R>p&8*XxQbuJByZjD`S3_nF~12O zEC`_d8h5XoTbY*JpvCOTkmbAU#d7ZHFl1*|4}=&JhTjA(`))iezAi7Zeh63{45el3 zE{e+E@eyypBq+N(j@WSGM)WLVg(#aWbPt!iE?R&KyBkpstOj4l-P!no^8#zmCFtt0 zElYNx#k{QDtmIc;J&Jj$(tzE~--kuyNO!fsUvwtR5-$?($`|-yUBhzYoS1x!qPonV zwUQe*j~HpRdHyBt9!lMomN1BfBh{n3NGa$942()_~18TE%f_$qW1Sq*+Q`k8k#X2p;A>vfoDOWQJ;d~;Zvgw}YWRV~w zJ0Yuzt5y*#-xmroFhm7V7q0kjvSU>;F;Rl>#8;_C^m+A!*1pWYu`guf0<4#~*WEnz*b=3(mo9F@F=nfN@%3`4DB&ENaCduIl_sVka^Tt}2AP(f; zOH9JFXi>xJ5JPs(L6jeR{45!Sna_BcBV_momIl_n=76A9EH6|ueo1`U zeJLM$pj0(hHLuZVpL%Nhf+8c2o5w-baAZ_jN-{e|ws|AxO|o*`Dl-WA%t=D*q{Bq( zfiuUvyV6dWOAJ{(exlzv&&1Ep*1qbw35{N0)Tr%r>SQ!tG#A)OIO-X#eG~zm4yIY4 zLkF@Hg21b>u57osOW>B_NoEPyjmQF?8JBE;>kMO* zF2JW41)tn?q}!b!WP~Go&yo7nmUY%P)UZ++4auXFTP7L863U^ zm1wRb5Sl4FHI$9`fVo{HpXW|k61Ck{b(PMBF>2w4G+AZ+jS@7lDs`(`XmIgWJI@+g zK%lZ)*;Jm8qK>WJyE952NLG6^{ZX%M--xvKRm!GgmwixbNE0)bm(&4AloOs`YqM2! zbLEHXPDO33D$D9cTCUrDAgV;#N34myt;*hjSH@yvkNomV3$gT6)<^<_PcY{SA<7%8 zbFKvt#q0kex-Y=2omKK)ec{ZI7EQNUkdq@wXSb6^H!$~^F62yAW-H?pgi*v!+I;%c zeJfQ4jQXf~Nmhksr&DPaEoL&6Bwv%fW*>N&P+Wx3*nO_1iL)Ps(ZTaXh@C{|Ql^Se zFxY1my%Am&<~xDKLZQjRdpGAZcKA9Iq|69(c!%J~&x?rKY*VjYjj%|7_N_y?yjN)K zzO@HyPRvKpXs&B$Qm)$-oU3*0@F3~&<6D^se43FLs{C3L&=M{UNC+EB}8++xFZg(DbCB9KP*@-Mxey&$e`%)16sZ1 zxs07V%1yBID4%01zcjii;SxiHyR~``(8Dk?^$4VJM)Q?EGJKV!EE3dd&jD6h`;ftn zD|YUxCg+A+s%HTV7Z+1!;II@Ev>Uw9uAL?b^J1eRavOw_UV1}lD5d%DCc6-sipDBU z_9GvW2lfq;nVRJ;rdEP0*VM#prJNk}sg0SSV4k8j&u$vcP-RC=R$9S6ykQ%hdmJ@rn>L7e(~0b+Uif1U zOiwb$s@^T;H>i}(N@*V(#}wOjT8V@yb#BGzK6EOkbm#H=N6O^>X0S z81~bjru*rilRn^$uXFpSJbktEPkbfBc=^JYFEC&JuD-m#KRur3?|zAiiio z#7EHjV%3TwK3c^?;{rWC+}z$BA0|cbuWz8^lk@5Q@zeQ}+qa)ODOcC0)8j0Mjoz#8 aZht>wy?wvEd3ZE;N={*V_3F?6`1%juUU9Ji From 635eeffcea5b2f8d549eaf83581b3640e25a1e24 Mon Sep 17 00:00:00 2001 From: nschpy Date: Tue, 18 Mar 2025 01:23:51 +0300 Subject: [PATCH 05/23] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B3=D0=B5=D0=BD=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D1=8E?= =?UTF-8?q?=20borderWidth=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Tokens/Contexts/BorderWidthToken.swift | 3 ++ .../DefaultBorderTokensGenerator.swift | 52 +++++++++++++++---- 2 files changed, 46 insertions(+), 9 deletions(-) create mode 100644 Sources/FigmaGen/Generators/Tokens/Contexts/BorderWidthToken.swift diff --git a/Sources/FigmaGen/Generators/Tokens/Contexts/BorderWidthToken.swift b/Sources/FigmaGen/Generators/Tokens/Contexts/BorderWidthToken.swift new file mode 100644 index 0000000..a0df264 --- /dev/null +++ b/Sources/FigmaGen/Generators/Tokens/Contexts/BorderWidthToken.swift @@ -0,0 +1,3 @@ +import Foundation + +typealias BorderWidthToken = ContextToken diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/Borders/DefaultBorderTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/Borders/DefaultBorderTokensGenerator.swift index 85d2165..a52e7fc 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/Borders/DefaultBorderTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/Borders/DefaultBorderTokensGenerator.swift @@ -35,23 +35,57 @@ struct DefaultBorderTokensGenerator: BorderTokensGenerator { ) } - // MARK: - BorderTokensGenerator - - func generate(renderParameters: RenderParameters, tokenValues: TokenValues) throws { - let semanticBorders = try tokenValues.semantic.compactMap { tokenValue in - try getBorderToken(from: tokenValue, tokens: tokenValues) + private func getBorderWidth( + from token: TokenValue, + tokens: TokenValues + ) throws -> BorderWidthToken? { + guard case .borderWidth(let value) = token.type else { + return nil } - let coreBorders = try tokenValues.core.compactMap { tokenValue in - try getBorderToken(from: tokenValue, tokens: tokenValues) + return BorderWidthToken( + path: token.name.components(separatedBy: "."), + value: try tokensResolver.resolveValue( + value, + tokenValues: tokens, + theme: .undefined + ) + ) + } + + private func extractBorderData( + from tokens: [TokenValue], + tokenValues: TokenValues + ) throws -> (borders: [BorderToken], borderWidth: [BorderWidthToken]) { + try tokens.reduce((borders: [BorderToken](), borderWidth: [BorderWidthToken]())) { partialResult, value in + var result = partialResult + + if let borderToken = try getBorderToken(from: value, tokens: tokenValues) { + result.borders.append(borderToken) + } + + if let borderWidth = try getBorderWidth(from: value, tokens: tokenValues) { + result.borderWidth.append(borderWidth) + } + + return result } + } + + // MARK: - BorderTokensGenerator + + func generate(renderParameters: RenderParameters, tokenValues: TokenValues) throws { + let coreBorderData = try extractBorderData(from: tokenValues.core, tokenValues: tokenValues) + let semanticBorderData = try extractBorderData(from: tokenValues.semantic, tokenValues: tokenValues) try templateRenderer.renderTemplate( renderParameters.template, to: renderParameters.destination, context: [ - "coreBorders": coreBorders, - "semanticBorders": semanticBorders + "coreBorders": coreBorderData.borders, + "semanticBorders": semanticBorderData.borders, + "coreBorderWidth": coreBorderData.borderWidth, + "semanticBorderWidth": semanticBorderData.borderWidth ] ) } From 0c58e213ebfb2f1be00895208e66ce2b57f688f0 Mon Sep 17 00:00:00 2001 From: nschpy Date: Thu, 20 Mar 2025 11:28:21 +0300 Subject: [PATCH 06/23] =?UTF-8?q?=D0=A3=D0=B4=D0=B0=D0=BB=D0=B8=D0=BB=20?= =?UTF-8?q?=D0=BB=D0=B8=D1=88=D0=BD=D0=B8=D0=B9=20=D0=BA=D0=BE=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD=D1=82=D0=B0=D1=80=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/FigmaGen/Commands/TokensCommand.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Sources/FigmaGen/Commands/TokensCommand.swift b/Sources/FigmaGen/Commands/TokensCommand.swift index b2dc96d..28ad27c 100644 --- a/Sources/FigmaGen/Commands/TokensCommand.swift +++ b/Sources/FigmaGen/Commands/TokensCommand.swift @@ -244,7 +244,6 @@ final class TokensCommand: AsyncExecutableCommand { """ ) - // TODO: - @nschpy Обновить description ??? let bordersTemplateOptions = VariadicKey( "--borders-options", description: """ From 85cf24e655c0b0d7291aea018085cc9b261bcba1 Mon Sep 17 00:00:00 2001 From: nschpy Date: Wed, 26 Mar 2025 13:59:29 +0300 Subject: [PATCH 07/23] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=BD=D1=8B=D0=B5=20?= =?UTF-8?q?=D1=82=D0=B8=D0=BF=D1=8B=20=D0=B4=D0=BB=D1=8F=20=D0=B3=D0=B5?= =?UTF-8?q?=D0=BD=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B8=20=D0=B3=D1=80=D0=B0?= =?UTF-8?q?=D0=B4=D0=B8=D0=B5=D0=BD=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/FigmaGen/Commands/TokensCommand.swift | 31 +++++++++++++++++++ Sources/FigmaGen/Dependencies.swift | 10 +++++- .../Tokens/Contexts/LinearGradientToken.swift | 21 +++++++++++++ .../Tokens/DefaultTokensGenerator.swift | 15 +++++++-- ...ltTokensGenerationParametersResolver.swift | 8 ++++- .../DefaultGradientTokensGenerator.swift | 29 +++++++++++++++++ .../Gradient/GradientTokensGenerator.swift | 3 ++ ...DefaultGradientTokensContextProvider.swift | 10 ++++++ .../GradientTokensContextProvider.swift | 6 ++++ .../Tokens/TokensTemplateConfiguration.swift | 3 ++ .../TokensGenerationParameters.swift | 1 + Templates/GradientTokens.stencil | 1 + 12 files changed, 134 insertions(+), 4 deletions(-) create mode 100644 Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift create mode 100644 Sources/FigmaGen/Generators/Tokens/Generators/Gradient/DefaultGradientTokensGenerator.swift create mode 100644 Sources/FigmaGen/Generators/Tokens/Generators/Gradient/GradientTokensGenerator.swift create mode 100644 Sources/FigmaGen/Generators/Tokens/Providers/Gradient/DefaultGradientTokensContextProvider.swift create mode 100644 Sources/FigmaGen/Generators/Tokens/Providers/Gradient/GradientTokensContextProvider.swift create mode 100644 Templates/GradientTokens.stencil diff --git a/Sources/FigmaGen/Commands/TokensCommand.swift b/Sources/FigmaGen/Commands/TokensCommand.swift index 28ad27c..aae5b32 100644 --- a/Sources/FigmaGen/Commands/TokensCommand.swift +++ b/Sources/FigmaGen/Commands/TokensCommand.swift @@ -260,6 +260,30 @@ final class TokensCommand: AsyncExecutableCommand { """ ) + let gradientTemplate = Key( + "--gradient-template", + description: """ + Path to the template file. + If no template is passed a default template will be used. + """ + ) + + let gradientTemplateOptions = VariadicKey( + "--gradient-options", + description: """ + An option that will be merged with template context, and overwrite any values of the same name. + Can be repeated multiple times and must be in the format: -o "name:value". + """ + ) + + let gradientDestination = Key( + "--gradient-destination", + description: """ + The path to the file to generate. + By default, generated code will be printed on stdout. + """ + ) + // MARK: - Initializers init(generator: TokensGenerator) { @@ -345,6 +369,13 @@ extension TokensCommand { templateOptions: resolveTemplateOptions(bordersTemplateOptions.value), destination: bordersDestination.value ) + ], + gradient: [ + TemplateConfiguration( + template: gradientTemplate.value, + templateOptions: resolveTemplateOptions(gradientTemplateOptions.value), + destination: gradientDestination.value + ) ] ) ) diff --git a/Sources/FigmaGen/Dependencies.swift b/Sources/FigmaGen/Dependencies.swift index 25658fc..ff910bb 100644 --- a/Sources/FigmaGen/Dependencies.swift +++ b/Sources/FigmaGen/Dependencies.swift @@ -83,6 +83,8 @@ enum Dependencies { static let boxShadowTokensContextProvider: BoxShadowTokensContextProvider = DefaultBoxShadowTokensContextProvider() + static let gradientTokensContextProvider: GradientTokensContextProvider = DefaultGradientTokensContextProvider() + // MARK: - static let templateContextCoder: TemplateContextCoder = DefaultTemplateContextCoder() @@ -184,6 +186,11 @@ enum Dependencies { templateRenderer: templateRenderer ) + static let gradientTokensGenerator: GradientTokensGenerator = DefaultGradientTokensGenerator( + templateRenderer: templateRenderer, + provider: gradientTokensContextProvider + ) + static let tokensGenerator: TokensGenerator = DefaultTokensGenerator( tokensProvider: tokensProvider, tokensGenerationParametersResolver: tokensGenerationParametersResolver, @@ -194,7 +201,8 @@ enum Dependencies { boxShadowTokensGenerator: boxShadowTokensGenerator, themeTokensGenerator: themeTokensGenerator, spacingTokensGenerator: spacingTokensGenerator, - bordersTokensGenerator: borderTokensGenerator + bordersTokensGenerator: borderTokensGenerator, + gradientTokensGenerator: gradientTokensGenerator ) static let libraryGenerator: LibraryGenerator = DefaultLibraryGenerator( diff --git a/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift b/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift new file mode 100644 index 0000000..df7ff8f --- /dev/null +++ b/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift @@ -0,0 +1,21 @@ +import Foundation + +struct LinearGradientToken: Encodable { + + struct Stop: Encodable { + let color: ColorToken + let location: String + } + + struct ThemeValue: Encodable { + let stops: [Stop] + let angle: String + } + + let path: [String] + let name: String + + let dayTheme: ThemeValue + let nightTheme: ThemeValue + let zpDayTheme: ThemeValue +} diff --git a/Sources/FigmaGen/Generators/Tokens/DefaultTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/DefaultTokensGenerator.swift index 5cce8aa..135cb61 100644 --- a/Sources/FigmaGen/Generators/Tokens/DefaultTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/DefaultTokensGenerator.swift @@ -16,7 +16,7 @@ final class DefaultTokensGenerator: TokensGenerator { let themeTokensGenerator: ThemeTokensGenerator let spacingTokensGenerator: SpacingTokensGenerator let bordersTokensGenerator: BorderTokensGenerator - + let gradientTokensGenerator: GradientTokensGenerator // MARK: - Initializers @@ -30,7 +30,8 @@ final class DefaultTokensGenerator: TokensGenerator { boxShadowTokensGenerator: BoxShadowTokensGenerator, themeTokensGenerator: ThemeTokensGenerator, spacingTokensGenerator: SpacingTokensGenerator, - bordersTokensGenerator: BorderTokensGenerator + bordersTokensGenerator: BorderTokensGenerator, + gradientTokensGenerator: GradientTokensGenerator ) { self.tokensProvider = tokensProvider self.tokensGenerationParametersResolver = tokensGenerationParametersResolver @@ -42,6 +43,7 @@ final class DefaultTokensGenerator: TokensGenerator { self.themeTokensGenerator = themeTokensGenerator self.spacingTokensGenerator = spacingTokensGenerator self.bordersTokensGenerator = bordersTokensGenerator + self.gradientTokensGenerator = gradientTokensGenerator } // MARK: - Instance Methods @@ -57,6 +59,7 @@ final class DefaultTokensGenerator: TokensGenerator { try generateThemeTokens(parameters: parameters, tokenValues: tokenValues) try generateSpacingTokens(parameters: parameters, tokenValues: tokenValues) try generateBorderTokens(parameters: parameters, tokenValues: tokenValues) + try generateGradientTokens(parameters: parameters, tokenValues: tokenValues) } private func fetchTokens(from parameters: TokensGenerationParameters) async throws -> TokenValues { @@ -133,6 +136,14 @@ final class DefaultTokensGenerator: TokensGenerator { ) } + private func generateGradientTokens(parameters: TokensGenerationParameters, tokenValues: TokenValues) throws { + try generateTokens( + gradientTokensGenerator, + renderParameters: parameters.tokens.gradientRenderParameters, + tokenValues: tokenValues + ) + } + private func generateTokens( _ generator: BaseTokenGenerator, renderParameters: [RenderParameters]?, diff --git a/Sources/FigmaGen/Generators/Tokens/GenerationParametersResolver/DefaultTokensGenerationParametersResolver.swift b/Sources/FigmaGen/Generators/Tokens/GenerationParametersResolver/DefaultTokensGenerationParametersResolver.swift index 8add0c3..0c68907 100644 --- a/Sources/FigmaGen/Generators/Tokens/GenerationParametersResolver/DefaultTokensGenerationParametersResolver.swift +++ b/Sources/FigmaGen/Generators/Tokens/GenerationParametersResolver/DefaultTokensGenerationParametersResolver.swift @@ -94,6 +94,11 @@ final class DefaultTokensGenerationParametersResolver: TokensGenerationParameter defaultTemplateType: .native(name: "BorderTokens") ) + let gradientRenderParameters = renderParametersResolver.resolveRenderParameters( + templates: configuration.templates?.gradient, + defaultTemplateType: .native(name: "GradientTokens") + ) + return TokensGenerationParameters( file: file, remoteFile: remoteFile, @@ -105,7 +110,8 @@ final class DefaultTokensGenerationParametersResolver: TokensGenerationParameter boxShadowRenderParameters: boxShadowRenderParameters, themeRenderParameters: themeRenderParameters, spacingRenderParameters: spacingRenderParameters, - bordersRenderParameters: borderRenderParameters + bordersRenderParameters: borderRenderParameters, + gradientRenderParameters: gradientRenderParameters ) ) } diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/Gradient/DefaultGradientTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/Gradient/DefaultGradientTokensGenerator.swift new file mode 100644 index 0000000..e2ce972 --- /dev/null +++ b/Sources/FigmaGen/Generators/Tokens/Generators/Gradient/DefaultGradientTokensGenerator.swift @@ -0,0 +1,29 @@ +import Foundation + +struct DefaultGradientTokensGenerator: GradientTokensGenerator { + + // MARK: - Instance properties + + private let templateRenderer: TemplateRenderer + private let provider: GradientTokensContextProvider + + init( + templateRenderer: TemplateRenderer, + provider: GradientTokensContextProvider + ) { + self.templateRenderer = templateRenderer + self.provider = provider + } + + // MARK: - GradientTokensGenerator + + func generate(renderParameters: RenderParameters, tokenValues: TokenValues) throws { + let gradientContext = try provider.extractContext(from: tokenValues) + + try templateRenderer.renderTemplate( + renderParameters.template, + to: renderParameters.destination, + context: ["gradient": gradientContext] + ) + } +} diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/Gradient/GradientTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/Gradient/GradientTokensGenerator.swift new file mode 100644 index 0000000..0cb5b79 --- /dev/null +++ b/Sources/FigmaGen/Generators/Tokens/Generators/Gradient/GradientTokensGenerator.swift @@ -0,0 +1,3 @@ +import Foundation + +protocol GradientTokensGenerator: BaseTokenGenerator { } diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/Gradient/DefaultGradientTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/Gradient/DefaultGradientTokensContextProvider.swift new file mode 100644 index 0000000..62e51d2 --- /dev/null +++ b/Sources/FigmaGen/Generators/Tokens/Providers/Gradient/DefaultGradientTokensContextProvider.swift @@ -0,0 +1,10 @@ +import Foundation + +struct DefaultGradientTokensContextProvider: GradientTokensContextProvider { + + // MARK: - GradientTokensContextProvider + + func extractContext(from tokenValues: TokenValues) throws -> [String : Any] { + [:] + } +} diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/Gradient/GradientTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/Gradient/GradientTokensContextProvider.swift new file mode 100644 index 0000000..940f3b7 --- /dev/null +++ b/Sources/FigmaGen/Generators/Tokens/Providers/Gradient/GradientTokensContextProvider.swift @@ -0,0 +1,6 @@ +import Foundation + +protocol GradientTokensContextProvider { + + func extractContext(from tokenValues: TokenValues) throws -> [String : Any] +} diff --git a/Sources/FigmaGen/Models/Configuration/Tokens/TokensTemplateConfiguration.swift b/Sources/FigmaGen/Models/Configuration/Tokens/TokensTemplateConfiguration.swift index bf165db..9ceeb54 100644 --- a/Sources/FigmaGen/Models/Configuration/Tokens/TokensTemplateConfiguration.swift +++ b/Sources/FigmaGen/Models/Configuration/Tokens/TokensTemplateConfiguration.swift @@ -13,6 +13,7 @@ struct TokensTemplateConfiguration { let theme: [TemplateConfiguration]? let spacing: [TemplateConfiguration]? let borders: [TemplateConfiguration]? + let gradient: [TemplateConfiguration]? } // MARK: - Decodable @@ -30,6 +31,7 @@ extension TokensTemplateConfiguration: Decodable { case theme case spacing case borders + case gradient } // MARK: - Initializers @@ -51,5 +53,6 @@ extension TokensTemplateConfiguration: Decodable { theme = try container.decodeIfPresent(TemplateConfigurationWrapper.self, forKey: .theme)?.templates spacing = try container.decodeIfPresent(TemplateConfigurationWrapper.self, forKey: .spacing)?.templates borders = try? container.decodeIfPresent(TemplateConfigurationWrapper.self, forKey: .borders)?.templates + gradient = try? container.decodeIfPresent(TemplateConfigurationWrapper.self, forKey: .borders)?.templates } } diff --git a/Sources/FigmaGen/Models/Parameters/TokensGenerationParameters.swift b/Sources/FigmaGen/Models/Parameters/TokensGenerationParameters.swift index 6c4a7b0..b500391 100644 --- a/Sources/FigmaGen/Models/Parameters/TokensGenerationParameters.swift +++ b/Sources/FigmaGen/Models/Parameters/TokensGenerationParameters.swift @@ -16,6 +16,7 @@ struct TokensGenerationParameters { let themeRenderParameters: [RenderParameters]? let spacingRenderParameters: [RenderParameters]? let bordersRenderParameters: [RenderParameters]? + let gradientRenderParameters: [RenderParameters]? } // MARK: - Instance Properties diff --git a/Templates/GradientTokens.stencil b/Templates/GradientTokens.stencil new file mode 100644 index 0000000..17e803c --- /dev/null +++ b/Templates/GradientTokens.stencil @@ -0,0 +1 @@ +# TODO: mi.fedorov доделать шаблон From 8ff0b435512871c6060c71a6a104f77ef9ae088d Mon Sep 17 00:00:00 2001 From: nschpy Date: Thu, 27 Mar 2025 01:51:55 +0300 Subject: [PATCH 08/23] =?UTF-8?q?=D0=9E=D1=81=D0=BD=D0=BE=D0=B2=D0=BD?= =?UTF-8?q?=D0=B0=D1=8F=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D0=B0=20=D1=81?= =?UTF-8?q?=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D1=8F=20=D1=82=D0=BE=D0=BA?= =?UTF-8?q?=D0=B5=D0=BD=D0=BE=D0=B2=20=D0=B3=D1=80=D0=B0=D0=B4=D0=B8=D0=B5?= =?UTF-8?q?=D0=BD=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/FigmaGen/Dependencies.swift | 4 +- .../Tokens/Contexts/LinearGradientToken.swift | 19 +-- ...DefaultGradientTokensContextProvider.swift | 153 +++++++++++++++++- Sources/FigmaGen/Models/LinearGradient.swift | 15 ++ 4 files changed, 180 insertions(+), 11 deletions(-) diff --git a/Sources/FigmaGen/Dependencies.swift b/Sources/FigmaGen/Dependencies.swift index ff910bb..a307768 100644 --- a/Sources/FigmaGen/Dependencies.swift +++ b/Sources/FigmaGen/Dependencies.swift @@ -83,7 +83,9 @@ enum Dependencies { static let boxShadowTokensContextProvider: BoxShadowTokensContextProvider = DefaultBoxShadowTokensContextProvider() - static let gradientTokensContextProvider: GradientTokensContextProvider = DefaultGradientTokensContextProvider() + static let gradientTokensContextProvider: GradientTokensContextProvider = DefaultGradientTokensContextProvider( + tokensResolver: tokensResolver + ) // MARK: - diff --git a/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift b/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift index df7ff8f..53c4dfd 100644 --- a/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift +++ b/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift @@ -2,20 +2,21 @@ import Foundation struct LinearGradientToken: Encodable { - struct Stop: Encodable { - let color: ColorToken - let location: String + struct ColorStop: Encodable { + let color: String + let percentage: CGFloat } - struct ThemeValue: Encodable { - let stops: [Stop] - let angle: String + struct GradientThemeValue: Encodable { + let stops: [ColorStop] + let startPoint: CGPoint + let endPoint: CGPoint } let path: [String] let name: String - let dayTheme: ThemeValue - let nightTheme: ThemeValue - let zpDayTheme: ThemeValue + let dayTheme: GradientThemeValue + let nightTheme: GradientThemeValue + let zpDayTheme: GradientThemeValue } diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/Gradient/DefaultGradientTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/Gradient/DefaultGradientTokensContextProvider.swift index 62e51d2..9692c26 100644 --- a/Sources/FigmaGen/Generators/Tokens/Providers/Gradient/DefaultGradientTokensContextProvider.swift +++ b/Sources/FigmaGen/Generators/Tokens/Providers/Gradient/DefaultGradientTokensContextProvider.swift @@ -2,9 +2,160 @@ import Foundation struct DefaultGradientTokensContextProvider: GradientTokensContextProvider { + let tokensResolver: TokensResolver + + init(tokensResolver: TokensResolver) { + self.tokensResolver = tokensResolver + } + + // MARK: - Private methods + + private func resolvePoints(angle: CGFloat) -> (start: CGPoint, end: CGPoint)? { + let start = 3.0 * .pi / 2 + let u = start + angle + + let ucos = cos(u) + let usin = sin(u) + + let xedge = ucos > 0 ? 1.0 : 0 + let yedge = usin > 0 ? 1.0 : 0 + + let tx = ucos == 0 ? nil : (xedge - 0.5) / ucos + let ty = usin == 0 ? nil : (yedge - 0.5) / usin + + let t = [tx, ty] + .compactMap(\.self) + .filter { $0 > 0} + .min() + + guard let t else { + // Невозможно вычислить пересечение с границей + return nil + } + + let endPoint = CGPoint(x: 0.5 + t * ucos, y: 0.5 + t * usin) + let startPoint = CGPoint(x: 0.5 - t * ucos, y: 0.5 - t * usin) + + return (start: startPoint, end: endPoint) + } + + private func resolveThemeValue( + from gradient: LinearGradient, + tokenName: String + ) -> LinearGradientToken.GradientThemeValue? { + guard let points = resolvePoints(angle: gradient.radians) else { + return nil + } + + return LinearGradientToken.GradientThemeValue( + stops: gradient.colorStopList.compactMap { stop in + guard let percentage = Double(stop.percentage) else { + return nil + } + + return .init( + color: stop.color.hexString, + percentage: percentage + ) + }, + startPoint: points.start, + endPoint: points.end + ) + } + + private func resolveGradientToken( + tokenName: String, + fallbackColorToken: LinearGradientToken.GradientThemeValue, + tokenValues: TokenValues, + theme: Theme + ) throws -> LinearGradientToken.GradientThemeValue { + let themeData: (tokenValues: [TokenValue], warningPrefix: String) + switch theme { + case .night: + themeData = (tokenValues.hhNight, "Night") + + case .zpDay: + themeData = (tokenValues.zpDay, "ZpDay") + + case .day, .undefined: + themeData = ([], "") + } + + guard let themeToken = themeData.tokenValues.first(where: { $0.name == tokenName }) else { + return fallbackColorToken + } + + guard case .color(let themeValue) = themeToken.type else { + return fallbackColorToken + } + + let gradient = try tokensResolver.resolveLinearGradientValue( + themeValue, + tokenValues: tokenValues, + theme: theme + ) + + return resolveThemeValue(from: gradient, tokenName: tokenName) ?? fallbackColorToken + } + + private func createGradientToken( + _ gradientValue: String, + tokenName: String, + tokenValues: TokenValues + ) throws -> LinearGradientToken? { + let path = tokenName.components(separatedBy: ".") + let dayGradient = try tokensResolver.resolveLinearGradientValue( + gradientValue, + tokenValues: tokenValues, + theme: .day + ) + + guard let dayToken = resolveThemeValue(from: dayGradient, tokenName: tokenName) else { + return nil + } + + let nightToken = try resolveGradientToken( + tokenName: tokenName, + fallbackColorToken: dayToken, + tokenValues: tokenValues, + theme: .night + ) + + let zpDayToken = try resolveGradientToken( + tokenName: tokenName, + fallbackColorToken: dayToken, + tokenValues: tokenValues, + theme: .zpDay + ) + + return LinearGradientToken( + path: path, + name: tokenName, + dayTheme: dayToken, + nightTheme: nightToken, + zpDayTheme: zpDayToken + ) + } + + // TODO: @mi.fedorov поддержать мульти-темы + private func extractGradientToken( + from token: TokenValue, + tokenValues: TokenValues + ) throws -> LinearGradientToken? { + guard case .color(let dayValue) = token.type, dayValue.contains("gradient") else { + return nil + } + + return try createGradientToken(dayValue, tokenName: token.name, tokenValues: tokenValues) + } + // MARK: - GradientTokensContextProvider func extractContext(from tokenValues: TokenValues) throws -> [String : Any] { - [:] + let gradient = try tokenValues.hhDay.compactMap { + try extractGradientToken(from: $0, tokenValues: tokenValues) + } + + return [:] // TODO: Make structure } } diff --git a/Sources/FigmaGen/Models/LinearGradient.swift b/Sources/FigmaGen/Models/LinearGradient.swift index 92a0120..c97b708 100644 --- a/Sources/FigmaGen/Models/LinearGradient.swift +++ b/Sources/FigmaGen/Models/LinearGradient.swift @@ -17,3 +17,18 @@ struct LinearGradient: Codable, Hashable { let angle: String let colorStopList: [LinearColorStop] } + +extension LinearGradient { + + var radians: Double { + if angle.hasSuffix("deg"), let deg = Double(angle.replacingOccurrences(of: "deg", with: "")) { + return deg * .pi / 180 + } + + if angle.hasSuffix("rad"), let rad = Double(angle.replacingOccurrences(of: "rad", with: "")) { + return rad + } + + return Double(angle) ?? .zero + } +} From 90acb2bc3dfeef72c9d029931647db2f3ca73dab Mon Sep 17 00:00:00 2001 From: nschpy Date: Fri, 28 Mar 2025 01:48:28 +0300 Subject: [PATCH 09/23] =?UTF-8?q?=D0=93=D0=B5=D0=BD=D0=B5=D1=80=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=20=D0=B3=D1=80=D0=B0=D0=B4=D0=B8=D0=B5=D0=BD?= =?UTF-8?q?=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/FigmaGen/Dependencies.swift | 5 +- .../Tokens/Contexts/ColorToken.swift | 2 +- .../Tokens/Contexts/LinearGradientToken.swift | 2 +- .../Tokens/Contexts/TokenProtocol.swift | 12 ++++ .../Color/DefaultColorTokensGenerator.swift | 2 +- .../DefaultGradientTokensGenerator.swift | 10 +-- .../Theme/DefaultThemeTokensGenerator.swift | 9 ++- ...olorTokensContextProvider+Extensions.swift | 42 ++++++++++++ .../ColorTokensContextProvider.swift | 2 +- .../DefaultColorTokensContextProvider.swift | 38 +---------- ...DefaultGradientTokensContextProvider.swift | 26 +++++-- .../GradientTokensContextProvider.swift | 6 -- .../Resolver/DefaultTokensResolver.swift | 67 ++++++++++++++++--- .../Tokens/Resolver/TokensResolver.swift | 1 + .../Tokens/TokensTemplateConfiguration.swift | 2 +- Templates/GradientTokens.stencil | 48 ++++++++++++- 16 files changed, 202 insertions(+), 72 deletions(-) create mode 100644 Sources/FigmaGen/Generators/Tokens/Contexts/TokenProtocol.swift create mode 100644 Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/ColorTokensContextProvider+Extensions.swift rename Sources/FigmaGen/Generators/Tokens/Providers/{Gradient => ColorTokensContext}/DefaultGradientTokensContextProvider.swift (84%) delete mode 100644 Sources/FigmaGen/Generators/Tokens/Providers/Gradient/GradientTokensContextProvider.swift diff --git a/Sources/FigmaGen/Dependencies.swift b/Sources/FigmaGen/Dependencies.swift index a307768..8201736 100644 --- a/Sources/FigmaGen/Dependencies.swift +++ b/Sources/FigmaGen/Dependencies.swift @@ -83,7 +83,7 @@ enum Dependencies { static let boxShadowTokensContextProvider: BoxShadowTokensContextProvider = DefaultBoxShadowTokensContextProvider() - static let gradientTokensContextProvider: GradientTokensContextProvider = DefaultGradientTokensContextProvider( + static let gradientTokensContextProvider: ColorTokensContextProvider = DefaultGradientTokensContextProvider( tokensResolver: tokensResolver ) @@ -174,6 +174,7 @@ enum Dependencies { static let themeTokensGenerator: ThemeTokensGenerator = DefaultThemeTokensGenerator( colorTokensContextProvider: colorTokensContextProvider, + gradientTokensContextProvider: gradientTokensContextProvider, boxShadowsContextProvider: boxShadowTokensContextProvider, templateRenderer: templateRenderer ) @@ -190,7 +191,7 @@ enum Dependencies { static let gradientTokensGenerator: GradientTokensGenerator = DefaultGradientTokensGenerator( templateRenderer: templateRenderer, - provider: gradientTokensContextProvider + gradientProvider: gradientTokensContextProvider ) static let tokensGenerator: TokensGenerator = DefaultTokensGenerator( diff --git a/Sources/FigmaGen/Generators/Tokens/Contexts/ColorToken.swift b/Sources/FigmaGen/Generators/Tokens/Contexts/ColorToken.swift index 2a6e788..639ff65 100644 --- a/Sources/FigmaGen/Generators/Tokens/Contexts/ColorToken.swift +++ b/Sources/FigmaGen/Generators/Tokens/Contexts/ColorToken.swift @@ -1,6 +1,6 @@ import Foundation -struct ColorToken: Encodable { +struct ColorToken: TokenProtocol, Encodable { // MARK: - Nested Types diff --git a/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift b/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift index 53c4dfd..c74b046 100644 --- a/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift +++ b/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift @@ -1,6 +1,6 @@ import Foundation -struct LinearGradientToken: Encodable { +struct LinearGradientToken: TokenProtocol, Encodable { struct ColorStop: Encodable { let color: String diff --git a/Sources/FigmaGen/Generators/Tokens/Contexts/TokenProtocol.swift b/Sources/FigmaGen/Generators/Tokens/Contexts/TokenProtocol.swift new file mode 100644 index 0000000..d9198f3 --- /dev/null +++ b/Sources/FigmaGen/Generators/Tokens/Contexts/TokenProtocol.swift @@ -0,0 +1,12 @@ +import Foundation + +protocol TokenProtocol { + var name: String { get } + var path: [String] { get } +} + +extension TokenProtocol { + var name: String { + path.joined(separator: ".") + } +} diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/Color/DefaultColorTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/Color/DefaultColorTokensGenerator.swift index 88014fb..8e93fd6 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/Color/DefaultColorTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/Color/DefaultColorTokensGenerator.swift @@ -20,7 +20,7 @@ final class DefaultColorTokensGenerator: ColorTokensGenerator { // MARK: - Instance Methods func generate(renderParameters: RenderParameters, tokenValues: TokenValues) throws { - let context = try colorTokensContextProvider.fetchColorTokensContext(from: tokenValues) + let context = try colorTokensContextProvider.extractTokenContext(from: tokenValues) try templateRenderer.renderTemplate( renderParameters.template, diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/Gradient/DefaultGradientTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/Gradient/DefaultGradientTokensGenerator.swift index e2ce972..c347a5b 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/Gradient/DefaultGradientTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/Gradient/DefaultGradientTokensGenerator.swift @@ -5,25 +5,25 @@ struct DefaultGradientTokensGenerator: GradientTokensGenerator { // MARK: - Instance properties private let templateRenderer: TemplateRenderer - private let provider: GradientTokensContextProvider + private let provider: ColorTokensContextProvider init( templateRenderer: TemplateRenderer, - provider: GradientTokensContextProvider + gradientProvider: ColorTokensContextProvider ) { self.templateRenderer = templateRenderer - self.provider = provider + self.provider = gradientProvider } // MARK: - GradientTokensGenerator func generate(renderParameters: RenderParameters, tokenValues: TokenValues) throws { - let gradientContext = try provider.extractContext(from: tokenValues) + let gradientContext = try provider.extractTokenContext(from: tokenValues) try templateRenderer.renderTemplate( renderParameters.template, to: renderParameters.destination, - context: ["gradient": gradientContext] + context: ["gradients": gradientContext] ) } } diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/Theme/DefaultThemeTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/Theme/DefaultThemeTokensGenerator.swift index 5795c5f..782f478 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/Theme/DefaultThemeTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/Theme/DefaultThemeTokensGenerator.swift @@ -5,6 +5,7 @@ final class DefaultThemeTokensGenerator: ThemeTokensGenerator { // MARK: - Instance Properties let colorTokensContextProvider: ColorTokensContextProvider + let gradientTokensContextProvider: ColorTokensContextProvider let boxShadowsContextProvider: BoxShadowTokensContextProvider let templateRenderer: TemplateRenderer @@ -12,10 +13,12 @@ final class DefaultThemeTokensGenerator: ThemeTokensGenerator { init( colorTokensContextProvider: ColorTokensContextProvider, + gradientTokensContextProvider: ColorTokensContextProvider, boxShadowsContextProvider: BoxShadowTokensContextProvider, templateRenderer: TemplateRenderer ) { self.colorTokensContextProvider = colorTokensContextProvider + self.gradientTokensContextProvider = gradientTokensContextProvider self.boxShadowsContextProvider = boxShadowsContextProvider self.templateRenderer = templateRenderer } @@ -23,15 +26,17 @@ final class DefaultThemeTokensGenerator: ThemeTokensGenerator { // MARK: - Instance Methods func generate(renderParameters: RenderParameters, tokenValues: TokenValues) throws { - let colorsContext = try colorTokensContextProvider.fetchColorTokensContext(from: tokenValues) + let colorsContext = try colorTokensContextProvider.extractTokenContext(from: tokenValues) let boxShadowsContext = try boxShadowsContextProvider.fetchBoxShadowTokensContext(from: tokenValues) + let gradientsContext = try gradientTokensContextProvider.extractTokenContext(from: tokenValues) try templateRenderer.renderTemplate( renderParameters.template, to: renderParameters.destination, context: [ "colors": colorsContext, - "boxShadows": boxShadowsContext + "boxShadows": boxShadowsContext, + "gradients": gradientsContext ] ) } diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/ColorTokensContextProvider+Extensions.swift b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/ColorTokensContextProvider+Extensions.swift new file mode 100644 index 0000000..55de38d --- /dev/null +++ b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/ColorTokensContextProvider+Extensions.swift @@ -0,0 +1,42 @@ +import Foundation + +extension ColorTokensContextProvider { + + func structure( + tokens: [T], + atNamePath namePath: [String] = [], + contextName: String = "tokens" + ) -> [String: Any] { + var structuredTokens: [String: Any] = [:] + + if let name = namePath.last { + structuredTokens["name"] = name + } + + if !namePath.isEmpty { + structuredTokens["path"] = namePath + } + + let filteredTokens = tokens + .filter { $0.path.count == namePath.count + 1 } + .sorted { $0.name.lowercased() < $1.name.lowercased() } + + if !filteredTokens.isEmpty { + structuredTokens[contextName] = filteredTokens + } + + let childTokens = tokens.filter { $0.path.count > namePath.count + 1 } + + let children = Dictionary(grouping: childTokens) { $0.path[namePath.count] } + .sorted { $0.key < $1.key } + .map { name, tokens in + structure(tokens: tokens, atNamePath: namePath + [name], contextName: contextName) + } + + if !children.isEmpty { + structuredTokens["children"] = children + } + + return structuredTokens + } +} diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/ColorTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/ColorTokensContextProvider.swift index cbdfbce..785b0b8 100644 --- a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/ColorTokensContextProvider.swift +++ b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/ColorTokensContextProvider.swift @@ -4,5 +4,5 @@ protocol ColorTokensContextProvider { // MARK: - Instance Methods - func fetchColorTokensContext(from tokenValues: TokenValues) throws -> [String: Any] + func extractTokenContext(from tokenValues: TokenValues) throws -> [String: Any] } diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultColorTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultColorTokensContextProvider.swift index 8973278..10c25b9 100644 --- a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultColorTokensContextProvider.swift +++ b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultColorTokensContextProvider.swift @@ -101,43 +101,9 @@ final class DefaultColorTokensContextProvider: ColorTokensContextProvider { ) } - private func structure(tokenColors: [ColorToken], atNamePath namePath: [String] = []) -> [String: Any] { - var structuredColors: [String: Any] = [:] - - if let name = namePath.last { - structuredColors["name"] = name - } - - if !namePath.isEmpty { - structuredColors["path"] = namePath - } - - let colors = tokenColors - .filter { $0.path.count == namePath.count + 1 } - .sorted { $0.name.lowercased() < $1.name.lowercased() } - - if !colors.isEmpty { - structuredColors["colors"] = colors - } - - let childTokenColors = tokenColors.filter { $0.path.count > namePath.count + 1 } - - let children = Dictionary(grouping: childTokenColors) { $0.path[namePath.count] } - .sorted { $0.key < $1.key } - .map { name, colors in - structure(tokenColors: colors, atNamePath: namePath + [name]) - } - - if !children.isEmpty { - structuredColors["children"] = children - } - - return structuredColors - } - // MARK: - - func fetchColorTokensContext(from tokenValues: TokenValues) throws -> [String: Any] { + func extractTokenContext(from tokenValues: TokenValues) throws -> [String: Any] { let colors: [ColorToken] = try tokenValues.hhDay.compactMap { (token: TokenValue) in guard case .color(let dayValue) = token.type else { return nil @@ -157,6 +123,6 @@ final class DefaultColorTokensContextProvider: ColorTokensContextProvider { ) } - return structure(tokenColors: colors) + return structure(tokens: colors, contextName: "colors") } } diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/Gradient/DefaultGradientTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultGradientTokensContextProvider.swift similarity index 84% rename from Sources/FigmaGen/Generators/Tokens/Providers/Gradient/DefaultGradientTokensContextProvider.swift rename to Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultGradientTokensContextProvider.swift index 9692c26..62db6e8 100644 --- a/Sources/FigmaGen/Generators/Tokens/Providers/Gradient/DefaultGradientTokensContextProvider.swift +++ b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultGradientTokensContextProvider.swift @@ -1,6 +1,6 @@ import Foundation -struct DefaultGradientTokensContextProvider: GradientTokensContextProvider { +struct DefaultGradientTokensContextProvider: ColorTokensContextProvider { let tokensResolver: TokensResolver @@ -49,7 +49,8 @@ struct DefaultGradientTokensContextProvider: GradientTokensContextProvider { return LinearGradientToken.GradientThemeValue( stops: gradient.colorStopList.compactMap { stop in - guard let percentage = Double(stop.percentage) else { + let percentage = stop.percentage.replacingOccurrences(of: "%", with: "") + guard let percentage = Double(percentage) else { return nil } @@ -101,9 +102,9 @@ struct DefaultGradientTokensContextProvider: GradientTokensContextProvider { private func createGradientToken( _ gradientValue: String, tokenName: String, + path: [String], tokenValues: TokenValues ) throws -> LinearGradientToken? { - let path = tokenName.components(separatedBy: ".") let dayGradient = try tokensResolver.resolveLinearGradientValue( gradientValue, tokenValues: tokenValues, @@ -142,20 +143,31 @@ struct DefaultGradientTokensContextProvider: GradientTokensContextProvider { from token: TokenValue, tokenValues: TokenValues ) throws -> LinearGradientToken? { - guard case .color(let dayValue) = token.type, dayValue.contains("gradient") else { + let path = token.name.components(separatedBy: ".") + + guard + case .color(let dayValue) = token.type, + dayValue.contains("gradient"), + path[0] != "color" + else { return nil } - return try createGradientToken(dayValue, tokenName: token.name, tokenValues: tokenValues) + return try createGradientToken( + dayValue, + tokenName: token.name, + path: path, + tokenValues: tokenValues + ) } // MARK: - GradientTokensContextProvider - func extractContext(from tokenValues: TokenValues) throws -> [String : Any] { + func extractTokenContext(from tokenValues: TokenValues) throws -> [String : Any] { let gradient = try tokenValues.hhDay.compactMap { try extractGradientToken(from: $0, tokenValues: tokenValues) } - return [:] // TODO: Make structure + return structure(tokens: gradient, contextName: "gradient") } } diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/Gradient/GradientTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/Gradient/GradientTokensContextProvider.swift deleted file mode 100644 index 940f3b7..0000000 --- a/Sources/FigmaGen/Generators/Tokens/Providers/Gradient/GradientTokensContextProvider.swift +++ /dev/null @@ -1,6 +0,0 @@ -import Foundation - -protocol GradientTokensContextProvider { - - func extractContext(from tokenValues: TokenValues) throws -> [String : Any] -} diff --git a/Sources/FigmaGen/Generators/Tokens/Resolver/DefaultTokensResolver.swift b/Sources/FigmaGen/Generators/Tokens/Resolver/DefaultTokensResolver.swift index c4bd3f2..3d0266c 100644 --- a/Sources/FigmaGen/Generators/Tokens/Resolver/DefaultTokensResolver.swift +++ b/Sources/FigmaGen/Generators/Tokens/Resolver/DefaultTokensResolver.swift @@ -68,6 +68,45 @@ final class DefaultTokensResolver: TokensResolver { return try makeColor(hex: value, alpha: 1.0) } + private func resolveRGBAWithHex( + hex: String, + alphaPercent: String, + value: String + ) throws -> Color { + let alpha = alphaPercent.replacingOccurrences(of: "%", with: "") + guard let alpha = Double(alpha) else { + throw TokensGeneratorError(code: .invalidAlphaComponent(alpha: alphaPercent + value)) + } + + return try makeColor(hex: hex, alpha: alpha / 100.0) + } + + private func resolveRGBA( + red: String, + green: String, + blue: String, + alpha: String, + rgbaValue: String + ) throws -> Color { + guard + let red = Double(red), + let green = Double(green), + let blue = Double(blue), + let alpha = Double(alpha) + else { + throw TokensGeneratorError(code: .invalidRGBAColorValue(rgba: rgbaValue)) + } + + let normalizationFactor: CGFloat = 255.0 + + return Color( + red: CGFloat(red) / normalizationFactor, + green: CGFloat(green) / normalizationFactor, + blue: CGFloat(blue) / normalizationFactor, + alpha: alpha + ) + } + // MARK: - TokensResolver func resolveValue(_ value: String, tokenValues: TokenValues, theme: Theme) throws -> String { @@ -127,18 +166,28 @@ final class DefaultTokensResolver: TokensResolver { .slice(from: "(", to: ")", includingBounds: false)? .components(separatedBy: ", ") - guard let components, components.count == 2 else { + guard let components else { throw TokensGeneratorError(code: .invalidRGBAColorValue(rgba: value)) } - let hex = components[0] - let alphaPercent = components[1] - - guard let alpha = Double(alphaPercent.dropLast()) else { - throw TokensGeneratorError(code: .invalidAlphaComponent(alpha: alphaPercent)) + switch components.count { + case .rgbaWithHex: + return try resolveRGBAWithHex( + hex: components[0], + alphaPercent: components[1], + value: value + ) + case .rgba: + return try resolveRGBA( + red: components[0], + green: components[1], + blue: components[2], + alpha: components[3], + rgbaValue: value + ) + default: + throw TokensGeneratorError(code: .invalidRGBAColorValue(rgba: value)) } - - return try makeColor(hex: hex, alpha: alpha / 100.0) } func resolveHexColorValue(_ value: String, tokenValues: TokenValues, theme: Theme) throws -> String { @@ -193,4 +242,6 @@ extension Int { fileprivate static let rgb = 3 fileprivate static let rrggbb = 6 + fileprivate static let rgbaWithHex = 2 + fileprivate static let rgba = 4 } diff --git a/Sources/FigmaGen/Generators/Tokens/Resolver/TokensResolver.swift b/Sources/FigmaGen/Generators/Tokens/Resolver/TokensResolver.swift index 81f7eb0..9cf1aba 100644 --- a/Sources/FigmaGen/Generators/Tokens/Resolver/TokensResolver.swift +++ b/Sources/FigmaGen/Generators/Tokens/Resolver/TokensResolver.swift @@ -34,6 +34,7 @@ protocol TokensResolver { /// /// Supported formats: /// - `rgba(hex_color, alpha-value-percentage)` + /// – `rgba(red, green, blue, alpha-value-percentage)` /// - TO DO: Support more formats /// /// [Color tokens examples and should be supported later](https://docs.tokens.studio/available-tokens/color-tokens#solid-colors) diff --git a/Sources/FigmaGen/Models/Configuration/Tokens/TokensTemplateConfiguration.swift b/Sources/FigmaGen/Models/Configuration/Tokens/TokensTemplateConfiguration.swift index 9ceeb54..532368c 100644 --- a/Sources/FigmaGen/Models/Configuration/Tokens/TokensTemplateConfiguration.swift +++ b/Sources/FigmaGen/Models/Configuration/Tokens/TokensTemplateConfiguration.swift @@ -53,6 +53,6 @@ extension TokensTemplateConfiguration: Decodable { theme = try container.decodeIfPresent(TemplateConfigurationWrapper.self, forKey: .theme)?.templates spacing = try container.decodeIfPresent(TemplateConfigurationWrapper.self, forKey: .spacing)?.templates borders = try? container.decodeIfPresent(TemplateConfigurationWrapper.self, forKey: .borders)?.templates - gradient = try? container.decodeIfPresent(TemplateConfigurationWrapper.self, forKey: .borders)?.templates + gradient = try? container.decodeIfPresent(TemplateConfigurationWrapper.self, forKey: .gradient)?.templates } } diff --git a/Templates/GradientTokens.stencil b/Templates/GradientTokens.stencil index 17e803c..5eb6714 100644 --- a/Templates/GradientTokens.stencil +++ b/Templates/GradientTokens.stencil @@ -1 +1,47 @@ -# TODO: mi.fedorov доделать шаблон +{% include "FileHeader.stencil" %} +{% if gradients %} +{% set gradientTypeName %}{{ options.colorTypeName|default:"LinearGradient" }}{% endset %} +{% macro propertyName name %}{{ name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords }}{% endmacro %} +{% macro typeName name %}{{ name|swiftIdentifier:"pretty"|upperFirstLetter|escapeReservedKeywords }}{% endmacro %} +{% macro recursiveBlock item %} + {% for gradient in item.gradient %} + + /// {{ gradient.name }} + /// + /// Day Theme: + {% for stop in gradient.dayTheme.stops %} + /// - {{ stop.color }} {{ stop.percentage }}% + {% endfor %} + /// Night Theme: + {% for stop in gradient.nightTheme.stops %} + /// - {{ stop.color }} {{ stop.percentage }}% + {% endfor %} + public let {% call propertyName gradient.path.last %}: {{ gradientTypeName }} + {% endfor %} + {% for child in item.children %} + {% if child.name == "gradient" %} + {% call recursiveBlock child %} + {% else %} + public struct {% call typeName child.name %} { + {% filter indent:4 %} + {% call recursiveBlock child %} + {% endfilter %} + } + + public let {% call propertyName child.name %}: {% call typeName child.name %} + {% endif %} + {% endfor %} +{% endmacro %} + +import SwiftUI + +public struct Gradients { + {% if gradients %} + {% call recursiveBlock gradients %} + {% else %} + // No gradient tokens found + {% endif %} +} +{% else %} +// No color tokens found +{% endif %} From e80f6ca1c5968742bb50c180781c763b0f8d4fae Mon Sep 17 00:00:00 2001 From: nschpy Date: Fri, 28 Mar 2025 19:06:47 +0300 Subject: [PATCH 10/23] =?UTF-8?q?=D0=9D=D0=B5=D0=B1=D0=BE=D0=BB=D1=8C?= =?UTF-8?q?=D1=88=D0=B8=D0=B5=20=D1=83=D0=BB=D1=83=D1=87=D1=88=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Tokens/Contexts/LinearGradientToken.swift | 10 ++++++++-- .../DefaultGradientTokensContextProvider.swift | 12 +++++++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift b/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift index c74b046..36e0023 100644 --- a/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift +++ b/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift @@ -7,10 +7,16 @@ struct LinearGradientToken: TokenProtocol, Encodable { let percentage: CGFloat } + // Нужен, т.к CGPoint нельзя использовать корректно в stencil шаблоне + struct Point: Encodable { + let x: CGFloat + let y: CGFloat + } + struct GradientThemeValue: Encodable { let stops: [ColorStop] - let startPoint: CGPoint - let endPoint: CGPoint + let startPoint: Point + let endPoint: Point } let path: [String] diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultGradientTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultGradientTokensContextProvider.swift index 62db6e8..5118544 100644 --- a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultGradientTokensContextProvider.swift +++ b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultGradientTokensContextProvider.swift @@ -59,8 +59,14 @@ struct DefaultGradientTokensContextProvider: ColorTokensContextProvider { percentage: percentage ) }, - startPoint: points.start, - endPoint: points.end + startPoint: LinearGradientToken.Point( + x: points.start.x, + y: points.start.y + ), + endPoint: LinearGradientToken.Point( + x: points.end.x, + y: points.end.y + ) ) } @@ -168,6 +174,6 @@ struct DefaultGradientTokensContextProvider: ColorTokensContextProvider { try extractGradientToken(from: $0, tokenValues: tokenValues) } - return structure(tokens: gradient, contextName: "gradient") + return structure(tokens: gradient, contextName: "gradients") } } From 82439e9e4f4c4b254825e554fce5cc910441d986 Mon Sep 17 00:00:00 2001 From: nschpy Date: Fri, 28 Mar 2025 22:26:09 +0300 Subject: [PATCH 11/23] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D0=B7=D0=BD=D0=B0=D1=87=D0=B5=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=20=D0=BF=D1=80=D0=BE=D1=86=D0=B5=D0=BD=D1=82=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=B2=20=D1=82=D0=BE=D0=BA=D0=B5=D0=BD=D0=B5=20=D0=B3=D1=80?= =?UTF-8?q?=D0=B0=D0=B4=D0=B8=D0=B5=D0=BD=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DefaultGradientTokensContextProvider.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultGradientTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultGradientTokensContextProvider.swift index 5118544..6d8df5d 100644 --- a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultGradientTokensContextProvider.swift +++ b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultGradientTokensContextProvider.swift @@ -56,7 +56,7 @@ struct DefaultGradientTokensContextProvider: ColorTokensContextProvider { return .init( color: stop.color.hexString, - percentage: percentage + percentage: percentage / 100 ) }, startPoint: LinearGradientToken.Point( From 904e57ddad535bae0542fb4201d757f48c406cb0 Mon Sep 17 00:00:00 2001 From: nschpy Date: Fri, 28 Mar 2025 22:33:30 +0300 Subject: [PATCH 12/23] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=B1=D0=B0?= =?UTF-8?q?=D0=B7=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE=20=D1=88=D0=B0=D0=B1=D0=BB?= =?UTF-8?q?=D0=BE=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Templates/GradientTokens.stencil | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Templates/GradientTokens.stencil b/Templates/GradientTokens.stencil index 5eb6714..8f1a445 100644 --- a/Templates/GradientTokens.stencil +++ b/Templates/GradientTokens.stencil @@ -4,7 +4,7 @@ {% macro propertyName name %}{{ name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords }}{% endmacro %} {% macro typeName name %}{{ name|swiftIdentifier:"pretty"|upperFirstLetter|escapeReservedKeywords }}{% endmacro %} {% macro recursiveBlock item %} - {% for gradient in item.gradient %} + {% for gradient in item.gradients %} /// {{ gradient.name }} /// @@ -36,11 +36,7 @@ import SwiftUI public struct Gradients { - {% if gradients %} {% call recursiveBlock gradients %} - {% else %} - // No gradient tokens found - {% endif %} } {% else %} // No color tokens found From 0ae8760641f8345f2164141e4f8d2be087509987 Mon Sep 17 00:00:00 2001 From: nschpy Date: Tue, 1 Apr 2025 00:35:48 +0300 Subject: [PATCH 13/23] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B4=D0=B8=D0=BD=D0=B0=D0=BC=D0=B8?= =?UTF-8?q?=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D1=85=20=D1=82=D0=B5=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Tokens/Contexts/ColorToken.swift | 6 +- .../Tokens/DefaultTokensGenerator.swift | 44 ++++++++--- ...ltTokensGenerationParametersResolver.swift | 5 ++ .../DefaultBaseColorTokensGenerator.swift | 13 +++- .../Generators/BaseTokenGenerator.swift | 7 +- .../DefaultBorderTokensGenerator.swift | 11 ++- .../DefaultBoxShadowTokensGenerator.swift | 7 +- .../Color/DefaultColorTokensGenerator.swift | 8 +- .../DefaultFontFamilyTokensGenerator.swift | 7 +- .../DefaultGradientTokensGenerator.swift | 13 +++- .../DefaultSpacingTokensGenerator.swift | 9 ++- .../Theme/DefaultThemeTokensGenerator.swift | 19 ++++- .../DefaultTypographyTokensGenerator.swift | 17 ++-- .../ColorTokensContextProvider.swift | 6 +- .../DefaultColorTokensContextProvider.swift | 78 +++++++++---------- .../Resolver/DefaultTokensResolver.swift | 10 +-- .../Tokens/Resolver/TokensResolver.swift | 8 +- .../Tokens/TokenThemesConfiguration.swift | 11 +++ .../Tokens/TokensConfiguration.swift | 5 ++ .../TokensGenerationParameters.swift | 2 + Sources/FigmaGen/Models/Token/Theme.swift | 37 +++++++-- .../FigmaGen/Models/Token/TokenValues.swift | 71 ++++++++++------- 22 files changed, 270 insertions(+), 124 deletions(-) create mode 100644 Sources/FigmaGen/Models/Configuration/Tokens/TokenThemesConfiguration.swift diff --git a/Sources/FigmaGen/Generators/Tokens/Contexts/ColorToken.swift b/Sources/FigmaGen/Generators/Tokens/Contexts/ColorToken.swift index 639ff65..44f01c8 100644 --- a/Sources/FigmaGen/Generators/Tokens/Contexts/ColorToken.swift +++ b/Sources/FigmaGen/Generators/Tokens/Contexts/ColorToken.swift @@ -4,7 +4,7 @@ struct ColorToken: TokenProtocol, Encodable { // MARK: - Nested Types - struct Theme: Encodable { + struct ColorValue: Encodable { // MARK: - Instance Properties @@ -14,9 +14,7 @@ struct ColorToken: TokenProtocol, Encodable { // MARK: - Instance Properties - let dayTheme: Theme - let nightTheme: Theme - let zpDayTheme: Theme let name: String let path: [String] + let themedValue: [Theme: ColorValue] } diff --git a/Sources/FigmaGen/Generators/Tokens/DefaultTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/DefaultTokensGenerator.swift index 135cb61..317e5a5 100644 --- a/Sources/FigmaGen/Generators/Tokens/DefaultTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/DefaultTokensGenerator.swift @@ -76,7 +76,9 @@ final class DefaultTokensGenerator: TokensGenerator { try generateTokens( spacingTokensGenerator, renderParameters: parameters.tokens.spacingRenderParameters, - tokenValues: tokenValues + tokenValues: tokenValues, + themes: parameters.themes, + fallbackTheme: parameters.fallbackTheme ) } @@ -84,7 +86,9 @@ final class DefaultTokensGenerator: TokensGenerator { try generateTokens( themeTokensGenerator, renderParameters: parameters.tokens.themeRenderParameters, - tokenValues: tokenValues + tokenValues: tokenValues, + themes: parameters.themes, + fallbackTheme: parameters.fallbackTheme ) } @@ -92,7 +96,9 @@ final class DefaultTokensGenerator: TokensGenerator { try generateTokens( boxShadowTokensGenerator, renderParameters: parameters.tokens.boxShadowRenderParameters, - tokenValues: tokenValues + tokenValues: tokenValues, + themes: parameters.themes, + fallbackTheme: parameters.fallbackTheme ) } @@ -100,7 +106,9 @@ final class DefaultTokensGenerator: TokensGenerator { try generateTokens( typographyTokensGenerator, renderParameters: parameters.tokens.typographyRenderParameters, - tokenValues: tokenValues + tokenValues: tokenValues, + themes: parameters.themes, + fallbackTheme: parameters.fallbackTheme ) } @@ -108,7 +116,9 @@ final class DefaultTokensGenerator: TokensGenerator { try generateTokens( fontFamilyTokensGenerator, renderParameters: parameters.tokens.fontFamilyRenderParameters, - tokenValues: tokenValues + tokenValues: tokenValues, + themes: parameters.themes, + fallbackTheme: parameters.fallbackTheme ) } @@ -116,7 +126,9 @@ final class DefaultTokensGenerator: TokensGenerator { try generateTokens( baseColorTokensGenerator, renderParameters: parameters.tokens.baseColorRenderParameters, - tokenValues: tokenValues + tokenValues: tokenValues, + themes: parameters.themes, + fallbackTheme: parameters.fallbackTheme ) } @@ -124,7 +136,9 @@ final class DefaultTokensGenerator: TokensGenerator { try generateTokens( colorTokensGenerator, renderParameters: parameters.tokens.colorRenderParameters, - tokenValues: tokenValues + tokenValues: tokenValues, + themes: parameters.themes, + fallbackTheme: parameters.fallbackTheme ) } @@ -132,7 +146,9 @@ final class DefaultTokensGenerator: TokensGenerator { try generateTokens( bordersTokensGenerator, renderParameters: parameters.tokens.bordersRenderParameters, - tokenValues: tokenValues + tokenValues: tokenValues, + themes: parameters.themes, + fallbackTheme: parameters.fallbackTheme ) } @@ -140,20 +156,26 @@ final class DefaultTokensGenerator: TokensGenerator { try generateTokens( gradientTokensGenerator, renderParameters: parameters.tokens.gradientRenderParameters, - tokenValues: tokenValues + tokenValues: tokenValues, + themes: parameters.themes, + fallbackTheme: parameters.fallbackTheme ) } private func generateTokens( _ generator: BaseTokenGenerator, renderParameters: [RenderParameters]?, - tokenValues: TokenValues + tokenValues: TokenValues, + themes: [Theme], + fallbackTheme: Theme ) throws { if let renderParametersList = renderParameters { for params in renderParametersList { try generator.generate( renderParameters: params, - tokenValues: tokenValues + tokenValues: tokenValues, + themes: themes, + fallbackTheme: fallbackTheme ) } } diff --git a/Sources/FigmaGen/Generators/Tokens/GenerationParametersResolver/DefaultTokensGenerationParametersResolver.swift b/Sources/FigmaGen/Generators/Tokens/GenerationParametersResolver/DefaultTokensGenerationParametersResolver.swift index 0c68907..099e831 100644 --- a/Sources/FigmaGen/Generators/Tokens/GenerationParametersResolver/DefaultTokensGenerationParametersResolver.swift +++ b/Sources/FigmaGen/Generators/Tokens/GenerationParametersResolver/DefaultTokensGenerationParametersResolver.swift @@ -50,6 +50,9 @@ final class DefaultTokensGenerationParametersResolver: TokensGenerationParameter ) } + let themes = configuration.themesConfiguration?.themes ?? [.light, .dark] + let fallbackTheme = configuration.themesConfiguration?.fallbackTheme ?? .light + if file.isNil && remoteFile.isNil { throw GenerationParametersError.invalidFileConfiguration } @@ -102,6 +105,8 @@ final class DefaultTokensGenerationParametersResolver: TokensGenerationParameter return TokensGenerationParameters( file: file, remoteFile: remoteFile, + themes: themes, + fallbackTheme: fallbackTheme, tokens: TokensGenerationParameters.TokensParameters( colorRenderParameters: colorRenderParameters, baseColorRenderParameters: baseColorRenderParameters, diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/BaseColor/DefaultBaseColorTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/BaseColor/DefaultBaseColorTokensGenerator.swift index 099fb13..848e6d1 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/BaseColor/DefaultBaseColorTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/BaseColor/DefaultBaseColorTokensGenerator.swift @@ -23,13 +23,22 @@ final class DefaultBaseColorTokensGenerator: BaseColorTokensGenerator { return BaseColorToken( path: token.name.components(separatedBy: "."), - value: try tokensResolver.resolveHexColorValue(value, tokenValues: tokenValues, theme: .undefined) + value: try tokensResolver.resolveHexColorValue( + value, + tokenValues: tokenValues, + theme: nil + ) ) } // MARK: - - func generate(renderParameters: RenderParameters, tokenValues: TokenValues) throws { + func generate( + renderParameters: RenderParameters, + tokenValues: TokenValues, + themes: [Theme], + fallbackTheme: Theme + ) throws { let colors = try tokenValues.colors.compactMap { try makeBaseColorToken(from: $0, tokenValues: tokenValues) } try templateRenderer.renderTemplate( diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/BaseTokenGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/BaseTokenGenerator.swift index 78792b3..01fbe5e 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/BaseTokenGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/BaseTokenGenerator.swift @@ -4,5 +4,10 @@ protocol BaseTokenGenerator { // MARK: - Instance Methods - func generate(renderParameters: RenderParameters, tokenValues: TokenValues) throws + func generate( + renderParameters: RenderParameters, + tokenValues: TokenValues, + themes: [Theme], + fallbackTheme: Theme + ) throws } diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/Borders/DefaultBorderTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/Borders/DefaultBorderTokensGenerator.swift index a52e7fc..34b9a45 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/Borders/DefaultBorderTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/Borders/DefaultBorderTokensGenerator.swift @@ -29,7 +29,7 @@ struct DefaultBorderTokensGenerator: BorderTokensGenerator { width: try tokensResolver.resolveValue( value.width, tokenValues: tokens, - theme: .undefined + theme: nil ), style: value.style ) @@ -48,7 +48,7 @@ struct DefaultBorderTokensGenerator: BorderTokensGenerator { value: try tokensResolver.resolveValue( value, tokenValues: tokens, - theme: .undefined + theme: nil ) ) } @@ -74,7 +74,12 @@ struct DefaultBorderTokensGenerator: BorderTokensGenerator { // MARK: - BorderTokensGenerator - func generate(renderParameters: RenderParameters, tokenValues: TokenValues) throws { + func generate( + renderParameters: RenderParameters, + tokenValues: TokenValues, + themes: [Theme], + fallbackTheme: Theme + ) throws { let coreBorderData = try extractBorderData(from: tokenValues.core, tokenValues: tokenValues) let semanticBorderData = try extractBorderData(from: tokenValues.semantic, tokenValues: tokenValues) diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/BoxShadow/DefaultBoxShadowTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/BoxShadow/DefaultBoxShadowTokensGenerator.swift index 14847a6..a10dd52 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/BoxShadow/DefaultBoxShadowTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/BoxShadow/DefaultBoxShadowTokensGenerator.swift @@ -16,7 +16,12 @@ final class DefaultBoxShadowTokensGenerator: BoxShadowTokensGenerator { // MARK: - Instance Methods - func generate(renderParameters: RenderParameters, tokenValues: TokenValues) throws { + func generate( + renderParameters: RenderParameters, + tokenValues: TokenValues, + themes: [Theme], + fallbackTheme: Theme + ) throws { let boxShadows = try boxShadowTokensContextProvider.fetchBoxShadowTokensContext(from: tokenValues) try templateRenderer.renderTemplate( diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/Color/DefaultColorTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/Color/DefaultColorTokensGenerator.swift index 8e93fd6..7c730fc 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/Color/DefaultColorTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/Color/DefaultColorTokensGenerator.swift @@ -19,8 +19,12 @@ final class DefaultColorTokensGenerator: ColorTokensGenerator { // MARK: - Instance Methods - func generate(renderParameters: RenderParameters, tokenValues: TokenValues) throws { - let context = try colorTokensContextProvider.extractTokenContext(from: tokenValues) + func generate(renderParameters: RenderParameters, tokenValues: TokenValues, themes: [Theme], fallbackTheme: Theme) throws { + let context = try colorTokensContextProvider.extractTokenContext( + from: tokenValues, + themes: themes, + fallbackTheme: fallbackTheme + ) try templateRenderer.renderTemplate( renderParameters.template, diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/FontFamily/DefaultFontFamilyTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/FontFamily/DefaultFontFamilyTokensGenerator.swift index 6d4d997..53ba107 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/FontFamily/DefaultFontFamilyTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/FontFamily/DefaultFontFamilyTokensGenerator.swift @@ -44,7 +44,12 @@ final class DefaultFontFamilyTokensGenerator: FontFamilyTokensGenerator { // MARK: - - func generate(renderParameters: RenderParameters, tokenValues: TokenValues) throws { + func generate( + renderParameters: RenderParameters, + tokenValues: TokenValues, + themes: [Theme], + fallbackTheme: Theme + ) throws { let fontFamilyTokens = try makeFontFamilyTokens(tokenValues: tokenValues) let fontWeightTokens = try makeFontWightTokens(tokenValues: tokenValues) diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/Gradient/DefaultGradientTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/Gradient/DefaultGradientTokensGenerator.swift index c347a5b..91db52d 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/Gradient/DefaultGradientTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/Gradient/DefaultGradientTokensGenerator.swift @@ -17,8 +17,17 @@ struct DefaultGradientTokensGenerator: GradientTokensGenerator { // MARK: - GradientTokensGenerator - func generate(renderParameters: RenderParameters, tokenValues: TokenValues) throws { - let gradientContext = try provider.extractTokenContext(from: tokenValues) + func generate( + renderParameters: RenderParameters, + tokenValues: TokenValues, + themes: [Theme], + fallbackTheme: Theme + ) throws { + let gradientContext = try provider.extractTokenContext( + from: tokenValues, + themes: themes, + fallbackTheme: fallbackTheme + ) try templateRenderer.renderTemplate( renderParameters.template, diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/Spacing/DefaultSpacingTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/Spacing/DefaultSpacingTokensGenerator.swift index 13f4c2d..8c978f1 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/Spacing/DefaultSpacingTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/Spacing/DefaultSpacingTokensGenerator.swift @@ -23,13 +23,18 @@ final class DefaultSpacingTokensGenerator: SpacingTokensGenerator { return SpacingToken( path: token.name.components(separatedBy: "."), - value: try tokensResolver.resolveValue(value, tokenValues: tokenValues, theme: .undefined) + value: try tokensResolver.resolveValue(value, tokenValues: tokenValues, theme: nil) ) } // MARK: - - func generate(renderParameters: RenderParameters, tokenValues: TokenValues) throws { + func generate( + renderParameters: RenderParameters, + tokenValues: TokenValues, + themes: [Theme], + fallbackTheme: Theme + ) throws { let coreSpacings = try tokenValues.core.compactMap { value in try makeSpacingToken(from: value, tokenValues: tokenValues) } diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/Theme/DefaultThemeTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/Theme/DefaultThemeTokensGenerator.swift index 782f478..1b863e9 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/Theme/DefaultThemeTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/Theme/DefaultThemeTokensGenerator.swift @@ -25,10 +25,23 @@ final class DefaultThemeTokensGenerator: ThemeTokensGenerator { // MARK: - Instance Methods - func generate(renderParameters: RenderParameters, tokenValues: TokenValues) throws { - let colorsContext = try colorTokensContextProvider.extractTokenContext(from: tokenValues) + func generate( + renderParameters: RenderParameters, + tokenValues: TokenValues, + themes: [Theme], + fallbackTheme: Theme + ) throws { + let colorsContext = try colorTokensContextProvider.extractTokenContext( + from: tokenValues, + themes: themes, + fallbackTheme: fallbackTheme + ) + let gradientsContext = try gradientTokensContextProvider.extractTokenContext( + from: tokenValues, + themes: themes, + fallbackTheme: fallbackTheme + ) let boxShadowsContext = try boxShadowsContextProvider.fetchBoxShadowTokensContext(from: tokenValues) - let gradientsContext = try gradientTokensContextProvider.extractTokenContext(from: tokenValues) try templateRenderer.renderTemplate( renderParameters.template, diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/Typography/DefaultTypographyTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/Typography/DefaultTypographyTokensGenerator.swift index ecd8a12..ea3d501 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/Typography/DefaultTypographyTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/Typography/DefaultTypographyTokensGenerator.swift @@ -24,7 +24,7 @@ final class DefaultTypographyTokensGenerator: TypographyTokensGenerator { let lineHeightResolvedValue = try tokensResolver.resolveValue( lineHeightValue, tokenValues: tokenValues, - theme: .undefined + theme: nil ) guard lineHeightResolvedValue.hasSuffix("%") else { @@ -35,7 +35,7 @@ final class DefaultTypographyTokensGenerator: TypographyTokensGenerator { } let fontSize = Double( - try tokensResolver.resolveValue(value.fontSize, tokenValues: tokenValues, theme: .undefined) + try tokensResolver.resolveValue(value.fontSize, tokenValues: tokenValues, theme: nil) ) let lineHeight = Double(lineHeightResolvedValue.dropLast()).map { $0 / 100.0 } @@ -65,12 +65,12 @@ final class DefaultTypographyTokensGenerator: TypographyTokensGenerator { let letterSpacing = Double( try tokensResolver - .resolveValue(letterSpacingValue, tokenValues: tokenValues, theme: .undefined) + .resolveValue(letterSpacingValue, tokenValues: tokenValues, theme: nil) .removingFirst("%") ).map { $0 / 100.0 } let fontSize = Double( - try tokensResolver.resolveValue(value.fontSize, tokenValues: tokenValues, theme: .undefined) + try tokensResolver.resolveValue(value.fontSize, tokenValues: tokenValues, theme: nil) ) guard let fontSize else { @@ -92,7 +92,7 @@ final class DefaultTypographyTokensGenerator: TypographyTokensGenerator { private func makeContextToken(value: String, tokenValues: TokenValues) throws -> ContextToken { ContextToken( path: value.components(separatedBy: "."), - value: try tokensResolver.resolveValue(value, tokenValues: tokenValues, theme: .undefined) + value: try tokensResolver.resolveValue(value, tokenValues: tokenValues, theme: nil) ) } @@ -164,7 +164,12 @@ final class DefaultTypographyTokensGenerator: TypographyTokensGenerator { // MARK: - - func generate(renderParameters: RenderParameters, tokenValues: TokenValues) throws { + func generate( + renderParameters: RenderParameters, + tokenValues: TokenValues, + themes: [Theme], + fallbackTheme: Theme + ) throws { let tokens = try makeTypographyTokens(tokenValues: tokenValues) try templateRenderer.renderTemplate( diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/ColorTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/ColorTokensContextProvider.swift index 785b0b8..1f327a2 100644 --- a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/ColorTokensContextProvider.swift +++ b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/ColorTokensContextProvider.swift @@ -4,5 +4,9 @@ protocol ColorTokensContextProvider { // MARK: - Instance Methods - func extractTokenContext(from tokenValues: TokenValues) throws -> [String: Any] + func extractTokenContext( + from tokenValues: TokenValues, + themes: [Theme], + fallbackTheme: Theme + ) throws -> [String: Any] } diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultColorTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultColorTokensContextProvider.swift index 10c25b9..fa14784 100644 --- a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultColorTokensContextProvider.swift +++ b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultColorTokensContextProvider.swift @@ -20,22 +20,12 @@ final class DefaultColorTokensContextProvider: ColorTokensContextProvider { private func resolveColorToken( tokenName: String, - fallbackColorToken: ColorToken.Theme, + fallbackColorToken: ColorToken.ColorValue, tokenValues: TokenValues, theme: Theme - ) throws -> ColorToken.Theme { - // Resolve theme data - let themeData: (tokenValues: [TokenValue], warningPrefix: String) - switch theme { - case .night: - themeData = (tokenValues.hhNight, "Night") - - case .zpDay: - themeData = (tokenValues.zpDay, "ZpDay") - - case .day, .undefined: - themeData = ([], "") - } + ) throws -> ColorToken.ColorValue { + let tokens = tokenValues.tokens(for: theme) + let themeData: (tokenValues: [TokenValue], warningPrefix: String) = (tokens, theme.key) // Resolve token and value guard let themeToken = themeData.tokenValues.first(where: { $0.name == tokenName }) else { @@ -58,53 +48,55 @@ final class DefaultColorTokensContextProvider: ColorTokensContextProvider { // Resolve reference let themeReference = try tokensResolver.resolveBaseReference(themeValue, tokenValues: themeData.tokenValues) - return ColorToken.Theme(value: themeHexColorValue, reference: themeReference) + return ColorToken.ColorValue(value: themeHexColorValue, reference: themeReference) } private func makeColorToken( - dayValue: String, + baseTokenValue: String, tokenName: String, tokenValues: TokenValues, - path: [String] + path: [String], + themes: [Theme], + fallbackTheme: Theme ) throws -> ColorToken { - let dayColorToken = ColorToken.Theme( + let fallbackColorToken = ColorToken.ColorValue( value: try tokensResolver.resolveHexColorValue( - dayValue, + baseTokenValue, tokenValues: tokenValues, - theme: .day + theme: fallbackTheme ), reference: try tokensResolver.resolveBaseReference( - dayValue, - tokenValues: tokenValues.hhDay + baseTokenValue, + tokenValues: tokenValues.tokens(for: fallbackTheme) ) ) - let nightColorToken = try resolveColorToken( - tokenName: tokenName, - fallbackColorToken: dayColorToken, - tokenValues: tokenValues, - theme: .night - ) - let zpDayColorToken = try resolveColorToken( - tokenName: tokenName, - fallbackColorToken: dayColorToken, - tokenValues: tokenValues, - theme: .zpDay - ) + let colors = try themes.map { theme in + guard theme != fallbackTheme else { + return (theme, fallbackColorToken) + } + + let token = try resolveColorToken( + tokenName: tokenName, + fallbackColorToken: fallbackColorToken, + tokenValues: tokenValues, + theme: theme + ) + + return (theme, token) + } return ColorToken( - dayTheme: dayColorToken, - nightTheme: nightColorToken, - zpDayTheme: zpDayColorToken, name: tokenName, - path: path + path: path, + themedValue: [:] ) } // MARK: - - func extractTokenContext(from tokenValues: TokenValues) throws -> [String: Any] { - let colors: [ColorToken] = try tokenValues.hhDay.compactMap { (token: TokenValue) in + func extractTokenContext(from tokenValues: TokenValues, themes: [Theme], fallbackTheme: Theme) throws -> [String: Any] { + let colors: [ColorToken] = try tokenValues.tokens(for: fallbackTheme).compactMap { (token: TokenValue) in guard case .color(let dayValue) = token.type else { return nil } @@ -116,10 +108,12 @@ final class DefaultColorTokensContextProvider: ColorTokensContextProvider { } return try makeColorToken( - dayValue: dayValue, + baseTokenValue: dayValue, tokenName: token.name, tokenValues: tokenValues, - path: path + path: path, + themes: themes, + fallbackTheme: fallbackTheme ) } diff --git a/Sources/FigmaGen/Generators/Tokens/Resolver/DefaultTokensResolver.swift b/Sources/FigmaGen/Generators/Tokens/Resolver/DefaultTokensResolver.swift index 3d0266c..9595a54 100644 --- a/Sources/FigmaGen/Generators/Tokens/Resolver/DefaultTokensResolver.swift +++ b/Sources/FigmaGen/Generators/Tokens/Resolver/DefaultTokensResolver.swift @@ -60,7 +60,7 @@ final class DefaultTokensResolver: TokensResolver { } } - private func resolveColorValue(_ value: String, tokenValues: TokenValues, theme: Theme) throws -> Color { + private func resolveColorValue(_ value: String, tokenValues: TokenValues, theme: Theme?) throws -> Color { if value.hasPrefix("rgba") { return try resolveRGBAColorValue(value, tokenValues: tokenValues, theme: theme) } @@ -109,7 +109,7 @@ final class DefaultTokensResolver: TokensResolver { // MARK: - TokensResolver - func resolveValue(_ value: String, tokenValues: TokenValues, theme: Theme) throws -> String { + func resolveValue(_ value: String, tokenValues: TokenValues, theme: Theme?) throws -> String { let themeTokens = tokenValues.getThemeTokenValues(theme: theme) let resolvedValue = try value.replacingOccurrences(matchingPattern: #"\{.*?\}"#) { referenceName in @@ -161,7 +161,7 @@ final class DefaultTokensResolver: TokensResolver { } } - func resolveRGBAColorValue(_ value: String, tokenValues: TokenValues, theme: Theme) throws -> Color { + func resolveRGBAColorValue(_ value: String, tokenValues: TokenValues, theme: Theme?) throws -> Color { let components = try resolveValue(value, tokenValues: tokenValues, theme: theme) .slice(from: "(", to: ")", includingBounds: false)? .components(separatedBy: ", ") @@ -190,7 +190,7 @@ final class DefaultTokensResolver: TokensResolver { } } - func resolveHexColorValue(_ value: String, tokenValues: TokenValues, theme: Theme) throws -> String { + func resolveHexColorValue(_ value: String, tokenValues: TokenValues, theme: Theme?) throws -> String { let resolvedValue = try resolveValue(value, tokenValues: tokenValues, theme: theme) if resolvedValue.hasPrefix("#") { @@ -199,7 +199,7 @@ final class DefaultTokensResolver: TokensResolver { return try resolveColorValue(resolvedValue, tokenValues: tokenValues, theme: theme).hexString } - func resolveLinearGradientValue(_ value: String, tokenValues: TokenValues, theme: Theme) throws -> LinearGradient { + func resolveLinearGradientValue(_ value: String, tokenValues: TokenValues, theme: Theme?) throws -> LinearGradient { let value = try resolveValue(value, tokenValues: tokenValues, theme: theme) guard let startFunctionIndex = value.firstIndex(of: "("), let endFunctionIndex = value.lastIndex(of: ")") else { diff --git a/Sources/FigmaGen/Generators/Tokens/Resolver/TokensResolver.swift b/Sources/FigmaGen/Generators/Tokens/Resolver/TokensResolver.swift index 9cf1aba..94ed17b 100644 --- a/Sources/FigmaGen/Generators/Tokens/Resolver/TokensResolver.swift +++ b/Sources/FigmaGen/Generators/Tokens/Resolver/TokensResolver.swift @@ -15,7 +15,7 @@ protocol TokensResolver { /// - tokenValues: All token values /// - theme: Theme /// - Returns: Resolved value. - func resolveValue(_ value: String, tokenValues: TokenValues, theme: Theme) throws -> String + func resolveValue(_ value: String, tokenValues: TokenValues, theme: Theme?) throws -> String /// Resolving `reference` from `tokenValues`. /// @@ -50,7 +50,7 @@ protocol TokensResolver { /// - tokenValues: All token values /// - theme: Theme /// - Returns: ``Color`` object with values resolved from `rgba()` - func resolveRGBAColorValue(_ value: String, tokenValues: TokenValues, theme: Theme) throws -> Color + func resolveRGBAColorValue(_ value: String, tokenValues: TokenValues, theme: Theme?) throws -> Color /// Resolving references and mathematical expressions in `value` using ``resolveValue(_:tokenValues:)`` /// and convert `rgba()` to hex value @@ -69,7 +69,7 @@ protocol TokensResolver { /// - tokenValues: All token values /// - theme: Theme /// - Returns: Hex value of the color - func resolveHexColorValue(_ value: String, tokenValues: TokenValues, theme: Theme) throws -> String + func resolveHexColorValue(_ value: String, tokenValues: TokenValues, theme: Theme?) throws -> String /// Resolving references and mathematical expressions in `value` using ``resolveValue(_:tokenValues:)`` /// and convert `linear-gradient()` to ``LinearGradient`` object @@ -91,5 +91,5 @@ protocol TokensResolver { /// - tokenValues: All token values /// - theme: Theme /// - Returns: ``LinearGradient`` object with values resolved from `linear-gradient()` - func resolveLinearGradientValue(_ value: String, tokenValues: TokenValues, theme: Theme) throws -> LinearGradient + func resolveLinearGradientValue(_ value: String, tokenValues: TokenValues, theme: Theme?) throws -> LinearGradient } diff --git a/Sources/FigmaGen/Models/Configuration/Tokens/TokenThemesConfiguration.swift b/Sources/FigmaGen/Models/Configuration/Tokens/TokenThemesConfiguration.swift new file mode 100644 index 0000000..e721d50 --- /dev/null +++ b/Sources/FigmaGen/Models/Configuration/Tokens/TokenThemesConfiguration.swift @@ -0,0 +1,11 @@ +import Foundation + +struct TokenThemesConfiguration: Codable { + let themes: [Theme] + let fallbackTheme: Theme + + init(themes: [Theme], fallbackTheme: Theme) { + self.themes = themes + self.fallbackTheme = fallbackTheme + } +} diff --git a/Sources/FigmaGen/Models/Configuration/Tokens/TokensConfiguration.swift b/Sources/FigmaGen/Models/Configuration/Tokens/TokensConfiguration.swift index d8c64a6..f2f1f09 100644 --- a/Sources/FigmaGen/Models/Configuration/Tokens/TokensConfiguration.swift +++ b/Sources/FigmaGen/Models/Configuration/Tokens/TokensConfiguration.swift @@ -14,6 +14,7 @@ struct TokensConfiguration: Decodable { let file: FileConfiguration? let remoteRepoConfig: RemoteRepoConfiguration? let accessToken: AccessTokenConfiguration? + let themesConfiguration: TokenThemesConfiguration? let templates: TokensTemplateConfiguration? // MARK: - Initializers @@ -28,17 +29,20 @@ struct TokensConfiguration: Decodable { self.remoteRepoConfig = try container.decodeIfPresent(forKey: .remoteRepoConfig) self.templates = try container.decodeIfPresent(forKey: .templates) + self.themesConfiguration = try TokenThemesConfiguration(from: decoder) } init( file: FileConfiguration?, remoteRepoConfig: RemoteRepoConfiguration?, accessToken: AccessTokenConfiguration?, + themesConfiguration: TokenThemesConfiguration?, templates: TokensTemplateConfiguration? ) { self.file = file self.remoteRepoConfig = remoteRepoConfig self.accessToken = accessToken + self.themesConfiguration = themesConfiguration self.templates = templates } @@ -53,6 +57,7 @@ struct TokensConfiguration: Decodable { file: file ?? base.file, remoteRepoConfig: remoteRepoConfig, accessToken: accessToken ?? base.accessToken, + themesConfiguration: themesConfiguration, templates: templates ) } diff --git a/Sources/FigmaGen/Models/Parameters/TokensGenerationParameters.swift b/Sources/FigmaGen/Models/Parameters/TokensGenerationParameters.swift index b500391..6ef83c3 100644 --- a/Sources/FigmaGen/Models/Parameters/TokensGenerationParameters.swift +++ b/Sources/FigmaGen/Models/Parameters/TokensGenerationParameters.swift @@ -23,5 +23,7 @@ struct TokensGenerationParameters { let file: FileParameters? let remoteFile: RemoteFileParameters? + let themes: [Theme] + let fallbackTheme: Theme let tokens: TokensParameters } diff --git a/Sources/FigmaGen/Models/Token/Theme.swift b/Sources/FigmaGen/Models/Token/Theme.swift index e8ec3e3..4ec7b5d 100644 --- a/Sources/FigmaGen/Models/Token/Theme.swift +++ b/Sources/FigmaGen/Models/Token/Theme.swift @@ -1,8 +1,35 @@ import Foundation -enum Theme: Codable { - case day - case night - case zpDay - case undefined +struct Theme: Codable, Hashable { + + enum CodingKeys: CodingKey { + case key + } + + let key: String + + init(key: String) { + self.key = key + } + + init(from decoder: any Decoder) throws { + let container = try decoder.singleValueContainer() + + if let key = try? container.decode(String.self) { + self.key = key + } else { + let container = try decoder.container(keyedBy: CodingKeys.self) + self.key = try container.decode(String.self, forKey: .key) + } + } + + func encode(to encoder: any Encoder) throws { + var container = encoder.singleValueContainer() + return try container.encode(key) + } +} + +extension Theme { + static let light = Theme(key: "light") + static let dark = Theme(key: "dark") } diff --git a/Sources/FigmaGen/Models/Token/TokenValues.swift b/Sources/FigmaGen/Models/Token/TokenValues.swift index b2db6ed..516fde3 100644 --- a/Sources/FigmaGen/Models/Token/TokenValues.swift +++ b/Sources/FigmaGen/Models/Token/TokenValues.swift @@ -8,38 +8,14 @@ struct TokenValues: Hashable { let semantic: [TokenValue] let colors: [TokenValue] let typography: [TokenValue] - let hhDay: [TokenValue] - let hhNight: [TokenValue] - let zpDay: [TokenValue] - - // MARK: - Instance Properties - - /// Возвращает набор токенов для определенной темы. - /// Для undefined возвращается полный набор токенов. Нужен для Spacer, Font и других независимых от темы параметров. - func getThemeTokenValues(theme: Theme) -> [TokenValue] { - switch theme { - case .day: - return [hhDay, core, semantic, colors, typography].flatMap { $0 } - - case .night: - return [hhNight, core, semantic, colors, typography].flatMap { $0 } - - case .zpDay: - return [zpDay, core, semantic, colors, typography].flatMap { $0 } - - case .undefined: - return [core, semantic, colors, typography, hhDay, hhNight, zpDay].flatMap { $0 } - } - } + let themedTokens: [Theme: [TokenValue]] } // MARK: - Codable extension TokenValues: Codable { - // MARK: - Nested Types - - private enum CodingKeys: String, CodingKey { + private enum CodingKeys: String, CodingKey, CaseIterable { // MARK: - Enumeration Cases @@ -47,8 +23,45 @@ extension TokenValues: Codable { case semantic case colors case typography - case hhDay = "hh-day" - case hhNight = "hh-night" - case zpDay = "zp-day" + } + + init(from decoder: any Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + let staticKeys = CodingKeys.allCases.map { $0.rawValue } + let themedContainer = try decoder.container(keyedBy: AnyKey.self) + + self.core = try container.decode(forKey: .core) + self.semantic = try container.decode(forKey: .semantic) + self.colors = try container.decode(forKey: .colors) + self.typography = try container.decode(forKey: .typography) + self.themedTokens = Dictionary( + uniqueKeysWithValues: try themedContainer + .allKeys + .filter { key in + !staticKeys.contains(key.stringValue) + } + .map { key in + let tokens = try themedContainer.decode([TokenValue].self, forKey: key) + let theme = Theme(key: key.stringValue) + return (theme, tokens) + } + ) + } +} + +extension TokenValues { + + func tokens(for theme: Theme) -> [TokenValue] { + themedTokens[theme] ?? [] + } + + /// Возвращает набор токенов для определенной темы. + /// Для undefined возвращается полный набор токенов. Нужен для Spacer, Font и других независимых от темы параметров. + func getThemeTokenValues(theme: Theme?) -> [TokenValue] { + let allThemedTokens = themedTokens.values.flatMap { $0 } + let themeTokens = theme.map { themedTokens[$0] ?? [] } ?? allThemedTokens + let tokens = [core, semantic, colors, typography, themeTokens] + + return tokens.flatMap { $0 } } } From 0e4fd4b77dba010234f4d55ff2761798e0a477c3 Mon Sep 17 00:00:00 2001 From: nschpy Date: Tue, 1 Apr 2025 12:53:17 +0300 Subject: [PATCH 14/23] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D0=B3=D0=B5=D0=BD=D0=B5=D1=80=D0=B0=D1=82=D0=BE?= =?UTF-8?q?=D1=80=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/FigmaGen/Commands/TokensCommand.swift | 29 +++++++ .../Tokens/Contexts/BoxShadowToken.swift | 6 +- .../Tokens/Contexts/LinearGradientToken.swift | 4 +- .../DefaultBoxShadowTokensGenerator.swift | 6 +- .../DefaultFontFamilyTokensGenerator.swift | 12 ++- .../Theme/DefaultThemeTokensGenerator.swift | 6 +- .../BoxShadowTokensContextProvider.swift | 6 +- .../BoxShadowTokensContextProviderError.swift | 9 +-- ...efaultBoxShadowTokensContextProvider.swift | 58 +++++++------ .../DefaultColorTokensContextProvider.swift | 2 +- ...DefaultGradientTokensContextProvider.swift | 81 ++++++++++--------- 11 files changed, 139 insertions(+), 80 deletions(-) diff --git a/Sources/FigmaGen/Commands/TokensCommand.swift b/Sources/FigmaGen/Commands/TokensCommand.swift index aae5b32..89598fe 100644 --- a/Sources/FigmaGen/Commands/TokensCommand.swift +++ b/Sources/FigmaGen/Commands/TokensCommand.swift @@ -68,6 +68,20 @@ final class TokensCommand: AsyncExecutableCommand { """ ) + let themes = VariadicKey( + "--themes", + description: #""" + An option that will be merged with template context. + """# + ) + + let fallbackTheme = Key( + "--fallbackTheme", + description: """ + the default theme used when the requested theme is unavailable. Must be one of the values listed in themes. + """ + ) + let colorsTemplate = Key( "--colors-template", description: """ @@ -313,6 +327,7 @@ extension TokensCommand { file: resolveFileConfiguration(), remoteRepoConfig: resolveRemoteRepoConfiguration(), accessToken: resolveAccessTokenConfiguration(), + themesConfiguration: resolveTokenThemesConfiguration(), templates: TokensTemplateConfiguration( colors: [ TemplateConfiguration( @@ -437,4 +452,18 @@ extension TokensCommand { return templateOptions } + + private func resolveTokenThemesConfiguration() -> TokenThemesConfiguration? { + let themes = themes.value + let fallbackTheme = fallbackTheme.value + + guard let fallbackTheme, !themes.isEmpty else { + return nil + } + + return TokenThemesConfiguration( + themes: themes.map { Theme(key: $0) }, + fallbackTheme: Theme(key: fallbackTheme) + ) + } } diff --git a/Sources/FigmaGen/Generators/Tokens/Contexts/BoxShadowToken.swift b/Sources/FigmaGen/Generators/Tokens/Contexts/BoxShadowToken.swift index 99a35f9..df6d928 100644 --- a/Sources/FigmaGen/Generators/Tokens/Contexts/BoxShadowToken.swift +++ b/Sources/FigmaGen/Generators/Tokens/Contexts/BoxShadowToken.swift @@ -4,7 +4,7 @@ struct BoxShadowToken { // MARK: - Nested Types - struct Theme { + struct ShadowValue { // MARK: - Instance Properties @@ -19,7 +19,5 @@ struct BoxShadowToken { // MARK: - Instance Properties let path: [String] - let dayTheme: Theme - let nightTheme: Theme - let zpDayTheme: Theme + let themedValue: [Theme: ShadowValue] } diff --git a/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift b/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift index 36e0023..98adf1b 100644 --- a/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift +++ b/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift @@ -22,7 +22,5 @@ struct LinearGradientToken: TokenProtocol, Encodable { let path: [String] let name: String - let dayTheme: GradientThemeValue - let nightTheme: GradientThemeValue - let zpDayTheme: GradientThemeValue + let themedValue: [Theme: GradientThemeValue] } diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/BoxShadow/DefaultBoxShadowTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/BoxShadow/DefaultBoxShadowTokensGenerator.swift index a10dd52..9f6b8f6 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/BoxShadow/DefaultBoxShadowTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/BoxShadow/DefaultBoxShadowTokensGenerator.swift @@ -22,7 +22,11 @@ final class DefaultBoxShadowTokensGenerator: BoxShadowTokensGenerator { themes: [Theme], fallbackTheme: Theme ) throws { - let boxShadows = try boxShadowTokensContextProvider.fetchBoxShadowTokensContext(from: tokenValues) + let boxShadows = try boxShadowTokensContextProvider.fetchBoxShadowTokensContext( + from: tokenValues, + themes: themes, + fallbackTheme: fallbackTheme + ) try templateRenderer.renderTemplate( renderParameters.template, diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/FontFamily/DefaultFontFamilyTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/FontFamily/DefaultFontFamilyTokensGenerator.swift index 53ba107..a821550 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/FontFamily/DefaultFontFamilyTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/FontFamily/DefaultFontFamilyTokensGenerator.swift @@ -24,7 +24,11 @@ final class DefaultFontFamilyTokensGenerator: FontFamilyTokensGenerator { return FontFamilyToken( path: tokenValue.name.components(separatedBy: "."), - value: try tokensResolver.resolveValue(value, tokenValues: tokenValues, theme: .undefined) + value: try tokensResolver.resolveValue( + value, + tokenValues: tokenValues, + theme: nil + ) ) } } @@ -37,7 +41,11 @@ final class DefaultFontFamilyTokensGenerator: FontFamilyTokensGenerator { return FontWeightToken( path: tokenValue.name.components(separatedBy: "."), - value: try tokensResolver.resolveValue(value, tokenValues: tokenValues, theme: .undefined) + value: try tokensResolver.resolveValue( + value, + tokenValues: tokenValues, + theme: nil + ) ) } } diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/Theme/DefaultThemeTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/Theme/DefaultThemeTokensGenerator.swift index 1b863e9..d6af9c2 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/Theme/DefaultThemeTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/Theme/DefaultThemeTokensGenerator.swift @@ -41,7 +41,11 @@ final class DefaultThemeTokensGenerator: ThemeTokensGenerator { themes: themes, fallbackTheme: fallbackTheme ) - let boxShadowsContext = try boxShadowsContextProvider.fetchBoxShadowTokensContext(from: tokenValues) + let boxShadowsContext = try boxShadowsContextProvider.fetchBoxShadowTokensContext( + from: tokenValues, + themes: themes, + fallbackTheme: fallbackTheme + ) try templateRenderer.renderTemplate( renderParameters.template, diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/BoxShadowTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/BoxShadowTokensContextProvider.swift index a4a9597..19c27da 100644 --- a/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/BoxShadowTokensContextProvider.swift +++ b/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/BoxShadowTokensContextProvider.swift @@ -4,5 +4,9 @@ protocol BoxShadowTokensContextProvider { // MARK: - Instance Methods - func fetchBoxShadowTokensContext(from tokenValues: TokenValues) throws -> [BoxShadowToken] + func fetchBoxShadowTokensContext( + from tokenValues: TokenValues, + themes: [Theme], + fallbackTheme: Theme + ) throws -> [BoxShadowToken] } diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/BoxShadowTokensContextProviderError.swift b/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/BoxShadowTokensContextProviderError.swift index e38f8a6..780c938 100644 --- a/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/BoxShadowTokensContextProviderError.swift +++ b/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/BoxShadowTokensContextProviderError.swift @@ -8,8 +8,7 @@ struct BoxShadowTokensContextProviderError: Error, CustomStringConvertible { // MARK: - Enumeration Cases - case nightValueNotFound(tokenName: String) - case zpValueNotFound(tokenName: String) + case valueNotFound(tokenName: String, theme: String) } // MARK: - Instance Properties @@ -20,10 +19,8 @@ struct BoxShadowTokensContextProviderError: Error, CustomStringConvertible { var description: String { switch code { - case .nightValueNotFound(let tokenName): - return "Night value for token '\(tokenName)' not found" - case .zpValueNotFound(let tokenName): - return "ZpDay value for token '\(tokenName)' not found" + case let .valueNotFound(tokenName, theme): + return "\(theme) value for token '\(tokenName)' not found" } } } diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/DefaultBoxShadowTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/DefaultBoxShadowTokensContextProvider.swift index 4f5b353..5f98ba7 100644 --- a/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/DefaultBoxShadowTokensContextProvider.swift +++ b/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/DefaultBoxShadowTokensContextProvider.swift @@ -4,8 +4,8 @@ final class DefaultBoxShadowTokensContextProvider: BoxShadowTokensContextProvide // MARK: - Instance Methods - private func makeTheme(value: TokenBoxShadowValue) -> BoxShadowToken.Theme { - BoxShadowToken.Theme( + private func makeTheme(value: TokenBoxShadowValue) -> BoxShadowToken.ShadowValue { + BoxShadowToken.ShadowValue( color: value.color, type: value.type, x: value.x, @@ -16,42 +16,54 @@ final class DefaultBoxShadowTokensContextProvider: BoxShadowTokensContextProvide } private func makeBoxShadowToken( - from dayTokenValue: TokenValue, - tokenValues: TokenValues + from fallbackTokenValue: TokenValue, + tokenValues: TokenValues, + themes: [Theme], + fallbackTheme: Theme ) throws -> BoxShadowToken? { - guard case let .boxShadow(dayValue) = dayTokenValue.type else { + guard case let .boxShadow(fallbackValue) = fallbackTokenValue.type else { return nil } - guard let nightTokenValue = tokenValues.hhNight.first(where: { $0.name == dayTokenValue.name }) else { - throw BoxShadowTokensContextProviderError(code: .nightValueNotFound(tokenName: dayTokenValue.name)) - } + let shadows = try themes.map { theme in + guard theme != fallbackTheme else { + return (theme, makeTheme(value: fallbackValue)) + } - guard case let .boxShadow(nightValue) = nightTokenValue.type else { - throw BoxShadowTokensContextProviderError(code: .nightValueNotFound(tokenName: dayTokenValue.name)) - } + guard let nightTokenValue = tokenValues.tokens(for: theme).first(where: { $0.name == fallbackTokenValue.name }) else { + throw BoxShadowTokensContextProviderError(code: .valueNotFound(tokenName: fallbackTokenValue.name, theme: theme.key)) + } - guard let zpDayTokenValue = tokenValues.zpDay.first(where: { $0.name == dayTokenValue.name }) else { - throw BoxShadowTokensContextProviderError(code: .nightValueNotFound(tokenName: dayTokenValue.name)) - } + guard case let .boxShadow(boxShadowValue) = nightTokenValue.type else { + throw BoxShadowTokensContextProviderError(code: .valueNotFound(tokenName: fallbackTokenValue.name, theme: theme.key)) + } - guard case let .boxShadow(zpDayValue) = zpDayTokenValue.type else { - throw BoxShadowTokensContextProviderError(code: .zpValueNotFound(tokenName: dayTokenValue.name)) + return (theme, makeTheme(value: boxShadowValue)) } + return BoxShadowToken( - path: dayTokenValue.name.components(separatedBy: "."), - dayTheme: makeTheme(value: dayValue), - nightTheme: makeTheme(value: nightValue), - zpDayTheme: makeTheme(value: zpDayValue) + path: fallbackTokenValue.name.components(separatedBy: "."), + themedValue: Dictionary(uniqueKeysWithValues: shadows) ) } // MARK: - - func fetchBoxShadowTokensContext(from tokenValues: TokenValues) throws -> [BoxShadowToken] { - try tokenValues.hhDay - .compactMap { try makeBoxShadowToken(from: $0, tokenValues: tokenValues) } + func fetchBoxShadowTokensContext( + from tokenValues: TokenValues, + themes: [Theme], + fallbackTheme: Theme + ) throws -> [BoxShadowToken] { + try tokenValues.tokens(for: fallbackTheme) + .compactMap { + try makeBoxShadowToken( + from: $0, + tokenValues: tokenValues, + themes: themes, + fallbackTheme: fallbackTheme + ) + } .sorted { $0.path.joined() < $1.path.joined() } } } diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultColorTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultColorTokensContextProvider.swift index fa14784..718c5eb 100644 --- a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultColorTokensContextProvider.swift +++ b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultColorTokensContextProvider.swift @@ -89,7 +89,7 @@ final class DefaultColorTokensContextProvider: ColorTokensContextProvider { return ColorToken( name: tokenName, path: path, - themedValue: [:] + themedValue: Dictionary(uniqueKeysWithValues: colors) ) } diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultGradientTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultGradientTokensContextProvider.swift index 6d8df5d..e75d6ab 100644 --- a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultGradientTokensContextProvider.swift +++ b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultGradientTokensContextProvider.swift @@ -76,17 +76,8 @@ struct DefaultGradientTokensContextProvider: ColorTokensContextProvider { tokenValues: TokenValues, theme: Theme ) throws -> LinearGradientToken.GradientThemeValue { - let themeData: (tokenValues: [TokenValue], warningPrefix: String) - switch theme { - case .night: - themeData = (tokenValues.hhNight, "Night") - - case .zpDay: - themeData = (tokenValues.zpDay, "ZpDay") - - case .day, .undefined: - themeData = ([], "") - } + let tokens = tokenValues.tokens(for: theme) + let themeData: (tokenValues: [TokenValue], warningPrefix: String) = (tokens, theme.key) guard let themeToken = themeData.tokenValues.first(where: { $0.name == tokenName }) else { return fallbackColorToken @@ -109,69 +100,83 @@ struct DefaultGradientTokensContextProvider: ColorTokensContextProvider { _ gradientValue: String, tokenName: String, path: [String], - tokenValues: TokenValues + tokenValues: TokenValues, + themes: [Theme], + fallbackTheme: Theme ) throws -> LinearGradientToken? { - let dayGradient = try tokensResolver.resolveLinearGradientValue( + let fallbackGradient = try tokensResolver.resolveLinearGradientValue( gradientValue, tokenValues: tokenValues, - theme: .day + theme: fallbackTheme ) - guard let dayToken = resolveThemeValue(from: dayGradient, tokenName: tokenName) else { + guard let fallbackToken = resolveThemeValue(from: fallbackGradient, tokenName: tokenName) else { return nil } - let nightToken = try resolveGradientToken( - tokenName: tokenName, - fallbackColorToken: dayToken, - tokenValues: tokenValues, - theme: .night - ) + let gradients = try themes.map { theme in + guard theme != fallbackTheme else { + return (theme, fallbackToken) + } - let zpDayToken = try resolveGradientToken( - tokenName: tokenName, - fallbackColorToken: dayToken, - tokenValues: tokenValues, - theme: .zpDay - ) + let gradient = try resolveGradientToken( + tokenName: tokenName, + fallbackColorToken: fallbackToken, + tokenValues: tokenValues, + theme: theme + ) + + return (theme, gradient) + } return LinearGradientToken( path: path, name: tokenName, - dayTheme: dayToken, - nightTheme: nightToken, - zpDayTheme: zpDayToken + themedValue: Dictionary(uniqueKeysWithValues: gradients) ) } // TODO: @mi.fedorov поддержать мульти-темы private func extractGradientToken( from token: TokenValue, - tokenValues: TokenValues + tokenValues: TokenValues, + themes: [Theme], + fallbackTheme: Theme ) throws -> LinearGradientToken? { let path = token.name.components(separatedBy: ".") guard - case .color(let dayValue) = token.type, - dayValue.contains("gradient"), + case .color(let fallbackTokenValue) = token.type, + fallbackTokenValue.contains("gradient"), path[0] != "color" else { return nil } return try createGradientToken( - dayValue, + fallbackTokenValue, tokenName: token.name, path: path, - tokenValues: tokenValues + tokenValues: tokenValues, + themes: themes, + fallbackTheme: fallbackTheme ) } // MARK: - GradientTokensContextProvider - func extractTokenContext(from tokenValues: TokenValues) throws -> [String : Any] { - let gradient = try tokenValues.hhDay.compactMap { - try extractGradientToken(from: $0, tokenValues: tokenValues) + func extractTokenContext( + from tokenValues: TokenValues, + themes: [Theme], + fallbackTheme: Theme + ) throws -> [String : Any] { + let gradient = try tokenValues.tokens(for: fallbackTheme).compactMap { + try extractGradientToken( + from: $0, + tokenValues: tokenValues, + themes: themes, + fallbackTheme: fallbackTheme + ) } return structure(tokens: gradient, contextName: "gradients") From d39e0ed3aac421c6d50c5e02a26311184fafe987 Mon Sep 17 00:00:00 2001 From: nschpy Date: Wed, 2 Apr 2025 01:29:53 +0300 Subject: [PATCH 15/23] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BC=D0=BE=D0=B4=D0=B5=D0=BB=D0=B8=20=D1=82=D0=BE?= =?UTF-8?q?=D0=BA=D0=B5=D0=BD=D0=BE=D0=B2=20=D0=B8=D1=81=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D1=8C=D0=B7=D1=83=D1=8E=D1=89=D0=B8=D0=B5=20=D1=82=D0=B5=D0=BC?= =?UTF-8?q?=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/FigmaGen/Commands/TokensCommand.swift | 4 ++-- .../Generators/Tokens/Contexts/BoxShadowToken.swift | 2 +- .../Generators/Tokens/Contexts/ColorToken.swift | 2 +- .../Tokens/Contexts/LinearGradientToken.swift | 2 +- .../Theme/DefaultThemeTokensGenerator.swift | 3 ++- .../DefaultBoxShadowTokensContextProvider.swift | 4 ++-- .../DefaultColorTokensContextProvider.swift | 4 ++-- .../DefaultGradientTokensContextProvider.swift | 4 ++-- Sources/FigmaGen/Models/Token/Theme.swift | 11 +++-------- Sources/FigmaGen/Models/Token/TokenValues.swift | 2 +- Templates/ColorTokens.stencil | 5 +++-- Templates/Theme.stencil | 6 +++--- 12 files changed, 23 insertions(+), 26 deletions(-) diff --git a/Sources/FigmaGen/Commands/TokensCommand.swift b/Sources/FigmaGen/Commands/TokensCommand.swift index 89598fe..8213276 100644 --- a/Sources/FigmaGen/Commands/TokensCommand.swift +++ b/Sources/FigmaGen/Commands/TokensCommand.swift @@ -462,8 +462,8 @@ extension TokensCommand { } return TokenThemesConfiguration( - themes: themes.map { Theme(key: $0) }, - fallbackTheme: Theme(key: fallbackTheme) + themes: themes.map { Theme($0) }, + fallbackTheme: Theme(fallbackTheme) ) } } diff --git a/Sources/FigmaGen/Generators/Tokens/Contexts/BoxShadowToken.swift b/Sources/FigmaGen/Generators/Tokens/Contexts/BoxShadowToken.swift index df6d928..2b09e92 100644 --- a/Sources/FigmaGen/Generators/Tokens/Contexts/BoxShadowToken.swift +++ b/Sources/FigmaGen/Generators/Tokens/Contexts/BoxShadowToken.swift @@ -19,5 +19,5 @@ struct BoxShadowToken { // MARK: - Instance Properties let path: [String] - let themedValue: [Theme: ShadowValue] + let themedValue: [String: ShadowValue] } diff --git a/Sources/FigmaGen/Generators/Tokens/Contexts/ColorToken.swift b/Sources/FigmaGen/Generators/Tokens/Contexts/ColorToken.swift index 44f01c8..4045970 100644 --- a/Sources/FigmaGen/Generators/Tokens/Contexts/ColorToken.swift +++ b/Sources/FigmaGen/Generators/Tokens/Contexts/ColorToken.swift @@ -16,5 +16,5 @@ struct ColorToken: TokenProtocol, Encodable { let name: String let path: [String] - let themedValue: [Theme: ColorValue] + let themedValue: [String: ColorValue] } diff --git a/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift b/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift index 98adf1b..1cd6260 100644 --- a/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift +++ b/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift @@ -22,5 +22,5 @@ struct LinearGradientToken: TokenProtocol, Encodable { let path: [String] let name: String - let themedValue: [Theme: GradientThemeValue] + let themedValue: [String: GradientThemeValue] } diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/Theme/DefaultThemeTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/Theme/DefaultThemeTokensGenerator.swift index d6af9c2..3169b4e 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/Theme/DefaultThemeTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/Theme/DefaultThemeTokensGenerator.swift @@ -53,7 +53,8 @@ final class DefaultThemeTokensGenerator: ThemeTokensGenerator { context: [ "colors": colorsContext, "boxShadows": boxShadowsContext, - "gradients": gradientsContext + "gradients": gradientsContext, + "themes": themes.map { $0.key } ] ) } diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/DefaultBoxShadowTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/DefaultBoxShadowTokensContextProvider.swift index 5f98ba7..1a7c8a3 100644 --- a/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/DefaultBoxShadowTokensContextProvider.swift +++ b/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/DefaultBoxShadowTokensContextProvider.swift @@ -27,7 +27,7 @@ final class DefaultBoxShadowTokensContextProvider: BoxShadowTokensContextProvide let shadows = try themes.map { theme in guard theme != fallbackTheme else { - return (theme, makeTheme(value: fallbackValue)) + return (theme.key, makeTheme(value: fallbackValue)) } guard let nightTokenValue = tokenValues.tokens(for: theme).first(where: { $0.name == fallbackTokenValue.name }) else { @@ -38,7 +38,7 @@ final class DefaultBoxShadowTokensContextProvider: BoxShadowTokensContextProvide throw BoxShadowTokensContextProviderError(code: .valueNotFound(tokenName: fallbackTokenValue.name, theme: theme.key)) } - return (theme, makeTheme(value: boxShadowValue)) + return (theme.key, makeTheme(value: boxShadowValue)) } diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultColorTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultColorTokensContextProvider.swift index 718c5eb..5780079 100644 --- a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultColorTokensContextProvider.swift +++ b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultColorTokensContextProvider.swift @@ -73,7 +73,7 @@ final class DefaultColorTokensContextProvider: ColorTokensContextProvider { let colors = try themes.map { theme in guard theme != fallbackTheme else { - return (theme, fallbackColorToken) + return (theme.key, fallbackColorToken) } let token = try resolveColorToken( @@ -83,7 +83,7 @@ final class DefaultColorTokensContextProvider: ColorTokensContextProvider { theme: theme ) - return (theme, token) + return (theme.key, token) } return ColorToken( diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultGradientTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultGradientTokensContextProvider.swift index e75d6ab..886e398 100644 --- a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultGradientTokensContextProvider.swift +++ b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultGradientTokensContextProvider.swift @@ -116,7 +116,7 @@ struct DefaultGradientTokensContextProvider: ColorTokensContextProvider { let gradients = try themes.map { theme in guard theme != fallbackTheme else { - return (theme, fallbackToken) + return (theme.key, fallbackToken) } let gradient = try resolveGradientToken( @@ -126,7 +126,7 @@ struct DefaultGradientTokensContextProvider: ColorTokensContextProvider { theme: theme ) - return (theme, gradient) + return (theme.key, gradient) } return LinearGradientToken( diff --git a/Sources/FigmaGen/Models/Token/Theme.swift b/Sources/FigmaGen/Models/Token/Theme.swift index 4ec7b5d..7b5114d 100644 --- a/Sources/FigmaGen/Models/Token/Theme.swift +++ b/Sources/FigmaGen/Models/Token/Theme.swift @@ -8,7 +8,7 @@ struct Theme: Codable, Hashable { let key: String - init(key: String) { + init(_ key: String) { self.key = key } @@ -22,14 +22,9 @@ struct Theme: Codable, Hashable { self.key = try container.decode(String.self, forKey: .key) } } - - func encode(to encoder: any Encoder) throws { - var container = encoder.singleValueContainer() - return try container.encode(key) - } } extension Theme { - static let light = Theme(key: "light") - static let dark = Theme(key: "dark") + static let light = Theme("light") + static let dark = Theme("dark") } diff --git a/Sources/FigmaGen/Models/Token/TokenValues.swift b/Sources/FigmaGen/Models/Token/TokenValues.swift index 516fde3..27b74ca 100644 --- a/Sources/FigmaGen/Models/Token/TokenValues.swift +++ b/Sources/FigmaGen/Models/Token/TokenValues.swift @@ -42,7 +42,7 @@ extension TokenValues: Codable { } .map { key in let tokens = try themedContainer.decode([TokenValue].self, forKey: key) - let theme = Theme(key: key.stringValue) + let theme = Theme(key.stringValue) return (theme, tokens) } ) diff --git a/Templates/ColorTokens.stencil b/Templates/ColorTokens.stencil index eb9359d..95c0cc4 100644 --- a/Templates/ColorTokens.stencil +++ b/Templates/ColorTokens.stencil @@ -9,8 +9,9 @@ {% for color in item.colors %} /// {{ color.name }} /// - /// Day: {{ color.dayTheme.value }} - /// Night: {{ color.nightTheme.value }} + {% for theme, token in color.themedValue %} + /// {{ theme }}: {{ token.value }} + {% endfor %} {{ accessModifier }} let {% call propertyName color.path.last %}: {{ colorTypeName }} {% endfor %} {% for child in item.children %} diff --git a/Templates/Theme.stencil b/Templates/Theme.stencil index 5362449..9e972df 100644 --- a/Templates/Theme.stencil +++ b/Templates/Theme.stencil @@ -11,7 +11,7 @@ {% macro hexColor color %}{{ color|fullHex|uppercase|replace:"#","0x" }}{% endmacro %} {% macro argumentsBlock item theme parentTypeName %} {% for color in item.colors %} -{% call propertyName color.path.last %}: {{ colorTypeName }}(hex: {% call hexColor color[theme].value %}){% if not forloop.last %},{% endif %} +{% call propertyName color.path.last %}: {{ colorTypeName }}(hex: {% call hexColor color.themedValue[theme].value %}){% if not forloop.last %},{% endif %} {% endfor %} {% for child in item.children %} {% set childTypeName %}{% if parentTypeName %}{{ parentTypeName }}.{% endif %}{% call typeName child.name %}{% endset %} @@ -36,9 +36,9 @@ colors: {{ colorTokensTypeName }}( shadows: {{ boxShadowTokensTypeName }}( {% for boxShadow in boxShadows %} {% call propertyName boxShadow.path.last %}: {{ shadowTypeName }}( - offset: CGSize(width: {{ boxShadow[theme].x }}, height: {{ boxShadow[theme].y }}), + offset: CGSize(width: {{ boxShadow.themedValue[theme].x }}, height: {{ boxShadow.themedValue[theme].y }}), radius: {{ boxShadow[theme].blur }}, - color: {{ colorTypeName }}(hex: {% call hexColor boxShadow[theme].color %}), + color: {{ colorTypeName }}(hex: {% call hexColor boxShadow.themedValue[theme].color %}), opacity: 1.0 ){% if not forloop.last %},{% endif %} {% endfor %} From 5c3d80b85e85156ad3003b94e9779ad358eab1ee Mon Sep 17 00:00:00 2001 From: nschpy Date: Wed, 2 Apr 2025 22:21:42 +0300 Subject: [PATCH 16/23] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=88=D0=B0=D0=B1=D0=BB=D0=BE=D0=BD=D1=8B=20=D0=B8=20?= =?UTF-8?q?=D1=83=D0=B4=D0=B0=D0=BB=D0=B8=D0=BB=20=D0=BB=D0=B8=D1=88=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BB=D0=BE=D0=B3=D0=B8=20=D0=B8=D0=B7=20=D0=BA?= =?UTF-8?q?=D0=BE=D0=BD=D1=81=D0=BE=D0=BB=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Tokens/DefaultTokensGenerator.swift | 11 +++++++++ .../DefaultBaseColorTokensGenerator.swift | 5 +++- .../DefaultBoxShadowTokensGenerator.swift | 5 +++- .../Color/DefaultColorTokensGenerator.swift | 5 +++- .../DefaultGradientTokensGenerator.swift | 5 +++- .../DefaultColorTokensContextProvider.swift | 2 +- Sources/FigmaGen/Logger/Logger.swift | 10 ++++++-- .../Render/DefaultTemplateRenderer.swift | 2 +- .../DefaultRenderParametersResolver.swift | 10 +------- Templates/Theme.stencil | 24 +++++++++++-------- 10 files changed, 52 insertions(+), 27 deletions(-) diff --git a/Sources/FigmaGen/Generators/Tokens/DefaultTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/DefaultTokensGenerator.swift index 317e5a5..e511a61 100644 --- a/Sources/FigmaGen/Generators/Tokens/DefaultTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/DefaultTokensGenerator.swift @@ -75,6 +75,7 @@ final class DefaultTokensGenerator: TokensGenerator { private func generateSpacingTokens(parameters: TokensGenerationParameters, tokenValues: TokenValues) throws { try generateTokens( spacingTokensGenerator, + tokensName: "spacings", renderParameters: parameters.tokens.spacingRenderParameters, tokenValues: tokenValues, themes: parameters.themes, @@ -85,6 +86,7 @@ final class DefaultTokensGenerator: TokensGenerator { private func generateThemeTokens(parameters: TokensGenerationParameters, tokenValues: TokenValues) throws { try generateTokens( themeTokensGenerator, + tokensName: "theme", renderParameters: parameters.tokens.themeRenderParameters, tokenValues: tokenValues, themes: parameters.themes, @@ -95,6 +97,7 @@ final class DefaultTokensGenerator: TokensGenerator { private func generateBoxShadowTokens(parameters: TokensGenerationParameters, tokenValues: TokenValues) throws { try generateTokens( boxShadowTokensGenerator, + tokensName: "box shadow", renderParameters: parameters.tokens.boxShadowRenderParameters, tokenValues: tokenValues, themes: parameters.themes, @@ -105,6 +108,7 @@ final class DefaultTokensGenerator: TokensGenerator { private func generateTypographyTokens(parameters: TokensGenerationParameters, tokenValues: TokenValues) throws { try generateTokens( typographyTokensGenerator, + tokensName: "typogrphy", renderParameters: parameters.tokens.typographyRenderParameters, tokenValues: tokenValues, themes: parameters.themes, @@ -115,6 +119,7 @@ final class DefaultTokensGenerator: TokensGenerator { private func generateFontFamilyTokens(parameters: TokensGenerationParameters, tokenValues: TokenValues) throws { try generateTokens( fontFamilyTokensGenerator, + tokensName: "font family", renderParameters: parameters.tokens.fontFamilyRenderParameters, tokenValues: tokenValues, themes: parameters.themes, @@ -125,6 +130,7 @@ final class DefaultTokensGenerator: TokensGenerator { private func generateBaseColorsTokens(parameters: TokensGenerationParameters, tokenValues: TokenValues) throws { try generateTokens( baseColorTokensGenerator, + tokensName: "base colors", renderParameters: parameters.tokens.baseColorRenderParameters, tokenValues: tokenValues, themes: parameters.themes, @@ -135,6 +141,7 @@ final class DefaultTokensGenerator: TokensGenerator { private func generateColorsTokens(parameters: TokensGenerationParameters, tokenValues: TokenValues) throws { try generateTokens( colorTokensGenerator, + tokensName: "colors", renderParameters: parameters.tokens.colorRenderParameters, tokenValues: tokenValues, themes: parameters.themes, @@ -145,6 +152,7 @@ final class DefaultTokensGenerator: TokensGenerator { private func generateBorderTokens(parameters: TokensGenerationParameters, tokenValues: TokenValues) throws { try generateTokens( bordersTokensGenerator, + tokensName: "border", renderParameters: parameters.tokens.bordersRenderParameters, tokenValues: tokenValues, themes: parameters.themes, @@ -155,6 +163,7 @@ final class DefaultTokensGenerator: TokensGenerator { private func generateGradientTokens(parameters: TokensGenerationParameters, tokenValues: TokenValues) throws { try generateTokens( gradientTokensGenerator, + tokensName: "gradients", renderParameters: parameters.tokens.gradientRenderParameters, tokenValues: tokenValues, themes: parameters.themes, @@ -164,6 +173,7 @@ final class DefaultTokensGenerator: TokensGenerator { private func generateTokens( _ generator: BaseTokenGenerator, + tokensName: String, renderParameters: [RenderParameters]?, tokenValues: TokenValues, themes: [Theme], @@ -171,6 +181,7 @@ final class DefaultTokensGenerator: TokensGenerator { ) throws { if let renderParametersList = renderParameters { for params in renderParametersList { + logger.info("📦 Generating \(tokensName) tokens...", highlighted: true) try generator.generate( renderParameters: params, tokenValues: tokenValues, diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/BaseColor/DefaultBaseColorTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/BaseColor/DefaultBaseColorTokensGenerator.swift index 848e6d1..2084589 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/BaseColor/DefaultBaseColorTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/BaseColor/DefaultBaseColorTokensGenerator.swift @@ -44,7 +44,10 @@ final class DefaultBaseColorTokensGenerator: BaseColorTokensGenerator { try templateRenderer.renderTemplate( renderParameters.template, to: renderParameters.destination, - context: ["colors": colors] + context: [ + "colors": colors, + "themes": themes + ] ) } } diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/BoxShadow/DefaultBoxShadowTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/BoxShadow/DefaultBoxShadowTokensGenerator.swift index 9f6b8f6..abd8df8 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/BoxShadow/DefaultBoxShadowTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/BoxShadow/DefaultBoxShadowTokensGenerator.swift @@ -31,7 +31,10 @@ final class DefaultBoxShadowTokensGenerator: BoxShadowTokensGenerator { try templateRenderer.renderTemplate( renderParameters.template, to: renderParameters.destination, - context: ["boxShadows": boxShadows] + context: [ + "boxShadows": boxShadows, + "themes": themes.map { $0.key } + ] ) } } diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/Color/DefaultColorTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/Color/DefaultColorTokensGenerator.swift index 7c730fc..7d17ed0 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/Color/DefaultColorTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/Color/DefaultColorTokensGenerator.swift @@ -29,7 +29,10 @@ final class DefaultColorTokensGenerator: ColorTokensGenerator { try templateRenderer.renderTemplate( renderParameters.template, to: renderParameters.destination, - context: ["colors": context] + context: [ + "colors": context, + "themes": themes.map { $0.key } + ] ) } } diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/Gradient/DefaultGradientTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/Gradient/DefaultGradientTokensGenerator.swift index 91db52d..d6fd0b1 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/Gradient/DefaultGradientTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/Gradient/DefaultGradientTokensGenerator.swift @@ -32,7 +32,10 @@ struct DefaultGradientTokensGenerator: GradientTokensGenerator { try templateRenderer.renderTemplate( renderParameters.template, to: renderParameters.destination, - context: ["gradients": gradientContext] + context: [ + "gradients": gradientContext, + "themes": themes.map { $0.key } + ] ) } } diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultColorTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultColorTokensContextProvider.swift index 5780079..54bc3c9 100644 --- a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultColorTokensContextProvider.swift +++ b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultColorTokensContextProvider.swift @@ -15,7 +15,7 @@ final class DefaultColorTokensContextProvider: ColorTokensContextProvider { // MARK: - Instance Methods private func fallbackWarning(warningPrefix: String, tokenName: String) { - logger.warning("\(warningPrefix) value for token '\(tokenName)' not found, using day value.") + logger.warning("\(warningPrefix) value for token '\(tokenName)' not found, using day value.", isVerbose: true) } private func resolveColorToken( diff --git a/Sources/FigmaGen/Logger/Logger.swift b/Sources/FigmaGen/Logger/Logger.swift index c00cac1..0f5a3b9 100644 --- a/Sources/FigmaGen/Logger/Logger.swift +++ b/Sources/FigmaGen/Logger/Logger.swift @@ -43,9 +43,15 @@ struct Logger { print(message, terminator: terminator, isVerbose: isVerbose) } - func info(_ items: Any..., separator: String = " ", terminator: String = "\n", isVerbose: Bool = false) { + func info( + _ items: Any..., + separator: String = " ", + terminator: String = "\n", + highlighted: Bool = false, + isVerbose: Bool = false + ) { let message = items.joinedDescription(separator: separator) - print(message, terminator: terminator, isVerbose: isVerbose) + print(highlighted ? message.blue : message, terminator: terminator, isVerbose: isVerbose) } func warning(_ items: Any..., separator: String = " ", terminator: String = "\n", isVerbose: Bool = false) { diff --git a/Sources/FigmaGen/Render/DefaultTemplateRenderer.swift b/Sources/FigmaGen/Render/DefaultTemplateRenderer.swift index 27b4ed4..bcac67c 100644 --- a/Sources/FigmaGen/Render/DefaultTemplateRenderer.swift +++ b/Sources/FigmaGen/Render/DefaultTemplateRenderer.swift @@ -62,7 +62,7 @@ final class DefaultTemplateRenderer: TemplateRenderer { try filePath.write(output) case .console: - print(output) + logger.info(output) } } diff --git a/Sources/FigmaGen/Resolvers/RenderParameters/DefaultRenderParametersResolver.swift b/Sources/FigmaGen/Resolvers/RenderParameters/DefaultRenderParametersResolver.swift index f3ac399..49d1506 100644 --- a/Sources/FigmaGen/Resolvers/RenderParameters/DefaultRenderParametersResolver.swift +++ b/Sources/FigmaGen/Resolvers/RenderParameters/DefaultRenderParametersResolver.swift @@ -31,16 +31,8 @@ final class DefaultRenderParametersResolver: RenderParametersResolver { defaultTemplateType: RenderTemplateType, defaultDestination: RenderDestination ) -> [RenderParameters] { - let defaultRenderParameters = RenderParameters( - template: RenderTemplate( - type: defaultTemplateType, - options: [:] - ), - destination: defaultDestination - ) - guard let templates else { - return [defaultRenderParameters] + return [] } return templates.map { template in diff --git a/Templates/Theme.stencil b/Templates/Theme.stencil index 9e972df..b43e647 100644 --- a/Templates/Theme.stencil +++ b/Templates/Theme.stencil @@ -11,7 +11,11 @@ {% macro hexColor color %}{{ color|fullHex|uppercase|replace:"#","0x" }}{% endmacro %} {% macro argumentsBlock item theme parentTypeName %} {% for color in item.colors %} +{% if color.themedValue[theme] %} {% call propertyName color.path.last %}: {{ colorTypeName }}(hex: {% call hexColor color.themedValue[theme].value %}){% if not forloop.last %},{% endif %} +{% else %} + {% continue %} +{% endif %} {% endfor %} {% for child in item.children %} {% set childTypeName %}{% if parentTypeName %}{{ parentTypeName }}.{% endif %}{% call typeName child.name %}{% endset %} @@ -35,12 +39,16 @@ colors: {{ colorTokensTypeName }}( {% if boxShadows %} shadows: {{ boxShadowTokensTypeName }}( {% for boxShadow in boxShadows %} + {% if boxShadow.themedValue[theme] %} {% call propertyName boxShadow.path.last %}: {{ shadowTypeName }}( offset: CGSize(width: {{ boxShadow.themedValue[theme].x }}, height: {{ boxShadow.themedValue[theme].y }}), radius: {{ boxShadow[theme].blur }}, color: {{ colorTypeName }}(hex: {% call hexColor boxShadow.themedValue[theme].color %}), opacity: 1.0 ){% if not forloop.last %},{% endif %} + {% else %} + {% continue %} + {% endif %} {% endfor %} ) {% endif %} @@ -83,19 +91,15 @@ import AppKit extension {{ themeTypeName }} { - {{ accessModifier }} static let defaultLight = Self( - {% filter indent:8 %} - {% call colorsArgumentsBlock colors "dayTheme" %} - {% call shadowsArgumentsBlock boxShadows "dayTheme" %} - {% endfilter %} - ) - - {{ accessModifier }} static let defaultDark = Self( + {% for theme in themes %} + {% set themePropertyName %}{{ theme||swiftIdentifier:"pretty"|lowerFirstWord }}{% endset %} + {{ accessModifier }} static let {{ themePropertyName }} = Self( {% filter indent:8 %} - {% call colorsArgumentsBlock colors "nightTheme" %} - {% call shadowsArgumentsBlock boxShadows "nightTheme" %} + {% call colorsArgumentsBlock colors theme %} + {% call shadowsArgumentsBlock boxShadows theme %} {% endfilter %} ) + {% endfor %} } {% if colors or boxShadows %} From 080edfa38f0b39ed89585b7ac58f2c1d26ddbd54 Mon Sep 17 00:00:00 2001 From: nschpy Date: Thu, 3 Apr 2025 21:28:54 +0300 Subject: [PATCH 17/23] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D0=B3=D0=B5=D0=BD=D0=B5=D1=80=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D1=8E=20=D0=B7=D0=BD=D0=B0=D1=87=D0=B5=D0=BD=D0=B8=D0=B9=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D1=82=D0=B5=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Tokens/Contexts/BoxShadowToken.swift | 22 +-- .../Tokens/Contexts/ColorToken.swift | 13 +- .../Tokens/Contexts/LinearGradientToken.swift | 11 +- .../Tokens/Contexts/TokenThemeValue.swift | 12 ++ .../DefaultBoxShadowTokensGenerator.swift | 8 +- .../Color/DefaultColorTokensGenerator.swift | 22 ++- .../DefaultGradientTokensGenerator.swift | 15 +- .../Theme/DefaultThemeTokensGenerator.swift | 16 +- .../BoxShadowTokensContextProvider.swift | 2 +- ...efaultBoxShadowTokensContextProvider.swift | 81 ++++---- .../ColorTokensContextProvider.swift | 2 +- .../DefaultColorTokensContextProvider.swift | 112 +++++++++++ ...faultColorTokensContextProviderError.swift | 13 ++ .../DefaultColorTokensContextProvider.swift | 122 ------------ ...DefaultGradientTokensContextProvider.swift | 184 ------------------ ...DefaultGradientTokensContextProvider.swift | 151 ++++++++++++++ ...ltGradientTokensContextProviderError.swift | 15 ++ Sources/FigmaGen/Models/Token/Theme.swift | 15 +- 18 files changed, 414 insertions(+), 402 deletions(-) create mode 100644 Sources/FigmaGen/Generators/Tokens/Contexts/TokenThemeValue.swift create mode 100644 Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Colors/DefaultColorTokensContextProvider.swift create mode 100644 Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Colors/DefaultColorTokensContextProviderError.swift delete mode 100644 Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultColorTokensContextProvider.swift delete mode 100644 Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultGradientTokensContextProvider.swift create mode 100644 Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Gradient/DefaultGradientTokensContextProvider.swift create mode 100644 Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Gradient/DefaultGradientTokensContextProviderError.swift diff --git a/Sources/FigmaGen/Generators/Tokens/Contexts/BoxShadowToken.swift b/Sources/FigmaGen/Generators/Tokens/Contexts/BoxShadowToken.swift index 2b09e92..cc2e156 100644 --- a/Sources/FigmaGen/Generators/Tokens/Contexts/BoxShadowToken.swift +++ b/Sources/FigmaGen/Generators/Tokens/Contexts/BoxShadowToken.swift @@ -2,22 +2,14 @@ import Foundation struct BoxShadowToken { - // MARK: - Nested Types - - struct ShadowValue { - - // MARK: - Instance Properties - - let color: String - let type: String - let x: String - let y: String - let blur: String - let spread: String - } - // MARK: - Instance Properties let path: [String] - let themedValue: [String: ShadowValue] + + let color: String + let type: String + let x: String + let y: String + let blur: String + let spread: String } diff --git a/Sources/FigmaGen/Generators/Tokens/Contexts/ColorToken.swift b/Sources/FigmaGen/Generators/Tokens/Contexts/ColorToken.swift index 4045970..6538217 100644 --- a/Sources/FigmaGen/Generators/Tokens/Contexts/ColorToken.swift +++ b/Sources/FigmaGen/Generators/Tokens/Contexts/ColorToken.swift @@ -2,19 +2,10 @@ import Foundation struct ColorToken: TokenProtocol, Encodable { - // MARK: - Nested Types - - struct ColorValue: Encodable { - - // MARK: - Instance Properties - - let value: String - let reference: String - } - // MARK: - Instance Properties let name: String let path: [String] - let themedValue: [String: ColorValue] + let value: String + let reference: String } diff --git a/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift b/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift index 1cd6260..f517621 100644 --- a/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift +++ b/Sources/FigmaGen/Generators/Tokens/Contexts/LinearGradientToken.swift @@ -13,14 +13,9 @@ struct LinearGradientToken: TokenProtocol, Encodable { let y: CGFloat } - struct GradientThemeValue: Encodable { - let stops: [ColorStop] - let startPoint: Point - let endPoint: Point - } - let path: [String] let name: String - - let themedValue: [String: GradientThemeValue] + let stops: [ColorStop] + let startPoint: Point + let endPoint: Point } diff --git a/Sources/FigmaGen/Generators/Tokens/Contexts/TokenThemeValue.swift b/Sources/FigmaGen/Generators/Tokens/Contexts/TokenThemeValue.swift new file mode 100644 index 0000000..45d6127 --- /dev/null +++ b/Sources/FigmaGen/Generators/Tokens/Contexts/TokenThemeValue.swift @@ -0,0 +1,12 @@ +import Foundation + +struct TokenThemeValue { + + let themeName: String + let value: T + + init(theme: String, value: T) { + self.themeName = theme + self.value = value + } +} diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/BoxShadow/DefaultBoxShadowTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/BoxShadow/DefaultBoxShadowTokensGenerator.swift index abd8df8..ee4b2ee 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/BoxShadow/DefaultBoxShadowTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/BoxShadow/DefaultBoxShadowTokensGenerator.swift @@ -28,12 +28,16 @@ final class DefaultBoxShadowTokensGenerator: BoxShadowTokensGenerator { fallbackTheme: fallbackTheme ) + let dictBoxShadows = Dictionary(uniqueKeysWithValues: boxShadows.map { ($0.themeName, $0.value) }) + try templateRenderer.renderTemplate( renderParameters.template, to: renderParameters.destination, context: [ - "boxShadows": boxShadows, - "themes": themes.map { $0.key } + "themedBoxShadows": boxShadows, + "dictBoxShadows": dictBoxShadows, + "themes": themes.map { $0.name }, + "fallbackTheme": fallbackTheme ] ) } diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/Color/DefaultColorTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/Color/DefaultColorTokensGenerator.swift index 7d17ed0..9227e24 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/Color/DefaultColorTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/Color/DefaultColorTokensGenerator.swift @@ -19,19 +19,33 @@ final class DefaultColorTokensGenerator: ColorTokensGenerator { // MARK: - Instance Methods - func generate(renderParameters: RenderParameters, tokenValues: TokenValues, themes: [Theme], fallbackTheme: Theme) throws { - let context = try colorTokensContextProvider.extractTokenContext( + func generate( + renderParameters: RenderParameters, + tokenValues: TokenValues, + themes: [Theme], + fallbackTheme: Theme + ) throws { + let colorsContext = try colorTokensContextProvider.extractTokenContext( from: tokenValues, themes: themes, fallbackTheme: fallbackTheme ) + let dictColorsContext = Dictionary( + uniqueKeysWithValues: colorsContext + .map { + ($0.themeName, $0.value) + } + ) + try templateRenderer.renderTemplate( renderParameters.template, to: renderParameters.destination, context: [ - "colors": context, - "themes": themes.map { $0.key } + "themedColors": colorsContext, + "dictThemedColors": dictColorsContext, + "themes": themes, + "fallbackTheme": fallbackTheme ] ) } diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/Gradient/DefaultGradientTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/Gradient/DefaultGradientTokensGenerator.swift index d6fd0b1..7bd1b4d 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/Gradient/DefaultGradientTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/Gradient/DefaultGradientTokensGenerator.swift @@ -23,18 +23,27 @@ struct DefaultGradientTokensGenerator: GradientTokensGenerator { themes: [Theme], fallbackTheme: Theme ) throws { - let gradientContext = try provider.extractTokenContext( + let gradientsContext = try provider.extractTokenContext( from: tokenValues, themes: themes, fallbackTheme: fallbackTheme ) + let dictGradientsContext = Dictionary( + uniqueKeysWithValues: gradientsContext + .map { + ($0.themeName, $0.value) + } + ) + try templateRenderer.renderTemplate( renderParameters.template, to: renderParameters.destination, context: [ - "gradients": gradientContext, - "themes": themes.map { $0.key } + "themedGradients": gradientsContext, + "dictThemedGradients": dictGradientsContext, + "themes": themes, + "fallbackTheme": fallbackTheme ] ) } diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/Theme/DefaultThemeTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/Theme/DefaultThemeTokensGenerator.swift index 3169b4e..3e17a57 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/Theme/DefaultThemeTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/Theme/DefaultThemeTokensGenerator.swift @@ -25,6 +25,10 @@ final class DefaultThemeTokensGenerator: ThemeTokensGenerator { // MARK: - Instance Methods + func dictionaryValue(from tokens: [TokenThemeValue]) -> [String: T] { + Dictionary(uniqueKeysWithValues: tokens.map { ($0.themeName, $0.value) }) + } + func generate( renderParameters: RenderParameters, tokenValues: TokenValues, @@ -51,10 +55,14 @@ final class DefaultThemeTokensGenerator: ThemeTokensGenerator { renderParameters.template, to: renderParameters.destination, context: [ - "colors": colorsContext, - "boxShadows": boxShadowsContext, - "gradients": gradientsContext, - "themes": themes.map { $0.key } + "themedColors": colorsContext, + "themedBoxShadows": boxShadowsContext, + "themedGradients": gradientsContext, + "dictThemedColors": dictionaryValue(from: colorsContext), + "dictThemedGradients": dictionaryValue(from: gradientsContext), + "dictBoxShadows": dictionaryValue(from: boxShadowsContext), + "themes": themes.map { $0.name }, + "fallbackTheme": fallbackTheme.name ] ) } diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/BoxShadowTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/BoxShadowTokensContextProvider.swift index 19c27da..eb56669 100644 --- a/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/BoxShadowTokensContextProvider.swift +++ b/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/BoxShadowTokensContextProvider.swift @@ -8,5 +8,5 @@ protocol BoxShadowTokensContextProvider { from tokenValues: TokenValues, themes: [Theme], fallbackTheme: Theme - ) throws -> [BoxShadowToken] + ) throws -> [TokenThemeValue<[BoxShadowToken]>] } diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/DefaultBoxShadowTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/DefaultBoxShadowTokensContextProvider.swift index 1a7c8a3..02273b5 100644 --- a/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/DefaultBoxShadowTokensContextProvider.swift +++ b/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/DefaultBoxShadowTokensContextProvider.swift @@ -4,48 +4,50 @@ final class DefaultBoxShadowTokensContextProvider: BoxShadowTokensContextProvide // MARK: - Instance Methods - private func makeTheme(value: TokenBoxShadowValue) -> BoxShadowToken.ShadowValue { - BoxShadowToken.ShadowValue( - color: value.color, - type: value.type, - x: value.x, - y: value.y, - blur: value.blur, - spread: value.spread + private func resolveBoxShadowToken( + token: TokenValue, + values: TokenValues, + theme: Theme + ) throws -> BoxShadowToken? { + let tokens = values.tokens(for: theme) + + guard let themedToken = tokens.first(where: { $0.name == token.name }) else { + return nil + } + + guard case let .boxShadow(boxShadowValue) = token.type else { + return nil + } + + return BoxShadowToken( + path: token.name.components(separatedBy: "."), + color: boxShadowValue.color, + type: boxShadowValue.type, + x: boxShadowValue.x, + y: boxShadowValue.y, + blur: boxShadowValue.blur, + spread: boxShadowValue.spread ) } private func makeBoxShadowToken( - from fallbackTokenValue: TokenValue, + from token: TokenValue, tokenValues: TokenValues, - themes: [Theme], + theme: Theme, fallbackTheme: Theme ) throws -> BoxShadowToken? { - guard case let .boxShadow(fallbackValue) = fallbackTokenValue.type else { + guard case .boxShadow(_) = token.type else { return nil } - let shadows = try themes.map { theme in - guard theme != fallbackTheme else { - return (theme.key, makeTheme(value: fallbackValue)) - } - - guard let nightTokenValue = tokenValues.tokens(for: theme).first(where: { $0.name == fallbackTokenValue.name }) else { - throw BoxShadowTokensContextProviderError(code: .valueNotFound(tokenName: fallbackTokenValue.name, theme: theme.key)) - } + let fallbackToken = try resolveBoxShadowToken(token: token, values: tokenValues, theme: fallbackTheme) + let resolvedToken = try resolveBoxShadowToken(token: token, values: tokenValues, theme: theme) - guard case let .boxShadow(boxShadowValue) = nightTokenValue.type else { - throw BoxShadowTokensContextProviderError(code: .valueNotFound(tokenName: fallbackTokenValue.name, theme: theme.key)) - } - - return (theme.key, makeTheme(value: boxShadowValue)) + guard let fallbackToken else { + throw BoxShadowTokensContextProviderError(code: .valueNotFound(tokenName: token.name, theme: theme.name)) } - - return BoxShadowToken( - path: fallbackTokenValue.name.components(separatedBy: "."), - themedValue: Dictionary(uniqueKeysWithValues: shadows) - ) + return resolvedToken ?? fallbackToken } // MARK: - @@ -54,16 +56,15 @@ final class DefaultBoxShadowTokensContextProvider: BoxShadowTokensContextProvide from tokenValues: TokenValues, themes: [Theme], fallbackTheme: Theme - ) throws -> [BoxShadowToken] { - try tokenValues.tokens(for: fallbackTheme) - .compactMap { - try makeBoxShadowToken( - from: $0, - tokenValues: tokenValues, - themes: themes, - fallbackTheme: fallbackTheme - ) - } - .sorted { $0.path.joined() < $1.path.joined() } + ) throws -> [TokenThemeValue<[BoxShadowToken]>] { + return try themes.map { theme in + let shadows = try tokenValues.tokens(for: fallbackTheme) + .compactMap { + try makeBoxShadowToken(from: $0, tokenValues: tokenValues, theme: theme, fallbackTheme: fallbackTheme) + } + .sorted { $0.path.joined() < $1.path.joined() } + + return TokenThemeValue(theme: theme.name, value: shadows) + } } } diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/ColorTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/ColorTokensContextProvider.swift index 1f327a2..8f49706 100644 --- a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/ColorTokensContextProvider.swift +++ b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/ColorTokensContextProvider.swift @@ -8,5 +8,5 @@ protocol ColorTokensContextProvider { from tokenValues: TokenValues, themes: [Theme], fallbackTheme: Theme - ) throws -> [String: Any] + ) throws -> [TokenThemeValue<[String: Any]>] } diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Colors/DefaultColorTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Colors/DefaultColorTokensContextProvider.swift new file mode 100644 index 0000000..05aae4d --- /dev/null +++ b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Colors/DefaultColorTokensContextProvider.swift @@ -0,0 +1,112 @@ +import Foundation + +final class DefaultColorTokensContextProvider: ColorTokensContextProvider { + + // MARK: - Instance Properties + + let tokensResolver: TokensResolver + + // MARK: - Initializers + + init(tokensResolver: TokensResolver) { + self.tokensResolver = tokensResolver + } + + // MARK: - Instance Methods + + private func fallbackWarning(warningPrefix: String, tokenName: String, fallbackTheme: String) { + logger.warning("\(warningPrefix) value for token '\(tokenName)' not found, using \(fallbackTheme)", isVerbose: true) + } + + private func resolveColorToken( + token: TokenValue, + theme: Theme, + tokenValues: TokenValues + ) throws -> ColorToken? { + let tokens = tokenValues.tokens(for: theme) + + guard let themeToken = tokens.first(where: { $0.name == token.name }) else { + return nil + } + + guard case .color(let themeValue) = themeToken.type else { + return nil + } + + // Resolve hex color value + let themeHexColorValue = try tokensResolver.resolveHexColorValue( + themeValue, + tokenValues: tokenValues, + theme: theme + ) + + // Resolve reference + let themeReference = try tokensResolver.resolveBaseReference(themeValue, tokenValues: tokens) + + let path = token.name.components(separatedBy: ".") + + return ColorToken( + name: token.name, + path: path, + value: themeHexColorValue, + reference: themeReference + ) + } + + func makeColorToken( + using token: TokenValue, + values: TokenValues, + theme: Theme, + fallbackTheme: Theme + ) throws -> ColorToken? { + guard case .color(let dayValue) = token.type else { + return nil + } + + let path = token.name.components(separatedBy: ".") + + guard path[0] != "gradient" && !dayValue.contains("gradient") else { + return nil + } + + let fallbackToken = try resolveColorToken(token: token, theme: fallbackTheme, tokenValues: values) + let resolvedToken = try resolveColorToken(token: token, theme: theme, tokenValues: values) + + guard let fallbackToken else { + throw DefaultColorTokensContextProviderError.fallbackTokenNotFound(token.name) + } + + guard let resolvedToken else { + fallbackWarning(warningPrefix: theme.name, tokenName: token.name, fallbackTheme: fallbackTheme.name) + return fallbackToken + } + + return resolvedToken + } + + // MARK: - + + func extractTokenContext( + from tokenValues: TokenValues, + themes: [Theme], + fallbackTheme: Theme + ) throws -> [TokenThemeValue<[String: Any]>] { + return try themes.map { theme in + let colors = try tokenValues + .tokens(for: theme) + .compactMap { token in + try makeColorToken( + using: token, + values: tokenValues, + theme: theme, + fallbackTheme: fallbackTheme + ) + } + + return TokenThemeValue( + theme: theme.name, + value: structure(tokens: colors, contextName: "colors") + ) + } + } +} diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Colors/DefaultColorTokensContextProviderError.swift b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Colors/DefaultColorTokensContextProviderError.swift new file mode 100644 index 0000000..a339dac --- /dev/null +++ b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Colors/DefaultColorTokensContextProviderError.swift @@ -0,0 +1,13 @@ +import Foundation + +enum DefaultColorTokensContextProviderError: Error, CustomStringConvertible { + + case fallbackTokenNotFound(String) + + var description: String { + switch self { + case let .fallbackTokenNotFound(tokenName): + "Fallback color token not found for \(tokenName) token." + } + } +} diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultColorTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultColorTokensContextProvider.swift deleted file mode 100644 index 54bc3c9..0000000 --- a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultColorTokensContextProvider.swift +++ /dev/null @@ -1,122 +0,0 @@ -import Foundation - -final class DefaultColorTokensContextProvider: ColorTokensContextProvider { - - // MARK: - Instance Properties - - let tokensResolver: TokensResolver - - // MARK: - Initializers - - init(tokensResolver: TokensResolver) { - self.tokensResolver = tokensResolver - } - - // MARK: - Instance Methods - - private func fallbackWarning(warningPrefix: String, tokenName: String) { - logger.warning("\(warningPrefix) value for token '\(tokenName)' not found, using day value.", isVerbose: true) - } - - private func resolveColorToken( - tokenName: String, - fallbackColorToken: ColorToken.ColorValue, - tokenValues: TokenValues, - theme: Theme - ) throws -> ColorToken.ColorValue { - let tokens = tokenValues.tokens(for: theme) - let themeData: (tokenValues: [TokenValue], warningPrefix: String) = (tokens, theme.key) - - // Resolve token and value - guard let themeToken = themeData.tokenValues.first(where: { $0.name == tokenName }) else { - fallbackWarning(warningPrefix: themeData.warningPrefix, tokenName: tokenName) - return fallbackColorToken - } - - guard case .color(let themeValue) = themeToken.type else { - fallbackWarning(warningPrefix: themeData.warningPrefix, tokenName: tokenName) - return fallbackColorToken - } - - // Resolve hex color value - let themeHexColorValue = try tokensResolver.resolveHexColorValue( - themeValue, - tokenValues: tokenValues, - theme: theme - ) - - // Resolve reference - let themeReference = try tokensResolver.resolveBaseReference(themeValue, tokenValues: themeData.tokenValues) - - return ColorToken.ColorValue(value: themeHexColorValue, reference: themeReference) - } - - private func makeColorToken( - baseTokenValue: String, - tokenName: String, - tokenValues: TokenValues, - path: [String], - themes: [Theme], - fallbackTheme: Theme - ) throws -> ColorToken { - let fallbackColorToken = ColorToken.ColorValue( - value: try tokensResolver.resolveHexColorValue( - baseTokenValue, - tokenValues: tokenValues, - theme: fallbackTheme - ), - reference: try tokensResolver.resolveBaseReference( - baseTokenValue, - tokenValues: tokenValues.tokens(for: fallbackTheme) - ) - ) - - let colors = try themes.map { theme in - guard theme != fallbackTheme else { - return (theme.key, fallbackColorToken) - } - - let token = try resolveColorToken( - tokenName: tokenName, - fallbackColorToken: fallbackColorToken, - tokenValues: tokenValues, - theme: theme - ) - - return (theme.key, token) - } - - return ColorToken( - name: tokenName, - path: path, - themedValue: Dictionary(uniqueKeysWithValues: colors) - ) - } - - // MARK: - - - func extractTokenContext(from tokenValues: TokenValues, themes: [Theme], fallbackTheme: Theme) throws -> [String: Any] { - let colors: [ColorToken] = try tokenValues.tokens(for: fallbackTheme).compactMap { (token: TokenValue) in - guard case .color(let dayValue) = token.type else { - return nil - } - - let path = token.name.components(separatedBy: ".") - - guard path[0] != "gradient" && !dayValue.contains("gradient") else { - return nil - } - - return try makeColorToken( - baseTokenValue: dayValue, - tokenName: token.name, - tokenValues: tokenValues, - path: path, - themes: themes, - fallbackTheme: fallbackTheme - ) - } - - return structure(tokens: colors, contextName: "colors") - } -} diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultGradientTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultGradientTokensContextProvider.swift deleted file mode 100644 index 886e398..0000000 --- a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/DefaultGradientTokensContextProvider.swift +++ /dev/null @@ -1,184 +0,0 @@ -import Foundation - -struct DefaultGradientTokensContextProvider: ColorTokensContextProvider { - - let tokensResolver: TokensResolver - - init(tokensResolver: TokensResolver) { - self.tokensResolver = tokensResolver - } - - // MARK: - Private methods - - private func resolvePoints(angle: CGFloat) -> (start: CGPoint, end: CGPoint)? { - let start = 3.0 * .pi / 2 - let u = start + angle - - let ucos = cos(u) - let usin = sin(u) - - let xedge = ucos > 0 ? 1.0 : 0 - let yedge = usin > 0 ? 1.0 : 0 - - let tx = ucos == 0 ? nil : (xedge - 0.5) / ucos - let ty = usin == 0 ? nil : (yedge - 0.5) / usin - - let t = [tx, ty] - .compactMap(\.self) - .filter { $0 > 0} - .min() - - guard let t else { - // Невозможно вычислить пересечение с границей - return nil - } - - let endPoint = CGPoint(x: 0.5 + t * ucos, y: 0.5 + t * usin) - let startPoint = CGPoint(x: 0.5 - t * ucos, y: 0.5 - t * usin) - - return (start: startPoint, end: endPoint) - } - - private func resolveThemeValue( - from gradient: LinearGradient, - tokenName: String - ) -> LinearGradientToken.GradientThemeValue? { - guard let points = resolvePoints(angle: gradient.radians) else { - return nil - } - - return LinearGradientToken.GradientThemeValue( - stops: gradient.colorStopList.compactMap { stop in - let percentage = stop.percentage.replacingOccurrences(of: "%", with: "") - guard let percentage = Double(percentage) else { - return nil - } - - return .init( - color: stop.color.hexString, - percentage: percentage / 100 - ) - }, - startPoint: LinearGradientToken.Point( - x: points.start.x, - y: points.start.y - ), - endPoint: LinearGradientToken.Point( - x: points.end.x, - y: points.end.y - ) - ) - } - - private func resolveGradientToken( - tokenName: String, - fallbackColorToken: LinearGradientToken.GradientThemeValue, - tokenValues: TokenValues, - theme: Theme - ) throws -> LinearGradientToken.GradientThemeValue { - let tokens = tokenValues.tokens(for: theme) - let themeData: (tokenValues: [TokenValue], warningPrefix: String) = (tokens, theme.key) - - guard let themeToken = themeData.tokenValues.first(where: { $0.name == tokenName }) else { - return fallbackColorToken - } - - guard case .color(let themeValue) = themeToken.type else { - return fallbackColorToken - } - - let gradient = try tokensResolver.resolveLinearGradientValue( - themeValue, - tokenValues: tokenValues, - theme: theme - ) - - return resolveThemeValue(from: gradient, tokenName: tokenName) ?? fallbackColorToken - } - - private func createGradientToken( - _ gradientValue: String, - tokenName: String, - path: [String], - tokenValues: TokenValues, - themes: [Theme], - fallbackTheme: Theme - ) throws -> LinearGradientToken? { - let fallbackGradient = try tokensResolver.resolveLinearGradientValue( - gradientValue, - tokenValues: tokenValues, - theme: fallbackTheme - ) - - guard let fallbackToken = resolveThemeValue(from: fallbackGradient, tokenName: tokenName) else { - return nil - } - - let gradients = try themes.map { theme in - guard theme != fallbackTheme else { - return (theme.key, fallbackToken) - } - - let gradient = try resolveGradientToken( - tokenName: tokenName, - fallbackColorToken: fallbackToken, - tokenValues: tokenValues, - theme: theme - ) - - return (theme.key, gradient) - } - - return LinearGradientToken( - path: path, - name: tokenName, - themedValue: Dictionary(uniqueKeysWithValues: gradients) - ) - } - - // TODO: @mi.fedorov поддержать мульти-темы - private func extractGradientToken( - from token: TokenValue, - tokenValues: TokenValues, - themes: [Theme], - fallbackTheme: Theme - ) throws -> LinearGradientToken? { - let path = token.name.components(separatedBy: ".") - - guard - case .color(let fallbackTokenValue) = token.type, - fallbackTokenValue.contains("gradient"), - path[0] != "color" - else { - return nil - } - - return try createGradientToken( - fallbackTokenValue, - tokenName: token.name, - path: path, - tokenValues: tokenValues, - themes: themes, - fallbackTheme: fallbackTheme - ) - } - - // MARK: - GradientTokensContextProvider - - func extractTokenContext( - from tokenValues: TokenValues, - themes: [Theme], - fallbackTheme: Theme - ) throws -> [String : Any] { - let gradient = try tokenValues.tokens(for: fallbackTheme).compactMap { - try extractGradientToken( - from: $0, - tokenValues: tokenValues, - themes: themes, - fallbackTheme: fallbackTheme - ) - } - - return structure(tokens: gradient, contextName: "gradients") - } -} diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Gradient/DefaultGradientTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Gradient/DefaultGradientTokensContextProvider.swift new file mode 100644 index 0000000..248f5c3 --- /dev/null +++ b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Gradient/DefaultGradientTokensContextProvider.swift @@ -0,0 +1,151 @@ +import Foundation + +struct DefaultGradientTokensContextProvider: ColorTokensContextProvider { + + let tokensResolver: TokensResolver + + init(tokensResolver: TokensResolver) { + self.tokensResolver = tokensResolver + } + + // MARK: - Private methods + + private func resolvePoints(angle: CGFloat) -> (start: CGPoint, end: CGPoint)? { + let start = 3.0 * .pi / 2 + let u = start + angle + + let ucos = cos(u) + let usin = sin(u) + + let xedge = ucos > 0 ? 1.0 : 0 + let yedge = usin > 0 ? 1.0 : 0 + + let tx = ucos == 0 ? nil : (xedge - 0.5) / ucos + let ty = usin == 0 ? nil : (yedge - 0.5) / usin + + let t = [tx, ty] + .compactMap(\.self) + .filter { $0 > 0 } + .min() + + guard let t else { + // Невозможно вычислить пересечение с границей + return nil + } + + let endPoint = CGPoint( + x: round((0.5 + t * ucos) * 10) / 10, + y: round((0.5 + t * usin) * 10) / 10 + ) + let startPoint = CGPoint( + x: round((0.5 - t * ucos) * 10) / 10, + y: round((0.5 - t * usin) * 10) / 10 + ) + + return (start: startPoint, end: endPoint) + } + + private func resolveGradientToken( + for token: TokenValue, + theme: Theme, + values: TokenValues + ) throws -> LinearGradientToken? { + let tokens = values.tokens(for: theme) + + guard let themeToken = tokens.first(where: { $0.name == token.name }) else { + return nil + } + + guard case .color(let themeValue) = themeToken.type else { + return nil + } + + let gradient = try tokensResolver.resolveLinearGradientValue( + themeValue, + tokenValues: values, + theme: theme + ) + + let path = token.name.components(separatedBy: ".") + + guard let points = resolvePoints(angle: gradient.radians) else { + throw DefaultGradientTokensContextProviderError.invalidAngle(token.name) + } + + return LinearGradientToken( + path: path, + name: token.name, + stops: gradient.colorStopList.compactMap { stop in + let percentage = stop.percentage.replacingOccurrences(of: "%", with: "") + guard let percentage = Double(percentage) else { + return nil + } + + return .init( + color: stop.color.hexString, + percentage: percentage / 100 + ) + }, + startPoint: LinearGradientToken.Point( + x: points.start.x, + y: points.start.y + ), + endPoint: LinearGradientToken.Point( + x: points.end.x, + y: points.end.y + ) + ) + } + + private func makeGradientToken( + from token: TokenValue, + tokenValues: TokenValues, + theme: Theme, + fallbackTheme: Theme + ) throws -> LinearGradientToken? { + let path = token.name.components(separatedBy: ".") + + guard + case .color(let fallbackTokenValue) = token.type, + fallbackTokenValue.contains("gradient"), + path[0] != "color" + else { + return nil + } + + let fallbackToken = try resolveGradientToken(for: token, theme: fallbackTheme, values: tokenValues) + let resolvedToken = try resolveGradientToken(for: token, theme: theme, values: tokenValues) + + guard let fallbackToken else { + throw DefaultGradientTokensContextProviderError.fallbackTokenNotFound(token.name) + } + + return resolvedToken ?? fallbackToken + } + + // MARK: - GradientTokensContextProvider + + func extractTokenContext( + from tokenValues: TokenValues, + themes: [Theme], + fallbackTheme: Theme + ) throws -> [TokenThemeValue<[String: Any]>] { + return try themes.map { theme in + let gradients = try tokenValues + .tokens(for: theme) + .compactMap { token in + try makeGradientToken( + from: token, + tokenValues: tokenValues, + theme: theme, + fallbackTheme: fallbackTheme + ) + } + + return TokenThemeValue( + theme: theme.name, + value: structure(tokens: gradients, contextName: "gradients") + ) + } + } +} diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Gradient/DefaultGradientTokensContextProviderError.swift b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Gradient/DefaultGradientTokensContextProviderError.swift new file mode 100644 index 0000000..1ae5169 --- /dev/null +++ b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Gradient/DefaultGradientTokensContextProviderError.swift @@ -0,0 +1,15 @@ +import Foundation + +enum DefaultGradientTokensContextProviderError: Error, CustomStringConvertible { + case invalidAngle(String) + case fallbackTokenNotFound(String) + + var description: String { + switch self { + case .invalidAngle(let tokenName): + "Invalid agnle in gradient token: \(tokenName)" + case .fallbackTokenNotFound(let tokenName): + "Fallback token not found for \(tokenName)" + } + } +} diff --git a/Sources/FigmaGen/Models/Token/Theme.swift b/Sources/FigmaGen/Models/Token/Theme.swift index 7b5114d..f45f279 100644 --- a/Sources/FigmaGen/Models/Token/Theme.swift +++ b/Sources/FigmaGen/Models/Token/Theme.swift @@ -3,28 +3,29 @@ import Foundation struct Theme: Codable, Hashable { enum CodingKeys: CodingKey { - case key + case name } - let key: String + let name: String - init(_ key: String) { - self.key = key + init(_ name: String) { + self.name = name } init(from decoder: any Decoder) throws { let container = try decoder.singleValueContainer() - if let key = try? container.decode(String.self) { - self.key = key + if let name = try? container.decode(String.self) { + self.name = name } else { let container = try decoder.container(keyedBy: CodingKeys.self) - self.key = try container.decode(String.self, forKey: .key) + self.name = try container.decode(String.self, forKey: .name) } } } extension Theme { + static let light = Theme("light") static let dark = Theme("dark") } From a37844db0ac7dcfd910ddb3db7390d2c80923c05 Mon Sep 17 00:00:00 2001 From: nschpy Date: Fri, 4 Apr 2025 02:47:00 +0300 Subject: [PATCH 18/23] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B1=D0=B0=D0=B3=D0=BE=D0=B2?= =?UTF-8?q?=20=D0=BF=D1=80=D0=B8=20=D0=B3=D0=B5=D0=BD=D0=B5=D1=80=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D0=B8=20=D1=82=D0=B5=D0=BC=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/FigmaGen/Dependencies.swift | 3 +- .../DefaultBoxShadowTokensGenerator.swift | 6 +- .../Color/DefaultColorTokensGenerator.swift | 2 +- .../DefaultGradientTokensGenerator.swift | 2 +- .../Theme/DefaultThemeTokensGenerator.swift | 4 +- ...efaultBoxShadowTokensContextProvider.swift | 12 +++- .../DefaultColorTokensContextProvider.swift | 10 +-- ...faultColorTokensContextProviderError.swift | 13 ---- ...DefaultGradientTokensContextProvider.swift | 12 +++- .../StencilRecursiveTokenFindModicator.swift | 72 +++++++++++++++++++ 10 files changed, 106 insertions(+), 30 deletions(-) delete mode 100644 Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Colors/DefaultColorTokensContextProviderError.swift create mode 100644 Sources/FigmaGen/Render/StencilExtensions/Tokens/StencilRecursiveTokenFindModicator.swift diff --git a/Sources/FigmaGen/Dependencies.swift b/Sources/FigmaGen/Dependencies.swift index 8201736..05b0312 100644 --- a/Sources/FigmaGen/Dependencies.swift +++ b/Sources/FigmaGen/Dependencies.swift @@ -109,7 +109,8 @@ enum Dependencies { StencilCollectionDropLastModificator(), StencilCollectionRemovingFirstModificator(), StencilHexToAlphaFilter(), - StencilFullHexModificator() + StencilFullHexModificator(), + StencilRecursiveTokenFindModicator() ] static let templateRenderer: TemplateRenderer = DefaultTemplateRenderer( diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/BoxShadow/DefaultBoxShadowTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/BoxShadow/DefaultBoxShadowTokensGenerator.swift index ee4b2ee..602cae0 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/BoxShadow/DefaultBoxShadowTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/BoxShadow/DefaultBoxShadowTokensGenerator.swift @@ -35,9 +35,9 @@ final class DefaultBoxShadowTokensGenerator: BoxShadowTokensGenerator { to: renderParameters.destination, context: [ "themedBoxShadows": boxShadows, - "dictBoxShadows": dictBoxShadows, - "themes": themes.map { $0.name }, - "fallbackTheme": fallbackTheme + "dictThemedBoxShadows": dictBoxShadows, + "themes": themes, + "fallbackTheme": fallbackTheme.name ] ) } diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/Color/DefaultColorTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/Color/DefaultColorTokensGenerator.swift index 9227e24..f9dac3d 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/Color/DefaultColorTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/Color/DefaultColorTokensGenerator.swift @@ -45,7 +45,7 @@ final class DefaultColorTokensGenerator: ColorTokensGenerator { "themedColors": colorsContext, "dictThemedColors": dictColorsContext, "themes": themes, - "fallbackTheme": fallbackTheme + "fallbackTheme": fallbackTheme.name ] ) } diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/Gradient/DefaultGradientTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/Gradient/DefaultGradientTokensGenerator.swift index 7bd1b4d..0940cff 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/Gradient/DefaultGradientTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/Gradient/DefaultGradientTokensGenerator.swift @@ -43,7 +43,7 @@ struct DefaultGradientTokensGenerator: GradientTokensGenerator { "themedGradients": gradientsContext, "dictThemedGradients": dictGradientsContext, "themes": themes, - "fallbackTheme": fallbackTheme + "fallbackTheme": fallbackTheme.name ] ) } diff --git a/Sources/FigmaGen/Generators/Tokens/Generators/Theme/DefaultThemeTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/Generators/Theme/DefaultThemeTokensGenerator.swift index 3e17a57..6ab74f4 100644 --- a/Sources/FigmaGen/Generators/Tokens/Generators/Theme/DefaultThemeTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/Generators/Theme/DefaultThemeTokensGenerator.swift @@ -60,8 +60,8 @@ final class DefaultThemeTokensGenerator: ThemeTokensGenerator { "themedGradients": gradientsContext, "dictThemedColors": dictionaryValue(from: colorsContext), "dictThemedGradients": dictionaryValue(from: gradientsContext), - "dictBoxShadows": dictionaryValue(from: boxShadowsContext), - "themes": themes.map { $0.name }, + "dictThemedBoxShadows": dictionaryValue(from: boxShadowsContext), + "themes": themes, "fallbackTheme": fallbackTheme.name ] ) diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/DefaultBoxShadowTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/DefaultBoxShadowTokensContextProvider.swift index 02273b5..6565122 100644 --- a/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/DefaultBoxShadowTokensContextProvider.swift +++ b/Sources/FigmaGen/Generators/Tokens/Providers/BoxShadowTokensContext/DefaultBoxShadowTokensContextProvider.swift @@ -15,7 +15,7 @@ final class DefaultBoxShadowTokensContextProvider: BoxShadowTokensContextProvide return nil } - guard case let .boxShadow(boxShadowValue) = token.type else { + guard case let .boxShadow(boxShadowValue) = themedToken.type else { return nil } @@ -44,7 +44,15 @@ final class DefaultBoxShadowTokensContextProvider: BoxShadowTokensContextProvide let resolvedToken = try resolveBoxShadowToken(token: token, values: tokenValues, theme: theme) guard let fallbackToken else { - throw BoxShadowTokensContextProviderError(code: .valueNotFound(tokenName: token.name, theme: theme.name)) + logger.warning("Fallback token not found for \(token.name)", isVerbose: true) + return nil + } + + if resolvedToken.isNil { + logger.warning( + "\(theme.name) value for token '\(token.name)' not found, using \(fallbackTheme.name)", + isVerbose: true + ) } return resolvedToken ?? fallbackToken diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Colors/DefaultColorTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Colors/DefaultColorTokensContextProvider.swift index 05aae4d..7ab1536 100644 --- a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Colors/DefaultColorTokensContextProvider.swift +++ b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Colors/DefaultColorTokensContextProvider.swift @@ -73,15 +73,15 @@ final class DefaultColorTokensContextProvider: ColorTokensContextProvider { let resolvedToken = try resolveColorToken(token: token, theme: theme, tokenValues: values) guard let fallbackToken else { - throw DefaultColorTokensContextProviderError.fallbackTokenNotFound(token.name) + logger.warning("Fallback token not found for \(token.name)", isVerbose: true) + return nil } - guard let resolvedToken else { + if resolvedToken.isNil { fallbackWarning(warningPrefix: theme.name, tokenName: token.name, fallbackTheme: fallbackTheme.name) - return fallbackToken } - return resolvedToken + return resolvedToken ?? fallbackToken } // MARK: - @@ -93,7 +93,7 @@ final class DefaultColorTokensContextProvider: ColorTokensContextProvider { ) throws -> [TokenThemeValue<[String: Any]>] { return try themes.map { theme in let colors = try tokenValues - .tokens(for: theme) + .tokens(for: fallbackTheme) .compactMap { token in try makeColorToken( using: token, diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Colors/DefaultColorTokensContextProviderError.swift b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Colors/DefaultColorTokensContextProviderError.swift deleted file mode 100644 index a339dac..0000000 --- a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Colors/DefaultColorTokensContextProviderError.swift +++ /dev/null @@ -1,13 +0,0 @@ -import Foundation - -enum DefaultColorTokensContextProviderError: Error, CustomStringConvertible { - - case fallbackTokenNotFound(String) - - var description: String { - switch self { - case let .fallbackTokenNotFound(tokenName): - "Fallback color token not found for \(tokenName) token." - } - } -} diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Gradient/DefaultGradientTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Gradient/DefaultGradientTokensContextProvider.swift index 248f5c3..8a9efa4 100644 --- a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Gradient/DefaultGradientTokensContextProvider.swift +++ b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Gradient/DefaultGradientTokensContextProvider.swift @@ -117,7 +117,15 @@ struct DefaultGradientTokensContextProvider: ColorTokensContextProvider { let resolvedToken = try resolveGradientToken(for: token, theme: theme, values: tokenValues) guard let fallbackToken else { - throw DefaultGradientTokensContextProviderError.fallbackTokenNotFound(token.name) + logger.warning("Fallback token not found for \(token.name)", isVerbose: true) + return nil + } + + if resolvedToken.isNil { + logger.warning( + "\(theme.name) value for token '\(token.name)' not found, using \(fallbackTheme.name)", + isVerbose: true + ) } return resolvedToken ?? fallbackToken @@ -132,7 +140,7 @@ struct DefaultGradientTokensContextProvider: ColorTokensContextProvider { ) throws -> [TokenThemeValue<[String: Any]>] { return try themes.map { theme in let gradients = try tokenValues - .tokens(for: theme) + .tokens(for: fallbackTheme) .compactMap { token in try makeGradientToken( from: token, diff --git a/Sources/FigmaGen/Render/StencilExtensions/Tokens/StencilRecursiveTokenFindModicator.swift b/Sources/FigmaGen/Render/StencilExtensions/Tokens/StencilRecursiveTokenFindModicator.swift new file mode 100644 index 0000000..d98044b --- /dev/null +++ b/Sources/FigmaGen/Render/StencilExtensions/Tokens/StencilRecursiveTokenFindModicator.swift @@ -0,0 +1,72 @@ +import Foundation + +struct StencilRecursiveTokenFindModicator: StencilModificator { + + // MARK: - Instance Properties + + let name = "findTokenInThemes" + + // MARK: - Instance Methods + + func modify(input: Any, withArguments arguments: [Any?]) throws -> Any { + guard arguments.count > 1 else { + throw StencilModificatorError(code: .invalidArguments(arguments), filter: name) + } + + guard + let themesDict = input as? [String: [String: Any]], + let pathString = arguments[0] as? String, + let key = arguments[1] as? String + else { + return input + } + + let pathComponents = pathString.split(separator: ".").map(String.init) + var result: [String: Any] = [:] + + for (themeName, structuredDict) in themesDict { + if let token = findToken( + in: structuredDict, + name: pathString, + path: pathComponents, + key: key + ) { + result[themeName] = token + } + } + + return result + } + + private func findToken( + in dict: [String: Any], + name: String, + path: [String], + key: String + ) -> Any? { + if let tokens = dict[key] as? [TokenProtocol], let found = tokens.first(where: { $0.name == name }) { + return found + } + + guard !path.isEmpty else { + return nil + } + + guard let children = dict["children"] as? [[String: Any]] else { + return nil + } + + for child in children { + if let childName = child["name"] as? String, childName == path[0] { + return findToken( + in: child, + name: name, + path: Array(path.dropFirst()), + key: key + ) + } + } + + return nil + } +} From 3d8befc292cc03d715df78e8e3b995772620680c Mon Sep 17 00:00:00 2001 From: nschpy Date: Mon, 7 Apr 2025 18:38:12 +0300 Subject: [PATCH 19/23] =?UTF-8?q?=D0=A3=D0=BB=D1=83=D1=87=D1=88=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D0=BA=D0=BE=D0=B4=D0=B0=20+=20=D0=B8?= =?UTF-8?q?=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=BD=D0=B0=D0=B7?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=B3=D1=80=D0=B0=D0=B4=D0=B8?= =?UTF-8?q?=D0=B5=D0=BD=D1=82=D0=BE=D0=B2=20=D0=B2=20=D0=BA=D0=BE=D0=BD?= =?UTF-8?q?=D1=84=D0=B8=D0=B3=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/FigmaGen/Commands/TokensCommand.swift | 6 +++--- .../Generators/Tokens/DefaultTokensGenerator.swift | 2 +- .../DefaultTokensGenerationParametersResolver.swift | 4 ++-- .../Colors/DefaultColorTokensContextProvider.swift | 2 +- .../DefaultGradientTokensContextProvider.swift | 10 +++++----- .../Tokens/TokensTemplateConfiguration.swift | 6 +++--- .../Models/Parameters/TokensGenerationParameters.swift | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Sources/FigmaGen/Commands/TokensCommand.swift b/Sources/FigmaGen/Commands/TokensCommand.swift index 8213276..0266c79 100644 --- a/Sources/FigmaGen/Commands/TokensCommand.swift +++ b/Sources/FigmaGen/Commands/TokensCommand.swift @@ -70,9 +70,9 @@ final class TokensCommand: AsyncExecutableCommand { let themes = VariadicKey( "--themes", - description: #""" + description: """ An option that will be merged with template context. - """# + """ ) let fallbackTheme = Key( @@ -385,7 +385,7 @@ extension TokensCommand { destination: bordersDestination.value ) ], - gradient: [ + gradients: [ TemplateConfiguration( template: gradientTemplate.value, templateOptions: resolveTemplateOptions(gradientTemplateOptions.value), diff --git a/Sources/FigmaGen/Generators/Tokens/DefaultTokensGenerator.swift b/Sources/FigmaGen/Generators/Tokens/DefaultTokensGenerator.swift index e511a61..9994435 100644 --- a/Sources/FigmaGen/Generators/Tokens/DefaultTokensGenerator.swift +++ b/Sources/FigmaGen/Generators/Tokens/DefaultTokensGenerator.swift @@ -164,7 +164,7 @@ final class DefaultTokensGenerator: TokensGenerator { try generateTokens( gradientTokensGenerator, tokensName: "gradients", - renderParameters: parameters.tokens.gradientRenderParameters, + renderParameters: parameters.tokens.gradientsRenderParameters, tokenValues: tokenValues, themes: parameters.themes, fallbackTheme: parameters.fallbackTheme diff --git a/Sources/FigmaGen/Generators/Tokens/GenerationParametersResolver/DefaultTokensGenerationParametersResolver.swift b/Sources/FigmaGen/Generators/Tokens/GenerationParametersResolver/DefaultTokensGenerationParametersResolver.swift index 099e831..68a5667 100644 --- a/Sources/FigmaGen/Generators/Tokens/GenerationParametersResolver/DefaultTokensGenerationParametersResolver.swift +++ b/Sources/FigmaGen/Generators/Tokens/GenerationParametersResolver/DefaultTokensGenerationParametersResolver.swift @@ -98,7 +98,7 @@ final class DefaultTokensGenerationParametersResolver: TokensGenerationParameter ) let gradientRenderParameters = renderParametersResolver.resolveRenderParameters( - templates: configuration.templates?.gradient, + templates: configuration.templates?.gradients, defaultTemplateType: .native(name: "GradientTokens") ) @@ -116,7 +116,7 @@ final class DefaultTokensGenerationParametersResolver: TokensGenerationParameter themeRenderParameters: themeRenderParameters, spacingRenderParameters: spacingRenderParameters, bordersRenderParameters: borderRenderParameters, - gradientRenderParameters: gradientRenderParameters + gradientsRenderParameters: gradientRenderParameters ) ) } diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Colors/DefaultColorTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Colors/DefaultColorTokensContextProvider.swift index 7ab1536..b8608b5 100644 --- a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Colors/DefaultColorTokensContextProvider.swift +++ b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Colors/DefaultColorTokensContextProvider.swift @@ -65,7 +65,7 @@ final class DefaultColorTokensContextProvider: ColorTokensContextProvider { let path = token.name.components(separatedBy: ".") - guard path[0] != "gradient" && !dayValue.contains("gradient") else { + guard path.first != "gradient" && !dayValue.contains("gradient") else { return nil } diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Gradient/DefaultGradientTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Gradient/DefaultGradientTokensContextProvider.swift index 8a9efa4..64666d2 100644 --- a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Gradient/DefaultGradientTokensContextProvider.swift +++ b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Gradient/DefaultGradientTokensContextProvider.swift @@ -34,12 +34,12 @@ struct DefaultGradientTokensContextProvider: ColorTokensContextProvider { } let endPoint = CGPoint( - x: round((0.5 + t * ucos) * 10) / 10, - y: round((0.5 + t * usin) * 10) / 10 + x: round((0.5 + t * ucos) * 1000) / 1000, + y: round((0.5 + t * usin) * 1000) / 1000 ) let startPoint = CGPoint( - x: round((0.5 - t * ucos) * 10) / 10, - y: round((0.5 - t * usin) * 10) / 10 + x: round((0.5 - t * ucos) * 1000) / 1000, + y: round((0.5 - t * usin) * 1000) / 1000 ) return (start: startPoint, end: endPoint) @@ -108,7 +108,7 @@ struct DefaultGradientTokensContextProvider: ColorTokensContextProvider { guard case .color(let fallbackTokenValue) = token.type, fallbackTokenValue.contains("gradient"), - path[0] != "color" + path.first != "color" else { return nil } diff --git a/Sources/FigmaGen/Models/Configuration/Tokens/TokensTemplateConfiguration.swift b/Sources/FigmaGen/Models/Configuration/Tokens/TokensTemplateConfiguration.swift index 532368c..a3c9ec9 100644 --- a/Sources/FigmaGen/Models/Configuration/Tokens/TokensTemplateConfiguration.swift +++ b/Sources/FigmaGen/Models/Configuration/Tokens/TokensTemplateConfiguration.swift @@ -13,7 +13,7 @@ struct TokensTemplateConfiguration { let theme: [TemplateConfiguration]? let spacing: [TemplateConfiguration]? let borders: [TemplateConfiguration]? - let gradient: [TemplateConfiguration]? + let gradients: [TemplateConfiguration]? } // MARK: - Decodable @@ -31,7 +31,7 @@ extension TokensTemplateConfiguration: Decodable { case theme case spacing case borders - case gradient + case gradients } // MARK: - Initializers @@ -53,6 +53,6 @@ extension TokensTemplateConfiguration: Decodable { theme = try container.decodeIfPresent(TemplateConfigurationWrapper.self, forKey: .theme)?.templates spacing = try container.decodeIfPresent(TemplateConfigurationWrapper.self, forKey: .spacing)?.templates borders = try? container.decodeIfPresent(TemplateConfigurationWrapper.self, forKey: .borders)?.templates - gradient = try? container.decodeIfPresent(TemplateConfigurationWrapper.self, forKey: .gradient)?.templates + gradients = try? container.decodeIfPresent(TemplateConfigurationWrapper.self, forKey: .gradients)?.templates } } diff --git a/Sources/FigmaGen/Models/Parameters/TokensGenerationParameters.swift b/Sources/FigmaGen/Models/Parameters/TokensGenerationParameters.swift index 6ef83c3..248a679 100644 --- a/Sources/FigmaGen/Models/Parameters/TokensGenerationParameters.swift +++ b/Sources/FigmaGen/Models/Parameters/TokensGenerationParameters.swift @@ -16,7 +16,7 @@ struct TokensGenerationParameters { let themeRenderParameters: [RenderParameters]? let spacingRenderParameters: [RenderParameters]? let bordersRenderParameters: [RenderParameters]? - let gradientRenderParameters: [RenderParameters]? + let gradientsRenderParameters: [RenderParameters]? } // MARK: - Instance Properties From 0f8fa4e90944518bab955ea2fda986cd135daae7 Mon Sep 17 00:00:00 2001 From: nschpy Date: Tue, 8 Apr 2025 16:41:08 +0300 Subject: [PATCH 20/23] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D1=88=D0=B0=D0=B1=D0=BB=D0=BE=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Demo/.figmagen.yml | 4 + .../FigmaGenDemo/Generated/BorderTokens.swift | 142 +----------------- .../Generated/BoxShadowTokens.swift | 39 +++-- Demo/FigmaGenDemo/Generated/ColorTokens.swift | 40 ++--- Demo/FigmaGenDemo/Generated/Theme.swift | 5 +- Templates/BoxShadowTokens.stencil | 21 ++- Templates/ColorTokens.stencil | 6 +- Templates/GradientTokens.stencil | 14 +- Templates/Theme.stencil | 36 ++--- 9 files changed, 87 insertions(+), 220 deletions(-) diff --git a/Demo/.figmagen.yml b/Demo/.figmagen.yml index 40c3d07..a027a90 100644 --- a/Demo/.figmagen.yml +++ b/Demo/.figmagen.yml @@ -39,6 +39,10 @@ shadowStyles: tokens: file: https://www.figma.com/file/W6dy4CFSZWUVpVnSzNZIxA/FigmaGen-Tokens-Demo + themes: + - hh-day + - hh-night + fallbackTheme: hh-day templates: colors: - destination: FigmaGenDemo/Generated/ColorTokens.swift diff --git a/Demo/FigmaGenDemo/Generated/BorderTokens.swift b/Demo/FigmaGenDemo/Generated/BorderTokens.swift index 54f1d0c..93c9748 100644 --- a/Demo/FigmaGenDemo/Generated/BorderTokens.swift +++ b/Demo/FigmaGenDemo/Generated/BorderTokens.swift @@ -1,143 +1,3 @@ // swiftlint:disable all // Generated using FigmaGen - https://github.com/hhru/FigmaGen - -#if canImport(UIKit) -import UIKit -#else -import AppKit -#endif - -public struct BorderToken: Hashable { - public let width: CGFloat - public let style: String - - public init(width: CGFloat, style: String) { - self.width = width - self.style = style - } -} - -internal struct BorderTokens { - // MARK: - Instance Properties - - /// semantic.border.applied - /// - /// Width: 2 - /// Style: solid - internal var semanticBorderApplied: BorderToken { - BorderToken( - width: 2, - style: "solid" - ) - } - - /// semantic.border.checkable - /// - /// Width: 1.5 - /// Style: solid - internal var semanticBorderCheckable: BorderToken { - BorderToken( - width: 1.5, - style: "solid" - ) - } - - /// semantic.border.dashed-default - /// - /// Width: 2 - /// Style: dashed - internal var semanticBorderDashedDefault: BorderToken { - BorderToken( - width: 2, - style: "dashed" - ) - } - - /// semantic.border.dashed-focused - /// - /// Width: 2 - /// Style: dashed - internal var semanticBorderDashedFocused: BorderToken { - BorderToken( - width: 2, - style: "dashed" - ) - } - - /// semantic.border.default - /// - /// Width: 1 - /// Style: solid - internal var semanticBorderDefault: BorderToken { - BorderToken( - width: 1, - style: "solid" - ) - } - - /// semantic.border.disabled - /// - /// Width: 1 - /// Style: solid - internal var semanticBorderDisabled: BorderToken { - BorderToken( - width: 1, - style: "solid" - ) - } - - /// semantic.border.focused - /// - /// Width: 2 - /// Style: solid - internal var semanticBorderFocused: BorderToken { - BorderToken( - width: 2, - style: "solid" - ) - } - - /// semantic.border.hovered - /// - /// Width: 1 - /// Style: solid - internal var semanticBorderHovered: BorderToken { - BorderToken( - width: 1, - style: "solid" - ) - } - - /// semantic.border.invalid - /// - /// Width: 1 - /// Style: solid - internal var semanticBorderInvalid: BorderToken { - BorderToken( - width: 1, - style: "solid" - ) - } - - /// semantic.border.selected - /// - /// Width: 2 - /// Style: solid - internal var semanticBorderSelected: BorderToken { - BorderToken( - width: 2, - style: "solid" - ) - } - - /// semantic.border.tab-focused - /// - /// Width: 4 - /// Style: solid - internal var semanticBorderTabFocused: BorderToken { - BorderToken( - width: 4, - style: "solid" - ) - } -} +// No border tokens found diff --git a/Demo/FigmaGenDemo/Generated/BoxShadowTokens.swift b/Demo/FigmaGenDemo/Generated/BoxShadowTokens.swift index 83bf8dd..99d68fc 100644 --- a/Demo/FigmaGenDemo/Generated/BoxShadowTokens.swift +++ b/Demo/FigmaGenDemo/Generated/BoxShadowTokens.swift @@ -8,25 +8,34 @@ import AppKit public struct BoxShadowTokens { - /// level-1 - /// - /// Offset: day – x 0; y 4 / night – x 0; y 4 - /// Radius: day – 12 / night – 12 - /// Color: day – #7090b029 / night – #7090b029 + /// - hh-day: + /// Offset: x 0; y 4 + /// Radius: 12 + /// Color: #7090b029 + /// - hh-night: + /// Offset: x 0; y 4 + /// Radius: 12 + /// Color: #7090b029 public let level1: ShadowToken - /// level-2 - /// - /// Offset: day – x 0; y 8 / night – x 0; y 8 - /// Radius: day – 16 / night – 16 - /// Color: day – #7090b03d / night – #7090b03d + /// - hh-day: + /// Offset: x 0; y 8 + /// Radius: 16 + /// Color: #7090b03d + /// - hh-night: + /// Offset: x 0; y 8 + /// Radius: 16 + /// Color: #7090b03d public let level2: ShadowToken - /// level-3 - /// - /// Offset: day – x 0; y 12 / night – x 0; y 12 - /// Radius: day – 24 / night – 24 - /// Color: day – #7090b052 / night – #7090b052 + /// - hh-day: + /// Offset: x 0; y 12 + /// Radius: 24 + /// Color: #7090b052 + /// - hh-night: + /// Offset: x 0; y 12 + /// Radius: 24 + /// Color: #7090b052 public let level3: ShadowToken } diff --git a/Demo/FigmaGenDemo/Generated/ColorTokens.swift b/Demo/FigmaGenDemo/Generated/ColorTokens.swift index edb82ef..5d84619 100644 --- a/Demo/FigmaGenDemo/Generated/ColorTokens.swift +++ b/Demo/FigmaGenDemo/Generated/ColorTokens.swift @@ -11,18 +11,18 @@ public struct ColorTokens { public struct Accent { /// accent.bg /// - /// Day: #c3dafe - /// Night: #434190 + /// hh-day: #c3dafe + /// hh-night: #434190 public let bg: UIColor /// accent.default /// - /// Day: #7f9cf5 - /// Night: #5a67d8 + /// hh-day: #7f9cf5 + /// hh-night: #5a67d8 public let `default`: UIColor /// accent.onAccent /// - /// Day: #ffffff - /// Night: #ffffff + /// hh-day: #ffffff + /// hh-night: #ffffff public let onAccent: UIColor } @@ -30,18 +30,18 @@ public struct ColorTokens { public struct Bg { /// bg.default /// - /// Day: #ffffff - /// Night: #1a202c + /// hh-day: #ffffff + /// hh-night: #1a202c public let `default`: UIColor /// bg.muted /// - /// Day: #f7fafc - /// Night: #4a5568 + /// hh-day: #f7fafc + /// hh-night: #4a5568 public let muted: UIColor /// bg.subtle /// - /// Day: #edf2f7 - /// Night: #718096 + /// hh-day: #edf2f7 + /// hh-night: #718096 public let subtle: UIColor } @@ -49,18 +49,18 @@ public struct ColorTokens { public struct Fg { /// fg.default /// - /// Day: #000000 - /// Night: #ffffff + /// hh-day: #000000 + /// hh-night: #ffffff public let `default`: UIColor /// fg.muted /// - /// Day: #4a5568 - /// Night: #e2e8f0 + /// hh-day: #4a5568 + /// hh-night: #e2e8f0 public let muted: UIColor /// fg.subtle /// - /// Day: #a0aec0 - /// Night: #a0aec0 + /// hh-day: #a0aec0 + /// hh-night: #a0aec0 public let subtle: UIColor } @@ -68,8 +68,8 @@ public struct ColorTokens { public struct Shadows { /// shadows.default /// - /// Day: #1a202c - /// Night: #00000000 + /// hh-day: #1a202c + /// hh-night: #00000000 public let `default`: UIColor } diff --git a/Demo/FigmaGenDemo/Generated/Theme.swift b/Demo/FigmaGenDemo/Generated/Theme.swift index b5b9966..c159b81 100644 --- a/Demo/FigmaGenDemo/Generated/Theme.swift +++ b/Demo/FigmaGenDemo/Generated/Theme.swift @@ -26,7 +26,7 @@ public struct Theme { extension Theme { - public static let defaultLight = Self( + public static let hhDay = Self( colors: ColorTokens( accent: ColorTokens.Accent( bg: UIColor(hex: 0xC3DAFEFF), @@ -68,8 +68,7 @@ extension Theme { ) ) ) - - public static let defaultDark = Self( + public static let hhNight = Self( colors: ColorTokens( accent: ColorTokens.Accent( bg: UIColor(hex: 0x434190FF), diff --git a/Templates/BoxShadowTokens.stencil b/Templates/BoxShadowTokens.stencil index 42e2364..4f02db5 100644 --- a/Templates/BoxShadowTokens.stencil +++ b/Templates/BoxShadowTokens.stencil @@ -1,5 +1,5 @@ {% include "FileHeader.stencil" %} -{% if boxShadows %} +{% if dictThemedBoxShadows[fallbackTheme] %} {% set accessModifier %}{% if options.publicAccess %}public{% else %}internal{% endif %}{% endset %} {% set tokenTypeName %}{{ options.tokenTypeName|default:"BoxShadowTokens" }}{% endset %} {% set shadowTypeName %}{{ options.shadowTypeName|default:"Shadow" }}{% endset %} @@ -14,13 +14,18 @@ import AppKit #endif {{ accessModifier }} struct {{ tokenTypeName }} { - {% for boxShadow in boxShadows %} - - /// {{ boxShadow.path|dropFirst|join:" " }} - /// - /// Offset: day – x {{ boxShadow.dayTheme.x }}; y {{ boxShadow.nightTheme.y }} / night – x {{ boxShadow.nightTheme.x }}; y {{ boxShadow.nightTheme.y }} - /// Radius: day – {{ boxShadow.dayTheme.blur }} / night – {{ boxShadow.nightTheme.blur }} - /// Color: day – {{ boxShadow.dayTheme.color }} / night – {{ boxShadow.nightTheme.color }} + {% outer: for boxShadow in dictThemedBoxShadows[fallbackTheme] %} + + {% for themedValue in themedBoxShadows %} + {% for shadowToken in themedValue.value %} + {% if forloop.outer.counter == forloop.counter %} + /// - {{ themedValue.themeName }}: + /// Offset: x {{ shadowToken.x }}; y {{ shadowToken.y }} + /// Radius: {{ shadowToken.blur }} + /// Color: {{ shadowToken.color }} + {% endif %} + {% endfor %} + {% endfor %} {{ accessModifier }} let {% call propertyName boxShadow.path.last %}: {{ shadowTypeName }} {% endfor %} } diff --git a/Templates/ColorTokens.stencil b/Templates/ColorTokens.stencil index 95c0cc4..f947781 100644 --- a/Templates/ColorTokens.stencil +++ b/Templates/ColorTokens.stencil @@ -1,5 +1,5 @@ {% include "FileHeader.stencil" %} -{% if colors %} +{% if dictThemedColors[fallbackTheme] %} {% set colorTypeName %}{{ options.colorTypeName|default:"UIColor" }}{% endset %} {% set accessModifier %}{% if options.publicAccess %}public{% else %}internal{% endif %}{% endset %} {% set tokenTypeName %}{{ options.tokenTypeName|default:"ColorTokens" }}{% endset %} @@ -9,7 +9,7 @@ {% for color in item.colors %} /// {{ color.name }} /// - {% for theme, token in color.themedValue %} + {% for theme, token in dictThemedColors|findTokenInThemes:color.name,"colors" %} /// {{ theme }}: {{ token.value }} {% endfor %} {{ accessModifier }} let {% call propertyName color.path.last %}: {{ colorTypeName }} @@ -32,7 +32,7 @@ import AppKit #endif {{ accessModifier }} struct {{ tokenTypeName }} { - {% call recursiveBlock colors %} + {% call recursiveBlock dictThemedColors[fallbackTheme] %} } {% else %} // No color tokens found diff --git a/Templates/GradientTokens.stencil b/Templates/GradientTokens.stencil index 8f1a445..7f25690 100644 --- a/Templates/GradientTokens.stencil +++ b/Templates/GradientTokens.stencil @@ -1,5 +1,5 @@ {% include "FileHeader.stencil" %} -{% if gradients %} +{% if dictThemedGradients[fallbackTheme] %} {% set gradientTypeName %}{{ options.colorTypeName|default:"LinearGradient" }}{% endset %} {% macro propertyName name %}{{ name|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords }}{% endmacro %} {% macro typeName name %}{{ name|swiftIdentifier:"pretty"|upperFirstLetter|escapeReservedKeywords }}{% endmacro %} @@ -8,13 +8,11 @@ /// {{ gradient.name }} /// - /// Day Theme: - {% for stop in gradient.dayTheme.stops %} - /// - {{ stop.color }} {{ stop.percentage }}% + {% for theme, token in dictThemedGradients|findTokenInThemes:gradient.name,"gradients" %} + /// {{ theme }}: + {% for stop in token.stops %} + /// - {{ stop.color }} {{ stop.percentage }} {% endfor %} - /// Night Theme: - {% for stop in gradient.nightTheme.stops %} - /// - {{ stop.color }} {{ stop.percentage }}% {% endfor %} public let {% call propertyName gradient.path.last %}: {{ gradientTypeName }} {% endfor %} @@ -36,7 +34,7 @@ import SwiftUI public struct Gradients { - {% call recursiveBlock gradients %} + {% call recursiveBlock dictThemedGradients[fallbackTheme] %} } {% else %} // No color tokens found diff --git a/Templates/Theme.stencil b/Templates/Theme.stencil index b43e647..4311be6 100644 --- a/Templates/Theme.stencil +++ b/Templates/Theme.stencil @@ -11,11 +11,7 @@ {% macro hexColor color %}{{ color|fullHex|uppercase|replace:"#","0x" }}{% endmacro %} {% macro argumentsBlock item theme parentTypeName %} {% for color in item.colors %} -{% if color.themedValue[theme] %} -{% call propertyName color.path.last %}: {{ colorTypeName }}(hex: {% call hexColor color.themedValue[theme].value %}){% if not forloop.last %},{% endif %} -{% else %} - {% continue %} -{% endif %} +{% call propertyName color.path.last %}: {{ colorTypeName }}(hex: {% call hexColor color.value %}){% if not forloop.last %},{% endif %} {% endfor %} {% for child in item.children %} {% set childTypeName %}{% if parentTypeName %}{{ parentTypeName }}.{% endif %}{% call typeName child.name %}{% endset %} @@ -39,16 +35,12 @@ colors: {{ colorTokensTypeName }}( {% if boxShadows %} shadows: {{ boxShadowTokensTypeName }}( {% for boxShadow in boxShadows %} - {% if boxShadow.themedValue[theme] %} {% call propertyName boxShadow.path.last %}: {{ shadowTypeName }}( - offset: CGSize(width: {{ boxShadow.themedValue[theme].x }}, height: {{ boxShadow.themedValue[theme].y }}), - radius: {{ boxShadow[theme].blur }}, - color: {{ colorTypeName }}(hex: {% call hexColor boxShadow.themedValue[theme].color %}), + offset: CGSize(width: {{ boxShadow.x }}, height: {{ boxShadow.y }}), + radius: {{ boxShadow.blur }}, + color: {{ colorTypeName }}(hex: {% call hexColor boxShadow.color %}), opacity: 1.0 ){% if not forloop.last %},{% endif %} - {% else %} - {% continue %} - {% endif %} {% endfor %} ) {% endif %} @@ -62,27 +54,27 @@ import AppKit {{ accessModifier }} struct {{ themeTypeName }} { - {% if colors %} + {% if dictThemedColors[fallbackTheme] %} {{ accessModifier }} let colors: {{ colorTokensTypeName }} {% endif %} - {% if boxShadows %} + {% if dictThemedBoxShadows[fallbackTheme] %} {{ accessModifier }} let shadows: {{ boxShadowTokensTypeName }} {% endif %} {{ accessModifier }} let typographies: {{ typographyTokensTypeName }} init( - {% if colors %} + {% if dictThemedColors[fallbackTheme] %} colors: {{ colorTokensTypeName }}, {% endif %} - {% if boxShadows %} + {% if dictThemedBoxShadows[fallbackTheme] %} shadows: {{ boxShadowTokensTypeName }}, {% endif %} typographies: {{ typographyTokensTypeName }} = {{ typographyTokensTypeName }}() ) { - {% if colors %} + {% if dictThemedColors[fallbackTheme] %} self.colors = colors {% endif %} - {% if boxShadows %} + {% if dictThemedBoxShadows[fallbackTheme] %} self.shadows = shadows {% endif %} self.typographies = typographies @@ -92,17 +84,17 @@ import AppKit extension {{ themeTypeName }} { {% for theme in themes %} - {% set themePropertyName %}{{ theme||swiftIdentifier:"pretty"|lowerFirstWord }}{% endset %} + {% set themePropertyName %}{{ theme.name||swiftIdentifier:"pretty"|lowerFirstWord }}{% endset %} {{ accessModifier }} static let {{ themePropertyName }} = Self( {% filter indent:8 %} - {% call colorsArgumentsBlock colors theme %} - {% call shadowsArgumentsBlock boxShadows theme %} + {% call colorsArgumentsBlock dictThemedColors[theme.name] theme.name %} + {% call shadowsArgumentsBlock dictThemedBoxShadows[theme.name] theme.name %} {% endfilter %} ) {% endfor %} } -{% if colors or boxShadows %} +{% if dictThemedColors or dictThemedBoxShadows %} private extension {{ colorTypeName }} { convenience init(hex: UInt32) { From 29de193a045d07618db229b45ff0988b17ef7f57 Mon Sep 17 00:00:00 2001 From: nschpy Date: Tue, 8 Apr 2025 16:41:28 +0300 Subject: [PATCH 21/23] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8E=20ubuntu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d862b33..8ca95b8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,7 +47,7 @@ jobs: linux: name: Linux - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v2 - name: Ruby From f3c92915f285c356d5477d80633732e023fcb332 Mon Sep 17 00:00:00 2001 From: nschpy Date: Tue, 8 Apr 2025 16:41:41 +0300 Subject: [PATCH 22/23] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D1=82=D0=B5=D1=81=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tests/FigmaGenTests/TokensResolverTests.swift | 74 ++++++++----------- 1 file changed, 32 insertions(+), 42 deletions(-) diff --git a/Tests/FigmaGenTests/TokensResolverTests.swift b/Tests/FigmaGenTests/TokensResolverTests.swift index 8957fbd..84f1b58 100644 --- a/Tests/FigmaGenTests/TokensResolverTests.swift +++ b/Tests/FigmaGenTests/TokensResolverTests.swift @@ -20,15 +20,13 @@ final class TokensResolverTests: XCTestCase { semantic: [], colors: [], typography: [], - hhDay: [], - hhNight: [], - zpDay: [] + themedTokens: [:] ) let value = "{core.space.1-x} + {core.space.1-x} / 2" let expectedValue = "6" - let actualValue = try tokensResolver.resolveValue(value, tokenValues: tokenValues, theme: .day) + let actualValue = try tokensResolver.resolveValue(value, tokenValues: tokenValues, theme: .light) XCTAssertEqual(actualValue, expectedValue) } @@ -40,11 +38,11 @@ final class TokensResolverTests: XCTestCase { let pixelValue = "0px" let colorValue = "#ffffff" - let actualNumberValue = try tokensResolver.resolveValue(numberValue, tokenValues: .empty, theme: .day) - let actualPercentValue = try tokensResolver.resolveValue(percentValue, tokenValues: .empty, theme: .day) - let actualTextValue = try tokensResolver.resolveValue(textValue, tokenValues: .empty, theme: .day) - let actualPixelValue = try tokensResolver.resolveValue(pixelValue, tokenValues: .empty, theme: .day) - let actualColorValue = try tokensResolver.resolveValue(colorValue, tokenValues: .empty, theme: .day) + let actualNumberValue = try tokensResolver.resolveValue(numberValue, tokenValues: .empty, theme: .light) + let actualPercentValue = try tokensResolver.resolveValue(percentValue, tokenValues: .empty, theme: .light) + let actualTextValue = try tokensResolver.resolveValue(textValue, tokenValues: .empty, theme: .light) + let actualPixelValue = try tokensResolver.resolveValue(pixelValue, tokenValues: .empty, theme: .light) + let actualColorValue = try tokensResolver.resolveValue(colorValue, tokenValues: .empty, theme: .light) XCTAssertEqual(actualNumberValue, numberValue) XCTAssertEqual(actualPercentValue, percentValue) @@ -65,15 +63,13 @@ final class TokensResolverTests: XCTestCase { TokenValue(type: .core(value: "#ffffff"), name: "color.base.white") ], typography: [], - hhDay: [], - hhNight: [], - zpDay: [] + themedTokens: [:] ) let value = "rgba({color.base.white}, {semantic.opacity.disabled})" let expectedColor = Color(red: 1.0, green: 1.0, blue: 1.0, alpha: 0.48) - let actualColor = try tokensResolver.resolveRGBAColorValue(value, tokenValues: tokenValues, theme: .day) + let actualColor = try tokensResolver.resolveRGBAColorValue(value, tokenValues: tokenValues, theme: .light) XCTAssertEqual(actualColor, expectedColor) } @@ -82,7 +78,7 @@ final class TokensResolverTests: XCTestCase { let value = "rgba(#FFFFFF, 48%)" let expectedColor = Color(red: 1.0, green: 1.0, blue: 1.0, alpha: 0.48) - let actualColor = try tokensResolver.resolveRGBAColorValue(value, tokenValues: .empty, theme: .day) + let actualColor = try tokensResolver.resolveRGBAColorValue(value, tokenValues: .empty, theme: .light) XCTAssertEqual(actualColor, expectedColor) } @@ -99,9 +95,7 @@ final class TokensResolverTests: XCTestCase { TokenValue(type: .color(value: "#d64030"), name: "color.base.red.50") ], typography: [], - hhDay: [], - hhNight: [], - zpDay: [] + themedTokens: [:] ) let firstColor = "rgba({color.base.red.50}, {semantic.opacity.transparent})" @@ -135,7 +129,7 @@ final class TokensResolverTests: XCTestCase { let actualLinearGradient = try tokensResolver.resolveLinearGradientValue( value, tokenValues: tokenValues, - theme: .day + theme: .light ) XCTAssertEqual(actualLinearGradient, expectedLinearGradient) @@ -171,7 +165,7 @@ final class TokensResolverTests: XCTestCase { let actualLinearGradient = try tokensResolver.resolveLinearGradientValue( value, tokenValues: .empty, - theme: .day + theme: .light ) XCTAssertEqual(actualLinearGradient, expectedLinearGradient) @@ -190,9 +184,7 @@ final class TokensResolverTests: XCTestCase { TokenValue(type: .color(value: "#111"), name: "color.base.gray.5") ], typography: [], - hhDay: [], - hhNight: [], - zpDay: [] + themedTokens: [:] ) let value1 = "rgba({color.base.white}, {semantic.opacity.disabled})" @@ -201,8 +193,8 @@ final class TokensResolverTests: XCTestCase { let value2 = "rgba( {color.base.gray.5} , {semantic.opacity.disabled})" let expectedHexColor2 = "#1111117A" - let actualHexColor1 = try tokensResolver.resolveHexColorValue(value1, tokenValues: tokenValues, theme: .day) - let actualHexColor2 = try tokensResolver.resolveHexColorValue(value2, tokenValues: tokenValues, theme: .day) + let actualHexColor1 = try tokensResolver.resolveHexColorValue(value1, tokenValues: tokenValues, theme: .light) + let actualHexColor2 = try tokensResolver.resolveHexColorValue(value2, tokenValues: tokenValues, theme: .light) XCTAssertEqual(actualHexColor1, expectedHexColor1) XCTAssertEqual(actualHexColor2, expectedHexColor2) @@ -212,7 +204,7 @@ final class TokensResolverTests: XCTestCase { let value = "rgba(#FFFFFF, 48%)" let expectedHexColor = "#FFFFFF7A" - let actualHexColor = try tokensResolver.resolveHexColorValue(value, tokenValues: .empty, theme: .day) + let actualHexColor = try tokensResolver.resolveHexColorValue(value, tokenValues: .empty, theme: .light) XCTAssertEqual(actualHexColor, expectedHexColor) } @@ -225,18 +217,18 @@ final class TokensResolverTests: XCTestCase { TokenValue(type: .color(value: "#000000"), name: "color.base.black") ], typography: [], - hhDay: [], - hhNight: [ - TokenValue(type: .color(value: "{color.base.black}"), name: "color.background.primary"), - TokenValue(type: .color(value: "{color.background.primary}"), name: "color.background.primary.nested") - ], - zpDay: [] + themedTokens: [ + .dark: [ + TokenValue(type: .color(value: "{color.base.black}"), name: "color.background.primary"), + TokenValue(type: .color(value: "{color.background.primary}"), name: "color.background.primary.nested") + ] + ] ) let value = "{color.background.primary.nested}" let expectedBaseReference = "{color.base.black}" - let actualBaseReference = try tokensResolver.resolveBaseReference(value, tokenValues: tokenValues.hhNight) + let actualBaseReference = try tokensResolver.resolveBaseReference(value, tokenValues: tokenValues.tokens(for: .dark)) XCTAssertEqual(actualBaseReference, expectedBaseReference) } @@ -253,18 +245,18 @@ final class TokensResolverTests: XCTestCase { TokenValue(type: .color(value: "#000000"), name: "color.base.black") ], typography: [], - hhDay: [], - hhNight: [ - TokenValue(type: .color(value: "{color.base.black}"), name: "color.background.primary"), - TokenValue(type: .color(value: "{color.background.primary}"), name: "color.background.primary.nested") - ], - zpDay: [] + themedTokens: [ + .dark: [ + TokenValue(type: .color(value: "{color.base.black}"), name: "color.background.primary"), + TokenValue(type: .color(value: "{color.background.primary}"), name: "color.background.primary.nested") + ] + ] ) let value = "rgba( {color.background.primary.nested}, {semantic.opacity.disabled})" let expectedBaseReference = "rgba( {color.base.black}, {semantic.opacity.disabled})" - let actualBaseReference = try tokensResolver.resolveBaseReference(value, tokenValues: tokenValues.hhNight) + let actualBaseReference = try tokensResolver.resolveBaseReference(value, tokenValues: tokenValues.tokens(for: .dark)) XCTAssertEqual(actualBaseReference, expectedBaseReference) } @@ -279,9 +271,7 @@ extension TokenValues { semantic: [], colors: [], typography: [], - hhDay: [], - hhNight: [], - zpDay: [] + themedTokens: [:] ) } #endif From 524712865ef65a82fbcf6a0c121b99558ca68722 Mon Sep 17 00:00:00 2001 From: nschpy Date: Tue, 8 Apr 2025 16:50:36 +0300 Subject: [PATCH 23/23] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D0=B1=D0=B8=D0=BB=D0=B4=D0=B0=20=D0=BD=D0=B0=20CI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Gradient/DefaultGradientTokensContextProvider.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Gradient/DefaultGradientTokensContextProvider.swift b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Gradient/DefaultGradientTokensContextProvider.swift index 64666d2..dedc523 100644 --- a/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Gradient/DefaultGradientTokensContextProvider.swift +++ b/Sources/FigmaGen/Generators/Tokens/Providers/ColorTokensContext/Gradient/DefaultGradientTokensContextProvider.swift @@ -24,7 +24,7 @@ struct DefaultGradientTokensContextProvider: ColorTokensContextProvider { let ty = usin == 0 ? nil : (yedge - 0.5) / usin let t = [tx, ty] - .compactMap(\.self) + .compactMap { $0 } .filter { $0 > 0 } .min()