font_awesome5_rails 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +19 -7
  3. data/app/assets/fonts/fa-brands-400.eot +0 -0
  4. data/app/assets/fonts/fa-brands-400.svg +670 -603
  5. data/app/assets/fonts/fa-brands-400.ttf +0 -0
  6. data/app/assets/fonts/fa-brands-400.woff +0 -0
  7. data/app/assets/fonts/fa-brands-400.woff2 +0 -0
  8. data/app/assets/fonts/fa-regular-400.eot +0 -0
  9. data/app/assets/fonts/fa-regular-400.svg +93 -91
  10. data/app/assets/fonts/fa-regular-400.ttf +0 -0
  11. data/app/assets/fonts/fa-regular-400.woff +0 -0
  12. data/app/assets/fonts/fa-regular-400.woff2 +0 -0
  13. data/app/assets/fonts/fa-solid-900.eot +0 -0
  14. data/app/assets/fonts/fa-solid-900.svg +1147 -1070
  15. data/app/assets/fonts/fa-solid-900.ttf +0 -0
  16. data/app/assets/fonts/fa-solid-900.woff +0 -0
  17. data/app/assets/fonts/fa-solid-900.woff2 +0 -0
  18. data/app/assets/images/fa5/brands/bandcamp.svg +1 -1
  19. data/app/assets/images/fa5/brands/chromecast.svg +1 -1
  20. data/app/assets/images/fa5/brands/deezer.svg +1 -0
  21. data/app/assets/images/fa5/brands/edge-legacy.svg +1 -0
  22. data/app/assets/images/fa5/brands/google-pay.svg +1 -0
  23. data/app/assets/images/fa5/brands/google-plus.svg +1 -1
  24. data/app/assets/images/fa5/brands/laravel.svg +1 -1
  25. data/app/assets/images/fa5/brands/pied-piper.svg +1 -1
  26. data/app/assets/images/fa5/brands/rust.svg +1 -0
  27. data/app/assets/images/fa5/brands/safari.svg +1 -1
  28. data/app/assets/images/fa5/brands/tiktok.svg +1 -0
  29. data/app/assets/images/fa5/brands/tripadvisor.svg +1 -1
  30. data/app/assets/images/fa5/brands/twitch.svg +1 -1
  31. data/app/assets/images/fa5/brands/unsplash.svg +1 -0
  32. data/app/assets/images/fa5/brands/yahoo.svg +1 -1
  33. data/app/assets/images/fa5/solid/bacteria.svg +1 -0
  34. data/app/assets/images/fa5/solid/bacterium.svg +1 -0
  35. data/app/assets/images/fa5/solid/hand-holding-usd.svg +1 -1
  36. data/app/assets/images/fa5/solid/shapes.svg +1 -1
  37. data/app/assets/images/fa5/solid/sink.svg +1 -0
  38. data/app/assets/images/fa5/solid/swatchbook.svg +1 -1
  39. data/app/assets/images/fa5/solid/users-slash.svg +1 -0
  40. data/app/assets/images/fa5/solid/virus-slash.svg +1 -1
  41. data/app/assets/javascripts/all.min.js +2 -2
  42. data/app/assets/stylesheets/all.scss +68 -38
  43. data/app/assets/stylesheets/svg-with-js.min.css +1 -1
  44. data/app/helpers/font_awesome5/rails/icon_helper.rb +2 -2
  45. data/lib/font_awesome5_rails/parsers/fa_icon_parser.rb +3 -3
  46. data/lib/font_awesome5_rails/parsers/fa_layered_icon_parser.rb +2 -2
  47. data/lib/font_awesome5_rails/parsers/fa_stacked_icon_parser.rb +7 -2
  48. data/lib/font_awesome5_rails/parsers/parse_methods.rb +8 -8
  49. data/lib/font_awesome5_rails/version.rb +2 -2
  50. data/spec/font_awesome5_rails_spec.rb +18 -0
  51. metadata +13 -3
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com
2
+ * Font Awesome Free 5.14.0 by @fontawesome - https://fontawesome.com
3
3
  * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
