HSChooser
TypeA keyboard-driven floating chooser panel.
Create via hs.chooser.create(). Configure choices, set callbacks, then call .show().
Choice format
Each choice is a plain object with required text and optional subText, image, valid,
and contextMenu fields. All other fields are passed through to the onSelect callback unchanged.
The contextMenu array defines per-row right-click menu entries. Each entry is either
{ title: "...", action: (item) => {} } for a button or { type: "divider" } for a separator:
{
text: "Open Safari", subText: "com.apple.Safari",
image: HSImage.fromAppBundle("com.apple.Safari"), valid: true, myData: 42,
contextMenu: [
{ title: "Open", action: () => hs.urlevent.openURL("https://apple.com") },
{ type: "divider" },
{ title: "Copy bundle ID", action: () => hs.pasteboard.writeString("com.apple.Safari") }
]
}
Keyboard shortcuts
- Return — confirm selection
- Escape — dismiss (calls
onSelectwithnull) - ↑ / ↓ — move through results
Properties
query
string
The current text in the search field. Setting this from JS updates the display but
does not invoke the `onQueryChange` callback.
searchSubText
boolean
Whether searches match against `subText` in addition to `text` (default: `false`).
Only applies when a static choices array is provided.
enableDefaultForQuery
boolean
When `true` and the query is non-empty but there are no matching choices, `onSelect`
is called with `{ text: <query> }` instead of `null` (default: `false`).
onSelect
function | null
Called when the user confirms a selection, or null to remove the handler.
The argument is the chosen row object (the original dict you passed to `setChoices`,
with `text`, `subText`, `image`, `valid`, and any custom fields intact).
The argument is `null` when dismissed (Escape).
onQueryChange
function | null
Called on every keystroke with the new query string, or null to remove the handler.
Use this to debounce expensive searches or trigger async data fetching.
onHide
function | null
Called after the panel is hidden (for any reason: selection, Escape, or `hide()`), or null to remove the handler.
onInvalid
function | null
Called when the user activates a row whose `valid` field is `false`, or null to remove the handler.
The chooser stays open; the argument is the row dict (same shape as `onSelect`).
If unset, activating an invalid row is silently ignored.
Methods
setChoices(choices) -> HSChooser
on show. The function is responsible for filtering; the chooser displays all items it returns.
Declaration
setChoices(choices) -> HSChooser
Parameters
| Name | Type | Description |
|---|---|---|
| choices | JSValue | An array of choice objects, or a function `(query) => [...]` |
Returns
HSChooser
Self for chaining
Example
// Static
chooser.setChoices([{text: "Foo"}, {text: "Bar"}])
// Dynamic
chooser.setChoices(q => items.filter(i => i.text.toLowerCase().includes(q.toLowerCase())))
refreshChoices() -> HSChooser
Re-apply filtering (static choices) or re-invoke the choices function (dynamic).
Call after updating an external data source in an async `onQueryChange` handler.
Declaration
refreshChoices() -> HSChooser
Returns
HSChooser
Self for chaining
Example
chooser.refreshChoices()
show() -> HSChooser
Show the chooser.
Declaration
show() -> HSChooser
Returns
HSChooser
Self for chaining
Example
chooser.show()
hide() -> HSChooser
Hide the chooser without making a selection. Restores focus to the previously active window.
Declaration
hide() -> HSChooser
Returns
HSChooser
Self for chaining
Example
chooser.hide()
select(row) -> HSChooser
Programmatically confirm a selection.
Omit `row` to confirm the currently highlighted row. Fires `onSelect` (or `onInvalid`
for rows with `valid: false`) and hides the chooser.
Declaration
select(row) -> HSChooser
Parameters
| Name | Type | Description |
|---|---|---|
| row | JSValue | Zero-based row index, or omit to use the current selection. |
Returns
HSChooser
Self for chaining
Example
chooser.select() // confirm highlighted row
chooser.select(2) // confirm row at index 2
selectedRowContents(row) -> [String: Any]
Returns the dict for the highlighted row, or for a specific row by index.
Returns `null` if the index is out of range or no choices are set.
Declaration
selectedRowContents(row) -> [String: Any]
Parameters
| Name | Type | Description |
|---|---|---|
| row | JSValue | Zero-based row index, or omit to query the highlighted row. |
Returns
[String: Any]
The row dict (`{ text, subText?, image?, valid, ...extras }`) or `null`.
Example
const item = chooser.selectedRowContents()
const item = chooser.selectedRowContents(2)