rails_icons 1.0.0 → 1.2.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 (32) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +6 -5
  3. data/README.md +27 -13
  4. data/lib/generators/rails_icons/initializer_generator.rb +24 -65
  5. data/lib/generators/rails_icons/install_generator.rb +8 -4
  6. data/lib/generators/rails_icons/sync_generator.rb +12 -43
  7. data/lib/rails_icons/base_generator.rb +20 -0
  8. data/lib/rails_icons/configuration/animated.rb +3 -1
  9. data/lib/rails_icons/configuration/boxicons.rb +77 -0
  10. data/lib/rails_icons/configuration/feather.rb +24 -1
  11. data/lib/rails_icons/configuration/flags.rb +68 -0
  12. data/lib/rails_icons/configuration/heroicons.rb +39 -4
  13. data/lib/rails_icons/configuration/linear.rb +48 -0
  14. data/lib/rails_icons/configuration/lucide.rb +24 -1
  15. data/lib/rails_icons/configuration/phosphor.rb +144 -0
  16. data/lib/rails_icons/configuration/radix.rb +46 -0
  17. data/lib/rails_icons/configuration/sidekickicons.rb +104 -0
  18. data/lib/rails_icons/configuration/tabler.rb +29 -1
  19. data/lib/rails_icons/configuration/weather.rb +54 -0
  20. data/lib/rails_icons/configuration.rb +4 -11
  21. data/lib/rails_icons/errors.rb +15 -1
  22. data/lib/rails_icons/icon/attributes.rb +7 -1
  23. data/lib/rails_icons/icon/file_path.rb +57 -0
  24. data/lib/rails_icons/icon.rb +4 -18
  25. data/lib/rails_icons/libraries.rb +28 -41
  26. data/lib/rails_icons/sync/engine.rb +75 -0
  27. data/lib/rails_icons/sync/process_variants.rb +74 -0
  28. data/lib/rails_icons/sync/transformations.rb +27 -0
  29. data/lib/rails_icons/version.rb +1 -1
  30. data/lib/rails_icons.rb +1 -1
  31. metadata +15 -4
  32. data/lib/generators/rails_icons/sync/engine.rb +0 -87
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsIcons
4
+ class Configuration
5
+ module Linear
6
+ extend self
7
+
8
+ def config
9
+ ActiveSupport::OrderedOptions.new.tap do |options|
10
+ options.default_variant = nil
11
+ options.exclude_variants = []
12
+
13
+ options.default = default_options
14
+ end
15
+ end
16
+
17
+ def initializer_config
18
+ <<~RB.indent(2)
19
+ # Override Linear defaults
20
+ # config.libraries.linear.exclude_variants = []
21
+
22
+ # config.libraries.linear.default.css = "size-6"
23
+ # config.libraries.linear.default.stroke_width = "2"
24
+ # config.libraries.linear.default.data = {}
25
+ RB
26
+ end
27
+
28
+ def source
29
+ {
30
+ url: "https://github.com/cjpatoilo/linearicons.git",
31
+ variants: {
32
+ ".": "dist/svg" # Linear has no variants, store in the top directory
33
+ }
34
+ }
35
+ end
36
+
37
+ private
38
+
39
+ def default_options
40
+ ActiveSupport::OrderedOptions.new.tap do |options|
41
+ options.stroke_width = "2"
42
+ options.css = "size-6"
43
+ options.data = {}
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -2,15 +2,38 @@
2
2
 
3
3
  module RailsIcons
4
4
  class Configuration
5
- class Lucide
5
+ module Lucide
6
+ extend self
7
+
6
8
  def config
7
9
  ActiveSupport::OrderedOptions.new.tap do |options|
8
10
  options.default_variant = :outline
11
+ options.exclude_variants = []
9
12
 
10
13
  setup_outline_config(options)
11
14
  end
12
15
  end
13
16
 
