@robosophy/ui-vue 1.0.16 → 1.1.0
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/README.md +17 -27
- package/ai-context.md +1 -1
- package/components.md +17 -21
- package/dist/components/RsAccountSelector/RsAccountSelector.vue.d.ts +1 -1
- package/dist/components/RsIcon/RsIcon.vue.d.ts.map +1 -1
- package/dist/index.css +24 -107
- package/dist/index.js +36 -10
- package/dist/index.js.map +1 -1
- package/dist/plugin.d.ts +3 -3
- package/dist/vite.d.ts +1 -13
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +192 -179
- package/dist/vite.js.map +1 -1
- package/package.json +2 -8
package/dist/plugin.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export declare const components: readonly [{
|
|
|
15
15
|
open: () => any;
|
|
16
16
|
close: () => any;
|
|
17
17
|
}, import("vue").PublicProps, {
|
|
18
|
+
width: string;
|
|
18
19
|
accounts: import(".").RsAccountSelectorAccount[];
|
|
19
20
|
actions: import(".").RsAccountSelectorAction[];
|
|
20
21
|
footerActions: import(".").RsAccountSelectorAction[];
|
|
@@ -24,7 +25,6 @@ export declare const components: readonly [{
|
|
|
24
25
|
activeText: string;
|
|
25
26
|
selectText: string;
|
|
26
27
|
triggerAriaLabel: string;
|
|
27
|
-
width: string;
|
|
28
28
|
}, false, {}, {}, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, {}, any, import("vue").ComponentProvideOptions, {
|
|
29
29
|
P: {};
|
|
30
30
|
B: {};
|
|
@@ -40,6 +40,7 @@ export declare const components: readonly [{
|
|
|
40
40
|
onOpen?: (() => any) | undefined;
|
|
41
41
|
onClose?: (() => any) | undefined;
|
|
42
42
|
}>, {}, {}, {}, {}, {
|
|
43
|
+
width: string;
|
|
43
44
|
accounts: import(".").RsAccountSelectorAccount[];
|
|
44
45
|
actions: import(".").RsAccountSelectorAction[];
|
|
45
46
|
footerActions: import(".").RsAccountSelectorAction[];
|
|
@@ -49,7 +50,6 @@ export declare const components: readonly [{
|
|
|
49
50
|
activeText: string;
|
|
50
51
|
selectText: string;
|
|
51
52
|
triggerAriaLabel: string;
|
|
52
|
-
width: string;
|
|
53
53
|
}>;
|
|
54
54
|
__isFragment?: never;
|
|
55
55
|
__isTeleport?: never;
|
|
@@ -69,6 +69,7 @@ export declare const components: readonly [{
|
|
|
69
69
|
open: () => any;
|
|
70
70
|
close: () => any;
|
|
71
71
|
}, string, {
|
|
72
|
+
width: string;
|
|
72
73
|
accounts: import(".").RsAccountSelectorAccount[];
|
|
73
74
|
actions: import(".").RsAccountSelectorAction[];
|
|
74
75
|
footerActions: import(".").RsAccountSelectorAction[];
|
|
@@ -78,7 +79,6 @@ export declare const components: readonly [{
|
|
|
78
79
|
activeText: string;
|
|
79
80
|
selectText: string;
|
|
80
81
|
triggerAriaLabel: string;
|
|
81
|
-
width: string;
|
|
82
82
|
}, {}, string, {}, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, import("vue").ComponentProvideOptions> & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps & (new () => {
|
|
83
83
|
$slots: {
|
|
84
84
|
'trigger-avatar'?: (props: {
|
package/dist/vite.d.ts
CHANGED
|
@@ -15,21 +15,9 @@ export type RobosophyMaterialSymbolsOptions = {
|
|
|
15
15
|
scan?: boolean;
|
|
16
16
|
};
|
|
17
17
|
type IconUsageMap = Map<RsIconFamily, Set<string>>;
|
|
18
|
-
type MaterialSymbolsLinkAssets = {
|
|
19
|
-
cssHref: string;
|
|
20
|
-
fonts: Pick<GeneratedFontAsset, "href">[];
|
|
21
|
-
};
|
|
22
18
|
export declare function robosophyMaterialSymbols(options?: RobosophyMaterialSymbolsOptions): Plugin;
|
|
23
|
-
type GeneratedFontAsset = {
|
|
24
|
-
family: RsIconFamily;
|
|
25
|
-
fileName: string;
|
|
26
|
-
href: string;
|
|
27
|
-
source: Buffer;
|
|
28
|
-
};
|
|
29
19
|
export declare function collectMaterialSymbolUsages(config: Pick<ResolvedConfig, "root">, options?: RobosophyMaterialSymbolsOptions): Promise<IconUsageMap>;
|
|
30
|
-
export declare function buildMaterialSymbolsCss(
|
|
31
|
-
export declare function buildMaterialSymbolsHtmlTags(assets: MaterialSymbolsLinkAssets, options?: Pick<RobosophyMaterialSymbolsOptions, "preload">): HtmlTagDescriptor[];
|
|
32
|
-
export declare function injectMaterialSymbolsHtmlLinks(html: string, assets: MaterialSymbolsLinkAssets, options?: Pick<RobosophyMaterialSymbolsOptions, "preload">): string;
|
|
20
|
+
export declare function buildMaterialSymbolsCss(iconClasses: string): HtmlTagDescriptor[];
|
|
33
21
|
export declare function formatDetectedMaterialSymbols(usages: IconUsageMap): string;
|
|
34
22
|
export {};
|
|
35
23
|
//# sourceMappingURL=vite.d.ts.map
|
package/dist/vite.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite.d.ts","sourceRoot":"","sources":["../src/vite.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vite.d.ts","sourceRoot":"","sources":["../src/vite.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAA4B,MAAM,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAEhG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,KAAK,SAAS,GAAG,MAAM,GAAG;IAAE,MAAM,CAAC,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAClE,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,CAAC;AAE3E,MAAM,MAAM,+BAA+B,GAAG;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,KAAK,YAAY,GAAG,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AAyBnD,wBAAgB,wBAAwB,CACtC,OAAO,GAAE,+BAAoC,GAC5C,MAAM,CAsHR;AAqLD,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,EACpC,OAAO,GAAE,+BAAoC,GAC5C,OAAO,CAAC,YAAY,CAAC,CAmCvB;AAED,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,GAClB,iBAAiB,EAAE,CAUrB;AAuKD,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAI1E"}
|
package/dist/vite.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import { readFile, readdir } from "node:fs/promises";
|
|
3
|
-
import { join, extname
|
|
4
|
-
import { createRequire } from "node:module";
|
|
2
|
+
import { readFile, mkdir, readdir, writeFile } from "node:fs/promises";
|
|
3
|
+
import { join, extname } from "node:path";
|
|
5
4
|
import { fileURLToPath } from "node:url";
|
|
6
5
|
const families = ["outlined", "rounded", "sharp"];
|
|
7
6
|
const defaultFamily = "outlined";
|
|
@@ -17,45 +16,76 @@ const internalIconNames = [
|
|
|
17
16
|
"login",
|
|
18
17
|
"nest_eco_leaf"
|
|
19
18
|
];
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
25
|
-
const familyPackages = {
|
|
26
|
-
outlined: "@fontsource-variable/material-symbols-outlined",
|
|
27
|
-
rounded: "@fontsource-variable/material-symbols-rounded",
|
|
28
|
-
sharp: "@fontsource-variable/material-symbols-sharp"
|
|
29
|
-
};
|
|
30
|
-
const defaultFontDisplay = "swap";
|
|
31
|
-
const defaultPreload = false;
|
|
32
|
-
const require$1 = createRequire(import.meta.url);
|
|
19
|
+
const GITHUB_RAW = "https://raw.githubusercontent.com/google/material-design-icons/master/symbols/web";
|
|
20
|
+
const CACHE_BASE = join("node_modules", ".cache", "robosophy-svgs");
|
|
21
|
+
const BASE_OPSZ = 24;
|
|
22
|
+
const GRADE_VARIANTS = [0, -25, 200];
|
|
33
23
|
function robosophyMaterialSymbols(options = {}) {
|
|
34
24
|
const raw = (options.outputDir ?? "").trim().replace(/^\/+/, "");
|
|
35
25
|
const outputDir = raw.split("/").filter((part) => part && part !== "..").join("/") || "assets";
|
|
36
|
-
const fontVariant = options.fontVariant ?? "full";
|
|
37
26
|
let config;
|
|
27
|
+
let cacheDir;
|
|
38
28
|
let cachedAssets = null;
|
|
39
|
-
let
|
|
29
|
+
let cachedUsagesKey = "";
|
|
30
|
+
let needsRegeneration = true;
|
|
31
|
+
function usageMapKey(usages) {
|
|
32
|
+
const parts = [];
|
|
33
|
+
for (const family of families) {
|
|
34
|
+
const names = [...usages.get(family) ?? []].sort();
|
|
35
|
+
if (names.length > 0) {
|
|
36
|
+
parts.push(`${family}:${names.join(",")}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return parts.join("|") || "(empty)";
|
|
40
|
+
}
|
|
40
41
|
async function getAssets() {
|
|
41
|
-
if (
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
if (!needsRegeneration && cachedAssets) return cachedAssets;
|
|
43
|
+
const usages = await collectMaterialSymbolUsages(config, options);
|
|
44
|
+
const newKey = usageMapKey(usages);
|
|
45
|
+
if (newKey === cachedUsagesKey && cachedAssets) {
|
|
46
|
+
needsRegeneration = false;
|
|
47
|
+
return cachedAssets;
|
|
48
|
+
}
|
|
49
|
+
if (config.command !== "build" && cachedUsagesKey !== "") {
|
|
50
|
+
config.logger.info(
|
|
51
|
+
"[robosophy-material-symbols] icon usage changed, regenerating SVG sprite"
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
cachedUsagesKey = newKey;
|
|
55
|
+
cachedAssets = await ensureGeneratedAssets(config, options, cacheDir);
|
|
56
|
+
needsRegeneration = false;
|
|
44
57
|
return cachedAssets;
|
|
45
58
|
}
|
|
46
59
|
return {
|
|
47
60
|
name: "robosophy-material-symbols",
|
|
48
61
|
async configResolved(resolvedConfig) {
|
|
49
62
|
config = resolvedConfig;
|
|
63
|
+
cacheDir = join(config.root, CACHE_BASE);
|
|
64
|
+
await mkdir(cacheDir, { recursive: true });
|
|
65
|
+
},
|
|
66
|
+
async buildStart() {
|
|
67
|
+
if (config.command === "serve" || config.command === "build") {
|
|
68
|
+
await getAssets();
|
|
69
|
+
}
|
|
50
70
|
},
|
|
51
71
|
async transformIndexHtml() {
|
|
52
72
|
const assets = await getAssets();
|
|
53
|
-
|
|
73
|
+
const tag = {
|
|
74
|
+
tag: "svg",
|
|
75
|
+
attrs: {
|
|
76
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
77
|
+
style: "display:none;",
|
|
78
|
+
"aria-hidden": "true"
|
|
79
|
+
},
|
|
80
|
+
children: assets.spriteContent,
|
|
81
|
+
injectTo: "body-prepend"
|
|
82
|
+
};
|
|
83
|
+
return [tag, ...buildMaterialSymbolsCss(assets.css)];
|
|
54
84
|
},
|
|
55
85
|
configureServer(server) {
|
|
56
86
|
server.watcher.on("all", (_event, file) => {
|
|
57
87
|
if (sourceExtensions.has(extname(file))) {
|
|
58
|
-
|
|
88
|
+
needsRegeneration = true;
|
|
59
89
|
}
|
|
60
90
|
});
|
|
61
91
|
server.middlewares.use(async (request, response, next) => {
|
|
@@ -68,15 +98,10 @@ function robosophyMaterialSymbols(options = {}) {
|
|
|
68
98
|
const fileName = decodeURIComponent(
|
|
69
99
|
request.url.replace("/@robosophy-material-symbols/", "").split("?")[0] ?? ""
|
|
70
100
|
);
|
|
71
|
-
if (fileName === "rs-material-symbols.
|
|
72
|
-
response.setHeader("Content-Type", "
|
|
73
|
-
response.
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
const font = assets.fonts.find((asset) => asset.fileName === fileName);
|
|
77
|
-
if (font) {
|
|
78
|
-
response.setHeader("Content-Type", "font/woff2");
|
|
79
|
-
response.end(font.source);
|
|
101
|
+
if (fileName === "rs-material-symbols.svg") {
|
|
102
|
+
response.setHeader("Content-Type", "image/svg+xml; charset=utf-8");
|
|
103
|
+
response.setHeader("Cache-Control", "no-cache");
|
|
104
|
+
response.end(assets.fullSprite);
|
|
80
105
|
return;
|
|
81
106
|
}
|
|
82
107
|
next();
|
|
@@ -85,58 +110,144 @@ function robosophyMaterialSymbols(options = {}) {
|
|
|
85
110
|
}
|
|
86
111
|
});
|
|
87
112
|
},
|
|
88
|
-
async generateBundle(_outputOptions
|
|
113
|
+
async generateBundle(_outputOptions) {
|
|
89
114
|
const assets = await getAssets();
|
|
90
|
-
|
|
115
|
+
if (assets.fullSprite) {
|
|
91
116
|
this.emitFile({
|
|
92
|
-
fileName: `${outputDir}
|
|
93
|
-
name:
|
|
94
|
-
source:
|
|
117
|
+
fileName: `${outputDir}/rs-material-symbols.svg`,
|
|
118
|
+
name: "rs-material-symbols.svg",
|
|
119
|
+
source: assets.fullSprite,
|
|
95
120
|
type: "asset"
|
|
96
121
|
});
|
|
97
122
|
}
|
|
98
|
-
this.emitFile({
|
|
99
|
-
fileName: `${outputDir}/rs-material-symbols.css`,
|
|
100
|
-
name: "rs-material-symbols.css",
|
|
101
|
-
source: assets.css,
|
|
102
|
-
type: "asset"
|
|
103
|
-
});
|
|
104
123
|
}
|
|
105
124
|
};
|
|
106
125
|
}
|
|
107
|
-
|
|
108
|
-
const
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
${
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
126
|
+
function buildSvgVariants() {
|
|
127
|
+
const variants = [];
|
|
128
|
+
for (const grade of GRADE_VARIANTS) {
|
|
129
|
+
const gradeSuffix = grade === 0 ? "" : grade > 0 ? `grad${grade}` : `gradN${Math.abs(grade)}`;
|
|
130
|
+
const symbolGradeSuffix = grade === 0 ? "" : `-${gradeSuffix}`;
|
|
131
|
+
for (const fill of [false, true]) {
|
|
132
|
+
const fillSuffix = fill ? "fill1" : "";
|
|
133
|
+
const symbolFillSuffix = fill ? "-fill" : "";
|
|
134
|
+
const parts = [gradeSuffix, fillSuffix].filter(Boolean);
|
|
135
|
+
variants.push({
|
|
136
|
+
suffix: parts.length > 0 ? `${parts.join("")}_${BASE_OPSZ}px` : `${BASE_OPSZ}px`,
|
|
137
|
+
symbolSuffix: `${symbolGradeSuffix}${symbolFillSuffix}`
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return variants;
|
|
142
|
+
}
|
|
143
|
+
function buildSvgUrl(name, family, suffix) {
|
|
144
|
+
const style = family === "outlined" ? "materialsymbolsoutlined" : family === "rounded" ? "materialsymbolsrounded" : "materialsymbolssharp";
|
|
145
|
+
return `${GITHUB_RAW}/${name.toLowerCase()}/${style}/${name.toLowerCase()}_${suffix}.svg`;
|
|
146
|
+
}
|
|
147
|
+
function buildSymbolId(name, family, symbolSuffix) {
|
|
148
|
+
return `rs-icon-${family}-${name}${symbolSuffix}`;
|
|
149
|
+
}
|
|
150
|
+
async function fetchSvg(url) {
|
|
151
|
+
try {
|
|
152
|
+
const response = await fetch(url);
|
|
153
|
+
if (!response.ok) return null;
|
|
154
|
+
return await response.text();
|
|
155
|
+
} catch {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
async function loadSvgFromCache(cacheDir, cacheKey) {
|
|
160
|
+
const cachePath = join(cacheDir, `${cacheKey}.svg`);
|
|
161
|
+
try {
|
|
162
|
+
return await readFile(cachePath, "utf8");
|
|
163
|
+
} catch {
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
async function saveSvgToCache(cacheDir, cacheKey, content) {
|
|
168
|
+
const cachePath = join(cacheDir, `${cacheKey}.svg`);
|
|
169
|
+
try {
|
|
170
|
+
await writeFile(cachePath, content, "utf8");
|
|
171
|
+
} catch {
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function parseSvgPaths(svgContent) {
|
|
175
|
+
const viewBoxMatch = svgContent.match(/viewBox="([^"]+)"/i);
|
|
176
|
+
if (!viewBoxMatch) return null;
|
|
177
|
+
const paths = [];
|
|
178
|
+
const pathRegex = /<path\s+([^>]*)>/g;
|
|
179
|
+
let pathMatch;
|
|
180
|
+
while (pathMatch = pathRegex.exec(svgContent)) {
|
|
181
|
+
const attrs = pathMatch[1] ?? "";
|
|
182
|
+
const dMatch = attrs.match(/d="([^"]*)"/);
|
|
183
|
+
if (dMatch) {
|
|
184
|
+
paths.push(dMatch[1] ?? "");
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (paths.length === 0) return null;
|
|
188
|
+
return paths.map((d) => `<path fill="currentColor" d="${d}"/>`).join("");
|
|
189
|
+
}
|
|
190
|
+
async function generateSpriteAssets(usages, cacheDir, config) {
|
|
191
|
+
const symbols = [];
|
|
192
|
+
const iconClasses = [];
|
|
193
|
+
const variants = buildSvgVariants();
|
|
194
|
+
let totalFetched = 0;
|
|
195
|
+
let totalBytes = 0;
|
|
196
|
+
for (const family of families) {
|
|
197
|
+
const names = [...usages.get(family) ?? []].sort();
|
|
198
|
+
if (names.length === 0) continue;
|
|
199
|
+
for (const name of names) {
|
|
200
|
+
for (const variant of variants) {
|
|
201
|
+
const symbolId = buildSymbolId(name, family, variant.symbolSuffix);
|
|
202
|
+
const url = buildSvgUrl(name, family, variant.suffix);
|
|
203
|
+
const cacheKey = createHash("sha256").update(url).digest("hex").slice(0, 12);
|
|
204
|
+
let svgContent = cacheDir ? await loadSvgFromCache(cacheDir, cacheKey) : null;
|
|
205
|
+
if (!svgContent) {
|
|
206
|
+
svgContent = await fetchSvg(url);
|
|
207
|
+
if (!svgContent) continue;
|
|
208
|
+
if (cacheDir) {
|
|
209
|
+
await saveSvgToCache(cacheDir, cacheKey, svgContent);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
const pathContent = parseSvgPaths(svgContent);
|
|
213
|
+
if (!pathContent) continue;
|
|
214
|
+
symbols.push(
|
|
215
|
+
`<symbol id="${symbolId}" viewBox="0 -960 960 960" fill="currentColor">${pathContent}</symbol>`
|
|
216
|
+
);
|
|
217
|
+
totalFetched++;
|
|
218
|
+
totalBytes += svgContent.length;
|
|
122
219
|
}
|
|
123
|
-
} else {
|
|
124
|
-
config.logger.warn(
|
|
125
|
-
"[robosophy-material-symbols] No Material Symbols icons detected in source. Add them via the include option."
|
|
126
|
-
);
|
|
127
220
|
}
|
|
128
221
|
}
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}
|
|
222
|
+
const iconNames = /* @__PURE__ */ new Set();
|
|
223
|
+
for (const family of families) {
|
|
224
|
+
for (const name of usages.get(family) ?? []) {
|
|
225
|
+
iconNames.add(name);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
for (const name of [...iconNames].sort()) {
|
|
229
|
+
iconClasses.push(`.rs-icon-${name} { --rs-icon-content: "${name}"; }`);
|
|
230
|
+
}
|
|
231
|
+
const spriteContent = `<defs>${symbols.join("")}</defs>`;
|
|
232
|
+
const fullSprite = `<svg xmlns="http://www.w3.org/2000/svg" style="display:none" aria-hidden="true">${spriteContent}</svg>`;
|
|
233
|
+
const css = iconClasses.join("\n");
|
|
234
|
+
const totalIcons = [...usages.values()].reduce((sum, s) => sum + s.size, 0);
|
|
235
|
+
if (totalIcons > 0) {
|
|
236
|
+
const summary = formatDetectedMaterialSymbols(usages);
|
|
237
|
+
config.logger.info(
|
|
238
|
+
`[robosophy-material-symbols] ${totalIcons} icons detected, ${totalFetched} SVG variants (${(totalBytes / 1024).toFixed(1)} KB)
|
|
239
|
+
${summary}`
|
|
240
|
+
);
|
|
241
|
+
} else {
|
|
242
|
+
config.logger.warn(
|
|
243
|
+
"[robosophy-material-symbols] No Material Symbols icons detected in source. Add them via the include option."
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
return { fullSprite, spriteContent, css };
|
|
247
|
+
}
|
|
248
|
+
async function ensureGeneratedAssets(config, options, cacheDir) {
|
|
249
|
+
const usages = await collectMaterialSymbolUsages(config, options);
|
|
250
|
+
return generateSpriteAssets(usages, cacheDir, config);
|
|
140
251
|
}
|
|
141
252
|
async function collectMaterialSymbolUsages(config, options = {}) {
|
|
142
253
|
const usages = createUsageMap();
|
|
@@ -168,107 +279,15 @@ async function collectMaterialSymbolUsages(config, options = {}) {
|
|
|
168
279
|
}
|
|
169
280
|
return usages;
|
|
170
281
|
}
|
|
171
|
-
function buildMaterialSymbolsCss(
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
` font-display: ${fontDisplay};`,
|
|
179
|
-
" font-style: normal;",
|
|
180
|
-
" font-weight: 100 700;",
|
|
181
|
-
` src: url("${fontUrl}") format("woff2-variations");`,
|
|
182
|
-
"}"
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
lines.push(
|
|
186
|
-
`.rs-icon--rounded { font-family: "${familyFontNames.rounded}"; }`,
|
|
187
|
-
`.rs-icon--sharp { font-family: "${familyFontNames.sharp}"; }`,
|
|
188
|
-
".rs-icon--prime::before { content: var(--rs-icon-content); }"
|
|
189
|
-
);
|
|
190
|
-
const names = /* @__PURE__ */ new Set();
|
|
191
|
-
for (const family of families) {
|
|
192
|
-
for (const name of usages.get(family) ?? []) {
|
|
193
|
-
names.add(name);
|
|
282
|
+
function buildMaterialSymbolsCss(iconClasses) {
|
|
283
|
+
if (!iconClasses) return [];
|
|
284
|
+
return [
|
|
285
|
+
{
|
|
286
|
+
tag: "style",
|
|
287
|
+
children: iconClasses,
|
|
288
|
+
injectTo: "head"
|
|
194
289
|
}
|
|
195
|
-
|
|
196
|
-
for (const name of [...names].sort()) {
|
|
197
|
-
lines.push(`.rs-icon-${name} { --rs-icon-content: "${name}"; }`);
|
|
198
|
-
}
|
|
199
|
-
return `${lines.join("\n")}
|
|
200
|
-
`;
|
|
201
|
-
}
|
|
202
|
-
function buildMaterialSymbolsHtmlTags(assets, options = {}) {
|
|
203
|
-
const tags = [];
|
|
204
|
-
if (options.preload ?? defaultPreload) {
|
|
205
|
-
for (const font of assets.fonts) {
|
|
206
|
-
tags.push({
|
|
207
|
-
attrs: {
|
|
208
|
-
as: "font",
|
|
209
|
-
crossorigin: "",
|
|
210
|
-
href: font.href,
|
|
211
|
-
rel: "preload",
|
|
212
|
-
type: "font/woff2"
|
|
213
|
-
},
|
|
214
|
-
tag: "link",
|
|
215
|
-
injectTo: "head"
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
tags.push({
|
|
220
|
-
attrs: {
|
|
221
|
-
href: assets.cssHref,
|
|
222
|
-
rel: "stylesheet"
|
|
223
|
-
},
|
|
224
|
-
tag: "link",
|
|
225
|
-
injectTo: "head"
|
|
226
|
-
});
|
|
227
|
-
return tags;
|
|
228
|
-
}
|
|
229
|
-
function injectMaterialSymbolsHtmlLinks(html, assets, options = {}) {
|
|
230
|
-
const links = buildMaterialSymbolsHtmlTags(assets, options).map(formatHtmlLinkTag).filter((link) => !html.includes(`href="${getLinkHref(link)}"`));
|
|
231
|
-
return links.length === 0 ? html : html.replace("</head>", `${links.map((link) => ` ${link}`).join("\n")}
|
|
232
|
-
</head>`);
|
|
233
|
-
}
|
|
234
|
-
async function generateFontAssets(usages, devMode, base, outputDir, fontVariant) {
|
|
235
|
-
const subsetFont = (await import("subset-font")).default;
|
|
236
|
-
const fonts = [];
|
|
237
|
-
for (const family of families) {
|
|
238
|
-
const names = [...usages.get(family) ?? []].sort();
|
|
239
|
-
if (names.length === 0) {
|
|
240
|
-
continue;
|
|
241
|
-
}
|
|
242
|
-
const sourcePath = resolveFontPath(family, fontVariant);
|
|
243
|
-
const source = await readFile(sourcePath);
|
|
244
|
-
const subset = await subsetFont(source, names.join(" "), {
|
|
245
|
-
targetFormat: "woff2"
|
|
246
|
-
});
|
|
247
|
-
const hash = createHash("sha256").update(subset).digest("hex").slice(0, 8);
|
|
248
|
-
const fileName = `rs-material-symbols-${family}-${hash}.woff2`;
|
|
249
|
-
fonts.push({
|
|
250
|
-
family,
|
|
251
|
-
fileName,
|
|
252
|
-
href: fontHref(fileName, devMode, base, outputDir),
|
|
253
|
-
source: subset
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
return fonts;
|
|
257
|
-
}
|
|
258
|
-
function resolveFontPath(family, variant) {
|
|
259
|
-
return require$1.resolve(
|
|
260
|
-
`${familyPackages[family]}/files/material-symbols-${family}-latin-${variant}-normal.woff2`
|
|
261
|
-
);
|
|
262
|
-
}
|
|
263
|
-
function fontHref(fileName, devMode, base, outputDir) {
|
|
264
|
-
return devMode ? `/@robosophy-material-symbols/${fileName}` : withBase(base, `${outputDir}/${fileName}`);
|
|
265
|
-
}
|
|
266
|
-
function formatHtmlLinkTag(tag) {
|
|
267
|
-
const attrs = Object.entries(tag.attrs ?? {}).map(([name, value]) => value === "" ? name : `${name}="${value}"`).join(" ");
|
|
268
|
-
return `<${tag.tag}${attrs ? ` ${attrs}` : ""}>`;
|
|
269
|
-
}
|
|
270
|
-
function getLinkHref(link) {
|
|
271
|
-
return link.match(/\bhref="([^"]+)"/)?.[1] ?? "";
|
|
290
|
+
];
|
|
272
291
|
}
|
|
273
292
|
function collectFromSource(source, usages) {
|
|
274
293
|
const rsIconTagPattern = /<RsIcon\b([^>]*)>/g;
|
|
@@ -395,19 +414,13 @@ async function listSourceFiles(root) {
|
|
|
395
414
|
return [];
|
|
396
415
|
}
|
|
397
416
|
}
|
|
398
|
-
function withBase(base, path) {
|
|
399
|
-
const cleanBase = base.endsWith("/") ? base : `${base}/`;
|
|
400
|
-
return `${cleanBase}${path}`.replaceAll(`${sep}`, "/");
|
|
401
|
-
}
|
|
402
417
|
function formatDetectedMaterialSymbols(usages) {
|
|
403
418
|
return families.map((family) => `${family}: ${[...usages.get(family) ?? []].sort().join(", ")}`).join("\n");
|
|
404
419
|
}
|
|
405
420
|
export {
|
|
406
421
|
buildMaterialSymbolsCss,
|
|
407
|
-
buildMaterialSymbolsHtmlTags,
|
|
408
422
|
collectMaterialSymbolUsages,
|
|
409
423
|
formatDetectedMaterialSymbols,
|
|
410
|
-
injectMaterialSymbolsHtmlLinks,
|
|
411
424
|
robosophyMaterialSymbols
|
|
412
425
|
};
|
|
413
426
|
//# sourceMappingURL=vite.js.map
|