admiral-tools-figma 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +1 -0
- data/admiral-tools-figma.gemspec +9 -0
- data/admiraltools/actions/figma_download_images.rb +116 -0
- data/admiraltools/actions/figma_generate_styles.rb +77 -0
- data/admiraltools/actions/figma_get_image_links.rb +139 -0
- data/admiraltools/actions/figma_get_styles.rb +90 -0
- data/admiraltools/helper/admiraltools_helper.rb +18 -0
- data/admiraltools/helper/figma/figma_client/figma_client.rb +193 -0
- data/admiraltools/helper/figma/figma_client/models/api/primitives/figma_color.rb +35 -0
- data/admiraltools/helper/figma/figma_client/models/api/primitives/figma_component.rb +58 -0
- data/admiraltools/helper/figma/figma_client/models/api/primitives/figma_components_styles_meta.rb +30 -0
- data/admiraltools/helper/figma/figma_client/models/api/primitives/figma_frame_info.rb +46 -0
- data/admiraltools/helper/figma/figma_client/models/api/primitives/figma_node.rb +43 -0
- data/admiraltools/helper/figma/figma_client/models/api/primitives/figma_paint.rb +32 -0
- data/admiraltools/helper/figma/figma_client/models/api/primitives/figma_style.rb +48 -0
- data/admiraltools/helper/figma/figma_client/models/api/primitives/figma_type_style.rb +56 -0
- data/admiraltools/helper/figma/figma_client/models/api/results/figma_components_styles_result.rb +36 -0
- data/admiraltools/helper/figma/figma_client/models/api/results/figma_images_result.rb +25 -0
- data/admiraltools/helper/figma/figma_client/models/api/results/figma_nodes_result.rb +52 -0
- data/admiraltools/helper/figma/figma_client/models/domain/converters/figma_to_domain_converter.rb +98 -0
- data/admiraltools/helper/figma/figma_client/models/domain/primitives/color.rb +44 -0
- data/admiraltools/helper/figma/figma_client/models/domain/primitives/component.rb +86 -0
- data/admiraltools/helper/figma/figma_client/models/domain/primitives/components_list.rb +29 -0
- data/admiraltools/helper/figma/figma_client/models/domain/primitives/font.rb +56 -0
- data/admiraltools/helper/figma/figma_client/models/domain/primitives/frame_info.rb +46 -0
- data/admiraltools/helper/figma/figma_client/models/domain/primitives/image_link.rb +33 -0
- data/admiraltools/helper/figma/figma_client/models/domain/primitives/style.rb +113 -0
- data/admiraltools/helper/figma/figma_client/models/domain/primitives/styles_group.rb +22 -0
- data/admiraltools/helper/figma/figma_client/models/domain/primitives/styles_list.rb +29 -0
- data/admiraltools/helper/figma/figma_client/models/models.rb +25 -0
- data/admiraltools/helper/figma/figma_image_downloader/bin/svg2vectordrawable.jar +0 -0
- data/admiraltools/helper/figma/figma_image_downloader/figma_image_downloader.rb +65 -0
- data/admiraltools/helper/figma/figma_image_downloader/generators/folder_generator.rb +47 -0
- data/admiraltools/helper/figma/figma_image_downloader/generators/folder_generator_raw.rb +32 -0
- data/admiraltools/helper/figma/figma_image_downloader/generators/folder_generator_res.rb +38 -0
- data/admiraltools/helper/figma/figma_image_downloader/generators/folder_generator_xcassets.rb +180 -0
- data/admiraltools/helper/figma/figma_image_downloader/generators/generators.rb +6 -0
- data/admiraltools/helper/figma/figma_image_downloader/helpers/image_name_formatter.rb +72 -0
- data/admiraltools/helper/figma/figma_image_downloader/helpers/progress_tasks_logger.rb +22 -0
- data/admiraltools/helper/figma/figma_image_downloader/helpers/scale_formatter.rb +96 -0
- data/admiraltools/helper/figma/figma_image_downloader/helpers/svg_to_vector_converter.rb +12 -0
- data/admiraltools/helper/figma/figma_image_downloader/models/download_image_params.rb +31 -0
- data/admiraltools/helper/figma/figma_image_downloader/models/image_name_components.rb +10 -0
- data/admiraltools/helper/figma/figma_image_downloader/models/image_ref.rb +12 -0
- data/admiraltools/helper/figma/figma_image_downloader/models/image_set_ref.rb +14 -0
- data/admiraltools/helper/figma/figma_image_downloader/models/models.rb +5 -0
- data/admiraltools/helper/figma/figma_template_generator/figma_template_generator.rb +22 -0
- data/admiraltools/helper/figma/figma_template_generator/models/styles_template.rb +34 -0
- data/admiraltools/helper/figma/helpers/file_folder.rb +30 -0
- data/admiraltools/helper/figma/helpers/hash_access.rb +18 -0
- data/admiraltools/helper/figma/helpers/string_filters.rb +63 -0
- data/admiraltools/helper/figma/helpers/string_format.rb +60 -0
- data/admiraltools/helper/system/system.rb +17 -0
- data/admiraltools/version.rb +7 -0
- data/admiraltools.rb +18 -0
- metadata +96 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'figma_frame_info'
|
4
|
+
|
5
|
+
class FigmaComponent
|
6
|
+
attr_accessor \
|
7
|
+
:key,
|
8
|
+
:file_key,
|
9
|
+
:node_id,
|
10
|
+
:name,
|
11
|
+
:description,
|
12
|
+
:containing_frame
|
13
|
+
|
14
|
+
def initialize(key:, file_key:, node_id:, name:, description:, containing_frame:)
|
15
|
+
@key = key
|
16
|
+
@file_key = file_key
|
17
|
+
@node_id = node_id
|
18
|
+
@name = name
|
19
|
+
@description = description
|
20
|
+
@containing_frame = containing_frame
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.from_hash(hash)
|
24
|
+
return nil if hash.nil?
|
25
|
+
|
26
|
+
key = hash['key']
|
27
|
+
file_key = hash['file_key']
|
28
|
+
node_id = hash['node_id']
|
29
|
+
name = hash['name']
|
30
|
+
description = hash['description']
|
31
|
+
containing_frame_hash = hash['containing_frame']
|
32
|
+
containing_frame = containing_frame_hash.nil? ? nil : FigmaFrameInfo.from_hash(containing_frame_hash)
|
33
|
+
|
34
|
+
if !key.nil? && !file_key.nil? && !node_id.nil? && !name.nil?
|
35
|
+
return FigmaComponent.new(
|
36
|
+
key: key,
|
37
|
+
file_key: file_key,
|
38
|
+
node_id: node_id,
|
39
|
+
name: name,
|
40
|
+
description: description,
|
41
|
+
containing_frame: containing_frame
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
nil
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_hash
|
49
|
+
hash = {}
|
50
|
+
hash['key'] = key
|
51
|
+
hash['file_key'] = file_key
|
52
|
+
hash['node_id'] = node_id
|
53
|
+
hash['name'] = name
|
54
|
+
hash['description'] = description
|
55
|
+
hash['containing_frame'] = containing_frame.to
|
56
|
+
hash
|
57
|
+
end
|
58
|
+
end
|
data/admiraltools/helper/figma/figma_client/models/api/primitives/figma_components_styles_meta.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'figma_style'
|
4
|
+
require_relative 'figma_component'
|
5
|
+
|
6
|
+
class FigmaComponentsStylesMeta
|
7
|
+
attr_accessor :styles, :components
|
8
|
+
|
9
|
+
def initialize(styles:, components:)
|
10
|
+
@styles = styles
|
11
|
+
@components = components
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.from_hash(hash)
|
15
|
+
styles_hash = hash['styles']
|
16
|
+
components_hash = hash['components']
|
17
|
+
|
18
|
+
styles = styles_hash.nil? ? nil : styles_hash.map { |s| FigmaStyle.from_hash(s) }
|
19
|
+
components = components_hash.nil? ? nil : components_hash.map { |c| FigmaComponent.from_hash(c) }
|
20
|
+
|
21
|
+
FigmaComponentsStylesMeta.new(styles: styles, components: components)
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_hash
|
25
|
+
hash = {}
|
26
|
+
hash['styles'] = styles.map(&:to_hash) unless styles.nil?
|
27
|
+
hash['components'] = components.map(&:to_hash) unless components.nil?
|
28
|
+
hash
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class FigmaFrameInfo
|
4
|
+
attr_accessor \
|
5
|
+
:node_id,
|
6
|
+
:name,
|
7
|
+
:background_color,
|
8
|
+
:page_id,
|
9
|
+
:page_name
|
10
|
+
|
11
|
+
def initialize(node_id:, name:, background_color:, page_id:, page_name:)
|
12
|
+
@node_id = node_id
|
13
|
+
@name = name
|
14
|
+
@background_color = background_color
|
15
|
+
@page_id = page_id
|
16
|
+
@page_name = page_name
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.from_hash(hash)
|
20
|
+
return nil if hash.nil?
|
21
|
+
|
22
|
+
node_id = hash['nodeId']
|
23
|
+
name = hash['name']
|
24
|
+
background_color = hash['backgroundColor']
|
25
|
+
page_id = hash['pageId']
|
26
|
+
page_name = hash['pageName']
|
27
|
+
|
28
|
+
FigmaFrameInfo.new(
|
29
|
+
node_id: node_id,
|
30
|
+
name: name,
|
31
|
+
background_color: background_color,
|
32
|
+
page_id: page_id,
|
33
|
+
page_name: page_name
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_hash
|
38
|
+
hash = {}
|
39
|
+
hash['nodeId'] = node_id
|
40
|
+
hash['name'] = name
|
41
|
+
hash['backgroundColor'] = background_color
|
42
|
+
hash['pageId'] = page_id
|
43
|
+
hash['pageName'] = page_name
|
44
|
+
hash
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'figma_paint'
|
4
|
+
require_relative 'figma_type_style'
|
5
|
+
|
6
|
+
class FigmaNode
|
7
|
+
attr_accessor :id, :name, :type, :style, :fills
|
8
|
+
|
9
|
+
def initialize(id:, name:, type:, style:, fills:)
|
10
|
+
@id = id
|
11
|
+
@name = name
|
12
|
+
@type = type
|
13
|
+
@style = style
|
14
|
+
@fills = fills
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.from_hash(hash)
|
18
|
+
return nil if hash.nil?
|
19
|
+
|
20
|
+
id = hash['id']
|
21
|
+
name = hash['name']
|
22
|
+
type = hash['type']
|
23
|
+
style_hash = hash['style']
|
24
|
+
style = style_hash.nil? ? nil : FigmaTypeStyle.from_hash(style_hash)
|
25
|
+
fills = (hash['fills'] || []).map { |f| FigmaPaint.from_hash(f) }.compact || []
|
26
|
+
|
27
|
+
if !id.nil? && !name.nil? && !type.nil?
|
28
|
+
return FigmaNode.new(id: id, name: name, type: type, style: style, fills: fills)
|
29
|
+
end
|
30
|
+
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_hash
|
35
|
+
hash = {}
|
36
|
+
hash['id'] = id
|
37
|
+
hash['name'] = name
|
38
|
+
hash['type'] = type
|
39
|
+
hash['style'] = style.to_hash unless style.nil?
|
40
|
+
hash['fills'] = (fills || []).map(&:to_hash)
|
41
|
+
hash
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'figma_color'
|
4
|
+
|
5
|
+
class FigmaPaint
|
6
|
+
attr_accessor :type, :color, :opacity
|
7
|
+
|
8
|
+
def initialize(type:, color:, opacity:)
|
9
|
+
@type = type
|
10
|
+
@color = color
|
11
|
+
@opacity = opacity
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.from_hash(hash)
|
15
|
+
return nil if hash.nil?
|
16
|
+
|
17
|
+
type = hash['type']
|
18
|
+
color = FigmaColor.from_hash(hash['color'])
|
19
|
+
opacity = hash['opacity'] || 1.0
|
20
|
+
|
21
|
+
return FigmaPaint.new(type: type, color: color, opacity: opacity) if !type.nil? && !color.nil?
|
22
|
+
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_hash
|
27
|
+
hash = {}
|
28
|
+
hash['type'] = type
|
29
|
+
hash['color'] = color.to_hash unless color.nil?
|
30
|
+
hash
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
FIGMA_STYLE_TYPE_FILL = 'FILL'
|
4
|
+
FIGMA_STYLE_TYPE_TEXT = 'TEXT'
|
5
|
+
|
6
|
+
class FigmaStyle
|
7
|
+
attr_accessor \
|
8
|
+
:name,
|
9
|
+
:node_id,
|
10
|
+
:style_type,
|
11
|
+
:description
|
12
|
+
|
13
|
+
def initialize(
|
14
|
+
name:,
|
15
|
+
node_id:,
|
16
|
+
style_type:,
|
17
|
+
description:
|
18
|
+
)
|
19
|
+
@name = name
|
20
|
+
@node_id = node_id
|
21
|
+
@style_type = style_type
|
22
|
+
@description = description
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.from_hash(hash)
|
26
|
+
return nil if hash.nil?
|
27
|
+
|
28
|
+
name = hash['name']
|
29
|
+
node_id = hash['node_id']
|
30
|
+
style_type = hash['style_type']
|
31
|
+
description = hash['description']
|
32
|
+
|
33
|
+
if !name.nil? && !node_id.nil? && style_type
|
34
|
+
return FigmaStyle.new(name: name, node_id: node_id, style_type: style_type, description: description)
|
35
|
+
end
|
36
|
+
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_hash
|
41
|
+
hash = {}
|
42
|
+
hash['name'] = name
|
43
|
+
hash['node_id'] = node_id
|
44
|
+
hash['style_type'] = style_type
|
45
|
+
hash['description'] = description
|
46
|
+
hash
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class FigmaTypeStyle
|
4
|
+
attr_accessor \
|
5
|
+
:font_family,
|
6
|
+
:font_postscript_name,
|
7
|
+
:font_size,
|
8
|
+
:font_weight,
|
9
|
+
:letter_spacing
|
10
|
+
|
11
|
+
def initialize(
|
12
|
+
font_family:,
|
13
|
+
font_postscript_name:,
|
14
|
+
font_size:,
|
15
|
+
font_weight:,
|
16
|
+
letter_spacing:
|
17
|
+
)
|
18
|
+
@font_family = font_family
|
19
|
+
@font_postscript_name = font_postscript_name
|
20
|
+
@font_size = font_size
|
21
|
+
@font_weight = font_weight
|
22
|
+
@letter_spacing = letter_spacing
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.from_hash(hash)
|
26
|
+
return nil if hash.nil?
|
27
|
+
|
28
|
+
font_family = hash['fontFamily']
|
29
|
+
font_postscript_name = hash['fontPostScriptName']
|
30
|
+
font_size = hash['fontSize']
|
31
|
+
font_weight = hash['fontWeight']
|
32
|
+
letter_spacing = hash['letterSpacing']
|
33
|
+
|
34
|
+
if !font_family.nil? && !font_size.nil? && !font_weight.nil? && !letter_spacing.nil?
|
35
|
+
return FigmaTypeStyle.new(
|
36
|
+
font_family: font_family,
|
37
|
+
font_postscript_name: font_postscript_name,
|
38
|
+
font_size: font_size,
|
39
|
+
font_weight: font_weight,
|
40
|
+
letter_spacing: letter_spacing
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
nil
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_hash
|
48
|
+
hash = {}
|
49
|
+
hash['fontFamily'] = font_family
|
50
|
+
hash['fontPostscriptName'] = font_postscript_name
|
51
|
+
hash['fontSize'] = font_size
|
52
|
+
hash['fontWeight'] = font_weight
|
53
|
+
hash['letterSpacing'] = letter_spacing
|
54
|
+
hash
|
55
|
+
end
|
56
|
+
end
|
data/admiraltools/helper/figma/figma_client/models/api/results/figma_components_styles_result.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../primitives/figma_components_styles_meta'
|
4
|
+
|
5
|
+
class FigmaComponentsStylesResult
|
6
|
+
attr_accessor :error, :status, :meta
|
7
|
+
|
8
|
+
def initialize(error:, status:, meta:)
|
9
|
+
@error = error
|
10
|
+
@status = status
|
11
|
+
@meta = meta
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.from_hash(hash)
|
15
|
+
return nil if hash.nil?
|
16
|
+
|
17
|
+
error = hash['error']
|
18
|
+
status = hash['status']
|
19
|
+
meta_hash = hash['meta']
|
20
|
+
meta = meta_hash.nil? ? nil : FigmaComponentsStylesMeta.from_hash(meta_hash)
|
21
|
+
|
22
|
+
if !error.nil? && !status.nil? && !meta.nil?
|
23
|
+
return FigmaComponentsStylesResult.new(error: error, status: status, meta: meta)
|
24
|
+
end
|
25
|
+
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_hash
|
30
|
+
hash = {}
|
31
|
+
hash['error'] = error
|
32
|
+
hash['status'] = status
|
33
|
+
hash['meta'] = meta.to_hash unless meta.nil?
|
34
|
+
hash
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class FigmaImagesResult
|
4
|
+
attr_accessor :error, :images
|
5
|
+
|
6
|
+
def initialize(error:, images:)
|
7
|
+
@error = error
|
8
|
+
@images = images || []
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.from_hash(hash)
|
12
|
+
return nil if hash.nil?
|
13
|
+
|
14
|
+
error = hash['err']
|
15
|
+
images = hash['images']
|
16
|
+
FigmaImagesResult.new(error: error, images: images)
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_hash
|
20
|
+
hash = {}
|
21
|
+
hash['err'] = error
|
22
|
+
hash['images'] = images
|
23
|
+
hash
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../primitives/figma_node'
|
4
|
+
|
5
|
+
class FigmaNodesResult
|
6
|
+
attr_accessor :name, :nodes
|
7
|
+
|
8
|
+
def initialize(name:, nodes:)
|
9
|
+
@name = name
|
10
|
+
@nodes = nodes
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.from_hash(hash)
|
14
|
+
return nil if hash.nil?
|
15
|
+
|
16
|
+
name = hash['name']
|
17
|
+
nodes = FigmaNodesResult.parse_nodes(hash: hash['nodes'])
|
18
|
+
|
19
|
+
return FigmaNodesResult.new(name: name, nodes: nodes) if !name.nil? && !nodes.nil?
|
20
|
+
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_hash
|
25
|
+
hash = {}
|
26
|
+
hash['name'] = name
|
27
|
+
nodes_hash = (nodes || {})
|
28
|
+
nodes_result_hash = {}
|
29
|
+
|
30
|
+
nodes_hash.each do |k, v|
|
31
|
+
node = v['document'].to_hash
|
32
|
+
nodes_result_hash[k] = { 'document' => node } unless node.nil?
|
33
|
+
end
|
34
|
+
|
35
|
+
hash['nodes'] = nodes_result_hash
|
36
|
+
hash
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.parse_nodes(hash:)
|
40
|
+
return nil if hash.nil?
|
41
|
+
|
42
|
+
result_hash = {}
|
43
|
+
|
44
|
+
hash.each do |k, v|
|
45
|
+
node_hash = v['document']
|
46
|
+
node = FigmaNode.from_hash(node_hash)
|
47
|
+
result_hash[k] = { 'document' => node } unless node.nil?
|
48
|
+
end
|
49
|
+
|
50
|
+
result_hash
|
51
|
+
end
|
52
|
+
end
|
data/admiraltools/helper/figma/figma_client/models/domain/converters/figma_to_domain_converter.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../models'
|
4
|
+
|
5
|
+
class FigmaToDomainConverter
|
6
|
+
def convert_figma_style(figma_style:)
|
7
|
+
return nil if figma_style.nil?
|
8
|
+
|
9
|
+
Style.new(
|
10
|
+
name: figma_style.name,
|
11
|
+
node_id: figma_style.node_id,
|
12
|
+
style_type: figma_style.style_type,
|
13
|
+
description: figma_style.description
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
def fulfill_styles(figma_nodes_result:, figma_styles_result:)
|
18
|
+
return [] if figma_nodes_result.nil? || figma_styles_result.nil?
|
19
|
+
|
20
|
+
styles = []
|
21
|
+
figma_styles = figma_styles_result&.meta&.styles || []
|
22
|
+
nodes = figma_nodes_result&.nodes || {}
|
23
|
+
|
24
|
+
figma_styles.each do |s|
|
25
|
+
style = convert_figma_style(figma_style: s)
|
26
|
+
node = nodes.dig(s.node_id, 'document')
|
27
|
+
|
28
|
+
case s.style_type
|
29
|
+
when FIGMA_STYLE_TYPE_FILL
|
30
|
+
fills = node&.fills
|
31
|
+
next if fills.nil?
|
32
|
+
|
33
|
+
figma_paint = fills[0]
|
34
|
+
next if figma_paint.nil?
|
35
|
+
|
36
|
+
style&.color = Color.new(
|
37
|
+
r: figma_paint.color.r,
|
38
|
+
g: figma_paint.color.g,
|
39
|
+
b: figma_paint.color.b,
|
40
|
+
a: figma_paint.opacity
|
41
|
+
)
|
42
|
+
styles.push(style)
|
43
|
+
when FIGMA_STYLE_TYPE_TEXT
|
44
|
+
type_style = node&.style
|
45
|
+
next if type_style.nil?
|
46
|
+
|
47
|
+
style&.font = Font.new(
|
48
|
+
font_family: type_style.font_family,
|
49
|
+
font_postscript_name: type_style.font_postscript_name,
|
50
|
+
font_size: type_style.font_size,
|
51
|
+
font_weight: type_style.font_weight,
|
52
|
+
letter_spacing: type_style.letter_spacing
|
53
|
+
)
|
54
|
+
styles.push(style)
|
55
|
+
else
|
56
|
+
next
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
styles
|
61
|
+
end
|
62
|
+
|
63
|
+
def fulfill_components(figma_components:, image_links_hash:, image_format:)
|
64
|
+
return [] if figma_components.nil? || image_links_hash.nil?
|
65
|
+
|
66
|
+
components = []
|
67
|
+
figma_components.each do |c|
|
68
|
+
component = Component.new(
|
69
|
+
key: c.key,
|
70
|
+
file_key: c.file_key,
|
71
|
+
node_id: c.node_id,
|
72
|
+
name: c.name,
|
73
|
+
description: c.description
|
74
|
+
)
|
75
|
+
|
76
|
+
component.containing_frame = FrameInfo.new(
|
77
|
+
node_id: c.containing_frame.node_id,
|
78
|
+
name: c.containing_frame.name,
|
79
|
+
background_color: c.containing_frame.background_color,
|
80
|
+
page_id: c.containing_frame.page_id,
|
81
|
+
page_name: c.containing_frame.page_name
|
82
|
+
)
|
83
|
+
|
84
|
+
image_links = []
|
85
|
+
image_links_hash.each do |key, link_hash|
|
86
|
+
link = link_hash[c.node_id]
|
87
|
+
if !link.nil? && !key.nil? && !image_format.nil?
|
88
|
+
image_link = ImageLink.new(link: link, scale: key, image_format: image_format)
|
89
|
+
image_links.push(image_link)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
component.image_links = image_links
|
93
|
+
components.push(component)
|
94
|
+
end
|
95
|
+
|
96
|
+
components
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Color
|
4
|
+
attr_accessor :r, :g, :b, :a
|
5
|
+
|
6
|
+
def hex
|
7
|
+
format('#%02x%02x%02x', *[r, g, b].map { |v| v.to_f * 255 }).upcase
|
8
|
+
end
|
9
|
+
|
10
|
+
def hex_with_alpha
|
11
|
+
format('#%02x%02x%02x%02x', *[a, r, g, b].map { |v| v.to_f * 255 }).upcase
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(r:, g:, b:, a:)
|
15
|
+
@r = r
|
16
|
+
@g = g
|
17
|
+
@b = b
|
18
|
+
@a = a
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.from_hash(hash)
|
22
|
+
return nil if hash.nil?
|
23
|
+
|
24
|
+
r = hash['r']
|
25
|
+
g = hash['g']
|
26
|
+
b = hash['b']
|
27
|
+
a = hash['a']
|
28
|
+
|
29
|
+
return Color.new(r: r, g: g, b: b, a: a) if !r.nil? && !g.nil? && !b.nil? && !a.nil?
|
30
|
+
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_hash
|
35
|
+
hash = {}
|
36
|
+
hash['r'] = r
|
37
|
+
hash['g'] = g
|
38
|
+
hash['b'] = b
|
39
|
+
hash['a'] = a
|
40
|
+
hash['hex'] = hex
|
41
|
+
hash['hex_with_alpha'] = hex_with_alpha
|
42
|
+
hash
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'image_link'
|
4
|
+
require_relative 'frame_info'
|
5
|
+
|
6
|
+
class Component
|
7
|
+
attr_accessor \
|
8
|
+
:key,
|
9
|
+
:file_key,
|
10
|
+
:node_id,
|
11
|
+
:name,
|
12
|
+
:description,
|
13
|
+
:containing_frame,
|
14
|
+
:image_links
|
15
|
+
|
16
|
+
def single_scale?
|
17
|
+
links = image_links || []
|
18
|
+
return false if links.length > 1
|
19
|
+
|
20
|
+
link = links[0]
|
21
|
+
return false if link.nil?
|
22
|
+
|
23
|
+
image_format = link&.image_format
|
24
|
+
return false if image_format.nil?
|
25
|
+
|
26
|
+
scale = link.scale
|
27
|
+
image_format = image_format.downcase
|
28
|
+
scale == 1.0 && %w[svg pdf].include?(image_format)
|
29
|
+
end
|
30
|
+
|
31
|
+
def description_params
|
32
|
+
JSON.parse(description)
|
33
|
+
rescue StandardError
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
|
37
|
+
def initialize(key:, file_key:, node_id:, name:, description:, containing_frame: nil, image_links: nil)
|
38
|
+
@key = key
|
39
|
+
@file_key = file_key
|
40
|
+
@node_id = node_id
|
41
|
+
@name = name
|
42
|
+
@description = description
|
43
|
+
@containing_frame = containing_frame
|
44
|
+
@image_links = image_links
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.from_hash(hash)
|
48
|
+
return nil if hash.nil?
|
49
|
+
|
50
|
+
key = hash['key']
|
51
|
+
file_key = hash['file_key']
|
52
|
+
node_id = hash['node_id']
|
53
|
+
name = hash['name']
|
54
|
+
description = hash['description']
|
55
|
+
images_array = hash['image_links']
|
56
|
+
image_links = images_array&.map { |i| ImageLink.from_hash(i) }
|
57
|
+
containing_frame = FrameInfo.from_hash(hash['containing_frame'])
|
58
|
+
|
59
|
+
if !key.nil? && !file_key.nil? && !node_id.nil? && !name.nil?
|
60
|
+
return Component.new(
|
61
|
+
key: key,
|
62
|
+
file_key: file_key,
|
63
|
+
node_id: node_id,
|
64
|
+
name: name,
|
65
|
+
description: description,
|
66
|
+
containing_frame: containing_frame,
|
67
|
+
image_links: image_links
|
68
|
+
)
|
69
|
+
end
|
70
|
+
|
71
|
+
nil
|
72
|
+
end
|
73
|
+
|
74
|
+
def to_hash
|
75
|
+
hash = {}
|
76
|
+
hash['key'] = key
|
77
|
+
hash['file_key'] = file_key
|
78
|
+
hash['node_id'] = node_id
|
79
|
+
hash['name'] = name
|
80
|
+
hash['description'] = description
|
81
|
+
hash['image_links'] = image_links&.map { |i| i.to_hash } unless image_links.nil?
|
82
|
+
hash['description_params'] = description_params unless description_params.nil?
|
83
|
+
hash['containing_frame'] = containing_frame&.to_hash
|
84
|
+
hash
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require_relative 'component'
|
5
|
+
|
6
|
+
class ComponentsList
|
7
|
+
attr_accessor :components
|
8
|
+
|
9
|
+
def initialize(components:)
|
10
|
+
@components = components
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.from_hash(hash)
|
14
|
+
hash.map { |s| Component.from_hash(s) }
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_hash
|
18
|
+
components.map(&:to_hash)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.from_json(json)
|
22
|
+
components = (JSON.parse(json) || []).map { |s| Component.from_hash(s) }
|
23
|
+
ComponentsList.new(components: components)
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_json(*_args)
|
27
|
+
components.map(&:to_hash).to_json
|
28
|
+
end
|
29
|
+
end
|