feat: improved icon search — matches Lucide tags/keywords

The icon picker now searches against the Lucide tags.json keyword list,
not just the icon name. Searching 'meeting' now finds 'calendar',
'red-heart' finds 'heart', etc. Tags are loaded alongside icon names
from the CDN with fallback.
This commit is contained in:
2026-06-10 20:19:57 -04:00
parent 3c4fc2d91c
commit 6978401613
2 changed files with 13 additions and 4 deletions
+3 -3
View File
File diff suppressed because one or more lines are too long
+10 -1
View File
@@ -1070,6 +1070,7 @@ class IconSuggestModal extends Modal {
private onSubmit: (icon: string) => void; private onSubmit: (icon: string) => void;
private selected: string; private selected: string;
private allIcons: string[] = []; private allIcons: string[] = [];
private tagsMap: Record<string, string[]> = {};
private loaded = false; private loaded = false;
constructor(app: App, currentIcon: string, onSubmit: (icon: string) => void) { constructor(app: App, currentIcon: string, onSubmit: (icon: string) => void) {
@@ -1165,7 +1166,12 @@ class IconSuggestModal extends Modal {
const q = query.toLowerCase().trim(); const q = query.toLowerCase().trim();
const matches = q const matches = q
? this.allIcons.filter(function(n) { return n.includes(q); }).slice(0, 80) ? this.allIcons.filter((n) => {
if (n.includes(q)) return true;
const tags = this.tagsMap[n];
if (tags) return tags.some(t => t.includes(q));
return false;
}).slice(0, 80)
: this.allIcons.slice(0, 80); : this.allIcons.slice(0, 80);
if (matches.length === 0) { if (matches.length === 0) {
@@ -1262,13 +1268,16 @@ class IconSuggestModal extends Modal {
try { try {
var r = await fetch('https://cdn.jsdelivr.net/npm/lucide-static@0.517.0/tags.json'); var r = await fetch('https://cdn.jsdelivr.net/npm/lucide-static@0.517.0/tags.json');
var d = await r.json(); var d = await r.json();
this.tagsMap = d as Record<string, string[]>;
this.allIcons = Object.keys(d).sort(); this.allIcons = Object.keys(d).sort();
} catch (_e) { } catch (_e) {
try { try {
var r2 = await fetch('https://lucide.dev/api/tags'); var r2 = await fetch('https://lucide.dev/api/tags');
var d2 = await r2.json(); var d2 = await r2.json();
this.tagsMap = d2 as Record<string, string[]>;
this.allIcons = Object.keys(d2).sort(); this.allIcons = Object.keys(d2).sort();
} catch (_e2) { } catch (_e2) {
this.tagsMap = {};
this.allIcons = Object.keys(FALLBACK_ICONS).sort(); this.allIcons = Object.keys(FALLBACK_ICONS).sort();
} }
} }