heroicons_helper 0.4.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -5
- data/lib/heroicons_helper/data.json +1 -3682
- data/lib/heroicons_helper/icon.rb +19 -16
- data/lib/heroicons_helper/version.rb +1 -1
- data/lib/heroicons_helper.rb +16 -3
- data/package-lock.json +15 -15
- data/package.json +1 -1
- data/script/keywords.json +1 -1
- data/script/update_heroicons +19 -36
- metadata +2 -2
@@ -1,19 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "set"
|
4
|
+
|
3
5
|
module HeroiconsHelper
|
4
6
|
# Icon to show heroicons by name and variant.
|
5
7
|
class Icon
|
6
|
-
attr_reader :path, :attributes, :width, :height, :
|
8
|
+
attr_reader :path, :attributes, :width, :height, :name, :variant, :keywords
|
7
9
|
|
8
10
|
VARIANT_OUTLINE = "outline"
|
9
11
|
VARIANT_SOLID = "solid"
|
10
|
-
|
12
|
+
VARIANT_MINI = "mini"
|
13
|
+
VALID_VARIANTS = Set.new([VARIANT_OUTLINE, VARIANT_SOLID, VARIANT_MINI]).freeze
|
11
14
|
|
12
|
-
def initialize(
|
13
|
-
@
|
15
|
+
def initialize(name, variant, attributes: {})
|
16
|
+
@name = name.to_s
|
14
17
|
@variant = variant.to_s
|
15
18
|
|
16
|
-
heroicon = get_heroicon(@
|
19
|
+
heroicon = get_heroicon(@name, @variant)
|
17
20
|
|
18
21
|
@path = heroicon["path"]
|
19
22
|
@width = heroicon["width"]
|
@@ -30,7 +33,7 @@ module HeroiconsHelper
|
|
30
33
|
|
31
34
|
# Returns an string representing a <svg> tag
|
32
35
|
def to_svg
|
33
|
-
"
|
36
|
+
"<!-- Heroicon name: #{@variant}/#{@name} --><svg xmlns=\"http://www.w3.org/2000/svg\" #{html_attributes}>#{@path}</svg>"
|
34
37
|
end
|
35
38
|
|
36
39
|
private def html_attributes
|
@@ -52,9 +55,9 @@ module HeroiconsHelper
|
|
52
55
|
accessible
|
53
56
|
end
|
54
57
|
|
55
|
-
# prepare the
|
58
|
+
# prepare the heroicon class
|
56
59
|
private def classes
|
57
|
-
"heroicon heroicon-#{@
|
60
|
+
"heroicon heroicon-#{@name}-#{@variant} #{@attributes[:class]} ".strip
|
58
61
|
end
|
59
62
|
|
60
63
|
private def variant_attributes
|
@@ -64,7 +67,7 @@ module HeroiconsHelper
|
|
64
67
|
fill: "none",
|
65
68
|
stroke: "currentColor",
|
66
69
|
}
|
67
|
-
when VARIANT_SOLID
|
70
|
+
when VARIANT_SOLID, VARIANT_MINI
|
68
71
|
{
|
69
72
|
fill: "currentColor",
|
70
73
|
}
|
@@ -75,7 +78,7 @@ module HeroiconsHelper
|
|
75
78
|
"0 0 #{@width} #{@height}"
|
76
79
|
end
|
77
80
|
|
78
|
-
# determine the height and width of the
|
81
|
+
# determine the height and width of the heroicon based on :size option
|
79
82
|
private def size
|
80
83
|
size = {
|
81
84
|
width: @width,
|
@@ -101,17 +104,17 @@ module HeroiconsHelper
|
|
101
104
|
(width.to_i * @height) / @width
|
102
105
|
end
|
103
106
|
|
104
|
-
private def get_heroicon(
|
105
|
-
raise ArgumentError, "Icon name can't be empty" if
|
107
|
+
private def get_heroicon(name, variant)
|
108
|
+
raise ArgumentError, "Icon name can't be empty" if name.empty?
|
106
109
|
|
107
|
-
raise ArgumentError, "Variant `#{variant.inspect}` is invalid; must be one of #{
|
110
|
+
raise ArgumentError, "Variant `#{variant.inspect}` is invalid; must be one of #{VALID_VARIANTS.join(", ")}" unless VALID_VARIANTS.include?(variant)
|
108
111
|
|
109
|
-
icon = HeroiconsHelper::
|
112
|
+
icon = HeroiconsHelper::ICON_NAMES[name]
|
110
113
|
|
111
|
-
raise ArgumentError, "Couldn't find Heroicon for `#{
|
114
|
+
raise ArgumentError, "Couldn't find Heroicon for `#{name.inspect}`" unless icon
|
112
115
|
|
113
116
|
icon_variant = icon["variants"][variant]
|
114
|
-
raise ArgumentError, "Heroicon for `#{
|
117
|
+
raise ArgumentError, "Heroicon for `#{name.inspect}` doesn't have variant `#{variant.inspect}`" unless icon_variant
|
115
118
|
|
116
119
|
{
|
117
120
|
"name" => icon["name"],
|
data/lib/heroicons_helper.rb
CHANGED
@@ -7,9 +7,22 @@ require "json"
|
|
7
7
|
|
8
8
|
module HeroiconsHelper
|
9
9
|
file_data = File.read(File.join(File.dirname(__FILE__), "./heroicons_helper/data.json"))
|
10
|
-
|
10
|
+
ICON_NAMES = JSON.parse(file_data).freeze
|
11
11
|
|
12
|
-
def heroicon(
|
13
|
-
|
12
|
+
def heroicon(name, variant:, **attributes)
|
13
|
+
cache_key = HeroiconsHelper::Cache.get_key(
|
14
|
+
name: name,
|
15
|
+
variant: variant,
|
16
|
+
height: attributes[:height],
|
17
|
+
width: attributes[:width]
|
18
|
+
)
|
19
|
+
|
20
|
+
cached_heroicon = HeroiconsHelper::Cache.read(cache_key)
|
21
|
+
return cached_heroicon unless cached_heroicon.nil?
|
22
|
+
|
23
|
+
heroicon = ::HeroiconsHelper::Icon.new(name, variant, attributes: attributes)
|
24
|
+
HeroiconsHelper::Cache.set(cache_key, heroicon)
|
25
|
+
|
26
|
+
heroicon
|
14
27
|
end
|
15
28
|
end
|
data/package-lock.json
CHANGED
@@ -9,7 +9,7 @@
|
|
9
9
|
"cheerio": "1.0.0-rc.11",
|
10
10
|
"fs-extra": "^7.0.1",
|
11
11
|
"globby": "11.0.0",
|
12
|
-
"heroicons": "^
|
12
|
+
"heroicons": "^2.0.0",
|
13
13
|
"lodash.merge": "4.6.2",
|
14
14
|
"trim-newlines": "3.0.1",
|
15
15
|
"yargs": "15.1.0"
|
@@ -289,9 +289,9 @@
|
|
289
289
|
"dev": true
|
290
290
|
},
|
291
291
|
"node_modules/entities": {
|
292
|
-
"version": "4.3.
|
293
|
-
"resolved": "https://registry.npmjs.org/entities/-/entities-4.3.
|
294
|
-
"integrity": "sha512
|
292
|
+
"version": "4.3.1",
|
293
|
+
"resolved": "https://registry.npmjs.org/entities/-/entities-4.3.1.tgz",
|
294
|
+
"integrity": "sha512-o4q/dYJlmyjP2zfnaWDUC6A3BQFmVTX+tZPezK7k0GLSU9QYCauscf5Y+qcEPzKL+EixVouYDgLQK5H9GrLpkg==",
|
295
295
|
"dev": true,
|
296
296
|
"engines": {
|
297
297
|
"node": ">=0.12"
|
@@ -412,9 +412,9 @@
|
|
412
412
|
"dev": true
|
413
413
|
},
|
414
414
|
"node_modules/heroicons": {
|
415
|
-
"version": "
|
416
|
-
"resolved": "https://registry.npmjs.org/heroicons/-/heroicons-
|
417
|
-
"integrity": "sha512-
|
415
|
+
"version": "2.0.7",
|
416
|
+
"resolved": "https://registry.npmjs.org/heroicons/-/heroicons-2.0.7.tgz",
|
417
|
+
"integrity": "sha512-BuYwHlgmMIPy1lut5ADTZnsk/FqenSx9f9UxbbABDtTO2GV0Ec/k7VgDs6CCcEnaZ8IDH9mbzyeS/HVpqpxXnQ==",
|
418
418
|
"dev": true
|
419
419
|
},
|
420
420
|
"node_modules/htmlparser2": {
|
@@ -784,7 +784,7 @@
|
|
784
784
|
"node_modules/which-module": {
|
785
785
|
"version": "2.0.0",
|
786
786
|
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
|
787
|
-
"integrity": "
|
787
|
+
"integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==",
|
788
788
|
"dev": true
|
789
789
|
},
|
790
790
|
"node_modules/wrap-ansi": {
|
@@ -1043,9 +1043,9 @@
|
|
1043
1043
|
"dev": true
|
1044
1044
|
},
|
1045
1045
|
"entities": {
|
1046
|
-
"version": "4.3.
|
1047
|
-
"resolved": "https://registry.npmjs.org/entities/-/entities-4.3.
|
1048
|
-
"integrity": "sha512
|
1046
|
+
"version": "4.3.1",
|
1047
|
+
"resolved": "https://registry.npmjs.org/entities/-/entities-4.3.1.tgz",
|
1048
|
+
"integrity": "sha512-o4q/dYJlmyjP2zfnaWDUC6A3BQFmVTX+tZPezK7k0GLSU9QYCauscf5Y+qcEPzKL+EixVouYDgLQK5H9GrLpkg==",
|
1049
1049
|
"dev": true
|
1050
1050
|
},
|
1051
1051
|
"fast-glob": {
|
@@ -1136,9 +1136,9 @@
|
|
1136
1136
|
"dev": true
|
1137
1137
|
},
|
1138
1138
|
"heroicons": {
|
1139
|
-
"version": "
|
1140
|
-
"resolved": "https://registry.npmjs.org/heroicons/-/heroicons-
|
1141
|
-
"integrity": "sha512-
|
1139
|
+
"version": "2.0.7",
|
1140
|
+
"resolved": "https://registry.npmjs.org/heroicons/-/heroicons-2.0.7.tgz",
|
1141
|
+
"integrity": "sha512-BuYwHlgmMIPy1lut5ADTZnsk/FqenSx9f9UxbbABDtTO2GV0Ec/k7VgDs6CCcEnaZ8IDH9mbzyeS/HVpqpxXnQ==",
|
1142
1142
|
"dev": true
|
1143
1143
|
},
|
1144
1144
|
"htmlparser2": {
|
@@ -1391,7 +1391,7 @@
|
|
1391
1391
|
"which-module": {
|
1392
1392
|
"version": "2.0.0",
|
1393
1393
|
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
|
1394
|
-
"integrity": "
|
1394
|
+
"integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==",
|
1395
1395
|
"dev": true
|
1396
1396
|
},
|
1397
1397
|
"wrap-ansi": {
|
data/package.json
CHANGED
data/script/keywords.json
CHANGED
data/script/update_heroicons
CHANGED
@@ -19,8 +19,9 @@ const { argv } = yargs
|
|
19
19
|
type: "array",
|
20
20
|
describe: "Input SVG files",
|
21
21
|
default: [
|
22
|
-
"node_modules/heroicons/outline/*.svg",
|
23
|
-
"node_modules/heroicons/solid/*.svg",
|
22
|
+
"node_modules/heroicons/24/outline/*.svg",
|
23
|
+
"node_modules/heroicons/24/solid/*.svg",
|
24
|
+
"node_modules/heroicons/20/solid/*.svg",
|
24
25
|
],
|
25
26
|
})
|
26
27
|
.option("output", {
|
@@ -38,45 +39,28 @@ const svgFilepaths = filepaths.filter(
|
|
38
39
|
|
39
40
|
if (svgFilepaths.length === 0) {
|
40
41
|
// eslint-disable-next-line no-console
|
41
|
-
console.error(`No input SVG file(s) found in ${
|
42
|
+
console.error(`No input SVG file(s) found in ${filepaths.join(", ")}`);
|
42
43
|
process.exit(1);
|
43
44
|
}
|
44
45
|
|
45
46
|
let exitCode = 0;
|
46
47
|
|
47
|
-
const validTypes = ["solid", "outline"];
|
48
|
-
const defaultOutlineWidth = "24";
|
49
|
-
const defaultSolidWidth = "
|
48
|
+
const validTypes = ["solid", "outline", "mini"];
|
49
|
+
const defaultOutlineWidth = parseInt("24");
|
50
|
+
const defaultSolidWidth = parseInt("24");
|
51
|
+
const defaultMiniWidth = parseInt("20");
|
50
52
|
|
51
53
|
const icons = svgFilepaths.map((filepath) => {
|
52
54
|
try {
|
53
|
-
|
54
|
-
|
55
|
-
let
|
56
|
-
|
57
|
-
case "outline":
|
58
|
-
widthSize = defaultOutlineWidth;
|
59
|
-
break;
|
60
|
-
case "solid":
|
61
|
-
widthSize = defaultSolidWidth;
|
62
|
-
break;
|
63
|
-
default:
|
64
|
-
throw new Error(`Unknown icon type: ${type}`);
|
65
|
-
}
|
66
|
-
|
67
|
-
const filenamePattern = /(.+)(?:-[0-9]{1,2})?-([0-9]{2}).svg$/;
|
68
|
-
const filenameReplacePattern = /\.svg$/;
|
69
|
-
|
70
|
-
if (!filenamePattern.test(filename)) {
|
71
|
-
filename = filename.replace(filenameReplacePattern, `-${widthSize}.svg`);
|
72
|
-
}
|
73
|
-
|
74
|
-
const [, name, height] = filename.match(filenamePattern);
|
55
|
+
const filename = path.parse(filepath).base;
|
56
|
+
let splitDir = path.parse(filepath).dir.split("/");
|
57
|
+
let type = splitDir.pop();
|
58
|
+
const size = splitDir.pop();
|
75
59
|
|
76
60
|
const svg = fs.readFileSync(path.resolve(filepath), "utf8");
|
77
61
|
const svgElement = cheerio.load(svg)("svg");
|
78
|
-
let svgWidth = parseInt(svgElement.attr("width"));
|
79
|
-
let svgHeight = parseInt(svgElement.attr("height"));
|
62
|
+
let svgWidth = parseInt(svgElement.attr("width")) || parseInt(size);
|
63
|
+
let svgHeight = parseInt(svgElement.attr("height")) || parseInt(size);
|
80
64
|
const svgViewBox = svgElement.attr("viewBox");
|
81
65
|
const svgPath = trimNewlines(svgElement.html()).trim();
|
82
66
|
|
@@ -94,12 +78,6 @@ const icons = svgFilepaths.map((filepath) => {
|
|
94
78
|
throw new Error(`${filename}: Missing viewBox attribute.`);
|
95
79
|
}
|
96
80
|
|
97
|
-
if (svgHeight != parseInt(height)) {
|
98
|
-
throw new Error(
|
99
|
-
`${filename}: Height in filename (${height}) does not match height attribute of SVG (${svgHeight})`
|
100
|
-
);
|
101
|
-
}
|
102
|
-
|
103
81
|
const viewBoxPattern = /0 0 ([0-9]+) ([0-9]+)/;
|
104
82
|
|
105
83
|
if (!viewBoxPattern.test(svgViewBox)) {
|
@@ -122,6 +100,11 @@ const icons = svgFilepaths.map((filepath) => {
|
|
122
100
|
);
|
123
101
|
}
|
124
102
|
|
103
|
+
if (svgWidth == defaultMiniWidth && type == "solid") {
|
104
|
+
type = "mini";
|
105
|
+
}
|
106
|
+
const name = filename.slice(0, -4);
|
107
|
+
|
125
108
|
return {
|
126
109
|
name,
|
127
110
|
keywords: keywords[name] || [],
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: heroicons_helper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Garen J. Torikian
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-08-26 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A package that distributes Heroicons as a gem, for easy inclusion in
|
14
14
|
Ruby projects.
|