API Docs

A 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 onSelect with null)
  • ↑ / ↓ — move through results

Properties

identifier

string
Stable UUID string for this chooser instance.

query

string
The current text in the search field. Setting this from JS updates the display but does not invoke the `onQueryChange` callback.

placeholder

string
Placeholder text shown in the empty search field (default: `"Search..."`).

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`).

selectedRow

number
The zero-based index of the currently highlighted row (-1 when empty).

width

number
Width of the chooser as a fraction of the screen width (default: `0.5` = 50 %).

visibleRows

number
Maximum number of rows visible at once without scrolling (default: `10`).

isVisible

boolean
`true` if the chooser panel is currently on screen.

onSelect

JSValue
Called when the user confirms a selection. 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

JSValue
Called on every keystroke with the new query string. Use this to debounce expensive searches or trigger async data fetching.

onShow

JSValue
Called after the panel becomes visible.

onHide

JSValue
Called after the panel is hidden (for any reason: selection, Escape, or `hide()`).

onInvalid

JSValue
Called when the user activates a row whose `valid` field is `false`. 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.
setChoices(choices) -> HSChooser
Name Type Description
choices JSValue An array of choice objects, or a function `(query) => [...]`
HSChooser
Self for chaining
// 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.
refreshChoices() -> HSChooser
HSChooser
Self for chaining
chooser.refreshChoices()

show() -> HSChooser

Show the chooser.
show() -> HSChooser
HSChooser
Self for chaining
chooser.show()

hide() -> HSChooser

Hide the chooser without making a selection. Restores focus to the previously active window.
hide() -> HSChooser
HSChooser
Self for chaining
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.
select(row) -> HSChooser
Name Type Description
row JSValue Zero-based row index, or omit to use the current selection.
HSChooser
Self for chaining
chooser.select()     // confirm highlighted row
chooser.select(2)    // confirm row at index 2

selectedRowContents(row) -> NSDictionary

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.
selectedRowContents(row) -> NSDictionary
Name Type Description
row JSValue Zero-based row index, or omit to query the highlighted row.
NSDictionary
The row dict (`{ text, subText?, image?, valid, ...extras }`) or `null`.
const item = chooser.selectedRowContents()
const item = chooser.selectedRowContents(2)