feat(icons): upgrade from Material Icons to Material Symbols

- Replace legacy Material Icons (2,008 icons) with Material Symbols (3,798 icons)
- Adds missing icons reported in issue #6079: robot_2, manufacturing, cognition, cognition_2, neurology
- Update font: MaterialIcons-Regular.ttf (349KB) -> material-symbols-outlined.woff2 (456KB)
- Update icon names constant with 1,790 additional icons (+89% increase)
- Create extraction script for future icon updates
- Configure filled style to match previous appearance

Resolves #6079
This commit is contained in:
Johannes Millan 2026-01-21 15:13:09 +01:00
parent 01f8c6cd5f
commit 709e688d6d
5 changed files with 2127 additions and 284 deletions

File diff suppressed because it is too large Load diff

View file

@ -13,10 +13,14 @@
}
.material-icons {
font-family: 'Material Symbols Outlined';
font-family: 'Material Symbols Outlined', sans-serif;
@include material-icon.materialIconBase();
// Set default font variation settings for consistent appearance
// FILL: 0 (outlined), wght: 400 (normal), GRAD: 0 (default), opsz: 24 (24px)
font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
// FILL: 1 (filled), wght: 400 (normal), GRAD: 0 (default), opsz: 24 (24px)
font-variation-settings:
'FILL' 1,
'wght' 400,
'GRAD' 0,
'opsz' 24;
}

View file

@ -1,5 +1,5 @@
@mixin materialIconBase() {
font-family: 'Material Icons';
font-family: 'Material Symbols Outlined', sans-serif;
font-weight: normal;
font-style: normal;
font-size: 24px; /* Preferred icon size */

View file

@ -0,0 +1,48 @@
const fs = require('fs');
const path = require('path');
// Read TypeScript definitions from node_modules
const defsPath = path.join(
__dirname,
'../node_modules/@material-symbols/font-400/index.d.ts',
);
const defsContent = fs.readFileSync(defsPath, 'utf8');
// Extract icon names from the TypeScript array type
// The file contains: type MaterialSymbols = ["icon1", "icon2", ...]
const iconNames = [];
const lines = defsContent.split('\n');
for (const line of lines) {
const trimmed = line.trim();
// Match lines like: "icon_name",
const match = trimmed.match(/^"([^"]+)",?$/);
if (match) {
iconNames.push(match[1]);
}
}
// Sort alphabetically
iconNames.sort();
// Write to TypeScript constant file
const output = `export const MATERIAL_ICONS: string[] = [\n${iconNames.map((name) => ` '${name}',`).join('\n')}\n];\n`;
const outputPath = path.join(__dirname, '../src/app/ui/material-icons.const.ts');
fs.writeFileSync(outputPath, output);
console.log(`✓ Generated ${iconNames.length} Material Symbols icon names`);
// Verify specific icons mentioned in issue #6079 are present
const missingIcons = [
'robot_2',
'manufacturing',
'cognition',
'cognition_2',
'neurology',
];
const found = missingIcons.filter((icon) => iconNames.includes(icon));
const notFound = missingIcons.filter((icon) => !iconNames.includes(icon));
console.log(`\nVerification of issue #6079 icons:`);
found.forEach((icon) => console.log(`${icon} - FOUND`));
notFound.forEach((icon) => console.log(`${icon} - NOT FOUND`));