SearchDropdown
A SearchDropdown is a text field with a filtered list of choices under it. Its value is the picked choice. With multi-select, the value is the picked choices joined with ", "; a choice can contain a comma.
The choices are ChoiceItems: a row can also show an icon, a detail text (such as a shortcut) and a group, and a choice can be disabled. See Choice items.
<UIToolbox.SearchDropdown label="Asset" placeholder="Search assets..."
choices="Stone Texture,Grass Texture,Character Model" multi-select="false" />
var assets = new SearchDropdown("Asset") { Choices = assetNames, MultiSelect = true, ShowSelectedCount = true };
assets.SelectionChanged += picked => Debug.Log(string.Join(", ", picked));
// A chip for each picked tag, and a button that clears them all
var tags = new SearchDropdown("Tags") { Choices = tagNames, MultiSelect = true, ShowChips = true, ShowClearButton = true };
// Rows under a header per asset type
assets.GroupOf = name => name.EndsWith("Texture") ? "Textures" : name.EndsWith("Model") ? "Models" : null;
// Matches from a server, 250 ms after the last key
var users = new SearchDropdown("User") { MinSearchLength = 2 };
users.AsyncSearch = async (query, token) => await userService.FindNamesAsync(query, token);
// Rich rows: a group, a detail text on the right, and a disabled choice
var commands = new SearchDropdown("Command")
{
Items = new List<ChoiceItem>
{
new("Open", "Ctrl+O", openIcon, group: "File"),
new("Print", "Ctrl+P", group: "File", enabled: false),
new("Undo", "Ctrl+Z", group: "Edit")
}
};
| Member | Description |
|---|---|
Items |
The ChoiceItems to pick from. The value and SelectedItems hold their Text. |
Choices (choices) |
The texts of Items. A set replaces Items with plain items. |
Placeholder (placeholder) |
Text in the empty field. |
MultiSelect (multi-select) |
A click toggles a choice and the list stays open (false). |
FuzzySearch (fuzzy-search) |
Also matches choices that contain the typed letters in order (true). Substring matches come first. |
MinSearchLength (min-search-length) |
A shorter query shows every choice (0). |
ShowSelectedCount (show-selected-count) |
With multi-select, the closed field shows "N selected" instead of the names (false). |
ShowChips (show-chips) |
With multi-select, each picked choice is a chip with a remove button in front of the text (false). |
ShowClearButton (show-clear-button) |
Shows a "×" button at the end of the field while a choice is picked (false). A click clears the selection. |
ClearSelection() |
Unselects every choice, with a ChangeEvent and SelectionChanged. |
KeepQuery (keep-query) |
While no choice is picked, the field keeps the typed text when the list closes, and the next open filters by it (false). For a search box that also filters a page through QueryChanged. |
RecentCount (recent-count) |
How many recent picks show first when the query is empty (5). 0 turns it off. |
SelectedItems |
The picked choices, in pick order. |
FilteredItems |
The choices in the list now. |
IsOpen, Open(), Close() |
The popup state. |
MakeItem, BindItem |
Custom rows. The default row has an icon, the text and the detail. BindItem gets the row element and its ChoiceItem. |
SelectionChanged |
Raised after a pick, a removed chip or a clear, with SelectedItems. |
QueryChanged |
Raised when the typed text changes, or when code sets Query. |
Query |
The typed text. Set it to restore a search, for example when a page comes back: it raises QueryChanged and does not open the list. With KeepQuery, the field shows it. |
ChoiceList.Filter(items, textOf, query, fuzzy), ChoiceList.Filter(strings, query, fuzzy) |
The static filter the control uses. |
HighlightMatches (highlight-matches) |
Marks the matched letters in the default rows (true). |
ChoiceList.HighlightText(text, query, fuzzy, color) |
The rich text of a marked row, for a custom BindItem with Query. |
GroupOf |
Gives the group of a choice without a ChoiceItem.Group. A header row shows before each group; null has no header. |
AsyncSearch |
Gets the matches for a query from a slow source instead of filtering Choices. See below. |
SearchDelay (search-delay) |
The milliseconds after the last key before AsyncSearch runs (250). |
IsSearching |
True while an AsyncSearch waits or runs. |
- Typing opens the list and filters it. Typing is not a value change; only a pick sends a
ChangeEvent. - Up and Down move the highlight, from the keyboard and from a gamepad. Enter picks it. Escape and Tab close the list and restore the field text. With the list closed, a second Escape clears the kept query (
KeepQuery), or the selection when the field has the clear button. While the list is closed, Alt+Down opens it and a plain arrow moves the focus. - A press outside the field and the list closes it.
- With
show-chips, the chips show the selection and the text is only for the query. A click on the "×" of a chip removes that choice. Backspace in an empty text removes the last chip. Many chips go to the next line. The value is still the joined text. - The chip buttons and the clear button are not stops for Tab or a gamepad. With a gamepad, pick a marked choice in the list again to remove it.
- The list is added to the workspace (or the top element of the document), so a window does not clip it.
- The mark shows the first run that contains the query or, for a fuzzy match, each letter. A
<in a choice shows as text. The mark color is the USS property--tb-choice-list-matchon the popup (tb-choice-list); it must be see-through. - The groups keep the order of their best match, and the choices keep their order in a group.
FilteredItemshas the choices in the shown order, without the headers. The keys pass over the headers and the disabled choices. A click on a header or a disabled choice picks nothing. AsyncSearchruns when the query hasMinSearchLengthletters (at least 1). A shorter query showsChoices. While it waits, the list shows "Searching…". A newer query or a close cancels the token of the older search, and its late results are dropped. The results show in their order, with no filter. An exception shows "Search failed" and goes to the console.- An
AsyncSearchresult keeps the icon, detail and group of theItemsentry with the same text.
Styling
The rules are in Assets/UIToolbox/Runtime/Resources/UIToolbox/Styles/Controls.uss.
| Class | Element |
|---|---|
tb-search-dropdown |
The field. |
tb-search-dropdown--boxed |
Set with show-chips or show-clear-button. The box around the chips, the text and the clear button draws the border, and the text box has none. |
tb-search-dropdown__chips |
The row of chips in front of the text. |
tb-search-dropdown__chip |
A chip. It holds tb-search-dropdown__chip-text (a Label) and tb-search-dropdown__chip-remove (a Button). |
tb-search-dropdown__clear |
The clear button at the end of the field. |
tb-search-dropdown__popup |
The list under the field, with tb-choice-list. It is in the workspace or the top element of the document, not in the field. |
tb-choice-list |
The popup of a list of choices. The classes below are on its parts. |
tb-choice-list__row |
A list row. It holds a group header and a choice, and shows one of them. tb-choice-list__row--group marks a header row, which has no hover or highlight. |
tb-choice-list__group |
A group header: small, bold and muted. |
tb-choice-list__item |
A choice in a row. tb-choice-list__item--selected marks a picked choice, tb-choice-list__item--disabled a disabled one. |
tb-choice-list__icon, tb-choice-list__text, tb-choice-list__detail |
The parts of a default row: a 16 px image, the text, and the muted detail on the right. |
tb-choice-list__empty |
The "No results", "Searching…" or "Search failed" label. |
--tb-choice-list-match (on tb-choice-list) |
The see-through mark behind the matched letters. |
The highlighted row is the ListView selection: .tb-choice-list .unity-collection-view__item--selected. The text and the detail of the highlighted row use --tb-color-accent-text.