rails_icons 0.4.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/README.md +75 -60
  4. data/app/assets/svg/rails_icons/icons/animated/bouncing-dots.svg +1 -0
  5. data/app/assets/svg/rails_icons/icons/animated/faded-spinner.svg +1 -0
  6. data/app/assets/svg/rails_icons/icons/animated/fading-dots.svg +1 -0
  7. data/app/assets/svg/rails_icons/icons/animated/trailing-spinner.svg +1 -0
  8. data/lib/generators/rails_icons/initializer_generator.rb +89 -2
  9. data/lib/generators/rails_icons/install_generator.rb +27 -0
  10. data/lib/generators/rails_icons/sync_generator.rb +16 -37
  11. data/lib/generators/rails_icons/templates/initializer.rb.tt +0 -16
  12. data/lib/rails_icons/configuration/animated.rb +24 -0
  13. data/lib/rails_icons/configuration/boxicons.rb +74 -0
  14. data/lib/rails_icons/configuration/feather.rb +45 -0
  15. data/lib/rails_icons/configuration/heroicons.rb +101 -0
  16. data/lib/rails_icons/configuration/lucide.rb +50 -0
  17. data/lib/rails_icons/configuration/phosphor.rb +141 -0
  18. data/lib/rails_icons/configuration/radix.rb +44 -0
  19. data/lib/rails_icons/configuration/tabler.rb +67 -0
  20. data/lib/rails_icons/configuration.rb +13 -12
  21. data/lib/rails_icons/helpers/icon_helper.rb +3 -4
  22. data/lib/rails_icons/icon/attributes.rb +9 -3
  23. data/lib/rails_icons/icon/file_path.rb +57 -0
  24. data/lib/rails_icons/icon.rb +37 -45
  25. data/lib/rails_icons/libraries.rb +24 -0
  26. data/lib/rails_icons/railtie.rb +6 -0
  27. data/lib/rails_icons/sync/engine.rb +75 -0
  28. data/lib/rails_icons/sync/process_variants.rb +64 -0
  29. data/lib/rails_icons/sync/transformations.rb +27 -0
  30. data/lib/rails_icons/version.rb +1 -1
  31. data/lib/rails_icons.rb +2 -12
  32. data/rails_icons.gemspec +3 -3
  33. metadata +26 -10
  34. data/lib/rails_icons/icon_configs/heroicons_config.rb +0 -66
  35. data/lib/rails_icons/icon_configs/lucide_config.rb +0 -28
  36. data/lib/rails_icons/icon_configs/tabler_config.rb +0 -41
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsIcons
4
+ class Configuration
5
+ module Heroicons
6
+ extend self
7
+
8
+ def config
9
+ ActiveSupport::OrderedOptions.new.tap do |options|
10
+ options.default_variant = :outline
11
+
12
+ setup_outline_config(options)
13
+ setup_solid_config(options)
14
+ setup_mini_config(options)
15
+ setup_micro_config(options)
16
+ end
17
+ end
18
+
19
+ def initializer_config
20
+ <<~RB.indent(2)
21
+ # Override Heroicon defaults
22
+ # config.libraries.heroicons.outline.default.css = "size-6"
23
+ # config.libraries.heroicons.outline.default.stroke_width = "1.5"
24
+ # config.libraries.heroicons.outline.default.data = {}
25
+
26
+ # config.libraries.heroicons.solid.default.css = "size-6"
27
+ # config.libraries.heroicons.solid.default.data = {}
28
+
29
+ # config.libraries.heroicons.mini.default.css = "size-5"
30
+ # config.libraries.heroicons.mini.default.data = {}
31
+
32
+ # config.libraries.heroicons.micro.default.css = "size-4"
33
+ # config.libraries.heroicons.micro.default.data = {}
34
+ RB
35
+ end
36
+
37
+ def source
38
+ {
39
+ url: "https://github.com/tailwindlabs/heroicons.git",
40
+ variants: {
41
+ outline: "optimized/24/outline",
42
+ solid: "optimized/24/solid",
43
+ mini: "optimized/20/solid",
44
+ micro: "optimized/16/solid"
45
+ }
46
+ }
47
+ end
48
+
49
+ private
50
+
51
+ def setup_outline_config(options)
52
+ options.outline = ActiveSupport::OrderedOptions.new
53
+ options.outline.default = default_outline_options
54
+ end
55
+
56
+ def setup_solid_config(options)
57
+ options.solid = ActiveSupport::OrderedOptions.new
58
+ options.solid.default = default_solid_options
59
+ end
60
+
61
+ def setup_mini_config(options)
62
+ options.mini = ActiveSupport::OrderedOptions.new
63
+ options.mini.default = default_mini_options
64
+ end
65
+
66
+ def setup_micro_config(options)
67
+ options.micro = ActiveSupport::OrderedOptions.new
68
+ options.micro.default = default_micro_options
69
+ end
70
+
71
+ def default_solid_options
72
+ ActiveSupport::OrderedOptions.new.tap do |options|
73
+ options.css = "size-6"
74
+ options.data = {}
75
+ end
76
+ end
77
+
78
+ def default_outline_options
79
+ ActiveSupport::OrderedOptions.new.tap do |options|
80
+ options.stroke_width = 1.5
81
+ options.css = "size-6"
82
+ options.data = {}
83
+ end
84
+ end
85
+
86
+ def default_mini_options
87
+ ActiveSupport::OrderedOptions.new.tap do |options|
88
+ options.css = "size-5"
89
+ options.data = {}
90
+ end
91
+ end
92
+
93
+ def default_micro_options
94
+ ActiveSupport::OrderedOptions.new.tap do |options|
95
+ options.css = "size-4"
96
+ options.data = {}
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsIcons
4
+ class Configuration
5
+ module Lucide
6
+ extend self
7
+
8
+ def config
9
+ ActiveSupport::OrderedOptions.new.tap do |options|
10
+ options.default_variant = :outline
11
+
12
+ setup_outline_config(options)
13
+ end
14
+ end
15
+
16
+ def initializer_config
17
+ <<~RB.indent(2)
18
+ # Override Lucide defaults
19
+ # config.libraries.lucide.outline.default.css = "size-6"
20
+ # config.libraries.lucide.outline.default.stroke_width = "1.5"
21
+ # config.libraries.lucide.outline.default.data = {}
22
+ RB
23
+ end
24
+
25
+ def source
26
+ {
27
+ url: "https://github.com/lucide-icons/lucide.git",
28
+ variants: {
29
+ outline: "icons"
30
+ }
31
+ }
32
+ end
33
+
34
+ private
35
+
36
+ def setup_outline_config(options)
37
+ options.outline = ActiveSupport::OrderedOptions.new
38
+ options.outline.default = default_outline_options
39
+ end
40
+
41
+ def default_outline_options
42
+ ActiveSupport::OrderedOptions.new.tap do |options|
43
+ options.stroke_width = "1.5"
44
+ options.css = "size-6"
45
+ options.data = {}
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsIcons
4
+ class Configuration
5
+ module Phosphor
6
+ extend self
7
+
8
+ def config
9
+ ActiveSupport::OrderedOptions.new.tap do |options|
10
+ options.default_variant = :regular
11
+
12
+ setup_bold_config(options)
13
+ setup_duotone_config(options)
14
+ setup_fill_config(options)
15
+ setup_light_config(options)
16
+ setup_regular_config(options)
17
+ setup_thin_config(options)
18
+ end
19
+ end
20
+
21
+ def initializer_config
22
+ <<~RB.indent(2)
23
+ # Override Phosphor defaults
24
+ # config.libraries.phosphor.bold.default.css = "size-6"
25
+ # config.libraries.phosphor.bold.default.data = {}
26
+
27
+ # config.libraries.phosphor.duotone.default.css = "size-6"
28
+ # config.libraries.phosphor.duotone.default.data = {}
29
+
30
+ # config.libraries.phosphor.fill.default.css = "size-6"
31
+ # config.libraries.phosphor.fill.default.data = {}
32
+
33
+ # config.libraries.phosphor.light.default.css = "size-6"
34
+ # config.libraries.phosphor.light.default.data = {}
35
+
36
+ # config.libraries.phosphor.regular.default.css = "size-6"
37
+ # config.libraries.phosphor.regular.default.data = {}
38
+
39
+ # config.libraries.phosphor.thin.default.css = "size-6"
40
+ # config.libraries.phosphor.thin.default.data = {}
41
+ RB
42
+ end
43
+
44
+ def source
45
+ {
46
+ url: "https://github.com/phosphor-icons/core.git",
47
+ variants: {
48
+ bold: "raw/bold",
49
+ duotone: "raw/duotone",
50
+ fill: "raw/fill",
51
+ light: "raw/light",
52
+ regular: "raw/regular",
53
+ thin: "raw/thin"
54
+ }
55
+ }
56
+ end
57
+
58
+ def transformations
59
+ {
60
+ filenames: {
61
+ delete_suffix: ["-bold", "-duotone", "-fill", "-light", "-thin"]
62
+ }
63
+ }
64
+ end
65
+
66
+ private
67
+
68
+ def setup_bold_config(options)
69
+ options.bold = ActiveSupport::OrderedOptions.new
70
+ options.bold.default = default_bold_options
71
+ end
72
+
73
+ def setup_duotone_config(options)
74
+ options.duotone = ActiveSupport::OrderedOptions.new
75
+ options.duotone.default = default_duotone_options
76
+ end
77
+
78
+ def setup_fill_config(options)
79
+ options.fill = ActiveSupport::OrderedOptions.new
80
+ options.fill.default = default_fill_options
81
+ end
82
+
83
+ def setup_light_config(options)
84
+ options.light = ActiveSupport::OrderedOptions.new
85
+ options.light.default = default_light_options
86
+ end
87
+
88
+ def setup_regular_config(options)
89
+ options.regular = ActiveSupport::OrderedOptions.new
90
+ options.regular.default = default_regular_options
91
+ end
92
+
93
+ def setup_thin_config(options)
94
+ options.thin = ActiveSupport::OrderedOptions.new
95
+ options.thin.default = default_thin_options
96
+ end
97
+
98
+ def default_bold_options
99
+ ActiveSupport::OrderedOptions.new.tap do |options|
100
+ options.css = "size-6"
101
+ options.data = {}
102
+ end
103
+ end
104
+
105
+ def default_duotone_options
106
+ ActiveSupport::OrderedOptions.new.tap do |options|
107
+ options.css = "size-6"
108
+ options.data = {}
109
+ end
110
+ end
111
+
112
+ def default_fill_options
113
+ ActiveSupport::OrderedOptions.new.tap do |options|
114
+ options.css = "size-6"
115
+ options.data = {}
116
+ end
117
+ end
118
+
119
+ def default_light_options
120
+ ActiveSupport::OrderedOptions.new.tap do |options|
121
+ options.css = "size-6"
122
+ options.data = {}
123
+ end
124
+ end
125
+
126
+ def default_regular_options
127
+ ActiveSupport::OrderedOptions.new.tap do |options|
128
+ options.css = "size-6"
129
+ options.data = {}
130
+ end
131
+ end
132
+
133
+ def default_thin_options
134
+ ActiveSupport::OrderedOptions.new.tap do |options|
135
+ options.css = "size-6"
136
+ options.data = {}
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsIcons
4
+ class Configuration
5
+ module Radix
6
+ extend self
7
+
8
+ def config
9
+ ActiveSupport::OrderedOptions.new.tap do |options|
10
+ options.default_variant = nil
11
+
12
+ options.default = default_options
13
+ end
14
+ end
15
+
16
+ def initializer_config
17
+ <<~RB.indent(2)
18
+ # Override Radix defaults
19
+ # config.libraries.radix.default.css = "size-6"
20
+ # config.libraries.radix.default.stroke_width = "2"
21
+ # config.libraries.radix.default.data = {}
22
+ RB
23
+ end
24
+
25
+ def source
26
+ {
27
+ url: "https://github.com/radix-ui/icons.git",
28
+ variants: {
29
+ ".": "packages/radix-icons/icons" # Radix has no variants, store in the top directory
30
+ }
31
+ }
32
+ end
33
+
34
+ private
35
+
36
+ def default_options
37
+ ActiveSupport::OrderedOptions.new.tap do |options|
38
+ options.css = "size-4"
39
+ options.data = {}
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsIcons
4
+ class Configuration
5
+ module Tabler
6
+ extend self
7
+
8
+ def config
9
+ ActiveSupport::OrderedOptions.new.tap do |options|
10
+ options.default_variant = :outline
11
+
12
+ setup_outline_config(options)
13
+ setup_filled_config(options)
14
+ end
15
+ end
16
+
17
+ def initializer_config
18
+ <<~RB.indent(2)
19
+ # Override Tabler defaults
20
+ # config.libraries.tabler.solid.default.css = "size-6"
21
+ # config.libraries.tabler.solid.default.data = {}
22
+
23
+ # config.libraries.tabler.outline.default.css = "size-6"
24
+ # config.libraries.tabler.outline.default.stroke_width = "2"
25
+ # config.libraries.tabler.outline.default.data = {}
26
+ RB
27
+ end
28
+
29
+ def source
30
+ {
31
+ url: "https://github.com/tabler/tabler-icons.git",
32
+ variants: {
33
+ filled: "icons/filled",
34
+ outline: "icons/outline"
35
+ }
36
+ }
37
+ end
38
+
39
+ private
40
+
41
+ def setup_outline_config(options)
42
+ options.outline = ActiveSupport::OrderedOptions.new
43
+ options.outline.default = default_outline_options
44
+ end
45
+
46
+ def setup_filled_config(options)
47
+ options.filled = ActiveSupport::OrderedOptions.new
48
+ options.filled.default = default_filled_options
49
+ end
50
+
51
+ def default_outline_options
52
+ ActiveSupport::OrderedOptions.new.tap do |options|
53
+ options.stroke_width = 2
54
+ options.css = "size-6"
55
+ options.data = {}
56
+ end
57
+ end
58
+
59
+ def default_filled_options
60
+ ActiveSupport::OrderedOptions.new.tap do |options|
61
+ options.css = "size-6"
62
+ options.data = {}
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -1,12 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "icon_configs/heroicons_config"
4
- require_relative "icon_configs/lucide_config"
5
- require_relative "icon_configs/tabler_config"
6
-
7
3
  module RailsIcons
