feat(web): add iconify tag icons for object classes

Replace the text class tag in the tree and inspector with one or more
MDI icons (hover shows the class name). Bundle only the used icons via
a generator script instead of the full set.
This commit is contained in:
2026-08-08 12:32:11 +08:00
parent 3b66e82b67
commit 4f37dabbe7
8 changed files with 235 additions and 4 deletions
+63
View File
@@ -0,0 +1,63 @@
// Generates apps/web/src/components/objectIcons.ts from the MDI icon set.
// Extracts only the icons referenced in ICON_NAMES so the bundle stays small,
// then registers them with Iconify's offline storage at import time.
import { readFileSync, writeFileSync, existsSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname, resolve } from 'node:path';
import { createRequire } from 'node:module';
const __dirname = dirname(fileURLToPath(import.meta.url));
// Resolve deps from apps/web, where the iconify packages are hoisted.
const webPkg = resolve(__dirname, '../apps/web/package.json');
const require = createRequire(webPkg);
// Resolve the mdi icons.json via the package entry (works from the pnpm store).
const mdiPkg = require.resolve('@iconify-json/mdi/icons.json');
const icons = JSON.parse(readFileSync(mdiPkg, 'utf8'));
const ICON_NAMES = [
'cards-outline',
'cards',
'bag-personal-outline',
'cube-outline',
'cube',
'circle-outline',
'image-outline',
'file-pdf-box',
'dice-6',
'chess-knight',
'table-large',
'help-circle-outline',
];
// Extract just the icons we need, keeping the set's prefix/dimensions.
const subset = {
prefix: icons.prefix,
width: icons.width,
height: icons.height,
icons: Object.fromEntries(
ICON_NAMES.filter((name) => icons.icons[name]).map((name) => [
name,
icons.icons[name],
]),
),
};
const missing = ICON_NAMES.filter((name) => !icons.icons[name]);
if (missing.length > 0) {
throw new Error(`Missing icons in mdi set: ${missing.join(', ')}`);
}
const out = resolve(__dirname, '../apps/web/src/components/objectIconsData.ts');
const body = `// Generated by scripts/generate-object-icons.mjs — do not edit by hand.
// Re-run \`node scripts/generate-object-icons.mjs\` after changing ICON_NAMES.
import { addCollection } from '@iconify/react';
const mdiSubset = ${JSON.stringify(subset, null, 2)};
addCollection(mdiSubset);
`;
writeFileSync(out, body);
console.log(`Wrote ${out} (${ICON_NAMES.length} icons)`);