4
4
  */
5
5
  .svg-inline--fa,svg:not(:root).svg-inline--fa{overflow:visible}.svg-inline--fa{display:inline-block;font-size:inherit;height:1em;vertical-align:-.125em}.svg-inline--fa.fa-lg{vertical-align:-.225em}.svg-inline--fa.fa-w-1{width:.0625em}.svg-inline--fa.fa-w-2{width:.125em}.svg-inline--fa.fa-w-3{width:.1875em}.svg-inline--fa.fa-w-4{width:.25em}.svg-inline--fa.fa-w-5{width:.3125em}.svg-inline--fa.fa-w-6{width:.375em}.svg-inline--fa.fa-w-7{width:.4375em}.svg-inline--fa.fa-w-8{width:.5em}.svg-inline--fa.fa-w-9{width:.5625em}.svg-inline--fa.fa-w-10{width:.625em}.svg-inline--fa.fa-w-11{width:.6875em}.svg-inline--fa.fa-w-12{width:.75em}.svg-inline--fa.fa-w-13{width:.8125em}.svg-inline--fa.fa-w-14{width:.875em}.svg-inline--fa.fa-w-15{width:.9375em}.svg-inline--fa.fa-w-16{width:1em}.svg-inline--fa.fa-w-17{width:1.0625em}.svg-inline--fa.fa-w-18{width:1.125em}.svg-inline--fa.fa-w-19{width:1.1875em}.svg-inline--fa.fa-w-20{width:1.25em}.svg-inline--fa.fa-pull-left{margin-right:.3em;width:auto}.svg-inline--fa.fa-pull-right{margin-left:.3em;width:auto}.svg-inline--fa.fa-border{height:1.5em}.svg-inline--fa.fa-li{width:2em}.svg-inline--fa.fa-fw{width:1.25em}.fa-layers svg.svg-inline--fa{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.fa-layers{display:inline-block;height:1em;position:relative;text-align:center;vertical-align:-.125em;width:1em}.fa-layers svg.svg-inline--fa{-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter,.fa-layers-text{display:inline-block;position:absolute;text-align:center}.fa-layers-text{left:50%;top:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter{background-color:#ff253a;border-radius:1em;-webkit-box-sizing:border-box;box-sizing:border-box;color:#fff;height:1.5em;line-height:1;max-width:5em;min-width:1.5em;overflow:hidden;padding:.25em;right:0;text-overflow:ellipsis;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-bottom-right{bottom:0;right:0;top:auto;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:bottom right;transform-origin:bottom right}.fa-layers-bottom-left{bottom:0;left:0;right:auto;top:auto;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:bottom left;transform-origin:bottom left}.fa-layers-top-right{right:0;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-top-left{left:0;right:auto;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top left;transform-origin:top left}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-webkit-transform:scaleY(-1);transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1);transform:scale(-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;position:relative;width:2.5em}.fa-stack-1x,.fa-stack-2x{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.svg-inline--fa.fa-stack-1x{height:1em;width:1.25em}.svg-inline--fa.fa-stack-2x{height:2em;width:2.5em}.fa-inverse{color:#fff}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.svg-inline--fa .fa-primary{fill:var(--fa-primary-color,currentColor);opacity:1;opacity:var(--fa-primary-opacity,1)}.svg-inline--fa .fa-secondary{fill:var(--fa-secondary-color,currentColor)}.svg-inline--fa .fa-secondary,.svg-inline--fa.fa-swap-opacity .fa-primary{opacity:.4;opacity:var(--fa-secondary-opacity,.4)}.svg-inline--fa.fa-swap-opacity .fa-secondary{opacity:1;opacity:var(--fa-primary-opacity,1)}.svg-inline--fa mask .fa-primary,.svg-inline--fa mask .fa-secondary{fill:#000}.fad.fa-inverse{color:#fff}
@@ -16,8 +16,8 @@ module FontAwesome5
16
16
  parser = FaStackedIconParser.new(icon, options)
17
17
 
18
18
  tags = content_tag :span, class: parser.span_classes, title: parser.title do
19
- content_tag(:i, nil, class: (parser.reverse ? parser.second_icon_classes : parser.first_icon_classes) ) +
20
- content_tag(:i, nil, class: (parser.reverse ? parser.first_icon_classes : parser.second_icon_classes) )
19
+ content_tag(:i, nil, class: (parser.reverse ? parser.second_icon_classes : parser.first_icon_classes), **parser.more_options(:base_options) ) +
20
+ content_tag(:i, nil, class: (parser.reverse ? parser.first_icon_classes : parser.second_icon_classes), **parser.more_options(:icon_options) )
21
21
  end
22
22
  tags += parser.text unless parser.text.nil?
23
23
  tags
@@ -13,12 +13,12 @@ class FaIconParser
13
13
  @style = options[:style]
14
14
  @text = options[:text]
15
15
  @title = options[:title]
16
- @right = options[:right] || false
16
+ @right = options[:right] == true
17
17
  @attrs = options.except(:text, :type, :class, :icon, :animation, :size, :right)
18
18
  end
19
19
 
20
20
  def classes
21
- @classes ||= get_all_classes
21
+ @classes ||= parse_classes
22
22
  end
23
23
 
24
24
  def sizes
@@ -35,7 +35,7 @@ class FaIconParser
35
35
 
36
36
  private
37
37
 
38
- def get_all_classes
38
+ def parse_classes
39
39
  tmp = []
40
40
  tmp << icon_type(@options[:type])
41
41
  tmp += arr_with_fa(@icon)
@@ -15,12 +15,12 @@ class FaLayeredIconParser
15
15
  end
16
16
 
17
17
  def classes
18
- @classes ||= get_all_classes
18
+ @classes ||= parse_classes
19
19
  end
20
20
 
21
21
  private
22
22
 
23
- def get_all_classes
23
+ def parse_classes
24
24
  tmp = ["fa-layers"]
25
25
  tmp << "fa-fw" if @aligned
26
26
  tmp += @options[:class].split(" ") unless @options[:class].nil?
@@ -8,7 +8,7 @@ class FaStackedIconParser
8
8
  def initialize(icon, options)
9
9
  @icon = icon
10
10
  @text = options[:text]
11
- @reverse = options[:reverse].nil? ? false : options[:reverse]
11
+ @reverse = options[:reverse] == true
12
12
  @title = options[:title]
13
13
  @options = options
14
14
  end
@@ -25,6 +25,10 @@ class FaStackedIconParser
25
25
  @second_icon_classes ||= parse_icon_classes(@icon, false)
26
26
  end
27
27
 
28
+ def more_options(key)
29
+ options[key] ? options[key].except(:class, :text) : {}
30
+ end
31
+
28
32
  private
29
33
 
30
34
  def parse_span_classes
@@ -38,7 +42,8 @@ class FaStackedIconParser
38
42
  tmp << icon_type(first && @options[:base_type].present? ? @options[:base_type] : @options[:type])
39
43
  tmp += arr_with_fa(klass)
40
44
  tmp << (first ? "fa-stack-2x" : "fa-stack-1x")
45
+ key = first ? :base_options : :icon_options
46
+ tmp << options[key][:class] if options[key] && options[key][:class]
41
47
  tmp.uniq.join(" ").strip
42
48
  end
43
-
44
49
  end
@@ -2,15 +2,15 @@ module ParseMethods
2
2
 
3
3
  def icon_type(type)
4
4
  return "fas" if type.nil?
5
- case type.to_s
6
- when "far", "regular"
5
+ case type.to_sym
6
+ when :far, :regular
7
7
  "far"
8
- when "fal", "light"
8
+ when :fal, :light
9
9
  "fal"
10
- when "fab", "brand"
10
+ when :fab, :brand
11
11
  "fab"
12
- when "fad", "duotone"
13
- "fad"
12
+ when :fad, :duotone
13
+ "fad"
14
14
  else
15
15
  "fas"
16
16
  end
@@ -30,9 +30,9 @@ module ParseMethods
30
30
  def handle_input(input)
31
31
  case input
32
32
  when Symbol
33
- input.to_s.gsub('_', '-')
33
+ input.to_s.dasherize
34
34
  when Array
35
- input.collect{ |i| i.to_s.gsub('_', '-') }.join(' ')
35
+ input.join(' ').dasherize
36
36
  else
37
37
  input.to_s
38
38
  end
@@ -1,4 +1,4 @@
1
1
  module FontAwesome5Rails
2
- FA_VERSION = '5.13.0'
3
- VERSION = '1.1.1'
2
+ FA_VERSION = '5.14.0'
3
+ VERSION = '1.2.0'
4
4
  end
@@ -146,6 +146,24 @@ describe FontAwesome5Rails do
146
146
  expect(send method, [:camera, :inverse], base: :circle, title: 'Camera')
147
147
  .to eq '<span class="fa-stack" title="Camera"><i class="fas fa-circle fa-stack-2x"></i><i class="fas fa-camera fa-inverse fa-stack-1x"></i></span>'
148
148
  end
149
+
150
+ it 'should return correct tags with base_options' do
151
+ expect(send method, 'camera', base: 'circle', base_options: { class: 'test' })
152
+ .to eq '<span class="fa-stack"><i class="fas fa-circle fa-stack-2x test"></i><i class="fas fa-camera fa-stack-1x"></i></span>'
153
+
154
+ expect(send method, 'camera', base: 'circle', base_options: { class: 'test', label: 'label' })
155
+ .to eq '<span class="fa-stack"><i class="fas fa-circle fa-stack-2x test" label="label"></i><i class="fas fa-camera fa-stack-1x"></i></span>'
156
+ end
157
+
158
+ it 'should return correct tags with icon_options' do
159
+ expect(send method, 'camera', base: 'circle', icon_options: { class: 'test', label: 'label' })
160
+ .to eq '<span class="fa-stack"><i class="fas fa-circle fa-stack-2x"></i><i class="fas fa-camera fa-stack-1x test" label="label"></i></span>'
161
+ end
162
+
163
+ it 'should return correct tags with base_options and icon_options' do
164
+ expect(send method, 'camera', base: 'circle', icon_options: { class: 'icon', label: 'icon' }, base_options: { class: 'base', aria: 'base' })
165
+ .to eq '<span class="fa-stack"><i class="fas fa-circle fa-stack-2x base" aria="base"></i><i class="fas fa-camera fa-stack-1x icon" label="icon"></i></span>'
166
+ end
149
167
  end
150
168
  end
151
169
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: font_awesome5_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - tomkra
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-28 00:00:00.000000000 Z
11
+ date: 2020-07-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -175,6 +175,7 @@ files:
175
175
  - app/assets/images/fa5/brands/d-and-d.svg
176
176
  - app/assets/images/fa5/brands/dailymotion.svg
177
177
  - app/assets/images/fa5/brands/dashcube.svg
178
+ - app/assets/images/fa5/brands/deezer.svg
178
179
  - app/assets/images/fa5/brands/delicious.svg
179
180
  - app/assets/images/fa5/brands/deploydog.svg
180
181
  - app/assets/images/fa5/brands/deskpro.svg
@@ -196,6 +197,7 @@ files:
196
197
  - app/assets/images/fa5/brands/dyalog.svg
197
198
  - app/assets/images/fa5/brands/earlybirds.svg
198
199
  - app/assets/images/fa5/brands/ebay.svg
200
+ - app/assets/images/fa5/brands/edge-legacy.svg
199
201
  - app/assets/images/fa5/brands/edge.svg
200
202
  - app/assets/images/fa5/brands/elementor.svg
201
203
  - app/assets/images/fa5/brands/ello.svg
@@ -256,6 +258,7 @@ files:
256
258
  - app/assets/images/fa5/brands/goodreads-g.svg
257
259
  - app/assets/images/fa5/brands/goodreads.svg
258
260
  - app/assets/images/fa5/brands/google-drive.svg
261
+ - app/assets/images/fa5/brands/google-pay.svg
259
262
  - app/assets/images/fa5/brands/google-play.svg
260
263
  - app/assets/images/fa5/brands/google-plus-g.svg
261
264
  - app/assets/images/fa5/brands/google-plus-square.svg
@@ -401,6 +404,7 @@ files:
401
404
  - app/assets/images/fa5/brands/rev.svg
402
405
  - app/assets/images/fa5/brands/rocketchat.svg
403
406
  - app/assets/images/fa5/brands/rockrms.svg
407
+ - app/assets/images/fa5/brands/rust.svg
404
408
  - app/assets/images/fa5/brands/safari.svg
405
409
  - app/assets/images/fa5/brands/salesforce.svg
406
410
  - app/assets/images/fa5/brands/sass.svg
@@ -458,6 +462,7 @@ files:
458
462
  - app/assets/images/fa5/brands/themeco.svg
459
463
  - app/assets/images/fa5/brands/themeisle.svg
460
464
  - app/assets/images/fa5/brands/think-peaks.svg
465
+ - app/assets/images/fa5/brands/tiktok.svg
461
466
  - app/assets/images/fa5/brands/trade-federation.svg
462
467
  - app/assets/images/fa5/brands/trello.svg
463
468
  - app/assets/images/fa5/brands/tripadvisor.svg
@@ -473,6 +478,7 @@ files:
473
478
  - app/assets/images/fa5/brands/umbraco.svg
474
479
  - app/assets/images/fa5/brands/uniregistry.svg
475
480
  - app/assets/images/fa5/brands/unity.svg
481
+ - app/assets/images/fa5/brands/unsplash.svg
476
482
  - app/assets/images/fa5/brands/untappd.svg
477
483
  - app/assets/images/fa5/brands/ups.svg
478
484
  - app/assets/images/fa5/brands/usb.svg
@@ -727,6 +733,8 @@ files:
727
733
  - app/assets/images/fa5/solid/backspace.svg
728
734
  - app/assets/images/fa5/solid/backward.svg
729
735
  - app/assets/images/fa5/solid/bacon.svg
736
+ - app/assets/images/fa5/solid/bacteria.svg
737
+ - app/assets/images/fa5/solid/bacterium.svg
730
738
  - app/assets/images/fa5/solid/bahai.svg
731
739
  - app/assets/images/fa5/solid/balance-scale-left.svg
732
740
  - app/assets/images/fa5/solid/balance-scale-right.svg
@@ -1435,6 +1443,7 @@ files:
1435
1443
  - app/assets/images/fa5/solid/signal.svg
1436
1444
  - app/assets/images/fa5/solid/signature.svg
1437
1445
  - app/assets/images/fa5/solid/sim-card.svg
1446
+ - app/assets/images/fa5/solid/sink.svg
1438
1447
  - app/assets/images/fa5/solid/sitemap.svg
1439
1448
  - app/assets/images/fa5/solid/skating.svg
1440
1449
  - app/assets/images/fa5/solid/skiing-nordic.svg
@@ -1626,6 +1635,7 @@ files:
1626
1635
  - app/assets/images/fa5/solid/user-times.svg
1627
1636
  - app/assets/images/fa5/solid/user.svg
1628
1637
  - app/assets/images/fa5/solid/users-cog.svg
1638
+ - app/assets/images/fa5/solid/users-slash.svg
1629
1639
  - app/assets/images/fa5/solid/users.svg
1630
1640
  - app/assets/images/fa5/solid/utensil-spoon.svg
1631
1641
  - app/assets/images/fa5/solid/utensils.svg
@@ -1759,7 +1769,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1759
1769
  - !ruby/object:Gem::Version
1760
1770
  version: '0'
1761
1771
  requirements: []
1762
- rubygems_version: 3.0.6
1772
+ rubygems_version: 3.0.8
1763
1773
  signing_key:
1764
1774
  specification_version: 4
1765
1775
  summary: an asset gemification of the font-awesome 5 icon font library