rails_icons 1.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 50dffad405d19a7a365d8dd5684422ac4b0b31fc5e8c9e001d841c2625ed0f66
4
- data.tar.gz: ac27f4feb6a7dae8d240896cbcad704675f566080aea2a1df4bad68608bcd0ae
3
+ metadata.gz: 628225582b62195c9f7bc3994d9fcad7aa37dc563b4d0e73069c5efdddd81332
4
+ data.tar.gz: 3241569575d809f7c6bbce51804cab8255df585f24a9473878432d2930596fcb
5
5
  SHA512:
6
- metadata.gz: 1b3b458095eb630a39f217be671c6bf58dc400c6e5caea9e7eee7ceebc51df6329dced01d3451f483b936f3fb5d59aaeea05de519565e36c12de3aa80abfbeb3
7
- data.tar.gz: 60a93aed59ef5c518c39d95b3814062a02240aa86cbfe34ca771164504747ea965fae97a3456cc50dc06e620c04ccc2c5d7825d7724ec7f3850abd583be0cf91
6
+ metadata.gz: c4226fb17440c8eb8949ecce47be982b7dc17f022e33b1bccc640dbd16b700096e2f6867dceace37c597e56919be83621523ac8f842976365dc81517149bf4cc
7
+ data.tar.gz: 1c1b35579576475f1b06ccf56416850c3d333402ebfefc63b8b1250b4317a196b04b15512ca5ac17cd26faba7298439114b4f175803c564ecbf1d22123db3eba
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rails_icons (1.0.0)
4
+ rails_icons (1.1.0)
5
5
  nokogiri (~> 1.16, >= 1.16.4)
6
6
  rails (> 6.1)
7
7
 