8
- # Configuration defines the available configuration options available for each of the icons sets
9
- # as well as sets the defaults to heroicons
4
+ def self.configuration
5
+ @configuration ||= Configuration.new
6
+ end
7
+
8
+ def self.configure
9
+ yield(configuration)
10
+ end
11
+
10
12
  class Configuration
11
13
  def initialize
12
14
  @config = ActiveSupport::OrderedOptions.new
@@ -30,17 +32,16 @@ module RailsIcons
30
32
  private
31
33
 
32
34
  def set_default_config
33
- @config.helper_name = "icon"
34
- @config.default_library = "heroicons"
35
- @config.default_set = "outline"
35
+ @config.default_library = nil
36
+ @config.destination_path = "app/assets/svg/icons"
36
37
  end
37
38
 
38
39
  def set_libraries_config
39
40
  @config.libraries = ActiveSupport::OrderedOptions.new
40
41
 
41
- @config.libraries.heroicons = HeroiconsConfig.new.config
42
- @config.libraries.lucide = LucideConfig.new.config
43
- @config.libraries.tabler = TablerConfig.new.config
42
+ RailsIcons.libraries.each { |name, library| @config.libraries[name] = library.config }
43
+
44
+ @config.libraries.animated = Configuration::Animated.config
44
45
  end
