Skip to Content
FrontendBundlesIconsSearch in IconDropdown

Search in IconDropdown

This page explains how IconDropdown.tsx actually uses the keywords.json files described in Keywords & Translations — from import, to attaching keywords to each icon, to matching what the user types.

Generating keywords.json files does nothing on its own. Every icon set needs to be explicitly wired into IconDropdown.tsx for its keywords to actually be searchable — this page covers that wiring.

1. The keywords field on IconOption

Every icon in the dropdown is an IconOption. It has one new, optional field:

interface IconOption { value: string; label: string; displayLabel: string; iconUrl: string; keywords?: string[]; // extra search terms - not shown in the UI }

Optional on purpose: an icon set that hasn’t been covered yet (or an icon with no matching word/override) simply has keywords: undefined, and search silently falls back to matching on label only — exactly like before this feature existed.

2. The single filter function: matchesSearch

Before this feature, the filter logic (label.toLowerCase().includes(term)) was duplicated in three places in the file. It’s now one function, used everywhere:

const matchesSearch = (icon: IconOption, term: string): boolean => { const lower = term.toLowerCase(); if (icon.label.toLowerCase().includes(lower)) return true; return icon.keywords?.some((kw) => kw.toLowerCase().includes(lower)) ?? false; };

An icon matches if the typed term is found in its technical label, OR in any of its keywords.

3. Wiring per icon library — 4 different key formats

Each icon library stores its mapping.json keys a bit differently, so each one attaches keywords a bit differently too. All four end up doing the same thing conceptually: look up the icon’s key in the imported keywords object, attach the result.

LibraryIcon key exampleHow keywords is looked up
font-awesome"fa fa-adjust"iconsFontAwesomeKeywords[name] — direct
glyphicons-v1"glyphicons glyphicons-user-add"v1KeywordSets[prefix]?.[name] — one keyword file per sub-library (basic, halflings, filetypes, socials), picked by prefix
glyphicons-v2"glyphicons-v2/halflings verify-check"v2KeywordSets[prefix]?.[name] — same idea, prefix is "glyphicons-v2/basic" etc.
phpc"phpc/favicons/admin admin-16-ico"phpcKeywords[key]direct, see below

Why phpc is different: one combined file instead of 46

phpc has 46 separate keywords.json files (one per icon subfolder). Importing all 46 in this component would mean 46 import statements. Instead, script/generate-keywords.py combines them at generation time into a single icons/phpc/keywords-with-filepath.json, keyed exactly like icons/phpc/mapping-with-filepath.json already is ("phpc/favicons/admin admin-16-ico"). That means:

import iconsPHPCKeywords from "../../icons/phpc/keywords-with-filepath.json"; // ... const phpcKeywords = iconsPHPCKeywords as Record<string, string[]>; Object.entries(iconsPHPC).forEach(([key, path]) => { iconsArray.push({ value: key, // ... keywords: phpcKeywords[key], // same key, no need to split/rebuild it }); });

One import, one direct lookup — no per-prefix table needed, unlike v1/v2.

Full runtime trace, on a real icon

This is the exact trace covered when we built this feature, kept here for reference.

Icon: phpc/favicons/admin admin-16-ico → keywords: ["administration 16 ico", "admin16ico"]

The icon’s technical name never contains “administration” — only keywords-with-filepath.json, consulted at step 1, made the match possible.

Last updated on