data/README.md CHANGED
@@ -16,7 +16,11 @@ The icons are sourced directly from their respective GitHub repositories, ensuri
16
16
  **Sponsored By [Rails Designer](https://railsdesigner.com/)**
17
17
 
18
18
  <a href="https://railsdesigner.com/" target="_blank">
19
- <img src="https://raw.githubusercontent.com/Rails-Designer/rails_icons/main/docs/rails_designer_icon.jpg" alt="Rails Designer logo" width="240" />
19
+ <picture>
20
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/Rails-Designer/rails_icons/HEAD/.github/logo-dark.svg">
21
+ <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/Rails-Designer/rails_icons/HEAD/.github/logo-light.svg">
22
+ <img alt="Rails Designer" src="https://raw.githubusercontent.com/Rails-Designer/rails_icons/HEAD/.github/logo-light.svg" width="240" style="max-width: 100%;">
23
+ </picture>
20
24
  </a>
21
25
 
22
26
 
@@ -56,6 +60,11 @@ icon "check", library: "heroicons"
56
60
  # Add CSS
57
61
  icon "check", class: "text-green-500"
58
62
 
63
+ # Add CSS with class_names
64
+ # article: https://railsdesigner.com/conditional-css-classes-in-rails/
65
+ # docs: https://edgeapi.rubyonrails.org/classes/ActionView/Helpers/TagHelper.html#method-i-token_list
66
+ icon "check", class: ["size-4", "bg-red-500": !verified?, "bg-green-500": verified?]
67
+
59
68
  # Add data attributes
60
69
  icon "check", data: { controller: "swap" }
61
70
 
@@ -66,10 +75,13 @@ icon "check", stroke_width: 2
66
75
 
67
76
  ## First-party libraries
68
77
 
69
- - [Feather](https://github.com/feathericons/feather)
70
- - [Heroicons](https://github.com/tailwindlabs/heroicons)
71
- - [Lucide](https://github.com/lucide-icons/lucide)
72
- - [Tabler](https://github.com/tabler/tabler-icons)
78
+ - [Boxicons](https://github.com/atisawd/boxicons) (1600+ icons)
79
+ - [Feather](https://github.com/feathericons/feather) (280+ icons)
80
+ - [Heroicons](https://github.com/tailwindlabs/heroicons) (300+ icons)
81
+ - [Lucide](https://github.com/lucide-icons/lucide) (1500+ icons)
82
+ - [Phosphor](https://github.com/phosphor-icons/core) (9000+ icons)
83
+ - [Radix](https://github.com/radix-ui/icons/) (300+ icons)
84
+ - [Tabler](https://github.com/tabler/tabler-icons) (5700+ icons)
73
85
 
74
86
 
75
87
  ## Animated icons
@@ -92,7 +104,6 @@ Need to use an icon from another library?
92
104
  2. add the (SVG) icons to the created directory **app/assets/svg/icons/simple_icons**;
93
105
 
94
106
  Every custom icon can now be used with the same interface as first-party icon libraries.
95
-
96
107
  ```ruby
97
108
  icon "apple", library: "simple_icons", class: "text-black"
98
109
  ```
@@ -100,13 +111,12 @@ icon "apple", library: "simple_icons", class: "text-black"
100
111
 
101
112
  ## Sync icons
102
113
 
103
- If a library gets updated, sync the icons to your app by running
104
-
114
+ To sync all installed libraries, run
105
115
  ```bash
106
- rails generate rails_icons:sync --libraries=LIBRARY_NAME
116
+ rails generate rails_icons:sync
107
117
  ```
108
118
 
109
- **Example**
119
+ To sync only a specific library, run
110
120
  ```bash
111
121
  rails generate rails_icons:sync --libraries=heroicons
112
122
 
@@ -4,8 +4,10 @@ module RailsIcons
4
4
  class InitializerGenerator < Rails::Generators::Base
5
5
  source_root File.expand_path("templates", __dir__)
6
6
 
7
- class_option :libraries, type: :array, default: [], desc: "Choose libraries (#{RailsIcons::Libraries.all.keys.join("/")})"
8
- class_option :destination, type: :string, default: "app/assets/svg/icons/", desc: "Specify destination folder for icons"
7
+ desc "Create the Rails Icons initializer."
8
+
9
+ class_option :libraries, type: :array, default: [], desc: "Choose libraries (#{RailsIcons.libraries.keys.join("/")})"
10
+ class_option :destination, type: :string, default: RailsIcons.configuration.destination_path, desc: "Specify destination folder for icons"
9
11
  class_option :custom, type: :string, desc: "Name of the custom library"
10
12
 
11
13
  def copy_initializer
@@ -21,13 +23,23 @@ module RailsIcons
21
23
  if options[:libraries].present?
22
24
  default_configuration = <<~RB.indent(2)
23
25
  config.default_library = "#{options[:libraries].first}"
24
- # config.default_variant = "" # Set a default variant if multiple exist
26
+ # config.default_variant = "" # Set a default variant for all libraries
25
27
  RB
26
28
 
27
29
  insert_into_file INITIALIZER, default_configuration, after: "RailsIcons.configure do |config|\n"
28
30
  end
29
31
  end
30
32
 
33
+ def insert_custom_destination_path
34
+ return if options[:destination] && options[:destination] == RailsIcons.configuration.destination_path
35
+
36
+ insert_into_file INITIALIZER, <<~RB.indent(2), after: "RailsIcons.configure do |config|\n"
37
+ # Default destination path
38
+ config.destination_path = "#{options[:destination]}"
39
+
40
+ RB
41
+ end
42
+
31
43
  def insert_libraries_configuration
32
44
  insert_into_file INITIALIZER, "\n#{library_configuration}", before: "end"
33
45
  end
@@ -61,67 +73,10 @@ module RailsIcons
61
73
  insert_into_file INITIALIZER, "\n#{custom_configuration}", after: "custom: {"
62
74
  end
63
75
 
64
- def create_custom_directory
65
- FileUtils.mkdir_p(File.join(options[:destination], options[:custom]))
66
- end
76
+ def create_custom_directory = FileUtils.mkdir_p(File.join(options[:destination], options[:custom]))
67
77
 
68
78
  def library_configuration
69
- configs = {
70
- feather: feather_config,
71
- heroicons: heroicons_config,
72
- lucide: lucide_config,
73
- tabler: tabler_config
74
- }
75
-
76
- options[:libraries].map { configs[_1.to_sym] }.join("\n")
77
- end
78
-
79
- def feather_config
80
- <<~RB.indent(2)
81
- # Override Feather defaults
82
- # config.libraries.feather.default.css = "size-6"
83
- # config.libraries.feather.default.stroke_width = "2"
84
- # config.libraries.feather.default.data = {}
85
- RB
86
- end
87
-
88
- def heroicons_config
89
- <<~RB.indent(2)
90
- # Override Heroicon defaults
91
- # config.libraries.heroicons.outline.default.css = "size-6"
92
- # config.libraries.heroicons.outline.default.stroke_width = "1.5"
93
- # config.libraries.heroicons.outline.default.data = {}
94
-
95
- # config.libraries.heroicons.solid.default.css = "size-6"
96
- # config.libraries.heroicons.solid.default.data = {}
97
-
98
- # config.libraries.heroicons.mini.default.css = "size-5"
99
- # config.libraries.heroicons.mini.default.data = {}
100
-
101
- # config.libraries.heroicons.micro.default.css = "size-4"
102
- # config.libraries.heroicons.micro.default.data = {}
103
- RB
104
- end
105
-
106
- def lucide_config
107
- <<~RB.indent(2)
108
- # Override Lucide defaults
109
- # config.libraries.lucide.outline.default.css = "size-6"
110
- # config.libraries.lucide.outline.default.stroke_width = "1.5"
111
- # config.libraries.lucide.outline.default.data = {}
112
- RB
113
- end
114
-
115
- def tabler_config
116
- <<~RB.indent(2)
117
- # Override Tabler defaults
118
- # config.libraries.tabler.solid.default.css = "size-6"
119
- # config.libraries.tabler.solid.default.data = {}
120
-
121
- # config.libraries.tabler.outline.default.css = "size-6"
122
- # config.libraries.tabler.outline.default.stroke_width = "2"
123
- # config.libraries.tabler.outline.default.data = {}
124
- RB
79
+ options[:libraries].map { RailsIcons.libraries[_1.to_sym].initializer_config }.join("\n")
125
80
  end
126
81
 
127
82
  def custom_configuration
@@ -4,8 +4,10 @@ module RailsIcons
4
4
  class InstallGenerator < Rails::Generators::Base
5
5
  source_root File.expand_path("templates", __dir__)
6
6
 
7
- class_option :libraries, type: :array, default: [], desc: "Choose libraries (#{RailsIcons::Libraries.all.keys.join("/")})"
8
- class_option :destination, type: :string, default: "app/assets/svg/icons/", desc: "Specify destination folder for icons"
7
+ desc "Install Rails Icons with the choosen libraries. This creates the configuration initializer and will sync the icons."
8
+
9
+ class_option :libraries, type: :array, default: [], desc: "Choose libraries (#{RailsIcons.libraries.keys.join("/")})"
10
+ class_option :destination, type: :string, default: RailsIcons.configuration.destination_path, desc: "Specify destination folder for icons"
9
11
  class_option :skip_sync, type: :boolean, default: false
10
12
 
11
13
  def initializer_generator
@@ -1,59 +1,31 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "fileutils"
4
- require_relative "sync/engine"
3
+ require "rails_icons/sync/engine"
5
4
 
6
5
  module RailsIcons
7
6
  class SyncGenerator < Rails::Generators::Base
8
- class_option :libraries, type: :array, default: [], desc: "Choose libraries (#{RailsIcons::Libraries.all.keys.join("/")})"
9
- class_option :destination, type: :string, default: "app/assets/svg/icons/", desc: "Specify destination folder for icons"
10
-
11
- desc "Sync an icon library(s) from their respective git repos."
12
7
  source_root File.expand_path("templates", __dir__)
13
8
 
14
- def sync_icons
15
- raise "[Rails Icons] Not a valid library" if options[:libraries].empty?
9
+ desc "Sync the choosen icon libraries from their respective git repos."
16
10
 
17
- clean_temp_directory
11
+ class_option :libraries, type: :array, default: [], desc: "Choose libraries (#{RailsIcons.libraries.keys.join("/")})"
18
12
 
19
- options[:libraries].each { |library| sync(library) }
13
+ def sync_icons
14
+ raise "[Rails Icons] Not a valid library" if libraries.empty?
20
15
 
21
- clean_temp_directory
16
+ libraries.each { Sync::Engine.new(_1).sync }
22
17
  end
23
18
 
24
19
  private
25
20
 
26
- def clean_temp_directory
27
- FileUtils.rm_rf(temp_directory) if Dir.exist?(temp_directory)
28
- end
29
-
30
- def sync(name)
31
- library = RailsIcons::Libraries.all.fetch(name.to_sym)
32
- library_path = File.join(temp_directory, library[:name])
33
-
34
- Sync::Engine.new(temp_directory, library).sync
35
-
36
- raise_library_not_found(name) unless Dir.exist?(library_path)
37
- copy_library(library[:name], library_path)
38
- end
39
-
40
- def temp_directory
41
- Rails.root.join("tmp/icons")
42
- end
43
-
44
- def copy_library(library, source)
45
- destination = File.join(options[:destination], library)
46
-
47
- FileUtils.mkdir_p(destination)
48
-
49
- FileUtils.cp_r(Dir.glob("#{source}/*"), destination)
50
-
51
- say "[Rails Icons] Synced '#{library}' library successfully #{%w[😃 🎉 ✨].sample}", :green
21
+ def libraries
22
+ options[:libraries].presence || synced_libraries
52
23
  end
53
24
 
54
- def raise_library_not_found(library)
55
- say "[Rails Icons] Could not find '#{library}' library 🤷", :red
56
- exit 1
25
+ def synced_libraries
26
+ RailsIcons.libraries.keys.map(&:to_s).select do |library|
27
+ Dir.exist?(File.join(RailsIcons.configuration.destination_path, library.to_s))
28
+ end
57
29
  end
58
30
  end
59
31
  end
@@ -2,7 +2,9 @@
2
2
 
3
3
  module RailsIcons
4
4
  class Configuration
5
- class Animated
5
+ module Animated
6
+ extend self
7
+
6
8
  def config
7
9
  ActiveSupport::OrderedOptions.new.tap do |options|
8
10
  options.default = default_options
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsIcons
4
+ class Configuration
5
+ module Boxicons
6
+ extend self
7
+
8
+ def config
9
+ ActiveSupport::OrderedOptions.new.tap do |options|
10
+ options.default_variant = :regular
11
+
12
+ setup_regular_config(options)
13
+ setup_solid_config(options)
14
+ setup_logos_config(options)
15
+ end
16
+ end
17
+
18
+ def initializer_config
19
+ <<~RB.indent(2)
20
+ # Override Boxicons defaults
21
+ # config.libraries.boxicons.solid.css = "size-6"
22
+ # config.libraries.boxicons.solid.data = {}
23
+
24
+ # config.libraries.boxicons.regular.css = "size-6"
25
+ # config.libraries.boxicons.regular.data = {}
26
+
27
+ # config.libraries.boxicons.logos.css = "size-6"
28
+ # config.libraries.boxicons.logos.data = {}
29
+ RB
30
+ end
31
+
32
+ def source
33
+ {
34
+ url: "https://github.com/atisawd/boxicons.git",
35
+ variants: {
36
+ logos: "svg/logos",
37
+ regular: "svg/regular",
38
+ solid: "svg/solid"
39
+ }
40
+ }
41
+ end
42
+
43
+ def transformations
44
+ {
45
+ filenames: {
46
+ delete_prefix: ["bxl-", "bx-", "bxs-"]
47
+ }
48
+ }
49
+ end
50
+
51
+ def setup_regular_config(options)
52
+ options.regular = ActiveSupport::OrderedOptions.new
53
+ options.regular.default = default_options
54
+ end
55
+
56
+ def setup_solid_config(options)
57
+ options.solid = ActiveSupport::OrderedOptions.new
58
+ options.solid.default = default_options
59
+ end
60
+
61
+ def setup_logos_config(options)
62
+ options.logos = ActiveSupport::OrderedOptions.new
63
+ options.logos.default = default_options
64
+ end
65
+
66
+ def default_options
67
+ ActiveSupport::OrderedOptions.new.tap do |options|
68
+ options.css = "size-6"
69
+ options.data = {}
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -2,7 +2,9 @@
2
2
 
3
3
  module RailsIcons
4
4
  class Configuration
5
- class Feather
5
+ module Feather
6
+ extend self
7
+
6
8
  def config
7
9
  ActiveSupport::OrderedOptions.new.tap do |options|
8
10
  options.default_variant = nil
@@ -11,6 +13,24 @@ module RailsIcons
11
13
  end
12
14
  end
13
15
 
16
+ def initializer_config
17
+ <<~RB.indent(2)
18
+ # Override Feather defaults
19
+ # config.libraries.feather.default.css = "size-6"
20
+ # config.libraries.feather.default.stroke_width = "2"
21
+ # config.libraries.feather.default.data = {}
22
+ RB
23
+ end
24
+
25
+ def source
26
+ {
27
+ url: "https://github.com/feathericons/feather.git",
28
+ variants: {
29
+ ".": "icons" # Feather has no variants, store in the top directory
30
+ }
31
+ }
32
+ end
33
+
14
34
  private
15
35
 
16
36
  def default_options
@@ -2,7 +2,9 @@
2
2
 
3
3
  module RailsIcons
4
4
  class Configuration
5
- class Heroicons
5
+ module Heroicons
6
+ extend self
7
+
6
8
  def config
7
9
  ActiveSupport::OrderedOptions.new.tap do |options|
8
10
  options.default_variant = :outline
@@ -14,6 +16,36 @@ module RailsIcons
14
16
  end
15
17
  end
16
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
+
17
49
  private
18
50
 
19
51
  def setup_outline_config(options)
@@ -2,7 +2,9 @@
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,6 +13,24 @@ module RailsIcons
11
13
  end
12
14
  end
13
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
+
14
34
  private
15
35
 
16
36
  def setup_outline_config(options)
@@ -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
@@ -2,7 +2,9 @@
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
@@ -12,6 +14,28 @@ module RailsIcons
12
14
  end
13
15
  end
14
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
+
15
39
  private
16
40
 
17
41
  def setup_outline_config(options)
@@ -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
@@ -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::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,3 +1,4 @@
1
+ require "rails_icons/icon/file_path"
1
2
  require "rails_icons/icon/attributes"
2
3
 
3
4
  class RailsIcons::Icon
@@ -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
@@ -1,45 +1,24 @@
1
- module RailsIcons
2
- module Libraries
3
- module_function
4
-
5
- def all
6
- {
7
- feather: {
8
- name: "feather",
9
- url: "https://github.com/feathericons/feather.git",
10
- variants: {
11
- ".": "icons" # Feather has no variants, store in the top directory
12
- }
13
- },
1
+ require_relative "configuration/animated"
2
+ require_relative "configuration/boxicons"
3
+ require_relative "configuration/feather"
4
+ require_relative "configuration/heroicons"
5
+ require_relative "configuration/lucide"
6
+ require_relative "configuration/phosphor"
7
+ require_relative "configuration/radix"
8
+ require_relative "configuration/tabler"
14
9
 
15
- heroicons: {
16
- name: "heroicons",
17
- url: "https://github.com/tailwindlabs/heroicons.git",
18
- variants: {
19
- outline: "optimized/24/outline",
20
- solid: "optimized/24/solid",
21
- mini: "optimized/20/solid",
22
- micro: "optimized/16/solid"
23
- }
24
- },
25
-
26
- lucide: {
27
- name: "lucide",
28
- url: "https://github.com/lucide-icons/lucide.git",
29
- variants: {
30
- outline: "icons"
31
- }
32
- },
10
+ module RailsIcons
11
+ extend self
33
12
 
34
- tabler: {
35
- name: "tabler",
36
- url: "https://github.com/tabler/tabler-icons.git",
37
- variants: {
38
- filled: "icons/filled",
39
- outline: "icons/outline"
40
- }
41
- }
42
- }
43
- end
13
+ def libraries
14
+ {
15
+ boxicons: RailsIcons::Configuration::Boxicons,
16
+ feather: RailsIcons::Configuration::Feather,
17
+ heroicons: RailsIcons::Configuration::Heroicons,
18
+ lucide: RailsIcons::Configuration::Lucide,
19
+ phosphor: RailsIcons::Configuration::Phosphor,
20
+ radix: RailsIcons::Configuration::Radix,
21
+ tabler: RailsIcons::Configuration::Tabler
22
+ }
44
23
  end
45
24
  end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+ require "rails_icons/sync/process_variants"
5
+
6
+ module RailsIcons
7
+ module Sync
8
+ class Engine < Rails::Generators::Base
9
+ def initialize(name)
10
+ super
11
+
12
+ raise "[Rails Icons] Not a valid library" if RailsIcons.libraries.keys.exclude?(name.to_sym)
13
+
14
+ @temp_directory, @name, @library = File.join(TEMP_DIRECTORY, name), name, RailsIcons.libraries.fetch(name.to_sym).source
15
+ end
16
+
17
+ def sync
18
+ clone_repository
19
+ process_variants
20
+ remove_non_svg_files
21
+
22
+ move_library
23
+
24
+ purge_temp_directory
25
+ rescue => error
26
+ say "[Rails Icons] Failed to sync icons: #{error.message}", :red
27
+
28
+ post_error_clean_up
29
+
30
+ raise
31
+ end
32
+
33
+ private
34
+
35
+ TEMP_DIRECTORY = Rails.root.join("tmp/icons").freeze
36
+
37
+ def clone_repository
38
+ raise "[Rails Icons] Failed to clone repository" unless system("git clone '#{@library[:url]}' '#{@temp_directory}'")
39
+
40
+ say "'#{@name}' repository cloned successfully."
41
+ end
42
+
43
+ def process_variants = Sync::ProcessVariants.new(@temp_directory, @name, @library).process
44
+
45
+ def remove_non_svg_files
46
+ Pathname.glob("#{@temp_directory}/**/*")
47
+ .select { _1.file? && _1.extname != ".svg" }
48
+ .each(&:delete)
49
+
50
+ say "[Rails Icons] Non-SVG files removed successfully"
51
+ end
52
+
53
+ def move_library
54
+ destination = File.join(RailsIcons.configuration.destination_path, @name)
55
+
56
+ FileUtils.mkdir_p(destination)
57
+ FileUtils.mv(Dir.glob("#{@temp_directory}/*"), destination, force: true)
58
+
59
+ say "[Rails Icons] Synced '#{@name}' library successfully #{%w[😃 🎉 ✨].sample}", :green
60
+ end
61
+
62
+ def purge_temp_directory = FileUtils.rm_rf(TEMP_DIRECTORY)
63
+
64
+ def post_error_clean_up
65
+ if yes?("Do you want to remove the temp files? ('#{@temp_directory}') [y/n]")
66
+ say "[Rails Icons] Cleaning up…"
67
+
68
+ FileUtils.rm_rf(@temp_directory)
69
+ else
70
+ say "[Rails Icons] Keeping files at: '#{@temp_directory}'"
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+ require "rails_icons/sync/transformations"
5
+
6
+ module RailsIcons
7
+ module Sync
8
+ class ProcessVariants < Rails::Generators::Base
9
+ def initialize(temp_directory, name, library)
10
+ @temp_directory, @name, @library = temp_directory, name, library
11
+ end
12
+
13
+ def process
14
+ original_variants = Dir.children(@temp_directory)
15
+
16
+ @library[:variants].each do |variant_name, variant_source_path|
17
+ source = File.join(@temp_directory, variant_source_path)
18
+ destination = File.join(@temp_directory, variant_name.to_s)
19
+
20
+ original_variants.delete(variant_name.to_s)
21
+
22
+ raise "[Rails Icons] Failed to find the icons directory: '#{source}'" unless Dir.exist?(source)
23
+
24
+ move_icons(source, destination)
25
+
26
+ apply_transformations_to(destination)
27
+ end
28
+
29
+ remove_files_and_folders(original_variants)
30
+
31
+ say "[Rails Icons] Icon variants processed successfully"
32
+ end
33
+
34
+ private
35
+
36
+ def move_icons(source, destination)
37
+ FileUtils.mkdir_p(destination)
38
+
39
+ Dir.each_child(source).each do |item|
40
+ FileUtils.mv(File.join(source, item), destination)
41
+ end
42
+ end
43
+
44
+ def apply_transformations_to(destination)
45
+ Dir.each_child(destination) do |filename|
46
+ File.rename(
47
+ File.join(destination, filename),
48
+ File.join(destination, Sync::Transformations.transform(filename, transformations.fetch(:filenames, {})))
49
+ )
50
+ end
51
+ end
52
+
53
+ def remove_files_and_folders(paths)
54
+ paths.each do |path|
55
+ FileUtils.rm_rf(File.join(@temp_directory, path))
56
+ end
57
+ end
58
+
59
+ def transformations
60
+ RailsIcons.libraries.dig(@name.to_sym)&.try(:transformations) || {}
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,27 @@
1
+ module RailsIcons
2
+ module Sync
3
+ class Transformations < Rails::Generators::Base
4
+ def self.transform(filename, rules = {})
5
+ basename = File.basename(filename, File.extname(filename))
6
+
7
+ transformed = rules.reduce(basename) do |fn, (type, value)|
8
+ TRANSFORMERS.fetch(type).call(fn, value)
9
+ end
10
+
11
+ [transformed, File.extname(filename)].join
12
+ end
13
+
14
+ private
15
+
16
+ TRANSFORMERS = {
17
+ delete_prefix: ->(filename, prefixes) {
18
+ Array(prefixes).reduce(filename) { _1.delete_prefix(_2) }
19
+ },
20
+
21
+ delete_suffix: ->(filename, suffixes) {
22
+ Array(suffixes).reduce(filename) { _1.delete_suffix(_2) }
23
+ }
24
+ }
25
+ end
26
+ end
27
+ end
@@ -1,3 +1,3 @@
1
1
  module RailsIcons
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
data/lib/rails_icons.rb CHANGED
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "rails_icons/version"
4
+ require_relative "rails_icons/libraries"
4
5
  require_relative "rails_icons/configuration"
5
6
  require_relative "rails_icons/engine"
6
7
  require_relative "rails_icons/errors"
7
8
  require_relative "rails_icons/railtie"
8
- require_relative "rails_icons/libraries"
9
9
  require_relative "rails_icons/icon"
10
10
 
11
11
  module RailsIcons
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_icons
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rails Designer Developers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-12-07 00:00:00.000000000 Z
11
+ date: 2025-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -67,23 +67,29 @@ files:
67
67
  - bin/setup
68
68
  - lib/generators/rails_icons/initializer_generator.rb
69
69
  - lib/generators/rails_icons/install_generator.rb
70
- - lib/generators/rails_icons/sync/engine.rb
71
70
  - lib/generators/rails_icons/sync_generator.rb
72
71
  - lib/generators/rails_icons/templates/initializer.rb.tt
73
72
  - lib/rails_icons.rb
74
73
  - lib/rails_icons/configuration.rb
75
74
  - lib/rails_icons/configuration/animated.rb
75
+ - lib/rails_icons/configuration/boxicons.rb
76
76
  - lib/rails_icons/configuration/feather.rb
77
77
  - lib/rails_icons/configuration/heroicons.rb
78
78
  - lib/rails_icons/configuration/lucide.rb
79
+ - lib/rails_icons/configuration/phosphor.rb
80
+ - lib/rails_icons/configuration/radix.rb
79
81
  - lib/rails_icons/configuration/tabler.rb
80
82
  - lib/rails_icons/engine.rb
81
83
  - lib/rails_icons/errors.rb
82
84
  - lib/rails_icons/helpers/icon_helper.rb
83
85
  - lib/rails_icons/icon.rb
84
86
  - lib/rails_icons/icon/attributes.rb
87
+ - lib/rails_icons/icon/file_path.rb
85
88
  - lib/rails_icons/libraries.rb
86
89
  - lib/rails_icons/railtie.rb
90
+ - lib/rails_icons/sync/engine.rb
91
+ - lib/rails_icons/sync/process_variants.rb
92
+ - lib/rails_icons/sync/transformations.rb
87
93
  - lib/rails_icons/version.rb
88
94
  - rails_icons.gemspec
89
95
  homepage: https://railsdesigner.com/rails-icons/
@@ -107,7 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
107
113
  - !ruby/object:Gem::Version
108
114
  version: '0'
109
115
  requirements: []
110
- rubygems_version: 3.5.23
116
+ rubygems_version: 3.3.7
111
117
  signing_key:
112
118
  specification_version: 4
113
119
  summary: Add any icon library to a Rails app
@@ -1,87 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "fileutils"
4
-
5
- module RailsIcons
6
- module Sync
7
- class Engine < Rails::Generators::Base
8
- def initialize(temp_icons_directory, library)
9
- super
10
-
11
- @temp_directory, @library = File.join(temp_icons_directory, library[:name]), library
12
- end
13
-
14
- def sync
15
- clone
16
- filter_variants_from_directory
17
- remove_non_svg_files
18
- rescue => error
19
- say "[Rails Icons] Failed to sync icons: #{error.message}", :red
20
-
21
- post_error_clean_up
22
-
23
- raise
24
- end
25
-
26
- private
27
-
28
- def clone
29
- raise "[Rails Icons] Failed to clone repository" unless system("git clone '#{@library[:url]}' '#{@temp_directory}'")
30
-
31
- say "#{@library[:name]} repository cloned successfully."
32
- end
33
-
34
- def filter_variants_from_directory
35
- original_set_list = Dir.children(@temp_directory)
36
-
37
- @library[:variants].each do |variant_name, variant_source_path|
38
- source = File.join(@temp_directory, variant_source_path)
39
- destination = File.join(@temp_directory, variant_name.to_s)
40
-
41
- # Whitelist variant directory if present in original_set_list to prevent deletion
42
- original_set_list.delete(variant_name.to_s)
43
-
44
- raise "[Rails Icons] Failed to find the icons directory: '#{source}'" unless Dir.exist?(source)
45
-
46
- move_icons(source, destination)
47
- end
48
-
49
- remove_files_and_folders(original_set_list)
50
-
51
- say "[Rails Icons] Icon variants filtered successfully"
52
- end
53
-
54
- def remove_non_svg_files
55
- Pathname.glob("#{@temp_directory}/**/*")
56
- .select { |p| p.file? && p.extname != ".svg" }
57
- .each(&:delete)
58
-
59
- say "[Rails Icons] Non-SVG files removed successfully"
60
- end
61
-
62
- def post_error_clean_up
63
- if yes?("Do you want to remove the temp files? ('#{@temp_directory}')")
64
- say "[Rails Icons] Cleaning up…"
65
-
66
- FileUtils.rm_rf(@temp_directory)
67
- else
68
- say "[Rails Icons] Keeping files at: '#{@temp_directory}'"
69
- end
70
- end
71
-
72
- def move_icons(source, destination)
73
- FileUtils.mkdir_p(destination)
74
-
75
- Dir.children(source).each do |item|
76
- FileUtils.mv(File.join(source, item), destination)
77
- end
78
- end
79
-
80
- def remove_files_and_folders(paths)
81
- paths.each do |path|
82
- FileUtils.rm_rf(File.join(@temp_directory, path))
83
- end
84
- end
85
- end
86
- end
87
- end