45
46
  end
46
47
  end
@@ -4,14 +4,13 @@ require_relative "../configuration"
4
4
 
5
5
  module RailsIcons
6
6
  module Helpers
7
- # Define the "icon" helper to generate and display icons
8
7
  module IconHelper
9
- def icon(name, library: RailsIcons.configuration.default_library, set: nil, **args)
8
+ def icon(name, library: RailsIcons.configuration.default_library, variant: nil, **arguments)
10
9
  RailsIcons::Icon.new(
11
10
  name: name,
12
11
  library: library,
13
- set: set,
14
- args: args
12
+ variant: variant,
13
+ arguments: arguments
15
14
  ).svg
16
15
  end
17
16
  end
@@ -3,13 +3,15 @@
3
3
  module RailsIcons
4
4
  class Icon
5
5
  class Attributes
6
- def initialize(default_attributes: {}, args: {})
7
- @merged_attributes = default_attributes.merge(args)
6
+ def initialize(default_attributes: {}, arguments: {})
7
+ @merged_attributes = default_attributes.merge(arguments)
8
8
  end
9
9
 
10
10
  def attach(to:)
11
11
  @merged_attributes.each do |key, value|
12
- if value.is_a?(Hash)
12
+ if key == :class
13
+ class_attribute(key, value, to)
14
+ elsif value.is_a?(Hash)
13
15
  hash_attributes(key, value, to)
