How IconDropdown Works
IconDropdown is a searchable combobox that combines all 4 icon libraries into one flat, paginated list. This page covers the component’s internals end to end: what its props do, how it loads data, how pagination and selection work.
This page is about the component’s general mechanics. For exactly how the search box matches French words and synonyms, see Search in IconDropdown instead — that’s covered in depth there, not repeated here.
Verified directly against src/components/IconDropdown.tsx in
frontend-icons-react-nextjs-bundle
(main branch).
The lifecycle, in one diagram
1. Props
interface Accesses {
all: boolean;
fontAwesome?: boolean;
glyphiconsV1?: boolean;
glyphiconsV2?: boolean;
phpc?: boolean;
}
interface IconDropdownProps {
accesses: Accesses;
defaultValue?: string;
onChange?: (selectedValue: string, selectedIconUrl: string) => void;
showSearch?: boolean;
// ...plus label, helperText, error, disabled, etc. (standard form-field props)
}accesses.all is a global override — when it’s true, every
individual accesses.xxx flag is ignored and every library loads. It’s
checked with ||: accesses.glyphiconsV1 || accesses.all.
2. Loading the icons — one useEffect
On mount (and whenever the access flags change), the component builds one flat array, iconsArray: IconOption[]. Each library gets its own if (canAccessX) { ... } block that pushes directly into that array — there’s no intermediate merge step:
const canAccessGlyphiconV1 = accesses.glyphiconsV1 || accesses.all;
// ...same pattern for fontAwesome, glyphiconsV2, phpc
useEffect(() => {
const iconsArray: IconOption[] = [];
if (canAccessGlyphiconV1) {
// ...builds and pushes glyphicons-v1 icons
}
if (canAccessGlyphiconV2) {
// ...builds and pushes glyphicons-v2 icons
}
// ...phpc, fontAwesome
setIcons(iconsArray);
setFilteredIcons(iconsArray.slice(0, ITEMS_PER_PAGE));
}, [canAccessFontAwesome, canAccessGlyphiconV1, canAccessGlyphiconV2, canAccessPHPC]);The exact shape of each block differs per library — see Search in IconDropdown and Adding New Icons for those details.
Two separate states come out of this:
| State | Contents |
|---|---|
icons | The full list — can be several thousand entries |
filteredIcons | Only the first ITEMS_PER_PAGE (50) — what’s actually rendered |
3. Searching — matchesSearch
The search box only re-filters on Enter or a button click — not on every keystroke. Typing just updates searchState.field; handleSearch() is what actually runs matchesSearch over icons and rewrites filteredIcons. See Search in IconDropdown for how matchesSearch itself matches on label or keywords.
4. Infinite-scroll pagination
Since filteredIcons only ever holds 50 (or a multiple of 50) entries at a time:
handleScrolldetects the list is close to its bottom (scrollTop + clientHeight >= scrollHeight - 10)- that calls
handleLoadMore, which bumpspageand re-slices the filtered array topage * 50
This is pure client-side pagination — everything is already in memory from step 2, there’s no extra network request.
5. Resolving defaultValue — findIconByValue
defaultValue can arrive in more than one shape — a full CSS class like "fa fa-book", just "book", or the component’s own internal value. findIconByValue tries several strategies in order, falling through to the next if one fails:
- Exact match on
value - Case-insensitive match on
value - Extract the icon name from a
"fa fa-xxx"CSS class, then match onlabel - Match on
labelalone, orvalueending with/label
This keeps old data (saved before some naming tweak) from silently breaking the display.
6. Selecting an icon
const handleSelect = (selectedValue: string) => {
const icon = icons.find((i) => i.value === selectedValue);
setValue(selectedValue);
setOpen(false);
onChange?.(icon?.displayLabel || selectedValue, icon?.iconUrl || "");
};The parent never receives the internal value (which can look like "glyphicons-v1/filetypes/filetypes filetypes-txt") — it gets displayLabel (the readable name) and iconUrl (the full CDN URL, prefixed with NEXT_PUBLIC_ICONS_URL).
Related pages
- Search in IconDropdown — how
matchesSearchand thekeywordsfield actually work - Adding New Icons — adding one icon to a folder that’s already wired in, or wiring up a brand-new folder