avo-icons 0.1.0 → 0.1.1

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: 723efbbd2aa4adf88b418aa9af5de57601362e0c82a322fe8ceae38f3802193a
4
- data.tar.gz: 44a1a68a09a166334db49677274941541f05b98b8b07bfbb19f84e13040010da
3
+ metadata.gz: afdb0b75a063a1d209c93ab86b8c399267abed0c700ccf8450c83ab7da19e879
4
+ data.tar.gz: 1009146281411a8c10d051621ab0f1d2370af19b99de63f2d5e25992b18acf35
5
5
  SHA512:
6
- metadata.gz: e00481d3e9b8bc33204226925f874c229e3ca954e2254c46e5ac0306c973a45518fc8db0eb2ce1630a0a9b6d21e689163445a35f4b355fe7649b107dc989c32b
7
- data.tar.gz: 310456a106e4b6d506538826bcf1d71c5c458f3b090f6dd089331db2c315ca76e90cc45d4d39716dd20aa1a8245c3cee1afa5713bd812e13162a7e31f1770ab3
6
+ metadata.gz: 2228b5b5656800c17028c90b7cf92170dd73d3433478491abb62ec2c783271790d6c9d31e8e0156e9d23555549c9412b07c377442a08437c6066edaf5f670697
7
+ data.tar.gz: 5419d618e7b911b18e5c4a56bef051b1d7bc55852ccbc0c1dd31f899c4e8056ddf3fd1ac5e638fe125126f33ce12c9968c7bbb9cfe386d7b2c588ff997345b55
data/README.md CHANGED
@@ -1,45 +1,205 @@
1
- # Avo::Icons
1
+ # Avo Icons
2
2
 