17
+ def initializer_config
18
+ <<~RB.indent(2)
19
+ # Override Lucide defaults
20
+ # config.libraries.lucide.exclude_variants = [] # Exclude specific variants
21
+
22
+ # config.libraries.lucide.outline.default.css = "size-6"
23
+ # config.libraries.lucide.outline.default.stroke_width = "1.5"
24
+ # config.libraries.lucide.outline.default.data = {}
25
+ RB
26
+ end
27
+
28
+ def source
29
+ {
30
+ url: "https://github.com/lucide-icons/lucide.git",
31
+ variants: {
32
+ outline: "icons"
33
+ }
34
+ }
35
+ end
36
+
14
37
  private
15
38
 
16
39
  def setup_outline_config(options)
@@ -0,0 +1,144 @@
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
+ options.exclude_variants = []
12
+
13
+ setup_bold_config(options)
14
+ setup_duotone_config(options)
15
+ setup_fill_config(options)
16
+ setup_light_config(options)
17
+ setup_regular_config(options)
18
+ setup_thin_config(options)
19
+ end
20
+ end
21
+
22
+ def initializer_config
23
+ <<~RB.indent(2)
24
+ # Override Phosphor defaults
25
+ # config.libraries.phosphor.exclude_variants = [:duotone, :thin] # Exclude specific variants
26
+
27
+ # config.libraries.phosphor.bold.default.css = "size-6"
28
+ # config.libraries.phosphor.bold.default.data = {}
29
+
30
+ # config.libraries.phosphor.duotone.default.css = "size-6"
31
+ # config.libraries.phosphor.duotone.default.data = {}
32
+
33
+ # config.libraries.phosphor.fill.default.css = "size-6"
34
+ # config.libraries.phosphor.fill.default.data = {}
35
+
36
+ # config.libraries.phosphor.light.default.css = "size-6"
37
+ # config.libraries.phosphor.light.default.data = {}
38
+
39
+ # config.libraries.phosphor.regular.default.css = "size-6"
40
+ # config.libraries.phosphor.regular.default.data = {}
41
+
42
+ # config.libraries.phosphor.thin.default.css = "size-6"
43
+ # config.libraries.phosphor.thin.default.data = {}
44
+ RB
45
+ end
46
+
47
+ def source
48
+ {
49
+ url: "https://github.com/phosphor-icons/core.git",
50
+ variants: {
51
+ bold: "raw/bold",
52
+ duotone: "raw/duotone",
53
+ fill: "raw/fill",
54
+ light: "raw/light",
55
+ regular: "raw/regular",
56
+ thin: "raw/thin"
57
+ }
58
+ }
59
+ end
60
+
61
+ def transformations
62
+ {
63
+ filenames: {
64
+ delete_suffix: ["-bold", "-duotone", "-fill", "-light", "-thin"]
65
+ }
66
+ }
67
+ end
68
+
69
+ private
70
+
71
+ def setup_bold_config(options)
72
+ options.bold = ActiveSupport::OrderedOptions.new
73
+ options.bold.default = default_bold_options
74
+ end
75
+
76
+ def setup_duotone_config(options)
77
+ options.duotone = ActiveSupport::OrderedOptions.new
78
+ options.duotone.default = default_duotone_options
79
+ end
80
+
81
+ def setup_fill_config(options)
82
+ options.fill = ActiveSupport::OrderedOptions.new
83
+ options.fill.default = default_fill_options
84
+ end
85
+
86
+ def setup_light_config(options)
87
+ options.light = ActiveSupport::OrderedOptions.new
88
+ options.light.default = default_light_options
89
+ end
90
+
91
+ def setup_regular_config(options)
92
+ options.regular = ActiveSupport::OrderedOptions.new
93
+ options.regular.default = default_regular_options
94
+ end
95
+
96
+ def setup_thin_config(options)
97
+ options.thin = ActiveSupport::OrderedOptions.new
98
+ options.thin.default = default_thin_options
99
+ end
100
+
101
+ def default_bold_options
102
+ ActiveSupport::OrderedOptions.new.tap do |options|
103
+ options.css = "size-6"
104
+ options.data = {}
105
+ end
106
+ end
107
+
108
+ def default_duotone_options
109
+ ActiveSupport::OrderedOptions.new.tap do |options|
110
+ options.css = "size-6"
111
+ options.data = {}
112
+ end
113
+ end
114
+
115
+ def default_fill_options
116
+ ActiveSupport::OrderedOptions.new.tap do |options|
117
+ options.css = "size-6"
118
+ options.data = {}
119
+ end
120
+ end
121
+
122
+ def default_light_options
123
+ ActiveSupport::OrderedOptions.new.tap do |options|
124
+ options.css = "size-6"
125
+ options.data = {}
126
+ end
127
+ end
128
+
129
+ def default_regular_options
130
+ ActiveSupport::OrderedOptions.new.tap do |options|
131
+ options.css = "size-6"
132
+ options.data = {}
133
+ end
134
+ end
135
+
136
+ def default_thin_options
137
+ ActiveSupport::OrderedOptions.new.tap do |options|
138
+ options.css = "size-6"
139
+ options.data = {}
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,46 @@
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
+ options.exclude_variants = []
12
+
13
+ options.default = default_options
14
+ end
15
+ end
16
+
17
+ def initializer_config
18
+ <<~RB.indent(2)
19
+ # Override Radix defaults
20
+ # config.libraries.radix.exclude_variants = [] # Radix has no variants, this is provided for backwards compatibility
21
+ # config.libraries.radix.default.css = "size-6"
22
+ # config.libraries.radix.default.stroke_width = "2"
23
+ # config.libraries.radix.default.data = {}
24
+ RB
25
+ end
26
+
27
+ def source
28
+ {
29
+ url: "https://github.com/radix-ui/icons.git",
30
+ variants: {
31
+ ".": "packages/radix-icons/icons" # Radix has no variants, store in the top directory
32
+ }
33
+ }
34
+ end
35
+
36
+ private
37
+
38
+ def default_options
39
+ ActiveSupport::OrderedOptions.new.tap do |options|
40
+ options.css = "size-4"
41
+ options.data = {}
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsIcons
4
+ class Configuration
5
+ module Sidekickicons
6
+ extend self
7
+
8
+ def config
9
+ ActiveSupport::OrderedOptions.new.tap do |options|
10
+ options.default_variant = :outline
11
+ options.exclude_variants = []
12
+
13
+ setup_outline_config(options)
14
+ setup_solid_config(options)
15
+ setup_mini_config(options)
16
+ setup_micro_config(options)
17
+ end
18
+ end
19
+
20
+ def initializer_config
21
+ <<~RB.indent(2)
22
+ # Override Sidekickicons defaults
23
+ # config.libraries.sidekickicons.exclude_variants = [:mini, :micro] # Exclude specific variants
24
+
25
+ # config.libraries.sidekickicons.outline.default.css = "size-6"
26
+ # config.libraries.sidekickicons.outline.default.stroke_width = "1.5"
27
+ # config.libraries.sidekickicons.outline.default.data = {}
28
+
29
+ # config.libraries.sidekickicons.solid.default.css = "size-6"
30
+ # config.libraries.sidekickicons.solid.default.data = {}
31
+
32
+ # config.libraries.sidekickicons.mini.default.css = "size-5"
33
+ # config.libraries.sidekickicons.mini.default.data = {}
34
+
35
+ # config.libraries.sidekickicons.micro.default.css = "size-4"
36
+ # config.libraries.sidekickicons.micro.default.data = {}
37
+ RB
38
+ end
39
+
40
+ def source
41
+ {
42
+ url: "https://github.com/ndri/sidekickicons",
43
+ variants: {
44
+ outline: "optimized/24/outline",
45
+ solid: "optimized/24/solid",
46
+ mini: "optimized/20/solid",
47
+ micro: "optimized/16/solid"
48
+ }
49
+ }
50
+ end
51
+
52
+ private
53
+
54
+ def setup_outline_config(options)
55
+ options.outline = ActiveSupport::OrderedOptions.new
56
+ options.outline.default = default_outline_options
57
+ end
58
+
59
+ def setup_solid_config(options)
60
+ options.solid = ActiveSupport::OrderedOptions.new
61
+ options.solid.default = default_solid_options
62
+ end
63
+
64
+ def setup_mini_config(options)
65
+ options.mini = ActiveSupport::OrderedOptions.new
66
+ options.mini.default = default_mini_options
67
+ end
68
+
69
+ def setup_micro_config(options)
70
+ options.micro = ActiveSupport::OrderedOptions.new
71
+ options.micro.default = default_micro_options
72
+ end
73
+
74
+ def default_solid_options
75
+ ActiveSupport::OrderedOptions.new.tap do |options|
76
+ options.css = "size-6"
77
+ options.data = {}
78
+ end
79
+ end
80
+
81
+ def default_outline_options
82
+ ActiveSupport::OrderedOptions.new.tap do |options|
83
+ options.stroke_width = 1.5
84
+ options.css = "size-6"
85
+ options.data = {}
86
+ end
87
+ end
88
+
89
+ def default_mini_options
90
+ ActiveSupport::OrderedOptions.new.tap do |options|
91
+ options.css = "size-5"
92
+ options.data = {}
93
+ end
94
+ end
95
+
96
+ def default_micro_options
97
+ ActiveSupport::OrderedOptions.new.tap do |options|
98
+ options.css = "size-4"
99
+ options.data = {}
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
@@ -2,16 +2,44 @@
2
2
 
