Overview
Reference usage
ToolPicker is a dialog for choosing tools and skills from a list grouped by source. Each row carries the human name, the identifier once in monospace, a one-line description and two trailing facts: a short word such as how risky the tool is (meta) and the level it starts at (detail). The level is read-only here; changing it happens wherever the chosen tools are listed once they are added. A skill follows the tools it uses, so it is listed with no checkbox (selectable: false) and says so in the trailing column.
The title's line carries a counter ("3 of 9 tools chosen"), a search field sits under it, and the list scrolls inside the dialog under sticky group headers ("Built in, 6", "GitHub, 3, none chosen", "Skills, 2, they follow the tools they use"). The picker edits a copy: Done writes the choices back to selected and calls onDone; Cancel, Escape and a click outside leave selected alone.
Usage
States
- Loading:
loadingkeeps the title and a live search field and draws three skeleton rows after 300 ms, so a quick load never flashes a placeholder. Done waits until the list is there. - Filtered to nothing: the search keeps what was typed, and the list says
No tools match “invoice”with "Try a shorter word." and one action, Clear search.noMatchTitletakes a string or a function of the query. - Forty or more tools: from
collapseFromselectable items (40 by default) the counter reads the total ("42 tools"; "42 tools, 3 chosen" once something is chosen), the group headers become buttons ("Built in 6 tools") and every group but the first starts collapsed. Searching opens every group that has a match.
Choices and order
selected holds item values. Done writes them in the order of items, followed by any value that no item names, so a choice the catalogue no longer offers is not silently dropped. A newly checked item's starting level is the consumer's to decide: give a dangerous tool a detail of "Always (default)" and the form that lists the chosen tools starts it there.
Chosen: Lookup order, Issue refund, Triage refunds.
When to use
- Letting a person choose several items that carry a name, an identifier, a description and trailing facts, from grouped sources.
- The list can be long enough to need search and collapsing groups, and some entries are shown but cannot be chosen.
- Choosing one item from a short list — use select or combobox instead.
- Moving items between two lists the person keeps open — use transfer-list instead.
Examples
Grouped tools and skills
Tools group by source with their risk and the level they start at on each row; skills are listed with no checkbox, because they follow the tools they use. Done keeps the choices, Cancel drops them.
Loading
While the list loads, the title and a live search field stay, and three skeleton rows appear after 300 ms so a quick load never flashes a placeholder. Done waits until the list is there.
Forty or more tools
From forty selectable items the counter reads the total, and every group but the first starts collapsed under its sticky header. The list scrolls inside the dialog, and searching opens every group that has a match.
Filtered to nothing
When the search matches nothing the field keeps its text and the picker says so, with a hint and one action, Clear search. Open it on a search with the bindable query.
Props
Name | Type | Default | Description |
|---|---|---|---|
open bindable | boolean | false | Whether the picker is open. Bindable. It closes itself on Done and Cancel, on Escape and on a
click outside, and opens with the chosen items as selected says. |
selected bindable | string[] | [] | The values of the chosen items. Bindable. The picker works on a copy while it is open: Done
writes it back (in the order of items, keeping any value no item names), and Cancel and
dismissing leave it alone. |
query bindable | text | '' | The text in the search field. Bindable. It is cleared when the picker closes, so it opens empty unless the page sets it before opening, such as to open on a search that matches nothing. |
items required | ToolPickerItem[] | Everything that can be listed, in the order it should read within each group. | |
groups | ToolPickerGroup[] | The groups, in the order they should appear, with a note for a group that cannot be chosen from. | |
title | text | 'Add tools and skills' | Heading of the dialog. |
itemNoun | text | 'tools' | What the items are called, plural, in the counter, the group counts and the empty state ("tools"). The counter reads "3 of 9 tools chosen". |
searchLabel | text | 'Search tools and skills' | Accessible name and placeholder of the search field. |
collapseFrom | number | 40 | How many selectable items it takes to switch to the long-list layout: the counter reads the total ("42 tools"), and every group but the first starts collapsed under its sticky header. |
loading | boolean | false | Draw the loading state: three skeleton rows, after 300 ms, under the title and a live search field. Nothing can be chosen until it is false. |
loadingLabel | text | 'Loading tools and skills' | Announced politely when the loading placeholder appears. |
noneChosenLabel | text | 'none chosen' | Words on a group's header, after its count, when none of its items is chosen and something else
is. Skills and other groups that cannot be chosen from show their note instead. |
emptyMetaLabel | text | 'No risk word' | Names the trailing column of an item with no meta, which draws an em dash. |
emptyLabel | text | 'No tools to choose from.' | The line shown when there is nothing at all to choose from (no search involved). |
noMatchTitle | text | The heading of the empty state, given what was typed. | |
noMatchHint | text | 'Try a shorter word.' | The line under the empty state's heading. |
clearSearchLabel | text | 'Clear search' | Label of the button in the empty state that clears the search. |
doneLabel | text | 'Done' | Label of the button that closes the picker and keeps the choices. |
cancelLabel | text | 'Cancel' | Label of the button that closes the picker and drops the choices made in it. |
onDone | (selected: string[]) => void | Called with the chosen values when Done is pressed, after selected is updated. | |
onCancel | () => void | Called when the picker is closed without keeping its choices: Cancel, Escape or a click outside. | |
triggerRef | HTMLElement | null | null | The element focus returns to when the picker closes, usually the button that opened it. |