14
16
  else
15
17
  string_attributes(key, value, to)
@@ -19,6 +21,10 @@ module RailsIcons
19
21
 
20
22
  private
21
23
 
24
+ def class_attribute(_, value, to)
25
+ to[:class] = ActionController::Base.helpers.token_list(value)
26
+ end
27
+
22
28
  def hash_attributes(key, value, to)
23
29
  value.each do |nested_key, nested_value|
24
30
  nested_attribute_name = format_attribute_name("#{key}-#{nested_key}")
@@ -0,0 +1,57 @@
1
+ module RailsIcons
2
+ class Icon
3
+ class FilePath
4
+ def initialize(name:, library:, variant:)
5
+ @name = name
6
+ @library = library
7
+ @variant = variant
8
+ end
9
+
10
+ def call
11
+ return animated_icons_path if @library.animated?
12
+ return custom_library_path if @library.custom?
13
+
14
+ icon_path = icons_path_in_app || icons_path_in_engines
15
+
16
+ raise RailsIcons::NotFound if icon_path.nil?
17
+
18
+ icon_path
19
+ end
20
+
21
+ private
22
+
23
+ def animated_icons_path = RailsIcons::Engine.root.join("app", "assets", "svg", "rails_icons", "icons", "animated", "#{@name}.svg")
24
+
25
+ def custom_library_path = Rails.root.join(@library.custom_path, "#{@name}.svg")
26
+
27
+ def icons_path_in_app
28
+ path = app_path
29
+
30
+ path if File.exist?(path)
31
+ end
32
+
33
+ def icons_path_in_engines
34
+ path = nil
35
+
36
+ Rails::Engine.subclasses.find do |engine|
37
+ path = engine.root.join(*parts)
38
+
39
+ path if File.exist?(path)
40
+ end
41
+
42
+ path
43
+ end
44
+
45
+ def app_path = Rails.root.join(*parts)
46
+
47
+ def parts
48
+ [
49
+ RailsIcons.configuration.destination_path,
50
+ @library,
51
+ @variant,
52
+ "#{@name}.svg"
53
+ ].compact_blank!
54
+ end
55
+ end
56
+ end
57
+ end
@@ -1,82 +1,74 @@
1
+ require "rails_icons/icon/file_path"
1
2
  require "rails_icons/icon/attributes"
