Module: ShadcnViewComponent::IconRegistry

Defined in:
lib/shadcn_view_component/icon_registry.rb

Overview

Backs Shadcn::Icon.register / .registered. Deliberately outside app/components, which Rails reloads in development: a hash living on the Shadcn::Icon module object would be discarded with it on the next code reload, silently un-registering every icon a host added at boot. lib/ is not reloaded, so this survives.

Constant Summary collapse

ALIASES =

lucide-react's own aliases, kept so call sites read like the TSX imports — Icon::Component.new("more-horizontal") is what pagination.tsx writes. They live here rather than beside the drawings because this is the file that has to know about them: a host registering "more-horizontal" and the gem rendering "ellipsis" are the same icon, and until they were resolved in one place the registration was stored under a key nothing ever looked up.

{
  "loader-2" => "loader-circle",
  "more-horizontal" => "ellipsis"
}.freeze

Class Method Summary collapse

Class Method Details

.canonical(name) ⇒ Object



32
33
34
# File 'lib/shadcn_view_component/icon_registry.rb', line 32

def self.canonical(name)
  ALIASES.fetch(name.to_s, name.to_s)
end

.drawing(source) ⇒ Object

What a <svg> element contains, with the whitespace its author used to lay it out taken back out. The outer element is deliberately dropped: Icon::Component renders that itself, with lucide's own attributes and lucide lucide-<name> classes, so a file's own <svg …> would arrive as a second opinion about the thing the component already owns.



60
61
62
63
64
# File 'lib/shadcn_view_component/icon_registry.rb', line 60

def self.drawing(source)
  inside = source[%r{<svg\b[^>]*>(.*)</svg>}m, 1].to_s

  inside.gsub(/>\s+</, "><").gsub(%r{\s+/>}, "/>").strip
end

.load_directory(path) ⇒ Object

Register every *.svg in a directory, under its own basename. This is how a host adds icons the gem does not bundle: download the SVGs it wants — lucide publishes them as files, and so does everyone else — drop them in a directory and point here from an initializer.

ShadcnViewComponent::IconRegistry.load_directory(
Rails.root.join("app/assets/icons")
)

It reads files, so it is the caller who decides when: an initializer pays once at boot. Nothing in the gem calls it — the bundled icons are generated into Icons::PATHS at build time, so a host that adds none reads no files at all.



49
50
51
52
53
# File 'lib/shadcn_view_component/icon_registry.rb', line 49

def self.load_directory(path)
  Dir.glob(File.join(path, "*.svg")).sort.each do |file|
    register(File.basename(file, ".svg"), drawing(File.read(file)))
  end
end

.register(name, path) ⇒ Object

Stored under the canonical name, so registering under either spelling reaches every call site that uses either — one icon, one entry.



28
29
30
# File 'lib/shadcn_view_component/icon_registry.rb', line 28

def self.register(name, path)
  registered[canonical(name)] = path
end

.registeredObject



22
23
24
# File 'lib/shadcn_view_component/icon_registry.rb', line 22

def self.registered
  @registered ||= {}
end