diff --git a/frontend/src/lib/components/IconPicker.svelte b/frontend/src/lib/components/IconPicker.svelte new file mode 100644 index 0000000..b0714b8 --- /dev/null +++ b/frontend/src/lib/components/IconPicker.svelte @@ -0,0 +1,93 @@ + + + + +
+ +
+ +{#if open} +
{ open = false; search = ''; }}>
+ +
+ +
+ + {#each filtered() as iconName} + + {/each} +
+
+{/if} diff --git a/frontend/src/lib/components/MdiIcon.svelte b/frontend/src/lib/components/MdiIcon.svelte new file mode 100644 index 0000000..79ee0ca --- /dev/null +++ b/frontend/src/lib/components/MdiIcon.svelte @@ -0,0 +1,9 @@ + + +{#if name && getMdiPath(name)} + +{/if} diff --git a/frontend/src/lib/mdi-lookup.ts b/frontend/src/lib/mdi-lookup.ts new file mode 100644 index 0000000..277a795 --- /dev/null +++ b/frontend/src/lib/mdi-lookup.ts @@ -0,0 +1,36 @@ +/** + * Lazy MDI icon path lookup. + * + * Instead of `import * as mdi from '@mdi/js'` (which loads ~5MB of SVG paths + * into memory), this module loads the full set once on first use and caches it. + * Vite only processes the import once, reducing HMR memory pressure. + */ + +let _cache: Record | null = null; + +async function _load(): Promise> { + if (_cache) return _cache; + const mod = await import('@mdi/js'); + _cache = mod as unknown as Record; + return _cache; +} + +// Eagerly load on module init (runs once) +let _ready: Record | null = null; +_load().then(m => { _ready = m; }); + +/** + * Get SVG path for an icon name. Returns empty string if not found or not yet loaded. + */ +export function getMdiPath(name: string): string { + if (!name || !_ready) return ''; + return (_ready as any)[name] || ''; +} + +/** + * Get all icon names (for IconPicker search). Returns empty array if not yet loaded. + */ +export function getAllMdiNames(): string[] { + if (!_ready) return []; + return Object.keys(_ready).filter(k => k.startsWith('mdi') && k !== 'default'); +}