3
- `avo-icons` was built as a dependency for [Avo](https://avohq.io/), is a Ruby gem designed to seamlessly integrate [Heroicons](https://heroicons.com/) and [Tabler Icons](https://tabler.io/icons) SVGs into [Avo](https://avohq.io/).
3
+ A lightweight, standalone gem for serving icon SVGs effortlessly in Rails applications. This gem provides access to Heroicons and Tabler Icons with smart caching and configurable search paths.
4
+
5
+ ## Features
6
+
7
+ - **Multiple Icon Sets**: Includes Heroicons (outline, solid, mini, micro) and Tabler Icons (outline, filled)
8
+ - **Smart Caching**: Intelligent caching strategy for optimal performance
9
+ - **Configurable Paths**: Pluggable system to add custom SVG search paths
10
+ - **Rails-Ready**: Seamlessly integrates with any Rails application
11
+ - **Asset Pipeline Support**: Works with Sprockets and Propshaft
12
+
13
+ ## Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ ```ruby
18
+ gem 'avo-icons'
19
+ ```
20
+
21
+ And then execute:
22
+
23
+ ```bash
24
+ bundle install
25
+ ```
4
26
 
5
27
  ## Usage
6
28
 
7
- ### Heroicons
29
+ ### Basic Usage
30
+
31
+ The `svg` helper is automatically available in all your views:
32
+
33
+ ```erb
34
+ <%= svg "heroicons/outline/user" %>
35
+ <%= svg "heroicons/solid/heart", class: "w-6 h-6" %>
36
+ <%= svg "tabler/outline/home", class: "w-5 h-5 text-gray-500" %>
37
+ ```
8
38
 
9
- Prepend the `heroicons` namespace and then the variant `outline`, `solid`, `mini`, or `micro` and then the icon name.
39
+ You can omit the `.svg` extension - it will be added automatically:
10
40
 
11
41
  ```erb
12
- <%= svg "heroicons/outline/academic-cap.svg" %>
42
+ <%= svg "heroicons/outline/user" %>
43
+ <!-- Same as: -->
44
+ <%= svg "heroicons/outline/user.svg" %>
13
45
  ```
14
46
 
47
+ ### Available Icon Sets
48
+
49
+ - **Heroicons**:
50
+ - `heroicons/outline/` - Outline style icons
51
+ - `heroicons/solid/` - Solid style icons
52
+ - `heroicons/mini/` - Mini size icons
53
+ - `heroicons/micro/` - Micro size icons
54
+
55
+ - **Tabler Icons**:
56
+ - `tabler/outline/` - Outline style icons
57
+ - `tabler/filled/` - Filled style icons
58
+
59
+ ### Adding Custom SVG Paths
60
+
61
+ You can configure additional paths to search for SVG files. Create an initializer:
62
+
15
63
  ```ruby
16
- # in the menu builder
17
- # config/initializers/avo.rb
18
- Avo.configure do |config|
19
- config.main_menu = -> {
20
- section "Store", icon: "heroicons/outline/academic-cap" do
21
- resource Avo::Resources::Store
22
- end
23
- end
64
+ # config/initializers/avo_icons.rb
65
+
66
+ Avo::Icons.configure do |config|
67
+ # Add a static path
68
+ config.add_path(Rails.root.join("app", "assets", "images", "icons"))
69
+
70
+ # Add a path from another gem or engine
71
+ config.add_path(MyEngine::Engine.root.join("app", "assets", "svgs"))
72
+
73
+ # Add a dynamic path using a proc
74
+ config.add_path(->(filename) {
75
+ Rails.root.join("vendor", "assets", "custom-icons", filename)
76
+ })
24
77
  end
25
78
  ```
26
79
 
27
- ### Tabler Icons
80
+ ### Search Order
81
+
82
+ The gem searches for SVG files in the following order:
28
83
 
29
- Prepend the `tabler` namespace and then the variant `outline` or `filled` and then the icon name.
84
+ 1. Asset pipeline (Sprockets/Propshaft)
85
+ 2. `app/assets/svgs/` in your Rails app
86
+ 3. Rails root directory
87
+ 4. Heroicons in avo-icons gem
88
+ 5. Tabler Icons in avo-icons gem
89
+ 6. Custom paths (in order of configuration)
90
+ 7. All Rails asset paths (including engines)
91
+
92
+ ### Passing Options
93
+
94
+ The `svg` helper accepts all options supported by the [inline_svg](https://github.com/jamesmartin/inline_svg) gem:
30
95
 
31
96
  ```erb
32
- <%= svg "tabler/outline/settings.svg" %>
97
+ <%= svg "heroicons/outline/user",
98
+ class: "w-6 h-6",
99
+ aria: { hidden: true },
100
+ title: "User Profile" %>
33
101
  ```
34
102
 
103
+ ### Using in Controllers or Models
104
+
105
+ If you need to use the svg helper outside of views, include the helper module:
106
+
35
107
  ```ruby
36
- # in the menu builder
37
- # config/initializers/avo.rb
38
- Avo.configure do |config|
39
- config.main_menu = -> {
40
- section "Settings", icon: "tabler/outline/settings" do
41
- resource Avo::Resources::Setting
42
- end
108
+ class MyService
109
+ include Avo::Icons::Helpers
110
+
111
+ def user_icon
112
+ svg("heroicons/outline/user", class: "w-6 h-6")
43
113
  end
44
114
  end
45
115
  ```
116
+
117
+ ## Configuration
118
+
119
+ ### Custom Configuration
120
+
121
+ ```ruby
122
+ Avo::Icons.configure do |config|
123
+ # Add as many custom paths as needed
124
+ config.add_path("/path/to/your/svgs")
125
+ config.add_path(MyEngine::Engine.root.join("assets", "icons"))
126
+
127
+ # Use procs for dynamic paths
128
+ config.add_path(->(filename) {
129
+ # Custom logic to find SVGs
130
+ File.join("/custom/path", filename)
131
+ })
132
+ end
133
+ ```
134
+
135
+ ### Resetting Configuration
136
+
137
+ You can reset the configuration (useful in tests):
138
+
139
+ ```ruby
140
+ Avo::Icons.reset_configuration!
141
+ ```
142
+
143
+ ### Managing the Cache
144
+
145
+ The SVG cache is stored in `Avo::Icons.cached_svgs` and persists for the application lifecycle. You can manually clear or inspect it if needed:
146
+
147
+ ```ruby
148
+ # Clear the cache manually (e.g., after adding new SVG files)
149
+ Avo::Icons.cached_svgs = {}
150
+
151
+ # Check if a file is cached
152
+ Avo::Icons.cached_svgs["heroicons/outline/user.svg"]
153
+
154
+ # In development, you can clear the cache in an initializer to_prepare block
155
+ # if you want fresh lookups on each request:
156
+ Rails.application.config.to_prepare do
157
+ Avo::Icons.cached_svgs = {}
158
+ end
159
+ ```
160
+
161
+ ## Integration with Other Apps
162
+
163
+ This gem is designed to work with any Rails application, not just Avo. Simply add it to your Gemfile and start using the `svg` helper in your views.
164
+
165
+ ### Example: Adding to a Rails App
166
+
167
+ 1. Add to Gemfile:
168
+ ```ruby
169
+ gem 'avo-icons'
170
+ ```
171
+
172
+ 2. Bundle install:
173
+ ```bash
174
+ bundle install
175
+ ```
176
+
177
+ 3. Use in views:
178
+ ```erb
179
+ <%= svg "heroicons/outline/home", class: "w-5 h-5" %>
180
+ ```
181
+
182
+ 4. (Optional) Configure custom paths:
183
+ ```ruby
184
+ # config/initializers/avo_icons.rb
185
+ Avo::Icons.configure do |config|
186
+ config.add_path(Rails.root.join("app", "assets", "images", "custom-icons"))
187
+ end
188
+ ```
189
+
190
+ ## Performance
191
+
192
+ The gem uses smart caching to ensure SVG files are only located once per application lifecycle. This means:
193
+
194
+ - **First Request**: File is located and cached
195
+ - **Subsequent Requests**: Cached path is used (no file system lookup)
196
+ - **Production**: Cache persists for optimal performance
197
+ - **Development**: Cache persists by default. If you need fresh lookups (e.g., when adding new SVG files), manually clear the cache or configure a `to_prepare` hook
198
+
199
+ ## Contributing
200
+
201
+ Bug reports and pull requests are welcome on GitHub.
202
+
203
+ ## License
204
+
205
+ See LICENSE.md
@@ -0,0 +1,24 @@
1
+ module Avo
2
+ module Icons
3
+ class Configuration
4
+ attr_accessor :custom_paths
5
+
6
+ def initialize
7
+ @custom_paths = []
8
+ end
9
+
10
+ # Add a custom path to search for SVG files
11
+ # @param path [String, Pathname, Proc] A path or proc that returns a path
12
+ # @example
13
+ # Avo::Icons.configure do |config|
14
+ # config.add_path("/my/custom/svg/path")
15
+ # config.add_path(Rails.root.join("vendor", "assets", "svgs"))
16
+ # config.add_path(->(filename) { File.join("/dynamic/path", filename) })
17
+ # end
18
+ def add_path(path)
19
+ @custom_paths << path
20
+ end
21
+ end
22
+ end
23
+ end
24
+
@@ -0,0 +1,35 @@
1
+ module Avo
2
+ module Icons
3
+ module Helpers
4
+ # Use inline_svg gem but with our own finder implementation.
5
+ # @param file_name [String] The name of the SVG file (with or without .svg extension)
6
+ # @param args [Hash] Additional arguments to pass to inline_svg
7
+ # @return [String] The inline SVG HTML
8
+ # @example
9
+ # svg("heroicons/outline/user", class: "w-6 h-6")
10
+ # svg("my-icon", class: "w-4 h-4", aria: { hidden: true })
11
+ def svg(file_name, **args)
12
+ return if file_name.blank?
13
+
14
+ file_name = "#{file_name}.svg" unless file_name.end_with? ".svg"
15
+
16
+ with_asset_finder(Avo::Icons::SvgFinder) do
17
+ inline_svg file_name, **args
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ # Taken from the original library
24
+ # https://github.com/jamesmartin/inline_svg/blob/main/lib/inline_svg/action_view/helpers.rb#L76
25
+ def with_asset_finder(asset_finder)
26
+ Thread.current[:inline_svg_asset_finder] = asset_finder
27
+ output = yield
28
+ Thread.current[:inline_svg_asset_finder] = nil
29
+
30
+ output
31
+ end
32
+ end
33
+ end
34
+ end
35
+
@@ -1,6 +1,11 @@
1
1
  module Avo
2
2
  module Icons
3
3
  class Railtie < ::Rails::Railtie
4
+ initializer "avo-icons.helpers" do
5
+ ActiveSupport.on_load(:action_view) do
6
+ include Avo::Icons::Helpers
7
+ end
8
+ end
4
9
  end
5
10
  end
6
11
  end
@@ -0,0 +1,76 @@
1
+ module Avo
2
+ module Icons
3
+ class SvgFinder
4
+ def self.find_asset(filename)
5
+ new(filename)
6
+ end
7
+
8
+ def initialize(filename)
9
+ @filename = filename
10
+ end
11
+
12
+ # Use the default static finder logic. If that doesn't find anything, search according to our pattern:
13
+ def pathname
14
+ Avo::Icons.cached_svgs[@filename] ||= begin
15
+ found_asset = default_strategy
16
+
17
+ # Use the found asset
18
+ if found_asset.present?
19
+ found_asset
20
+ else
21
+ paths.find do |path|
22
+ File.exist? path
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ def paths
29
+ base_paths = [
30
+ Rails.root.join("app", "assets", "svgs", @filename),
31
+ Rails.root.join(@filename),
32
+ Avo::Icons.root.join("assets", "svgs", @filename),
33
+ Avo::Icons.root.join("assets", "svgs", "heroicons", "outline", @filename),
34
+ Avo::Icons.root.join("assets", "svgs", "heroicons", "solid", @filename),
35
+ Avo::Icons.root.join("assets", "svgs", "heroicons", "mini", @filename),
36
+ Avo::Icons.root.join("assets", "svgs", "heroicons", "micro", @filename),
37
+ Avo::Icons.root.join("assets", "svgs", "tabler", "outline", @filename),
38
+ Avo::Icons.root.join("assets", "svgs", "tabler", "filled", @filename),
39
+ # Add all paths from Rails including engines
40
+ *Rails.application.config.assets&.paths&.map { |path| File.join(path, @filename) }
41
+ ]
42
+
43
+ # Add custom paths from configuration
44
+ custom_paths = Avo::Icons.configuration.custom_paths.map do |custom_path|
45
+ if custom_path.is_a?(Proc)
46
+ custom_path.call(@filename)
47
+ else
48
+ File.join(custom_path.to_s, @filename)
49
+ end
50
+ end
51
+
52
+ (base_paths + custom_paths).map(&:to_s).uniq
53
+ end
54
+
55
+ def default_strategy
56
+ # If the app uses Propshaft, grab it from there
57
+ if defined?(Propshaft)
58
+ asset_path = ::Rails.application.assets.load_path.find(@filename)
59
+ asset_path&.path
60
+ elsif ::Rails.application.config.assets.compile
61
+ # Grab the asset from the compiled asset manifest
62
+ asset = ::Rails.application.assets[@filename]
63
+ Pathname.new(asset.filename) if asset.present?
64
+ else
65
+ # Grab the asset from the manifest
66
+ manifest = ::Rails.application.assets_manifest
67
+ asset_path = manifest.assets[@filename]
68
+ unless asset_path.nil?
69
+ ::Rails.root.join(manifest.directory, asset_path)
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+
@@ -1,5 +1,5 @@
1
1
  module Avo
2
2
  module Icons
3
- VERSION = "0.1.0"
3
+ VERSION = "0.1.1"
4
4
  end
5
5
  end
data/lib/avo/icons.rb CHANGED
@@ -1,10 +1,34 @@
1
+ require "inline_svg"
1
2
  require "avo/icons/version"
3
+ require "avo/icons/configuration"
4
+ require "avo/icons/svg_finder"
5
+ require "avo/icons/helpers"
2
6
  require "avo/icons/railtie"
3
7
 
4
8
  module Avo
5
9
  module Icons
6
- def self.root
7
- Pathname.new File.expand_path('..', __dir__)
10
+ class << self
11
+ attr_writer :configuration
12
+ attr_accessor :cached_svgs
13
+
14
+ def root
15
+ Pathname.new File.expand_path('..', __dir__)
16
+ end
17
+
18
+ def configuration
19
+ @configuration ||= Configuration.new
20
+ end
21
+
22
+ def configure
23
+ yield(configuration)
24
+ end
25
+
26
+ def reset_configuration!
27
+ @configuration = Configuration.new
28
+ end
8
29
  end
30
+
31
+ # Initialize cache
32
+ self.cached_svgs = {}
9
33
  end
10
34
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: avo-icons
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Bob
@@ -9,8 +9,23 @@ authors:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
  date: 1980-01-02 00:00:00.000000000 Z
12
- dependencies: []
13
- description: A lightweight Avo dependency for serving icon SVGs effortlessly.
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: inline_svg
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: A standalone Rails gem that provides Heroicons and Tabler Icons with
28
+ smart caching and configurable search paths. Works with any Rails application.
14
29
  email:
15
30
  - avo@avohq.io
16
31
  executables: []
@@ -7518,7 +7533,10 @@ files:
7518
7533
  - lib/assets/svgs/tabler/outline/zzz-off.svg
7519
7534
  - lib/assets/svgs/tabler/outline/zzz.svg
7520
7535
  - lib/avo/icons.rb
7536
+ - lib/avo/icons/configuration.rb
7537
+ - lib/avo/icons/helpers.rb
7521
7538
  - lib/avo/icons/railtie.rb
7539
+ - lib/avo/icons/svg_finder.rb
7522
7540
  - lib/avo/icons/version.rb
7523
7541
  - lib/tasks/avo/icons_tasks.rake
7524
7542
  homepage: https://avohq.io
@@ -7541,5 +7559,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
7541
7559
  requirements: []
7542
7560
  rubygems_version: 3.7.1
7543
7561
  specification_version: 4
7544
- summary: A lightweight Avo dependency for serving icon SVGs effortlessly.
7562
+ summary: A lightweight gem for serving icon SVGs effortlessly in Rails applications.
7545
7563
  test_files: []