2
3
 
3
4
  class RailsIcons::Icon
4
- def initialize(name:, library:, set:, args:)
5
+ def initialize(name:, library:, arguments:, variant: nil)
5
6
  @name = name
6
- @library = library.to_s
7
- @set = set
8
- @args = args
7
+ @library = library.to_s.inquiry
8
+ @variant = (variant || set_variant).to_s
9
+ @arguments = arguments
9
10
  end
10
11
 
11
12
  def svg
12
13
  raise RailsIcons::NotFound, error_message unless File.exist?(file_path)
13
14
 
14
- svg_file = Nokogiri::HTML::DocumentFragment.parse(File.read(file_path)).at_css("svg")
15
-
16
- attach_attributes to: svg_file
17
-
18
- svg_file.to_html.html_safe
15
+ Nokogiri::HTML::DocumentFragment.parse(File.read(file_path))
16
+ .at_css("svg")
17
+ .tap { |svg| attach_attributes(to: svg) }
18
+ .to_html
19
+ .html_safe
19
20
  end
20
21
 
21
22
  private
22
23
 
23
- def error_message
24
- "Icon not found: `#{@library} / #{set} / #{@name}`"
24
+ def set_variant
25
+ RailsIcons.configuration.default_variant.presence ||
26
+ RailsIcons.configuration.libraries.dig(@library.to_sym, :default_variant)
25
27
  end
