@ubean/icon 0.1.1 → 0.1.3
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/core-NcYHbOE5.js +212 -0
- package/dist/index.d.ts +123 -0
- package/dist/index.js +176 -0
- package/dist/runtime-Hp8OXvtC.d.ts +55 -0
- package/dist/runtime.d.ts +3 -0
- package/dist/runtime.js +40 -0
- package/dist/types-CVT8GSd7.d.ts +57 -0
- package/dist/vite-S6Ivh3te.d.ts +10408 -0
- package/dist/vite.d.ts +3 -0
- package/dist/vite.js +318 -0
- package/package.json +1 -1
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
//#region src/core.ts
|
|
2
|
+
const loadedCollections = /* @__PURE__ */ new Map();
|
|
3
|
+
const collectionLoaders = /* @__PURE__ */ new Map();
|
|
4
|
+
function parseIconName(name) {
|
|
5
|
+
if (!name || typeof name !== "string") return null;
|
|
6
|
+
const sep = name.indexOf(":");
|
|
7
|
+
if (sep === -1) return null;
|
|
8
|
+
const collection = name.slice(0, sep);
|
|
9
|
+
const icon = name.slice(sep + 1);
|
|
10
|
+
if (!collection || !icon) return null;
|
|
11
|
+
return {
|
|
12
|
+
collection,
|
|
13
|
+
icon
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function normalizeIconName(name) {
|
|
17
|
+
return name.trim().toLowerCase().replace(/[^a-z0-9:-]/g, "");
|
|
18
|
+
}
|
|
19
|
+
function registerCollection(collection) {
|
|
20
|
+
loadedCollections.set(collection.prefix, collection);
|
|
21
|
+
}
|
|
22
|
+
function registerCollectionLoader(loader) {
|
|
23
|
+
collectionLoaders.set(loader.prefix, loader);
|
|
24
|
+
}
|
|
25
|
+
async function loadCollection(prefix) {
|
|
26
|
+
if (loadedCollections.has(prefix)) return loadedCollections.get(prefix);
|
|
27
|
+
const loader = collectionLoaders.get(prefix);
|
|
28
|
+
if (loader) {
|
|
29
|
+
const collection = await loader.load();
|
|
30
|
+
loadedCollections.set(prefix, collection);
|
|
31
|
+
return collection;
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
function getLoadedCollection(prefix) {
|
|
36
|
+
return loadedCollections.get(prefix);
|
|
37
|
+
}
|
|
38
|
+
function resolveAlias(collection, iconName, visited = /* @__PURE__ */ new Set()) {
|
|
39
|
+
if (visited.has(iconName)) return null;
|
|
40
|
+
visited.add(iconName);
|
|
41
|
+
const icon = collection.icons[iconName];
|
|
42
|
+
if (icon) return icon;
|
|
43
|
+
const alias = collection.aliases?.[iconName];
|
|
44
|
+
if (!alias) return null;
|
|
45
|
+
const parentData = resolveAlias(collection, alias.parent, visited);
|
|
46
|
+
if (!parentData) return null;
|
|
47
|
+
return {
|
|
48
|
+
...parentData,
|
|
49
|
+
...alias,
|
|
50
|
+
body: alias.body ?? parentData.body
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function getIconData(collection, iconName) {
|
|
54
|
+
const icon = resolveAlias(collection, iconName);
|
|
55
|
+
if (!icon) return null;
|
|
56
|
+
return icon;
|
|
57
|
+
}
|
|
58
|
+
function resolveIconData(collection, iconName, overrides) {
|
|
59
|
+
const icon = getIconData(collection, iconName);
|
|
60
|
+
if (!icon) return null;
|
|
61
|
+
const width = overrides?.width ?? icon.width ?? collection.width ?? 24;
|
|
62
|
+
const height = overrides?.height ?? icon.height ?? collection.height ?? 24;
|
|
63
|
+
let body = icon.body;
|
|
64
|
+
const rotate = overrides?.rotate ?? icon.rotate ?? 0;
|
|
65
|
+
const hFlip = overrides?.hFlip ?? icon.hFlip ?? false;
|
|
66
|
+
const vFlip = overrides?.vFlip ?? icon.vFlip ?? false;
|
|
67
|
+
const transforms = [];
|
|
68
|
+
if (rotate) transforms.push(`rotate(${rotate * 90} ${width / 2} ${height / 2})`);
|
|
69
|
+
if (hFlip) transforms.push(`translate(${width} 0) scale(-1 1)`);
|
|
70
|
+
if (vFlip) transforms.push(`translate(0 ${height}) scale(1 -1)`);
|
|
71
|
+
if (transforms.length > 0) body = `<g transform="${transforms.join(" ")}">${body}</g>`;
|
|
72
|
+
const viewBox = icon.viewBox ?? `0 0 ${width} ${height}`;
|
|
73
|
+
return {
|
|
74
|
+
body,
|
|
75
|
+
width,
|
|
76
|
+
height,
|
|
77
|
+
viewBox
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function generateSvg(resolved, options) {
|
|
81
|
+
const { body, width, height, viewBox } = resolved;
|
|
82
|
+
const { className, style, ariaHidden = true, ariaLabel, title } = options ?? {};
|
|
83
|
+
const attrs = [
|
|
84
|
+
"xmlns=\"http://www.w3.org/2000/svg\"",
|
|
85
|
+
`viewBox="${viewBox}"`,
|
|
86
|
+
`width="${width}"`,
|
|
87
|
+
`height="${height}"`
|
|
88
|
+
];
|
|
89
|
+
if (className) attrs.push(`class="${className}"`);
|
|
90
|
+
if (style) {
|
|
91
|
+
const styleStr = Object.entries(style).map(([k, v]) => `${k.replace(/([A-Z])/g, "-$1").toLowerCase()}:${v}`).join(";");
|
|
92
|
+
attrs.push(`style="${styleStr}"`);
|
|
93
|
+
}
|
|
94
|
+
if (ariaHidden && !ariaLabel) attrs.push("aria-hidden=\"true\"");
|
|
95
|
+
else if (ariaLabel) attrs.push(`role="img" aria-label="${ariaLabel}"`);
|
|
96
|
+
let titleTag = "";
|
|
97
|
+
if (title) titleTag = `<title>${escapeHtml(title)}</title>`;
|
|
98
|
+
return `<svg ${attrs.join(" ")}>${titleTag}${body}</svg>`;
|
|
99
|
+
}
|
|
100
|
+
function escapeHtml(str) {
|
|
101
|
+
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
102
|
+
}
|
|
103
|
+
async function getIcon(name) {
|
|
104
|
+
const parsed = parseIconName(name);
|
|
105
|
+
if (!parsed) return null;
|
|
106
|
+
const collection = await loadCollection(parsed.collection);
|
|
107
|
+
if (!collection) return null;
|
|
108
|
+
return resolveIconData(collection, parsed.icon);
|
|
109
|
+
}
|
|
110
|
+
function getIconSync(name) {
|
|
111
|
+
const parsed = parseIconName(name);
|
|
112
|
+
if (!parsed) return null;
|
|
113
|
+
const collection = loadedCollections.get(parsed.collection);
|
|
114
|
+
if (!collection) return null;
|
|
115
|
+
return resolveIconData(collection, parsed.icon);
|
|
116
|
+
}
|
|
117
|
+
function listLoadedCollections() {
|
|
118
|
+
return Array.from(loadedCollections.keys());
|
|
119
|
+
}
|
|
120
|
+
function clearCollections() {
|
|
121
|
+
loadedCollections.clear();
|
|
122
|
+
collectionLoaders.clear();
|
|
123
|
+
}
|
|
124
|
+
function scanVueSfcForIcons(source) {
|
|
125
|
+
const icons = /* @__PURE__ */ new Set();
|
|
126
|
+
const attrPattern = /(?:icon|name)\s*=\s*["']([^"']*:[^"']*)["']/g;
|
|
127
|
+
const boundAttrPattern = /:(?:icon|name)\s*=\s*["']([^"']*:[^"']*)["']/g;
|
|
128
|
+
const iconFnPattern = /(?:getIcon|useIcon)\(\s*["']([^"']*:[^"']*)["']\s*\)/g;
|
|
129
|
+
let match;
|
|
130
|
+
while ((match = attrPattern.exec(source)) !== null) {
|
|
131
|
+
const name = normalizeIconName(match[1]);
|
|
132
|
+
if (parseIconName(name)) icons.add(name);
|
|
133
|
+
}
|
|
134
|
+
while ((match = boundAttrPattern.exec(source)) !== null) {
|
|
135
|
+
const name = normalizeIconName(match[1]);
|
|
136
|
+
if (parseIconName(name)) icons.add(name);
|
|
137
|
+
}
|
|
138
|
+
while ((match = iconFnPattern.exec(source)) !== null) {
|
|
139
|
+
const name = normalizeIconName(match[1]);
|
|
140
|
+
if (parseIconName(name)) icons.add(name);
|
|
141
|
+
}
|
|
142
|
+
return icons;
|
|
143
|
+
}
|
|
144
|
+
const SVG_TAG_RE = /<svg([^>]*)>([\s\S]*?)<\/svg>/i;
|
|
145
|
+
const SVG_ATTR_RE = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)\s*=\s*(?:"([^"]*)"|'([^']*)'|([^"'<>`\s]+))/g;
|
|
146
|
+
function parseSvgToIconData(svg) {
|
|
147
|
+
const match = SVG_TAG_RE.exec(svg);
|
|
148
|
+
if (!match) return null;
|
|
149
|
+
const attrs = match[1];
|
|
150
|
+
const body = match[2].trim();
|
|
151
|
+
if (!body) return null;
|
|
152
|
+
const attrMap = {};
|
|
153
|
+
let attrMatch;
|
|
154
|
+
SVG_ATTR_RE.lastIndex = 0;
|
|
155
|
+
while ((attrMatch = SVG_ATTR_RE.exec(attrs)) !== null) {
|
|
156
|
+
const name = attrMatch[1].toLowerCase();
|
|
157
|
+
attrMap[name] = attrMatch[2] ?? attrMatch[3] ?? attrMatch[4] ?? "";
|
|
158
|
+
}
|
|
159
|
+
const result = { body };
|
|
160
|
+
const width = parseNumber(attrMap.width);
|
|
161
|
+
const height = parseNumber(attrMap.height);
|
|
162
|
+
if (width) result.width = width;
|
|
163
|
+
if (height) result.height = height;
|
|
164
|
+
const viewBox = attrMap.viewbox;
|
|
165
|
+
if (viewBox) {
|
|
166
|
+
result.viewBox = viewBox;
|
|
167
|
+
const parts = viewBox.split(/[\s,]+/).map(Number).filter((n) => !Number.isNaN(n));
|
|
168
|
+
if (parts.length === 4 && (!width || !height)) {
|
|
169
|
+
const vbWidth = parts[2];
|
|
170
|
+
const vbHeight = parts[3];
|
|
171
|
+
if (!width && vbWidth) result.width = vbWidth;
|
|
172
|
+
if (!height && vbHeight) result.height = vbHeight;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
const rootAttrs = [];
|
|
176
|
+
for (const attr of [
|
|
177
|
+
"fill",
|
|
178
|
+
"stroke",
|
|
179
|
+
"stroke-width",
|
|
180
|
+
"stroke-linecap",
|
|
181
|
+
"stroke-linejoin",
|
|
182
|
+
"stroke-miterlimit"
|
|
183
|
+
]) if (attrMap[attr]) rootAttrs.push(`${attr}="${escapeHtml(attrMap[attr])}"`);
|
|
184
|
+
return result;
|
|
185
|
+
}
|
|
186
|
+
function parseNumber(value) {
|
|
187
|
+
if (!value) return void 0;
|
|
188
|
+
const n = parseFloat(value);
|
|
189
|
+
return Number.isFinite(n) && n > 0 ? n : void 0;
|
|
190
|
+
}
|
|
191
|
+
function createCollectionFromSvgMap(prefix, icons) {
|
|
192
|
+
const iconData = {};
|
|
193
|
+
let collectionWidth;
|
|
194
|
+
let collectionHeight;
|
|
195
|
+
for (const [name, svg] of Object.entries(icons)) {
|
|
196
|
+
const data = parseSvgToIconData(svg);
|
|
197
|
+
if (data) {
|
|
198
|
+
iconData[name] = data;
|
|
199
|
+
if (data.width && !collectionWidth && true) collectionWidth = data.width;
|
|
200
|
+
if (data.height && !collectionHeight && true) collectionHeight = data.height;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
const collection = {
|
|
204
|
+
prefix,
|
|
205
|
+
icons: iconData
|
|
206
|
+
};
|
|
207
|
+
if (collectionWidth) collection.width = collectionWidth;
|
|
208
|
+
if (collectionHeight) collection.height = collectionHeight;
|
|
209
|
+
return collection;
|
|
210
|
+
}
|
|
211
|
+
//#endregion
|
|
212
|
+
export { resolveIconData as _, getIcon as a, getLoadedCollection as c, normalizeIconName as d, parseIconName as f, resolveAlias as g, registerCollectionLoader as h, generateSvg as i, listLoadedCollections as l, registerCollection as m, createCollectionFromSvgMap as n, getIconData as o, parseSvgToIconData as p, escapeHtml as r, getIconSync as s, clearCollections as t, loadCollection as u, scanVueSfcForIcons as v };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { a as IconifyIconData, i as IconifyCollection, l as UbeanIconOptions, n as IconCollectionLoader, o as ResolvedCustomCollection, r as IconifyAlias, s as ResolvedIconData, t as CustomCollectionDirConfig } from "./types-CVT8GSd7.js";
|
|
2
|
+
import { n as ubeanIconPlugin, t as addIconCollection } from "./vite-S6Ivh3te.js";
|
|
3
|
+
import { S as scanVueSfcForIcons, _ as parseSvgToIconData, a as clearCollections, c as generateSvg, d as getIconSync, f as getLoadedCollection, g as parseIconName, h as normalizeIconName, i as getIconConfig, l as getIcon, m as loadCollection, n as configureIconRuntime, o as createCollectionFromSvgMap, p as listLoadedCollections, r as fetchIconFromApi, s as escapeHtml, t as buildIconCssIcon, u as getIconData, v as registerCollection, x as resolveIconData, y as registerCollectionLoader } from "./runtime-Hp8OXvtC.js";
|
|
4
|
+
import { PropType } from "vue";
|
|
5
|
+
//#region src/index.d.ts
|
|
6
|
+
interface UbeanIconProps {
|
|
7
|
+
name: string;
|
|
8
|
+
size?: string | number;
|
|
9
|
+
color?: string;
|
|
10
|
+
className?: string;
|
|
11
|
+
ariaLabel?: string;
|
|
12
|
+
title?: string;
|
|
13
|
+
mode?: 'svg' | 'css';
|
|
14
|
+
flip?: 'horizontal' | 'vertical' | 'both';
|
|
15
|
+
rotate?: number | string;
|
|
16
|
+
inline?: boolean;
|
|
17
|
+
}
|
|
18
|
+
declare const Icon: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
19
|
+
name: {
|
|
20
|
+
type: PropType<string>;
|
|
21
|
+
required: true;
|
|
22
|
+
};
|
|
23
|
+
size: {
|
|
24
|
+
type: PropType<string | number>;
|
|
25
|
+
default: string;
|
|
26
|
+
};
|
|
27
|
+
color: {
|
|
28
|
+
type: PropType<string>;
|
|
29
|
+
default: undefined;
|
|
30
|
+
};
|
|
31
|
+
className: {
|
|
32
|
+
type: PropType<string>;
|
|
33
|
+
default: string;
|
|
34
|
+
};
|
|
35
|
+
ariaLabel: {
|
|
36
|
+
type: PropType<string>;
|
|
37
|
+
default: undefined;
|
|
38
|
+
};
|
|
39
|
+
title: {
|
|
40
|
+
type: PropType<string>;
|
|
41
|
+
default: undefined;
|
|
42
|
+
};
|
|
43
|
+
mode: {
|
|
44
|
+
type: PropType<"svg" | "css">;
|
|
45
|
+
default: string;
|
|
46
|
+
};
|
|
47
|
+
flip: {
|
|
48
|
+
type: PropType<"horizontal" | "vertical" | "both">;
|
|
49
|
+
default: undefined;
|
|
50
|
+
};
|
|
51
|
+
rotate: {
|
|
52
|
+
type: PropType<string | number>;
|
|
53
|
+
default: undefined;
|
|
54
|
+
};
|
|
55
|
+
inline: {
|
|
56
|
+
type: BooleanConstructor;
|
|
57
|
+
default: boolean;
|
|
58
|
+
};
|
|
59
|
+
}>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
60
|
+
[key: string]: any;
|
|
61
|
+
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
62
|
+
name: {
|
|
63
|
+
type: PropType<string>;
|
|
64
|
+
required: true;
|
|
65
|
+
};
|
|
66
|
+
size: {
|
|
67
|
+
type: PropType<string | number>;
|
|
68
|
+
default: string;
|
|
69
|
+
};
|
|
70
|
+
color: {
|
|
71
|
+
type: PropType<string>;
|
|
72
|
+
default: undefined;
|
|
73
|
+
};
|
|
74
|
+
className: {
|
|
75
|
+
type: PropType<string>;
|
|
76
|
+
default: string;
|
|
77
|
+
};
|
|
78
|
+
ariaLabel: {
|
|
79
|
+
type: PropType<string>;
|
|
80
|
+
default: undefined;
|
|
81
|
+
};
|
|
82
|
+
title: {
|
|
83
|
+
type: PropType<string>;
|
|
84
|
+
default: undefined;
|
|
85
|
+
};
|
|
86
|
+
mode: {
|
|
87
|
+
type: PropType<"svg" | "css">;
|
|
88
|
+
default: string;
|
|
89
|
+
};
|
|
90
|
+
flip: {
|
|
91
|
+
type: PropType<"horizontal" | "vertical" | "both">;
|
|
92
|
+
default: undefined;
|
|
93
|
+
};
|
|
94
|
+
rotate: {
|
|
95
|
+
type: PropType<string | number>;
|
|
96
|
+
default: undefined;
|
|
97
|
+
};
|
|
98
|
+
inline: {
|
|
99
|
+
type: BooleanConstructor;
|
|
100
|
+
default: boolean;
|
|
101
|
+
};
|
|
102
|
+
}>> & Readonly<{}>, {
|
|
103
|
+
size: string | number;
|
|
104
|
+
color: string;
|
|
105
|
+
className: string;
|
|
106
|
+
ariaLabel: string;
|
|
107
|
+
title: string;
|
|
108
|
+
mode: "svg" | "css";
|
|
109
|
+
flip: "horizontal" | "vertical" | "both";
|
|
110
|
+
rotate: string | number;
|
|
111
|
+
inline: boolean;
|
|
112
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
113
|
+
declare function defineIconCollection(collection: IconifyCollection): IconifyCollection;
|
|
114
|
+
declare function defineIconCollectionLoader(prefix: string, loader: () => Promise<IconifyCollection>): {
|
|
115
|
+
prefix: string;
|
|
116
|
+
load: () => Promise<IconifyCollection>;
|
|
117
|
+
};
|
|
118
|
+
declare function useIcon(name: string): {
|
|
119
|
+
getSvg: () => Promise<string | null>;
|
|
120
|
+
getSvgSync: () => string | null;
|
|
121
|
+
};
|
|
122
|
+
//#endregion
|
|
123
|
+
export { type CustomCollectionDirConfig, Icon, Icon as default, type IconCollectionLoader, type IconifyAlias, type IconifyCollection, type IconifyIconData, type ResolvedCustomCollection, type ResolvedIconData, type UbeanIconOptions, UbeanIconProps, addIconCollection, buildIconCssIcon, clearCollections, configureIconRuntime, createCollectionFromSvgMap, defineIconCollection, defineIconCollectionLoader, escapeHtml, fetchIconFromApi, generateSvg, getIcon, getIconConfig, getIconData, getIconSync, getLoadedCollection, listLoadedCollections, loadCollection, normalizeIconName, parseIconName, parseSvgToIconData, registerCollection, registerCollectionLoader, resolveIconData, scanVueSfcForIcons, ubeanIconPlugin, useIcon };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { _ as resolveIconData, a as getIcon, c as getLoadedCollection, d as normalizeIconName, f as parseIconName, h as registerCollectionLoader, i as generateSvg, l as listLoadedCollections, m as registerCollection, n as createCollectionFromSvgMap, o as getIconData, p as parseSvgToIconData, r as escapeHtml, s as getIconSync, t as clearCollections, u as loadCollection, v as scanVueSfcForIcons } from "./core-NcYHbOE5.js";
|
|
2
|
+
import { buildIconCssIcon, configureIconRuntime, fetchIconFromApi, getIconConfig } from "./runtime.js";
|
|
3
|
+
import { addIconCollection, ubeanIconPlugin } from "./vite.js";
|
|
4
|
+
import { computed, defineComponent, h, ref, watchEffect } from "vue";
|
|
5
|
+
//#region src/index.ts
|
|
6
|
+
const Icon = defineComponent({
|
|
7
|
+
name: "UbeanIcon",
|
|
8
|
+
props: {
|
|
9
|
+
name: {
|
|
10
|
+
type: String,
|
|
11
|
+
required: true
|
|
12
|
+
},
|
|
13
|
+
size: {
|
|
14
|
+
type: [String, Number],
|
|
15
|
+
default: "1em"
|
|
16
|
+
},
|
|
17
|
+
color: {
|
|
18
|
+
type: String,
|
|
19
|
+
default: void 0
|
|
20
|
+
},
|
|
21
|
+
className: {
|
|
22
|
+
type: String,
|
|
23
|
+
default: ""
|
|
24
|
+
},
|
|
25
|
+
ariaLabel: {
|
|
26
|
+
type: String,
|
|
27
|
+
default: void 0
|
|
28
|
+
},
|
|
29
|
+
title: {
|
|
30
|
+
type: String,
|
|
31
|
+
default: void 0
|
|
32
|
+
},
|
|
33
|
+
mode: {
|
|
34
|
+
type: String,
|
|
35
|
+
default: "svg"
|
|
36
|
+
},
|
|
37
|
+
flip: {
|
|
38
|
+
type: String,
|
|
39
|
+
default: void 0
|
|
40
|
+
},
|
|
41
|
+
rotate: {
|
|
42
|
+
type: [String, Number],
|
|
43
|
+
default: void 0
|
|
44
|
+
},
|
|
45
|
+
inline: {
|
|
46
|
+
type: Boolean,
|
|
47
|
+
default: false
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
setup(props) {
|
|
51
|
+
const svgHtml = ref("");
|
|
52
|
+
const isLoading = ref(false);
|
|
53
|
+
const hasError = ref(false);
|
|
54
|
+
const sizeValue = computed(() => typeof props.size === "number" ? `${props.size}px` : props.size);
|
|
55
|
+
const transformStyle = computed(() => {
|
|
56
|
+
const transforms = [];
|
|
57
|
+
if (props.flip === "horizontal" || props.flip === "both") transforms.push("scaleX(-1)");
|
|
58
|
+
if (props.flip === "vertical" || props.flip === "both") transforms.push("scaleY(-1)");
|
|
59
|
+
if (props.rotate !== void 0) {
|
|
60
|
+
const deg = typeof props.rotate === "number" ? props.rotate : parseInt(props.rotate, 10);
|
|
61
|
+
if (!isNaN(deg)) transforms.push(`rotate(${deg}deg)`);
|
|
62
|
+
}
|
|
63
|
+
return transforms.length > 0 ? transforms.join(" ") : void 0;
|
|
64
|
+
});
|
|
65
|
+
const sizeStyle = computed(() => ({
|
|
66
|
+
width: sizeValue.value,
|
|
67
|
+
height: sizeValue.value,
|
|
68
|
+
display: props.inline ? "inline-block" : "inline-block",
|
|
69
|
+
verticalAlign: props.inline ? "-0.125em" : "middle",
|
|
70
|
+
transform: transformStyle.value
|
|
71
|
+
}));
|
|
72
|
+
const cssClass = computed(() => {
|
|
73
|
+
const parsed = parseIconName(props.name);
|
|
74
|
+
if (!parsed) return props.className;
|
|
75
|
+
const baseClass = `i-${parsed.collection}-${parsed.icon}`;
|
|
76
|
+
return props.className ? `${baseClass} ${props.className}` : baseClass;
|
|
77
|
+
});
|
|
78
|
+
async function loadIconSvg() {
|
|
79
|
+
if (props.mode === "css") return;
|
|
80
|
+
isLoading.value = true;
|
|
81
|
+
hasError.value = false;
|
|
82
|
+
try {
|
|
83
|
+
let resolved = getIconSync(props.name);
|
|
84
|
+
if (!resolved) resolved = await getIcon(props.name);
|
|
85
|
+
if (!resolved && getIconConfig().fallbackToApi && getIconConfig().iconifyApiEnabled) {
|
|
86
|
+
const fetchedSvg = await fetchIconFromApi(props.name);
|
|
87
|
+
if (fetchedSvg) {
|
|
88
|
+
svgHtml.value = fetchedSvg;
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (resolved) {
|
|
93
|
+
const parsed = parseIconName(props.name);
|
|
94
|
+
let finalResolved = resolved;
|
|
95
|
+
if (parsed) {
|
|
96
|
+
const collection = getLoadedCollection(parsed.collection);
|
|
97
|
+
if (collection) finalResolved = resolveIconData(collection, parsed.icon) ?? resolved;
|
|
98
|
+
}
|
|
99
|
+
svgHtml.value = generateSvg(finalResolved, {
|
|
100
|
+
className: props.className || void 0,
|
|
101
|
+
ariaHidden: !props.ariaLabel,
|
|
102
|
+
ariaLabel: props.ariaLabel,
|
|
103
|
+
title: props.title
|
|
104
|
+
});
|
|
105
|
+
} else {
|
|
106
|
+
hasError.value = true;
|
|
107
|
+
svgHtml.value = "";
|
|
108
|
+
}
|
|
109
|
+
} catch {
|
|
110
|
+
hasError.value = true;
|
|
111
|
+
svgHtml.value = "";
|
|
112
|
+
} finally {
|
|
113
|
+
isLoading.value = false;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
watchEffect(() => {
|
|
117
|
+
loadIconSvg();
|
|
118
|
+
});
|
|
119
|
+
return () => {
|
|
120
|
+
if (props.mode === "css") return h("span", {
|
|
121
|
+
class: cssClass.value,
|
|
122
|
+
style: {
|
|
123
|
+
...sizeStyle.value,
|
|
124
|
+
color: props.color
|
|
125
|
+
},
|
|
126
|
+
"aria-hidden": props.ariaLabel ? void 0 : "true",
|
|
127
|
+
"aria-label": props.ariaLabel,
|
|
128
|
+
role: props.ariaLabel ? "img" : void 0
|
|
129
|
+
});
|
|
130
|
+
if (isLoading.value || hasError.value || !svgHtml.value) return h("span", {
|
|
131
|
+
class: props.className,
|
|
132
|
+
style: sizeStyle.value,
|
|
133
|
+
"aria-hidden": "true"
|
|
134
|
+
});
|
|
135
|
+
return h("span", {
|
|
136
|
+
class: props.className,
|
|
137
|
+
style: {
|
|
138
|
+
...sizeStyle.value,
|
|
139
|
+
color: props.color
|
|
140
|
+
},
|
|
141
|
+
innerHTML: svgHtml.value,
|
|
142
|
+
"aria-hidden": props.ariaLabel ? void 0 : "true",
|
|
143
|
+
"aria-label": props.ariaLabel,
|
|
144
|
+
role: props.ariaLabel ? "img" : void 0
|
|
145
|
+
});
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
function defineIconCollection(collection) {
|
|
150
|
+
registerCollection(collection);
|
|
151
|
+
return collection;
|
|
152
|
+
}
|
|
153
|
+
function defineIconCollectionLoader(prefix, loader) {
|
|
154
|
+
const loaderDef = {
|
|
155
|
+
prefix,
|
|
156
|
+
load: loader
|
|
157
|
+
};
|
|
158
|
+
registerCollectionLoader(loaderDef);
|
|
159
|
+
return loaderDef;
|
|
160
|
+
}
|
|
161
|
+
function useIcon(name) {
|
|
162
|
+
return {
|
|
163
|
+
getSvg: async () => {
|
|
164
|
+
const resolved = await getIcon(name);
|
|
165
|
+
if (resolved) return generateSvg(resolved);
|
|
166
|
+
if (getIconConfig().fallbackToApi) return fetchIconFromApi(name);
|
|
167
|
+
return null;
|
|
168
|
+
},
|
|
169
|
+
getSvgSync: () => {
|
|
170
|
+
const resolved = getIconSync(name);
|
|
171
|
+
return resolved ? generateSvg(resolved) : null;
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
//#endregion
|
|
176
|
+
export { Icon, Icon as default, addIconCollection, buildIconCssIcon, clearCollections, configureIconRuntime, createCollectionFromSvgMap, defineIconCollection, defineIconCollectionLoader, escapeHtml, fetchIconFromApi, generateSvg, getIcon, getIconConfig, getIconData, getIconSync, getLoadedCollection, listLoadedCollections, loadCollection, normalizeIconName, parseIconName, parseSvgToIconData, registerCollection, registerCollectionLoader, resolveIconData, scanVueSfcForIcons, ubeanIconPlugin, useIcon };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { a as IconifyIconData, i as IconifyCollection, n as IconCollectionLoader, s as ResolvedIconData } from "./types-CVT8GSd7.js";
|
|
2
|
+
//#region src/core.d.ts
|
|
3
|
+
declare function parseIconName(name: string): {
|
|
4
|
+
collection: string;
|
|
5
|
+
icon: string;
|
|
6
|
+
} | null;
|
|
7
|
+
declare function normalizeIconName(name: string): string;
|
|
8
|
+
declare function registerCollection(collection: IconifyCollection): void;
|
|
9
|
+
declare function registerCollectionLoader(loader: IconCollectionLoader): void;
|
|
10
|
+
declare function loadCollection(prefix: string): Promise<IconifyCollection | null>;
|
|
11
|
+
declare function getLoadedCollection(prefix: string): IconifyCollection | undefined;
|
|
12
|
+
declare function resolveAlias(collection: IconifyCollection, iconName: string, visited?: Set<string>): IconifyIconData | null;
|
|
13
|
+
declare function getIconData(collection: IconifyCollection, iconName: string): IconifyIconData | null;
|
|
14
|
+
declare function resolveIconData(collection: IconifyCollection, iconName: string, overrides?: Partial<Pick<IconifyIconData, 'width' | 'height' | 'rotate' | 'hFlip' | 'vFlip'>>): ResolvedIconData | null;
|
|
15
|
+
declare function generateSvg(resolved: ResolvedIconData, options?: {
|
|
16
|
+
className?: string;
|
|
17
|
+
style?: Record<string, string>;
|
|
18
|
+
ariaHidden?: boolean;
|
|
19
|
+
ariaLabel?: string;
|
|
20
|
+
title?: string;
|
|
21
|
+
}): string;
|
|
22
|
+
declare function escapeHtml(str: string): string;
|
|
23
|
+
declare function getIcon(name: string): Promise<ResolvedIconData | null>;
|
|
24
|
+
declare function getIconSync(name: string): ResolvedIconData | null;
|
|
25
|
+
declare function listLoadedCollections(): string[];
|
|
26
|
+
declare function clearCollections(): void;
|
|
27
|
+
declare function scanVueSfcForIcons(source: string): Set<string>;
|
|
28
|
+
declare function parseSvgToIconData(svg: string): IconifyIconData | null;
|
|
29
|
+
declare function createCollectionFromSvgMap(prefix: string, icons: Record<string, string>): IconifyCollection;
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region src/runtime.d.ts
|
|
32
|
+
declare let config: {
|
|
33
|
+
fallbackToApi: boolean;
|
|
34
|
+
iconApiEndpoint: string;
|
|
35
|
+
ssr: boolean;
|
|
36
|
+
iconifyApiEnabled: boolean;
|
|
37
|
+
};
|
|
38
|
+
declare function configureIconRuntime(options: Partial<typeof config>): void;
|
|
39
|
+
declare function getIconConfig(): {
|
|
40
|
+
fallbackToApi: boolean;
|
|
41
|
+
iconApiEndpoint: string;
|
|
42
|
+
ssr: boolean;
|
|
43
|
+
iconifyApiEnabled: boolean;
|
|
44
|
+
};
|
|
45
|
+
declare function fetchIconFromApi(name: string, apiEndpoint?: string): Promise<string | null>;
|
|
46
|
+
declare function buildIconCssIcon(name: string, options?: {
|
|
47
|
+
size?: string | number;
|
|
48
|
+
color?: string;
|
|
49
|
+
className?: string;
|
|
50
|
+
}): {
|
|
51
|
+
className: string;
|
|
52
|
+
style: string;
|
|
53
|
+
};
|
|
54
|
+
//#endregion
|
|
55
|
+
export { scanVueSfcForIcons as S, parseSvgToIconData as _, clearCollections as a, resolveAlias as b, generateSvg as c, getIconSync as d, getLoadedCollection as f, parseIconName as g, normalizeIconName as h, getIconConfig as i, getIcon as l, loadCollection as m, configureIconRuntime as n, createCollectionFromSvgMap as o, listLoadedCollections as p, fetchIconFromApi as r, escapeHtml as s, buildIconCssIcon as t, getIconData as u, registerCollection as v, resolveIconData as x, registerCollectionLoader as y };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { a as IconifyIconData, c as ScannedIconUsage, i as IconifyCollection, n as IconCollectionLoader, o as ResolvedCustomCollection, r as IconifyAlias, s as ResolvedIconData, t as CustomCollectionDirConfig } from "./types-CVT8GSd7.js";
|
|
2
|
+
import { S as scanVueSfcForIcons, _ as parseSvgToIconData, a as clearCollections, b as resolveAlias, c as generateSvg, d as getIconSync, f as getLoadedCollection, g as parseIconName, h as normalizeIconName, i as getIconConfig, l as getIcon, m as loadCollection, n as configureIconRuntime, o as createCollectionFromSvgMap, p as listLoadedCollections, r as fetchIconFromApi, s as escapeHtml, t as buildIconCssIcon, u as getIconData, v as registerCollection, x as resolveIconData, y as registerCollectionLoader } from "./runtime-Hp8OXvtC.js";
|
|
3
|
+
export { type CustomCollectionDirConfig, type IconCollectionLoader, type IconifyAlias, type IconifyCollection, type IconifyIconData, type ResolvedCustomCollection, type ResolvedIconData, type ScannedIconUsage, buildIconCssIcon, clearCollections, configureIconRuntime, createCollectionFromSvgMap, escapeHtml, fetchIconFromApi, generateSvg, getIcon, getIconConfig, getIconData, getIconSync, getLoadedCollection, listLoadedCollections, loadCollection, normalizeIconName, parseIconName, parseSvgToIconData, registerCollection, registerCollectionLoader, resolveAlias, resolveIconData, scanVueSfcForIcons };
|
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { _ as resolveIconData, a as getIcon, c as getLoadedCollection, d as normalizeIconName, f as parseIconName, g as resolveAlias, h as registerCollectionLoader, i as generateSvg, l as listLoadedCollections, m as registerCollection, n as createCollectionFromSvgMap, o as getIconData, p as parseSvgToIconData, r as escapeHtml, s as getIconSync, t as clearCollections, u as loadCollection, v as scanVueSfcForIcons } from "./core-NcYHbOE5.js";
|
|
2
|
+
//#region src/runtime.ts
|
|
3
|
+
let config = {
|
|
4
|
+
fallbackToApi: true,
|
|
5
|
+
iconApiEndpoint: "https://api.iconify.design",
|
|
6
|
+
ssr: true,
|
|
7
|
+
iconifyApiEnabled: true
|
|
8
|
+
};
|
|
9
|
+
function configureIconRuntime(options) {
|
|
10
|
+
config = {
|
|
11
|
+
...config,
|
|
12
|
+
...options
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function getIconConfig() {
|
|
16
|
+
return { ...config };
|
|
17
|
+
}
|
|
18
|
+
async function fetchIconFromApi(name, apiEndpoint = config.iconApiEndpoint) {
|
|
19
|
+
const parsed = parseIconName(name);
|
|
20
|
+
if (!parsed) return null;
|
|
21
|
+
try {
|
|
22
|
+
const url = `${apiEndpoint}/${parsed.collection}/${parsed.icon}.svg`;
|
|
23
|
+
const res = await fetch(url);
|
|
24
|
+
if (!res.ok) return null;
|
|
25
|
+
return await res.text();
|
|
26
|
+
} catch {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function buildIconCssIcon(name, options) {
|
|
31
|
+
const { size = "1em", color = "currentColor", className = "" } = options ?? {};
|
|
32
|
+
const parsed = parseIconName(name);
|
|
33
|
+
const baseClass = `i-${parsed?.collection || ""}-${parsed?.icon || name}`;
|
|
34
|
+
return {
|
|
35
|
+
className: className ? `${baseClass} ${className}` : baseClass,
|
|
36
|
+
style: `display:inline-block;width:${size};height:${size};color:${color};background-color:currentColor;mask-size:100% 100%;mask-repeat:no-repeat;mask-position:center;-webkit-mask-size:100% 100%;-webkit-mask-repeat:no-repeat;-webkit-mask-position:center;`
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
export { buildIconCssIcon, clearCollections, configureIconRuntime, createCollectionFromSvgMap, escapeHtml, fetchIconFromApi, generateSvg, getIcon, getIconConfig, getIconData, getIconSync, getLoadedCollection, listLoadedCollections, loadCollection, normalizeIconName, parseIconName, parseSvgToIconData, registerCollection, registerCollectionLoader, resolveAlias, resolveIconData, scanVueSfcForIcons };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
//#region src/types.d.ts
|
|
2
|
+
interface IconifyCollection {
|
|
3
|
+
prefix: string;
|
|
4
|
+
width?: number;
|
|
5
|
+
height?: number;
|
|
6
|
+
icons: Record<string, IconifyIconData>;
|
|
7
|
+
aliases?: Record<string, IconifyAlias>;
|
|
8
|
+
}
|
|
9
|
+
interface IconifyIconData {
|
|
10
|
+
body: string;
|
|
11
|
+
width?: number;
|
|
12
|
+
height?: number;
|
|
13
|
+
viewBox?: string;
|
|
14
|
+
rotate?: number;
|
|
15
|
+
hFlip?: boolean;
|
|
16
|
+
vFlip?: boolean;
|
|
17
|
+
}
|
|
18
|
+
interface IconifyAlias extends Partial<IconifyIconData> {
|
|
19
|
+
parent: string;
|
|
20
|
+
}
|
|
21
|
+
interface ResolvedIconData {
|
|
22
|
+
body: string;
|
|
23
|
+
width?: number;
|
|
24
|
+
height?: number;
|
|
25
|
+
viewBox?: string;
|
|
26
|
+
}
|
|
27
|
+
interface UbeanIconOptions {
|
|
28
|
+
collections?: Record<string, IconifyCollection | (() => Promise<IconifyCollection>)>;
|
|
29
|
+
customCollections?: Record<string, string | CustomCollectionDirConfig>;
|
|
30
|
+
fallbackToApi?: boolean;
|
|
31
|
+
iconApiEndpoint?: string;
|
|
32
|
+
ssr?: boolean;
|
|
33
|
+
cssSelectorPrefix?: string;
|
|
34
|
+
cssWherePseudo?: boolean;
|
|
35
|
+
iconifyApiEnabled?: boolean;
|
|
36
|
+
}
|
|
37
|
+
interface CustomCollectionDirConfig {
|
|
38
|
+
dir: string;
|
|
39
|
+
prefix?: string;
|
|
40
|
+
normalizeIconName?: (name: string) => string;
|
|
41
|
+
}
|
|
42
|
+
interface ResolvedCustomCollection {
|
|
43
|
+
prefix: string;
|
|
44
|
+
dir: string;
|
|
45
|
+
normalizeIconName: (name: string) => string;
|
|
46
|
+
}
|
|
47
|
+
interface IconCollectionLoader {
|
|
48
|
+
prefix: string;
|
|
49
|
+
load: () => Promise<IconifyCollection>;
|
|
50
|
+
}
|
|
51
|
+
interface ScannedIconUsage {
|
|
52
|
+
name: string;
|
|
53
|
+
collection: string;
|
|
54
|
+
icon: string;
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
57
|
+
export { IconifyIconData as a, ScannedIconUsage as c, IconifyCollection as i, UbeanIconOptions as l, IconCollectionLoader as n, ResolvedCustomCollection as o, IconifyAlias as r, ResolvedIconData as s, CustomCollectionDirConfig as t };
|