@unocss/preset-icons 0.45.21 → 0.45.22

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.
package/dist/browser.cjs CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- const cdn = require('./shared/preset-icons.e1d73506.cjs');
5
+ const cdn = require('./shared/preset-icons.b3a2fafc.cjs');
6
6
  const core = require('./core.cjs');
7
7
  require('ohmyfetch');
8
8
  require('@unocss/core');
package/dist/browser.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { c as createCDNLoader, l as loadIcon } from './shared/preset-icons.d1472e4a.mjs';
1
+ import { c as createCDNLoader, l as loadIcon } from './shared/preset-icons.0f5b1443.mjs';
2
2
  import { createPresetIcons } from './core.mjs';
3
3
  export { combineLoaders, createPresetIcons } from './core.mjs';
4
4
  import 'ohmyfetch';
package/dist/core.cjs CHANGED
@@ -4,15 +4,25 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  const core = require('@unocss/core');
6
6
 
7
+ function encodeSVGforURL(svg) {
8
+ return svg.replace(/"/g, "'").replace(/%/g, "%25").replace(/#/g, "%23").replace(/</g, "%3C").replace(/>/g, "%3E").replace(/\s+/g, " ");
9
+ }
10
+
7
11
  function encodeSvgForCss(svg) {
8
12
  let useSvg = svg.startsWith("<svg>") ? svg.replace("<svg>", "<svg >") : svg;
9
13
  if (!useSvg.includes(" xmlns:xlink=") && useSvg.includes(" xlink:")) {
10
- useSvg = useSvg.replace("<svg ", '<svg xmlns:xlink="http://www.w3.org/1999/xlink" ');
14
+ useSvg = useSvg.replace(
15
+ "<svg ",
16
+ '<svg xmlns:xlink="http://www.w3.org/1999/xlink" '
17
+ );
11
18
  }
12
19
  if (!useSvg.includes(" xmlns=")) {
13
- useSvg = useSvg.replace("<svg ", '<svg xmlns="http://www.w3.org/2000/svg" ');
20
+ useSvg = useSvg.replace(
21
+ "<svg ",
22
+ '<svg xmlns="http://www.w3.org/2000/svg" '
23
+ );
14
24
  }
15
- return useSvg.replace(/"/g, "'").replace(/%/g, "%25").replace(/#/g, "%23").replace(/{/g, "%7B").replace(/}/g, "%7D").replace(/</g, "%3C").replace(/>/g, "%3E");
25
+ return encodeSVGforURL(useSvg);
16
26
  }
17
27
 
18
28
  const COLLECTION_NAME_PARTS_MAX = 3;
package/dist/core.mjs CHANGED
@@ -1,14 +1,24 @@
1
1
  import { warnOnce } from '@unocss/core';
2
2
 
3
+ function encodeSVGforURL(svg) {
4
+ return svg.replace(/"/g, "'").replace(/%/g, "%25").replace(/#/g, "%23").replace(/</g, "%3C").replace(/>/g, "%3E").replace(/\s+/g, " ");
5
+ }
6
+
3
7
  function encodeSvgForCss(svg) {
4
8
  let useSvg = svg.startsWith("<svg>") ? svg.replace("<svg>", "<svg >") : svg;
5
9
  if (!useSvg.includes(" xmlns:xlink=") && useSvg.includes(" xlink:")) {
6
- useSvg = useSvg.replace("<svg ", '<svg xmlns:xlink="http://www.w3.org/1999/xlink" ');
10
+ useSvg = useSvg.replace(
11
+ "<svg ",
12
+ '<svg xmlns:xlink="http://www.w3.org/1999/xlink" '
13
+ );
7
14
  }
8
15
  if (!useSvg.includes(" xmlns=")) {
9
- useSvg = useSvg.replace("<svg ", '<svg xmlns="http://www.w3.org/2000/svg" ');
16
+ useSvg = useSvg.replace(
17
+ "<svg ",
18
+ '<svg xmlns="http://www.w3.org/2000/svg" '
19
+ );
10
20
  }
11
- return useSvg.replace(/"/g, "'").replace(/%/g, "%25").replace(/#/g, "%23").replace(/{/g, "%7B").replace(/}/g, "%7D").replace(/</g, "%3C").replace(/>/g, "%3E");
21
+ return encodeSVGforURL(useSvg);
12
22
  }
13
23
 
14
24
  const COLLECTION_NAME_PARTS_MAX = 3;
package/dist/index.cjs CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- const cdn = require('./shared/preset-icons.e1d73506.cjs');
5
+ const cdn = require('./shared/preset-icons.b3a2fafc.cjs');
6
6
  const core = require('./core.cjs');
7
7
  require('ohmyfetch');
8
8
  require('@unocss/core');
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { c as createCDNLoader, l as loadIcon } from './shared/preset-icons.d1472e4a.mjs';
1
+ import { c as createCDNLoader, l as loadIcon } from './shared/preset-icons.0f5b1443.mjs';
2
2
  import { createPresetIcons, combineLoaders } from './core.mjs';
3
3
  export { combineLoaders, createPresetIcons } from './core.mjs';
4
4
  import 'ohmyfetch';
@@ -1,98 +1,120 @@
1
1
  import { $fetch } from 'ohmyfetch';
2
2
 
3
- const defaults = Object.freeze({
4
- inline: false,
5
- width: null,
6
- height: null,
7
- hAlign: "center",
8
- vAlign: "middle",
9
- slice: false,
10
- hFlip: false,
11
- vFlip: false,
12
- rotate: 0
13
- });
14
-
15
- const allKeys = Object.keys(defaults);
16
- allKeys.filter((key) => key !== "width" && key !== "height");
17
-
18
- const iconDefaults = Object.freeze({
19
- left: 0,
20
- top: 0,
21
- width: 16,
22
- height: 16,
3
+ const defaultIconDimensions = Object.freeze(
4
+ {
5
+ left: 0,
6
+ top: 0,
7
+ width: 16,
8
+ height: 16
9
+ }
10
+ );
11
+ const defaultIconTransformations = Object.freeze({
23
12
  rotate: 0,
24
13
  vFlip: false,
25
14
  hFlip: false
26
15
  });
27
- function fullIcon(data) {
28
- return { ...iconDefaults, ...data };
16
+ const defaultIconProps = Object.freeze({
17
+ ...defaultIconDimensions,
18
+ ...defaultIconTransformations
19
+ });
20
+ const defaultExtendedIconProps = Object.freeze({
21
+ ...defaultIconProps,
22
+ body: "",
23
+ hidden: false
24
+ });
25
+
26
+ const defaultIconSizeCustomisations = Object.freeze({
27
+ width: null,
28
+ height: null
29
+ });
30
+ const defaultIconCustomisations = Object.freeze({
31
+ ...defaultIconSizeCustomisations,
32
+ ...defaultIconTransformations
33
+ });
34
+
35
+ function mergeIconTransformations(obj1, obj2) {
36
+ const result = {};
37
+ if (!obj1.hFlip !== !obj2.hFlip) {
38
+ result.hFlip = true;
39
+ }
40
+ if (!obj1.vFlip !== !obj2.vFlip) {
41
+ result.vFlip = true;
42
+ }
43
+ const rotate = ((obj1.rotate || 0) + (obj2.rotate || 0)) % 4;
44
+ if (rotate) {
45
+ result.rotate = rotate;
46
+ }
47
+ return result;
29
48
  }
30
49
 
31
- function mergeIconData(icon, alias) {
32
- const result = { ...icon };
33
- for (const key in iconDefaults) {
34
- const prop = key;
35
- if (alias[prop] !== void 0) {
36
- const value = alias[prop];
37
- if (result[prop] === void 0) {
38
- result[prop] = value;
39
- continue;
40
- }
41
- switch (prop) {
42
- case "rotate":
43
- result[prop] = (result[prop] + value) % 4;
44
- break;
45
- case "hFlip":
46
- case "vFlip":
47
- result[prop] = value !== result[prop];
48
- break;
49
- default:
50
- result[prop] = value;
50
+ function mergeIconData(parent, child) {
51
+ const result = mergeIconTransformations(parent, child);
52
+ for (const key in defaultExtendedIconProps) {
53
+ if (key in defaultIconTransformations) {
54
+ if (key in parent && !(key in result)) {
55
+ result[key] = defaultIconTransformations[key];
51
56
  }
57
+ } else if (key in child) {
58
+ result[key] = child[key];
59
+ } else if (key in parent) {
60
+ result[key] = parent[key];
52
61
  }
53
62
  }
54
63
  return result;
55
64
  }
56
65
 
57
- function getIconData(data, name, full = false) {
58
- function getIcon(name2, iteration) {
59
- if (data.icons[name2] !== void 0) {
60
- return Object.assign({}, data.icons[name2]);
61
- }
62
- if (iteration > 5) {
63
- return null;
64
- }
65
- const aliases = data.aliases;
66
- if (aliases && aliases[name2] !== void 0) {
67
- const item = aliases[name2];
68
- const result2 = getIcon(item.parent, iteration + 1);
69
- if (result2) {
70
- return mergeIconData(result2, item);
71
- }
72
- return result2;
73
- }
74
- const chars = data.chars;
75
- if (!iteration && chars && chars[name2] !== void 0) {
76
- return getIcon(chars[name2], iteration + 1);
66
+ function getIconsTree(data, names) {
67
+ const icons = data.icons;
68
+ const aliases = data.aliases || {};
69
+ const resolved = /* @__PURE__ */ Object.create(null);
70
+ function resolve(name) {
71
+ if (icons[name]) {
72
+ return resolved[name] = [];
77
73
  }
78
- return null;
79
- }
80
- const result = getIcon(name, 0);
81
- if (result) {
82
- for (const key in iconDefaults) {
83
- if (result[key] === void 0 && data[key] !== void 0) {
84
- result[key] = data[key];
74
+ if (!(name in resolved)) {
75
+ resolved[name] = null;
76
+ const parent = aliases[name] && aliases[name].parent;
77
+ const value = parent && resolve(parent);
78
+ if (value) {
79
+ resolved[name] = [parent].concat(value);
85
80
  }
86
81
  }
82
+ return resolved[name];
87
83
  }
88
- return result && full ? fullIcon(result) : result;
84
+ (names || Object.keys(icons).concat(Object.keys(aliases))).forEach(resolve);
85
+ return resolved;
89
86
  }
90
87
 
91
- for (const prop in iconDefaults) {
92
- typeof iconDefaults[prop];
88
+ function internalGetIconData(data, name, tree) {
89
+ const icons = data.icons;
90
+ const aliases = data.aliases || {};
91
+ let currentProps = {};
92
+ function parse(name2) {
93
+ currentProps = mergeIconData(
94
+ icons[name2] || aliases[name2],
95
+ currentProps
96
+ );
97
+ }
98
+ parse(name);
99
+ tree.forEach(parse);
100
+ return mergeIconData(data, currentProps);
101
+ }
102
+ function getIconData(data, name) {
103
+ if (data.icons[name]) {
104
+ return internalGetIconData(data, name, []);
105
+ }
106
+ const tree = getIconsTree(data, [name])[name];
107
+ return tree ? internalGetIconData(data, name, tree) : null;
93
108
  }
94
109
 
95
- Object.keys(iconDefaults).concat([
110
+ ({
111
+ provider: "",
112
+ aliases: {},
113
+ not_found: {},
114
+ ...defaultIconDimensions
115
+ });
116
+
117
+ Object.keys(defaultIconDimensions).concat([
96
118
  "provider"
97
119
  ]);
98
120
 
@@ -102,7 +124,7 @@ function calculateSize(size, ratio, precision) {
102
124
  if (ratio === 1) {
103
125
  return size;
104
126
  }
105
- precision = precision === void 0 ? 100 : precision;
127
+ precision = precision || 100;
106
128
  if (typeof size === "number") {
107
129
  return Math.ceil(size * ratio * precision) / precision;
108
130
  }
@@ -135,40 +157,23 @@ function calculateSize(size, ratio, precision) {
135
157
  }
136
158
  }
137
159
 
138
- function preserveAspectRatio(props) {
139
- let result = "";
140
- switch (props.hAlign) {
141
- case "left":
142
- result += "xMin";
143
- break;
144
- case "right":
145
- result += "xMax";
146
- break;
147
- default:
148
- result += "xMid";
149
- }
150
- switch (props.vAlign) {
151
- case "top":
152
- result += "YMin";
153
- break;
154
- case "bottom":
155
- result += "YMax";
156
- break;
157
- default:
158
- result += "YMid";
159
- }
160
- result += props.slice ? " slice" : " meet";
161
- return result;
162
- }
163
160
  function iconToSVG(icon, customisations) {
161
+ const fullIcon = {
162
+ ...defaultIconProps,
163
+ ...icon
164
+ };
165
+ const fullCustomisations = {
166
+ ...defaultIconCustomisations,
167
+ ...customisations
168
+ };
164
169
  const box = {
165
- left: icon.left,
166
- top: icon.top,
167
- width: icon.width,
168
- height: icon.height
170
+ left: fullIcon.left,
171
+ top: fullIcon.top,
172
+ width: fullIcon.width,
173
+ height: fullIcon.height
169
174
  };
170
- let body = icon.body;
171
- [icon, customisations].forEach((props) => {
175
+ let body = fullIcon.body;
176
+ [fullIcon, fullCustomisations].forEach((props) => {
172
177
  const transformations = [];
173
178
  const hFlip = props.hFlip;
174
179
  const vFlip = props.vFlip;
@@ -177,12 +182,16 @@ function iconToSVG(icon, customisations) {
177
182
  if (vFlip) {
178
183
  rotation += 2;
179
184
  } else {
180
- transformations.push("translate(" + (box.width + box.left).toString() + " " + (0 - box.top).toString() + ")");
185
+ transformations.push(
186
+ "translate(" + (box.width + box.left).toString() + " " + (0 - box.top).toString() + ")"
187
+ );
181
188
  transformations.push("scale(-1 1)");
182
189
  box.top = box.left = 0;
183
190
  }
184
191
  } else if (vFlip) {
185
- transformations.push("translate(" + (0 - box.left).toString() + " " + (box.height + box.top).toString() + ")");
192
+ transformations.push(
193
+ "translate(" + (0 - box.left).toString() + " " + (box.height + box.top).toString() + ")"
194
+ );
186
195
  transformations.push("scale(1 -1)");
187
196
  box.top = box.left = 0;
188
197
  }
@@ -194,18 +203,24 @@ function iconToSVG(icon, customisations) {
194
203
  switch (rotation) {
195
204
  case 1:
196
205
  tempValue = box.height / 2 + box.top;
197
- transformations.unshift("rotate(90 " + tempValue.toString() + " " + tempValue.toString() + ")");
206
+ transformations.unshift(
207
+ "rotate(90 " + tempValue.toString() + " " + tempValue.toString() + ")"
208
+ );
198
209
  break;
199
210
  case 2:
200
- transformations.unshift("rotate(180 " + (box.width / 2 + box.left).toString() + " " + (box.height / 2 + box.top).toString() + ")");
211
+ transformations.unshift(
212
+ "rotate(180 " + (box.width / 2 + box.left).toString() + " " + (box.height / 2 + box.top).toString() + ")"
213
+ );
201
214
  break;
202
215
  case 3:
203
216
  tempValue = box.width / 2 + box.left;
204
- transformations.unshift("rotate(-90 " + tempValue.toString() + " " + tempValue.toString() + ")");
217
+ transformations.unshift(
218
+ "rotate(-90 " + tempValue.toString() + " " + tempValue.toString() + ")"
219
+ );
205
220
  break;
206
221
  }
207
222
  if (rotation % 2 === 1) {
208
- if (box.left !== 0 || box.top !== 0) {
223
+ if (box.left !== box.top) {
209
224
  tempValue = box.left;
210
225
  box.left = box.top;
211
226
  box.top = tempValue;
@@ -220,40 +235,27 @@ function iconToSVG(icon, customisations) {
220
235
  body = '<g transform="' + transformations.join(" ") + '">' + body + "</g>";
221
236
  }
222
237
  });
223
- let width, height;
224
- if (customisations.width === null && customisations.height === null) {
225
- height = "1em";
226
- width = calculateSize(height, box.width / box.height);
227
- } else if (customisations.width !== null && customisations.height !== null) {
228
- width = customisations.width;
229
- height = customisations.height;
230
- } else if (customisations.height !== null) {
231
- height = customisations.height;
232
- width = calculateSize(height, box.width / box.height);
238
+ const customisationsWidth = fullCustomisations.width;
239
+ const customisationsHeight = fullCustomisations.height;
240
+ const boxWidth = box.width;
241
+ const boxHeight = box.height;
242
+ let width;
243
+ let height;
244
+ if (customisationsWidth === null) {
245
+ height = customisationsHeight === null ? "1em" : customisationsHeight === "auto" ? boxHeight : customisationsHeight;
246
+ width = calculateSize(height, boxWidth / boxHeight);
233
247
  } else {
234
- width = customisations.width;
235
- height = calculateSize(width, box.height / box.width);
248
+ width = customisationsWidth === "auto" ? boxWidth : customisationsWidth;
249
+ height = customisationsHeight === null ? calculateSize(width, boxHeight / boxWidth) : customisationsHeight === "auto" ? boxHeight : customisationsHeight;
236
250
  }
237
- if (width === "auto") {
238
- width = box.width;
239
- }
240
- if (height === "auto") {
241
- height = box.height;
242
- }
243
- width = typeof width === "string" ? width : width.toString() + "";
244
- height = typeof height === "string" ? height : height.toString() + "";
245
251
  const result = {
246
252
  attributes: {
247
- width,
248
- height,
249
- preserveAspectRatio: preserveAspectRatio(customisations),
250
- viewBox: box.left.toString() + " " + box.top.toString() + " " + box.width.toString() + " " + box.height.toString()
253
+ width: width.toString(),
254
+ height: height.toString(),
255
+ viewBox: box.left.toString() + " " + box.top.toString() + " " + boxWidth.toString() + " " + boxHeight.toString()
251
256
  },
252
257
  body
253
258
  };
254
- if (customisations.inline) {
255
- result.inline = true;
256
- }
257
259
  return result;
258
260
  }
259
261
 
@@ -483,7 +485,9 @@ async function mergeIconProps(svg, collection, icon, options, propsProvider, aft
483
485
  props["xmlns:xlink"] = "http://www.w3.org/1999/xlink";
484
486
  }
485
487
  }
486
- const propsToAdd = Object.keys(props).map((p) => p === "width" && widthOnSvg || p === "height" && heightOnSvg ? null : `${p}="${props[p]}"`).filter((p) => p != null);
488
+ const propsToAdd = Object.keys(props).map(
489
+ (p) => p === "width" && widthOnSvg || p === "height" && heightOnSvg ? null : `${p}="${props[p]}"`
490
+ ).filter((p) => p != null);
487
491
  if (propsToAdd.length) {
488
492
  svg = svg.replace("<svg ", `<svg ${propsToAdd.join(" ")} `);
489
493
  }
@@ -528,10 +532,18 @@ async function getCustomIcon(custom, collection, icon, options) {
528
532
  const { transform } = options?.customizations ?? {};
529
533
  result = typeof transform === "function" ? await transform(result, collection, icon) : result;
530
534
  if (!result.startsWith("<svg")) {
531
- console.warn(`Custom icon "${icon}" in "${collection}" is not a valid SVG`);
535
+ console.warn(
536
+ `Custom icon "${icon}" in "${collection}" is not a valid SVG`
537
+ );
532
538
  return result;
533
539
  }
534
- return await mergeIconProps(options?.customizations?.trimCustomSvg === true ? trimSVG(result) : result, collection, icon, options, void 0);
540
+ return await mergeIconProps(
541
+ options?.customizations?.trimCustomSvg === true ? trimSVG(result) : result,
542
+ collection,
543
+ icon,
544
+ options,
545
+ void 0
546
+ );
535
547
  }
536
548
  }
537
549
 
@@ -539,9 +551,9 @@ async function searchForIcon(iconSet, collection, ids, options) {
539
551
  let iconData;
540
552
  const { customize } = options?.customizations ?? {};
541
553
  for (const id of ids) {
542
- iconData = getIconData(iconSet, id, true);
554
+ iconData = getIconData(iconSet, id);
543
555
  if (iconData) {
544
- let defaultCustomizations = { ...defaults };
556
+ let defaultCustomizations = { ...defaultIconCustomisations };
545
557
  if (typeof customize === "function")
546
558
  defaultCustomizations = customize(defaultCustomizations);
547
559
  const {
@@ -549,24 +561,31 @@ async function searchForIcon(iconSet, collection, ids, options) {
549
561
  body
550
562
  } = iconToSVG(iconData, defaultCustomizations);
551
563
  const scale = options?.scale;
552
- return await mergeIconProps(`<svg >${body}</svg>`, collection, id, options, () => {
553
- return { ...restAttributes };
554
- }, (props) => {
555
- if (typeof props.width === "undefined" || props.width === null) {
556
- if (typeof scale === "number") {
557
- props.width = `${scale}em`;
558
- } else {
559
- props.width = width;
564
+ return await mergeIconProps(
565
+ `<svg >${body}</svg>`,
566
+ collection,
567
+ id,
568
+ options,
569
+ () => {
570
+ return { ...restAttributes };
571
+ },
572
+ (props) => {
573
+ if (typeof props.width === "undefined" || props.width === null) {
574
+ if (typeof scale === "number") {
575
+ props.width = `${scale}em`;
576
+ } else {
577
+ props.width = width;
578
+ }
560
579
  }
561
- }
562
- if (typeof props.height === "undefined" || props.height === null) {
563
- if (typeof scale === "number") {
564
- props.height = `${scale}em`;
565
- } else {
566
- props.height = height;
580
+ if (typeof props.height === "undefined" || props.height === null) {
581
+ if (typeof scale === "number") {
582
+ props.height = `${scale}em`;
583
+ } else {
584
+ props.height = height;
585
+ }
567
586
  }
568
587
  }
569
- });
588
+ );
570
589
  }
571
590
  }
572
591
  }
@@ -578,7 +597,12 @@ const loadIcon = async (collection, icon, options) => {
578
597
  const result = await custom(icon);
579
598
  if (result) {
580
599
  if (typeof result === "string") {
581
- return await getCustomIcon(() => result, collection, icon, options);
600
+ return await getCustomIcon(
601
+ () => result,
602
+ collection,
603
+ icon,
604
+ options
605
+ );
582
606
  }
583
607
  if ("icons" in result) {
584
608
  const ids = [
@@ -586,7 +610,12 @@ const loadIcon = async (collection, icon, options) => {
586
610
  icon.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(),
587
611
  icon.replace(/([a-z])(\d+)/g, "$1-$2")
588
612
  ];
589
- return await searchForIcon(result, collection, ids, options);
613
+ return await searchForIcon(
614
+ result,
615
+ collection,
616
+ ids,
617
+ options
618
+ );
590
619
  }
591
620
  }
592
621
  } else {
@@ -2,99 +2,121 @@
2
2
 
3
3
  const ohmyfetch = require('ohmyfetch');
4
4
 
5
- const defaults = Object.freeze({
6
- inline: false,
7
- width: null,
8
- height: null,
9
- hAlign: "center",
10
- vAlign: "middle",
11
- slice: false,
12
- hFlip: false,
13
- vFlip: false,
14
- rotate: 0
15
- });
16
-
17
- const allKeys = Object.keys(defaults);
18
- allKeys.filter((key) => key !== "width" && key !== "height");
19
-
20
- const iconDefaults = Object.freeze({
21
- left: 0,
22
- top: 0,
23
- width: 16,
24
- height: 16,
5
+ const defaultIconDimensions = Object.freeze(
6
+ {
7
+ left: 0,
8
+ top: 0,
9
+ width: 16,
10
+ height: 16
11
+ }
12
+ );
13
+ const defaultIconTransformations = Object.freeze({
25
14
  rotate: 0,
26
15
  vFlip: false,
27
16
  hFlip: false
28
17
  });
29
- function fullIcon(data) {
30
- return { ...iconDefaults, ...data };
18
+ const defaultIconProps = Object.freeze({
19
+ ...defaultIconDimensions,
20
+ ...defaultIconTransformations
21
+ });
22
+ const defaultExtendedIconProps = Object.freeze({
23
+ ...defaultIconProps,
24
+ body: "",
25
+ hidden: false
26
+ });
27
+
28
+ const defaultIconSizeCustomisations = Object.freeze({
29
+ width: null,
30
+ height: null
31
+ });
32
+ const defaultIconCustomisations = Object.freeze({
33
+ ...defaultIconSizeCustomisations,
34
+ ...defaultIconTransformations
35
+ });
36
+
37
+ function mergeIconTransformations(obj1, obj2) {
38
+ const result = {};
39
+ if (!obj1.hFlip !== !obj2.hFlip) {
40
+ result.hFlip = true;
41
+ }
42
+ if (!obj1.vFlip !== !obj2.vFlip) {
43
+ result.vFlip = true;
44
+ }
45
+ const rotate = ((obj1.rotate || 0) + (obj2.rotate || 0)) % 4;
46
+ if (rotate) {
47
+ result.rotate = rotate;
48
+ }
49
+ return result;
31
50
  }
32
51
 
33
- function mergeIconData(icon, alias) {
34
- const result = { ...icon };
35
- for (const key in iconDefaults) {
36
- const prop = key;
37
- if (alias[prop] !== void 0) {
38
- const value = alias[prop];
39
- if (result[prop] === void 0) {
40
- result[prop] = value;
41
- continue;
42
- }
43
- switch (prop) {
44
- case "rotate":
45
- result[prop] = (result[prop] + value) % 4;
46
- break;
47
- case "hFlip":
48
- case "vFlip":
49
- result[prop] = value !== result[prop];
50
- break;
51
- default:
52
- result[prop] = value;
52
+ function mergeIconData(parent, child) {
53
+ const result = mergeIconTransformations(parent, child);
54
+ for (const key in defaultExtendedIconProps) {
55
+ if (key in defaultIconTransformations) {
56
+ if (key in parent && !(key in result)) {
57
+ result[key] = defaultIconTransformations[key];
53
58
  }
59
+ } else if (key in child) {
60
+ result[key] = child[key];
61
+ } else if (key in parent) {
62
+ result[key] = parent[key];
54
63
  }
55
64
  }
56
65
  return result;
57
66
  }
58
67
 
59
- function getIconData(data, name, full = false) {
60
- function getIcon(name2, iteration) {
61
- if (data.icons[name2] !== void 0) {
62
- return Object.assign({}, data.icons[name2]);
63
- }
64
- if (iteration > 5) {
65
- return null;
66
- }
67
- const aliases = data.aliases;
68
- if (aliases && aliases[name2] !== void 0) {
69
- const item = aliases[name2];
70
- const result2 = getIcon(item.parent, iteration + 1);
71
- if (result2) {
72
- return mergeIconData(result2, item);
73
- }
74
- return result2;
75
- }
76
- const chars = data.chars;
77
- if (!iteration && chars && chars[name2] !== void 0) {
78
- return getIcon(chars[name2], iteration + 1);
68
+ function getIconsTree(data, names) {
69
+ const icons = data.icons;
70
+ const aliases = data.aliases || {};
71
+ const resolved = /* @__PURE__ */ Object.create(null);
72
+ function resolve(name) {
73
+ if (icons[name]) {
74
+ return resolved[name] = [];
79
75
  }
80
- return null;
81
- }
82
- const result = getIcon(name, 0);
83
- if (result) {
84
- for (const key in iconDefaults) {
85
- if (result[key] === void 0 && data[key] !== void 0) {
86
- result[key] = data[key];
76
+ if (!(name in resolved)) {
77
+ resolved[name] = null;
78
+ const parent = aliases[name] && aliases[name].parent;
79
+ const value = parent && resolve(parent);
80
+ if (value) {
81
+ resolved[name] = [parent].concat(value);
87
82
  }
88
83
  }
84
+ return resolved[name];
89
85
  }
90
- return result && full ? fullIcon(result) : result;
86
+ (names || Object.keys(icons).concat(Object.keys(aliases))).forEach(resolve);
87
+ return resolved;
91
88
  }
92
89
 
93
- for (const prop in iconDefaults) {
94
- typeof iconDefaults[prop];
90
+ function internalGetIconData(data, name, tree) {
91
+ const icons = data.icons;
92
+ const aliases = data.aliases || {};
93
+ let currentProps = {};
94
+ function parse(name2) {
95
+ currentProps = mergeIconData(
96
+ icons[name2] || aliases[name2],
97
+ currentProps
98
+ );
99
+ }
100
+ parse(name);
101
+ tree.forEach(parse);
102
+ return mergeIconData(data, currentProps);
103
+ }
104
+ function getIconData(data, name) {
105
+ if (data.icons[name]) {
106
+ return internalGetIconData(data, name, []);
107
+ }
108
+ const tree = getIconsTree(data, [name])[name];
109
+ return tree ? internalGetIconData(data, name, tree) : null;
95
110
  }
96
111
 
97
- Object.keys(iconDefaults).concat([
112
+ ({
113
+ provider: "",
114
+ aliases: {},
115
+ not_found: {},
116
+ ...defaultIconDimensions
117
+ });
118
+
119
+ Object.keys(defaultIconDimensions).concat([
98
120
  "provider"
99
121
  ]);
100
122
 
@@ -104,7 +126,7 @@ function calculateSize(size, ratio, precision) {
104
126
  if (ratio === 1) {
105
127
  return size;
106
128
  }
107
- precision = precision === void 0 ? 100 : precision;
129
+ precision = precision || 100;
108
130
  if (typeof size === "number") {
109
131
  return Math.ceil(size * ratio * precision) / precision;
110
132
  }
@@ -137,40 +159,23 @@ function calculateSize(size, ratio, precision) {
137
159
  }
138
160
  }
139
161
 
140
- function preserveAspectRatio(props) {
141
- let result = "";
142
- switch (props.hAlign) {
143
- case "left":
144
- result += "xMin";
145
- break;
146
- case "right":
147
- result += "xMax";
148
- break;
149
- default:
150
- result += "xMid";
151
- }
152
- switch (props.vAlign) {
153
- case "top":
154
- result += "YMin";
155
- break;
156
- case "bottom":
157
- result += "YMax";
158
- break;
159
- default:
160
- result += "YMid";
161
- }
162
- result += props.slice ? " slice" : " meet";
163
- return result;
164
- }
165
162
  function iconToSVG(icon, customisations) {
163
+ const fullIcon = {
164
+ ...defaultIconProps,
165
+ ...icon
166
+ };
167
+ const fullCustomisations = {
168
+ ...defaultIconCustomisations,
169
+ ...customisations
170
+ };
166
171
  const box = {
167
- left: icon.left,
168
- top: icon.top,
169
- width: icon.width,
170
- height: icon.height
172
+ left: fullIcon.left,
173
+ top: fullIcon.top,
174
+ width: fullIcon.width,
175
+ height: fullIcon.height
171
176
  };
172
- let body = icon.body;
173
- [icon, customisations].forEach((props) => {
177
+ let body = fullIcon.body;
178
+ [fullIcon, fullCustomisations].forEach((props) => {
174
179
  const transformations = [];
175
180
  const hFlip = props.hFlip;
176
181
  const vFlip = props.vFlip;
@@ -179,12 +184,16 @@ function iconToSVG(icon, customisations) {
179
184
  if (vFlip) {
180
185
  rotation += 2;
181
186
  } else {
182
- transformations.push("translate(" + (box.width + box.left).toString() + " " + (0 - box.top).toString() + ")");
187
+ transformations.push(
188
+ "translate(" + (box.width + box.left).toString() + " " + (0 - box.top).toString() + ")"
189
+ );
183
190
  transformations.push("scale(-1 1)");
184
191
  box.top = box.left = 0;
185
192
  }
186
193
  } else if (vFlip) {
187
- transformations.push("translate(" + (0 - box.left).toString() + " " + (box.height + box.top).toString() + ")");
194
+ transformations.push(
195
+ "translate(" + (0 - box.left).toString() + " " + (box.height + box.top).toString() + ")"
196
+ );
188
197
  transformations.push("scale(1 -1)");
189
198
  box.top = box.left = 0;
190
199
  }
@@ -196,18 +205,24 @@ function iconToSVG(icon, customisations) {
196
205
  switch (rotation) {
197
206
  case 1:
198
207
  tempValue = box.height / 2 + box.top;
199
- transformations.unshift("rotate(90 " + tempValue.toString() + " " + tempValue.toString() + ")");
208
+ transformations.unshift(
209
+ "rotate(90 " + tempValue.toString() + " " + tempValue.toString() + ")"
210
+ );
200
211
  break;
201
212
  case 2:
202
- transformations.unshift("rotate(180 " + (box.width / 2 + box.left).toString() + " " + (box.height / 2 + box.top).toString() + ")");
213
+ transformations.unshift(
214
+ "rotate(180 " + (box.width / 2 + box.left).toString() + " " + (box.height / 2 + box.top).toString() + ")"
215
+ );
203
216
  break;
204
217
  case 3:
205
218
  tempValue = box.width / 2 + box.left;
206
- transformations.unshift("rotate(-90 " + tempValue.toString() + " " + tempValue.toString() + ")");
219
+ transformations.unshift(
220
+ "rotate(-90 " + tempValue.toString() + " " + tempValue.toString() + ")"
221
+ );
207
222
  break;
208
223
  }
209
224
  if (rotation % 2 === 1) {
210
- if (box.left !== 0 || box.top !== 0) {
225
+ if (box.left !== box.top) {
211
226
  tempValue = box.left;
212
227
  box.left = box.top;
213
228
  box.top = tempValue;
@@ -222,40 +237,27 @@ function iconToSVG(icon, customisations) {
222
237
  body = '<g transform="' + transformations.join(" ") + '">' + body + "</g>";
223
238
  }
224
239
  });
225
- let width, height;
226
- if (customisations.width === null && customisations.height === null) {
227
- height = "1em";
228
- width = calculateSize(height, box.width / box.height);
229
- } else if (customisations.width !== null && customisations.height !== null) {
230
- width = customisations.width;
231
- height = customisations.height;
232
- } else if (customisations.height !== null) {
233
- height = customisations.height;
234
- width = calculateSize(height, box.width / box.height);
240
+ const customisationsWidth = fullCustomisations.width;
241
+ const customisationsHeight = fullCustomisations.height;
242
+ const boxWidth = box.width;
243
+ const boxHeight = box.height;
244
+ let width;
245
+ let height;
246
+ if (customisationsWidth === null) {
247
+ height = customisationsHeight === null ? "1em" : customisationsHeight === "auto" ? boxHeight : customisationsHeight;
248
+ width = calculateSize(height, boxWidth / boxHeight);
235
249
  } else {
236
- width = customisations.width;
237
- height = calculateSize(width, box.height / box.width);
250
+ width = customisationsWidth === "auto" ? boxWidth : customisationsWidth;
251
+ height = customisationsHeight === null ? calculateSize(width, boxHeight / boxWidth) : customisationsHeight === "auto" ? boxHeight : customisationsHeight;
238
252
  }
239
- if (width === "auto") {
240
- width = box.width;
241
- }
242
- if (height === "auto") {
243
- height = box.height;
244
- }
245
- width = typeof width === "string" ? width : width.toString() + "";
246
- height = typeof height === "string" ? height : height.toString() + "";
247
253
  const result = {
248
254
  attributes: {
249
- width,
250
- height,
251
- preserveAspectRatio: preserveAspectRatio(customisations),
252
- viewBox: box.left.toString() + " " + box.top.toString() + " " + box.width.toString() + " " + box.height.toString()
255
+ width: width.toString(),
256
+ height: height.toString(),
257
+ viewBox: box.left.toString() + " " + box.top.toString() + " " + boxWidth.toString() + " " + boxHeight.toString()
253
258
  },
254
259
  body
255
260
  };
256
- if (customisations.inline) {
257
- result.inline = true;
258
- }
259
261
  return result;
260
262
  }
261
263
 
@@ -485,7 +487,9 @@ async function mergeIconProps(svg, collection, icon, options, propsProvider, aft
485
487
  props["xmlns:xlink"] = "http://www.w3.org/1999/xlink";
486
488
  }
487
489
  }
488
- const propsToAdd = Object.keys(props).map((p) => p === "width" && widthOnSvg || p === "height" && heightOnSvg ? null : `${p}="${props[p]}"`).filter((p) => p != null);
490
+ const propsToAdd = Object.keys(props).map(
491
+ (p) => p === "width" && widthOnSvg || p === "height" && heightOnSvg ? null : `${p}="${props[p]}"`
492
+ ).filter((p) => p != null);
489
493
  if (propsToAdd.length) {
490
494
  svg = svg.replace("<svg ", `<svg ${propsToAdd.join(" ")} `);
491
495
  }
@@ -530,10 +534,18 @@ async function getCustomIcon(custom, collection, icon, options) {
530
534
  const { transform } = options?.customizations ?? {};
531
535
  result = typeof transform === "function" ? await transform(result, collection, icon) : result;
532
536
  if (!result.startsWith("<svg")) {
533
- console.warn(`Custom icon "${icon}" in "${collection}" is not a valid SVG`);
537
+ console.warn(
538
+ `Custom icon "${icon}" in "${collection}" is not a valid SVG`
539
+ );
534
540
  return result;
535
541
  }
536
- return await mergeIconProps(options?.customizations?.trimCustomSvg === true ? trimSVG(result) : result, collection, icon, options, void 0);
542
+ return await mergeIconProps(
543
+ options?.customizations?.trimCustomSvg === true ? trimSVG(result) : result,
544
+ collection,
545
+ icon,
546
+ options,
547
+ void 0
548
+ );
537
549
  }
538
550
  }
539
551
 
@@ -541,9 +553,9 @@ async function searchForIcon(iconSet, collection, ids, options) {
541
553
  let iconData;
542
554
  const { customize } = options?.customizations ?? {};
543
555
  for (const id of ids) {
544
- iconData = getIconData(iconSet, id, true);
556
+ iconData = getIconData(iconSet, id);
545
557
  if (iconData) {
546
- let defaultCustomizations = { ...defaults };
558
+ let defaultCustomizations = { ...defaultIconCustomisations };
547
559
  if (typeof customize === "function")
548
560
  defaultCustomizations = customize(defaultCustomizations);
549
561
  const {
@@ -551,24 +563,31 @@ async function searchForIcon(iconSet, collection, ids, options) {
551
563
  body
552
564
  } = iconToSVG(iconData, defaultCustomizations);
553
565
  const scale = options?.scale;
554
- return await mergeIconProps(`<svg >${body}</svg>`, collection, id, options, () => {
555
- return { ...restAttributes };
556
- }, (props) => {
557
- if (typeof props.width === "undefined" || props.width === null) {
558
- if (typeof scale === "number") {
559
- props.width = `${scale}em`;
560
- } else {
561
- props.width = width;
566
+ return await mergeIconProps(
567
+ `<svg >${body}</svg>`,
568
+ collection,
569
+ id,
570
+ options,
571
+ () => {
572
+ return { ...restAttributes };
573
+ },
574
+ (props) => {
575
+ if (typeof props.width === "undefined" || props.width === null) {
576
+ if (typeof scale === "number") {
577
+ props.width = `${scale}em`;
578
+ } else {
579
+ props.width = width;
580
+ }
562
581
  }
563
- }
564
- if (typeof props.height === "undefined" || props.height === null) {
565
- if (typeof scale === "number") {
566
- props.height = `${scale}em`;
567
- } else {
568
- props.height = height;
582
+ if (typeof props.height === "undefined" || props.height === null) {
583
+ if (typeof scale === "number") {
584
+ props.height = `${scale}em`;
585
+ } else {
586
+ props.height = height;
587
+ }
569
588
  }
570
589
  }
571
- });
590
+ );
572
591
  }
573
592
  }
574
593
  }
@@ -580,7 +599,12 @@ const loadIcon = async (collection, icon, options) => {
580
599
  const result = await custom(icon);
581
600
  if (result) {
582
601
  if (typeof result === "string") {
583
- return await getCustomIcon(() => result, collection, icon, options);
602
+ return await getCustomIcon(
603
+ () => result,
604
+ collection,
605
+ icon,
606
+ options
607
+ );
584
608
  }
585
609
  if ("icons" in result) {
586
610
  const ids = [
@@ -588,7 +612,12 @@ const loadIcon = async (collection, icon, options) => {
588
612
  icon.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(),
589
613
  icon.replace(/([a-z])(\d+)/g, "$1-$2")
590
614
  ];
591
- return await searchForIcon(result, collection, ids, options);
615
+ return await searchForIcon(
616
+ result,
617
+ collection,
618
+ ids,
619
+ options
620
+ );
592
621
  }
593
622
  }
594
623
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unocss/preset-icons",
3
- "version": "0.45.21",
3
+ "version": "0.45.22",
4
4
  "description": "Pure CSS Icons for UnoCSS",
5
5
  "author": "Anthony Fu <anthonyfu117@hotmail.com>",
6
6
  "license": "MIT",
@@ -47,12 +47,12 @@
47
47
  "*.css"
48
48
  ],
49
49
  "dependencies": {
50
- "@iconify/utils": "^1.0.33",
51
- "@unocss/core": "0.45.21",
50
+ "@iconify/utils": "^2.0.0",
51
+ "@unocss/core": "0.45.22",
52
52
  "ohmyfetch": "^0.4.18"
53
53
  },
54
54
  "devDependencies": {
55
- "@iconify/types": "^1.1.0"
55
+ "@iconify/types": "^2.0.0"
56
56
  },
57
57
  "scripts": {
58
58
  "build": "unbuild",