Searchable term/authority picker for large vocabularies (combobox + server-side search) #27
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
The object authoring form (frontend milestone 2, merged to
main@bb05331) renders term and authority flexible fields as plain native<select>s (web/src/objects/field-input.tsx→OptionsSelect). The full option set for the field's vocabulary / authority-kind is fetched and listed client-side (useTerms,useAuthorities). This is lean and fine while vocabularies are small, but it degrades once a vocabulary has hundreds/thousands of terms (huge<select>, large payload, no filtering).The value contract is
option value = term/authority id, so a richer picker can drop in without changing what's stored.What to do
<select>for term/authority fields with a searchable combobox (the shadcn Combobox/Command, or an equivalent) that filters as you type. (Note: a shadcnSelectwas added then removed during M2 since the native select was used; pick the combobox primitive deliberately.)GET /api/admin/vocabularies/{id}/terms?q=) and have the combobox query it (debounced) rather than loading all terms. Same for authorities by kind.References
web/src/objects/field-input.tsx(OptionsSelect,TermField,AuthorityField)web/src/api/queries.ts(useTerms,useAuthorities)docs/superpowers/specs/2026-06-04-frontend-spa-milestone-2-design.md→ "Out of scope / follow-ups").Done in
de035bd(merged tomain). Term/authority fields now render a searchable combobox built on Base UI'scomboboxprimitive (no new npm dependency): type-to-filter by active-locale label, client-side, with thevalue = idcontract preserved and a selected-item checkmark. The native<select>(OptionsSelect) is removed;labelInwas deduped to the sharedlib/labelslabelText. The combobox lands in the already-lazy object-form chunk; the index-bundle budget was raised 150→165 KB gz (the app has outgrown the early line).Server-side search deferred to a follow-up (filed separately) — current vocabularies are small, and the client-side filter covers them.