3
3
  module RailsIcons
4
4
  class Configuration
5
- class Tabler
5
+ module Tabler
6
+ extend self
7
+
6
8
  def config
7
9
  ActiveSupport::OrderedOptions.new.tap do |options|
8
10
  options.default_variant = :outline
11
+ options.exclude_variants = []
9
12
 
10
13
  setup_outline_config(options)
11
14
  setup_filled_config(options)
12
15
  end
13
16
  end
14
17
 
18
+ def initializer_config
19
+ <<~RB.indent(2)
20
+ # Override Tabler defaults
21
+ # config.libraries.tabler.exclude_variants = [] # Exclude specific variants
22
+
23
+ # config.libraries.tabler.regular.default.css = "size-6"
24
+ # config.libraries.tabler.solid.default.css = "size-6"
25
+ # config.libraries.tabler.solid.default.data = {}
26
+
27
+ # config.libraries.tabler.outline.default.css = "size-6"
28
+ # config.libraries.tabler.outline.default.stroke_width = "2"
29
+ # config.libraries.tabler.outline.default.data = {}
30
+ RB
31
+ end
32
+
33
+ def source
34
+ {
35
+ url: "https://github.com/tabler/tabler-icons.git",
36
+ variants: {
37
+ filled: "icons/filled",
38
+ outline: "icons/outline"
39
+ }
40
+ }
41
+ end
42
+
15
43
  private
