Class: Fontico::Manifest

Inherits:
Object
  • Object
show all
Defined in:
lib/fontico/manifest.rb

Overview

Parses icons.yml. Nested groups flatten to dotted names, so nav: { menu: lucide/menu } is addressable as icon("nav.menu").

Defined Under Namespace

Classes: Error

Constant Summary collapse

LOCAL_PATH =

Where local/ SVGs live when the manifest doesn't say otherwise.

"app/assets/icons"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data, path: nil) ⇒ Manifest

Returns a new instance of Manifest.



39
40
41
42
43
44
45
46
# File 'lib/fontico/manifest.rb', line 39

def initialize(data, path: nil)
  @path      = path
  @defaults  = data["defaults"]  || {}
  @providers = data["providers"] || {}
  @targets   = data["targets"]   || ["sprite"]
  @icons     = flatten(data["icons"] || {}).freeze
  validate!
end

Instance Attribute Details

#defaults ⇒ Object (readonly)

Returns the value of attribute defaults.



14
15
16
# File 'lib/fontico/manifest.rb', line 14

def defaults
  @defaults
end

#icons ⇒ Object (readonly)

Returns the value of attribute icons.



14
15
16
# File 'lib/fontico/manifest.rb', line 14

def icons
  @icons
end

#path ⇒ Object (readonly)

Returns the value of attribute path.



14
15
16
# File 'lib/fontico/manifest.rb', line 14

def path
  @path
end

#providers ⇒ Object (readonly)

Returns the value of attribute providers.



14
15
16
# File 'lib/fontico/manifest.rb', line 14

def providers
  @providers
end

#targets ⇒ Object (readonly)

Returns the value of attribute targets.



14
15
16
# File 'lib/fontico/manifest.rb', line 14

def targets
  @targets
end

Class Method Details

.deep_merge(left, right) ⇒ Object



35
36
37
# File 'lib/fontico/manifest.rb', line 35

def self.deep_merge(left, right)
  left.merge(right) { |_, a, b| a.is_a?(Hash) && b.is_a?(Hash) ? deep_merge(a, b) : b }
end

.load(*paths) ⇒ Object

Raises:

  • (Errno::ENOENT)


16
17
18
19
20
21
22
# File 'lib/fontico/manifest.rb', line 16

def self.load(*paths)
  paths = paths.flatten.compact.select { File.file?(_1) }
  raise Errno::ENOENT, "icons.yml" if paths.empty?

  data = paths.map { YAML.safe_load_file(_1) || {} }.reduce { |a, b| merge_data(a, b) }
  new(data, path: paths.last)
end

.merge_data(base, overlay) ⇒ Object

Later overlay wins a leaf; nested groups merge so an engine can ship auth.google and the app can add auth.apple without copying.



26
27
28
29
30
31
32
33
# File 'lib/fontico/manifest.rb', line 26

def self.merge_data(base, overlay)
  {
    "defaults" => (base["defaults"] || {}).merge(overlay["defaults"] || {}),
    "targets" => overlay["targets"] || base["targets"] || ["sprite"],
    "providers" => (base["providers"] || {}).merge(overlay["providers"] || {}),
    "icons" => deep_merge(base["icons"] || {}, overlay["icons"] || {})
  }
end

Instance Method Details

#[](name) ⇒ Object



52
# File 'lib/fontico/manifest.rb', line 52

def [](name) = icons.find { _1.name == name }

#default_provider ⇒ Object



48
# File 'lib/fontico/manifest.rb', line 48

def default_provider = defaults.fetch("provider", "lucide")

#local_icons ⇒ Object



60
# File 'lib/fontico/manifest.rb', line 60

def local_icons = icons.select(&:local?)

#local_path ⇒ Object



49
# File 'lib/fontico/manifest.rb', line 49

def local_path       = providers.dig("local", "path") || LOCAL_PATH

#remote_by_provider ⇒ Object

Vendor icons grouped by provider so the resolver can batch one HTTP request per provider instead of one per icon.



56
57
58
# File 'lib/fontico/manifest.rb', line 56

def remote_by_provider
  icons.reject(&:local?).group_by(&:provider).transform_values { _1.map(&:slug).uniq.sort }
end

#size ⇒ Object



50
# File 'lib/fontico/manifest.rb', line 50

def size             = defaults.fetch("size", 24).to_i