26
28
 
27
- def file_path
28
- custom_library.dig("path") ||
29
- Rails.root.join("app", "assets", "svg", "icons", @library, set, "#{@name}.svg")
30
- end
29
+ def error_message
30
+ attributes = [
31
+ @library,
32
+ @variant,
33
+ @name
34
+ ].compact_blank
31
35
 
32
- def custom_library?
33
- custom_library.present?
36
+ "Icon not found: `#{attributes.join(" / ")}`"
34
37
  end
35
38
 
39
+ def file_path = RailsIcons::Icon::FilePath.new(name: @name, library: @library, variant: @variant).call
40
+
36
41
  def attach_attributes(to:)
37
42
  RailsIcons::Icon::Attributes
38
- .new(default_attributes: default_attributes, args: @args)
43
+ .new(default_attributes: default_attributes, arguments: @arguments)
39
44
  .attach(to: to)
40
45
  end
41
46
 
42
47
  def default_attributes
43
48
  {
44
- "stroke-width": default_stroke_width,
45
- class: default_css,
46
- data: default_data
49
+ "stroke-width": default(:stroke_width),
50
+ data: default(:data),
51
+ class: default(:css)
47
52
  }
48
53
  end
49
54
 
50
- def set
51
- return @set if @set.present?
52
-
53
- RailsIcons.configuration.default_set
54
- end
55
-
56
- def default_css
57
- library_set_attributes.dig(:default, :css)
58
- end
59
-
60
- def default_data
61
- library_set_attributes.dig(:default, :data)
62
- end
63
-
64
- def default_stroke_width
65
- library_set_attributes.dig(:default, :stroke_width)
66
- end
67
-
68
- def library_set_attributes
69
- return custom_library || {} if custom_library?
55
+ def default(key) = library_attributes.dig(:default, key)
70
56
 
71
- RailsIcons.configuration.libraries.dig(@library, set) || {}
57
+ def library_attributes
58
+ custom_library? ? custom_library : RailsIcons.configuration.libraries.dig(@library, @variant) || {}
72
59
  end
73
60
 
74
61
  def custom_library
75
62
  RailsIcons
76
63
  .configuration
77
64
  .libraries
78
- .dig("custom")
79
- &.with_indifferent_access
80
- &.dig(@library, set) || {}
65
+ &.dig("custom")
66
+ &.dig(@library.to_sym)&.with_defaults(
67
+ {
68
+ path: [RailsIcons.configuration.destination_path, @library].join("/")
69
+ }
70
+ ) || {}
81
71
  end
72
+
73
+ def custom_library? = custom_library.present?
82
74
  end