16
44
 
17
45
  def setup_outline_config(options)
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsIcons
4
+ class Configuration
5
+ module Weather
6
+ extend self
7
+
8
+ def config
9
+ ActiveSupport::OrderedOptions.new.tap do |options|
10
+ options.default_variant = nil
11
+ options.exclude_variants = []
12
+
13
+ options.default = default_options
14
+ end
15
+ end
16
+
17
+ def initializer_config
18
+ <<~RB.indent(2)
19
+ # Override Weather defaults
20
+ # config.libraries.weather.exclude_variants = []
21
+
22
+ # config.libraries.weather.default.css = "size-6"
23
+ # config.libraries.weather.default.data = {}
24
+ RB
25
+ end
26
+
27
+ def source
28
+ {
29
+ url: "https://github.com/erikflowers/weather-icons.git",
30
+ variants: {
31
+ ".": "svg" # Weather has no variants, store in the top directory
32
+ }
33
+ }
34
+ end
35
+
36
+ def transformations
37
+ {
38
+ filenames: {
39
+ delete_prefix: ["wi-"]
40
+ }
41
+ }
42
+ end
43
+
44
+ private
45
+
46
+ def default_options
47
+ ActiveSupport::OrderedOptions.new.tap do |options|
48
+ options.css = "size-6"
49
+ options.data = {}
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -1,11 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "configuration/animated"
4
- require_relative "configuration/feather"
5
- require_relative "configuration/heroicons"
6
- require_relative "configuration/lucide"
7
- require_relative "configuration/tabler"
8
-
9
3
  module RailsIcons
