Phosphor icons: resolve by name via a generated map (T-314)
Replace the 49 hand-maintained named consts with one generated
label→codepoint map (phosphor_glyphs.g.dart, 1512 glyphs from the glyph
table via tool/gen_phosphor_glyphs.dart). Feature code now references
glyphs by their exact kebab-case name — PhosphorIcons.byName('folder') —
with no raw codepoints; this also lets a Lua extension name an icon
without crossing the FFI boundary with a codepoint.
byName is total: an unknown name degrades to the `placeholder` box so the
bug is visible (it's a real error), while phosphor_glyphs_test asserts
every byName('...') literal in lib/ resolves — recovering the typo check a
const gave. Migrated the 89 call sites. Adds EmptyIconPainter for an
intentional blank that still reserves the icon box; ClideFilterBox gains
showIcon to keep the slot aligned when blank.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
// Regenerates lib/widgets/src/icons/phosphor_glyphs.g.dart from the Phosphor
|
||||
// glyph table. Run from the repo root:
|
||||
//
|
||||
// dart run tool/gen_phosphor_glyphs.dart
|
||||
//
|
||||
// Source of truth is the glyph table shipped with the ui-design skill — each
|
||||
// row is `| `0xNNNN` | kebab-name | PascalName | |`. We keep only the codepoint
|
||||
// + the exact kebab-case upstream name, which is what code references via
|
||||
// PhosphorIcons.byName('…'). No Flutter imports — plain Dart, runnable with
|
||||
// `dart run`.
|
||||
import 'dart:io';
|
||||
|
||||
const _src = '.claude/skills/ui-design/references/phosphor-glyphs.md';
|
||||
const _out = 'lib/widgets/src/icons/phosphor_glyphs.g.dart';
|
||||
|
||||
void main() {
|
||||
final rows = File(_src).readAsLinesSync();
|
||||
// `| `0xe24a` | folder | Folder | |`
|
||||
final re = RegExp(r'^\|\s*`(0x[0-9a-fA-F]+)`\s*\|\s*([a-z0-9-]+)\s*\|');
|
||||
final glyphs = <String, int>{};
|
||||
for (final line in rows) {
|
||||
final m = re.firstMatch(line);
|
||||
if (m == null) continue;
|
||||
final code = int.parse(m.group(1)!.substring(2), radix: 16);
|
||||
glyphs[m.group(2)!] = code;
|
||||
}
|
||||
if (glyphs.length < 1000) {
|
||||
stderr.writeln('refusing to write: only ${glyphs.length} glyphs parsed from $_src');
|
||||
exit(1);
|
||||
}
|
||||
final names = glyphs.keys.toList()..sort();
|
||||
final b = StringBuffer()
|
||||
..writeln('// GENERATED by tool/gen_phosphor_glyphs.dart — do not edit by hand.')
|
||||
..writeln('// Source: $_src (${glyphs.length} glyphs).')
|
||||
..writeln('//')
|
||||
..writeln('// The single label→codepoint lookup for the bundled Phosphor font. Code')
|
||||
..writeln('// references glyphs by their exact kebab-case name via PhosphorIcons.byName;')
|
||||
..writeln('// raw codepoints live only here.')
|
||||
..writeln('library;')
|
||||
..writeln()
|
||||
..writeln('const Map<String, int> kPhosphorGlyphs = {');
|
||||
for (final n in names) {
|
||||
b.writeln(" '$n': 0x${glyphs[n]!.toRadixString(16)},");
|
||||
}
|
||||
b.writeln('};');
|
||||
File(_out).writeAsStringSync(b.toString());
|
||||
stdout.writeln('wrote $_out with ${glyphs.length} glyphs');
|
||||
}
|
||||
Reference in New Issue
Block a user