10
4
  def self.configuration
11
5
  @configuration ||= Configuration.new
@@ -39,16 +33,15 @@ module RailsIcons
39
33
 
40
34
  def set_default_config
41
35
  @config.default_library = nil
36
+ @config.destination_path = "app/assets/svg/icons"
42
37
  end
43
38
 
44
39
  def set_libraries_config
45
40
  @config.libraries = ActiveSupport::OrderedOptions.new
46
41
 
47
- @config.libraries.animated = Configuration::Animated.new.config
48
- @config.libraries.feather = Configuration::Feather.new.config
49
- @config.libraries.heroicons = Configuration::Heroicons.new.config
50
- @config.libraries.lucide = Configuration::Lucide.new.config
51
- @config.libraries.tabler = Configuration::Tabler.new.config
42
+ RailsIcons.libraries.each { |name, library| @config.libraries[name] = library.config }
43
+
44
+ @config.libraries.animated = Configuration::Animated.config
52
45
  end
53
46
  end
54
47
  end
@@ -1,5 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsIcons
4
- class NotFound < StandardError; end
4
+ class IconNotFound < StandardError
5
+ def initialize(icon_name)
6
+ super("The icon `#{icon_name}` is not available. Please check the icon name and try again.")
7
+ end
8
+ end
9
+
10
+ class LibraryNotFound < StandardError
11
+ def initialize(library_name)
12
+ if library_name.empty?
13
+ super("No libraries were specified. Please choose from: #{RailsIcons.libraries.keys.to_sentence(last_word_connector: " or ")}")
14
+ else
15
+ super("The library `#{library_name}` is not available. Please check the library name and try again.")
16
+ end
17
+ end
18
+ end
5
19
  end
@@ -9,7 +9,9 @@ module RailsIcons
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::IconNotFound 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,3 +1,4 @@
1
+ require "rails_icons/icon/file_path"
1
2
  require "rails_icons/icon/attributes"
2
3
 
3
4
  class RailsIcons::Icon
@@ -9,7 +10,7 @@ class RailsIcons::Icon
9
10
  end
10
11
 
11
12
  def svg
12
- raise RailsIcons::NotFound, error_message unless File.exist?(file_path)
13
+ raise RailsIcons::IconNotFound, error_message unless File.exist?(file_path)
13
14
 
14
15
  Nokogiri::HTML::DocumentFragment.parse(File.read(file_path))
15
16
  .at_css("svg")
@@ -35,22 +36,7 @@ class RailsIcons::Icon
35
36
  "Icon not found: `#{attributes.join(" / ")}`"
36
37
  end
37
38
 
38
- def file_path
39
- return RailsIcons::Engine.root.join("app", "assets", "svg", "rails_icons", "icons", "animated", "#{@name}.svg") if @library.animated?
40
- return Rails.root.join(custom_library.dig(:path), "#{@name}.svg") if custom_library?
41
-
42
- parts = [
43
- "app",
44
- "assets",
45
- "svg",
46
- "icons",
47
- @library,
48
- @variant,
49
- "#{@name}.svg"
50
- ].compact_blank!
51
-
52
- Rails.root.join(*parts)
53
- end
39
+ def file_path = RailsIcons::Icon::FilePath.new(name: @name, library: @library, variant: @variant).call
54
40
 
55
41
  def attach_attributes(to:)
56
42
  RailsIcons::Icon::Attributes
@@ -79,7 +65,7 @@ class RailsIcons::Icon
79
65
  &.dig("custom")
80
66
  &.dig(@library.to_sym)&.with_defaults(
81
67
  {
82
- path: "app/assets/svg/icons/#{@library}"
68
+ path: [RailsIcons.configuration.destination_path, @library].join("/")
83
69
  }
84
70
  ) || {}
85
71
  end