Read the selection

Events, and the difference between active and selected.

Loopem never touches your app on its own. It moves a track and tells you what happened; everything after that is yours.

ts
const stop = picker.on('select', ({ index, item }) => {
  show(item)
}, { immediate: true })

immediate calls the listener once on subscribe with the current value, so one line fills your view and keeps it up to date. on returns an unsubscribe.

Active is not selected

Keeping these apart is what stops a picker loading four hundred images as someone drags past them.

  • Active is where the track is. It changes continuously through a drag, every time an item crosses the center.
  • Selected is what was chosen. Under select: 'auto' it trails the active item by one settle. Under 'manual' it only moves on a click, Enter, or a call to select().
ts
picker.getActiveIndex()    // where the track is, right now
picker.getActiveItem()
picker.getSelectedIndex()  // what was chosen
picker.getSelectedItem()

Bind cheap things to active and expensive things to selected. A caption can follow your finger; a full-resolution image should not.

Browsing without choosing

select: 'manual' lets someone drag through the whole list while the stage stays put. It still snaps, because resting between two items reads as broken. It just does not commit.

ts
createPicker(el, {
  items,
  renderItem,
  select: 'manual',
})
Drag past a few and only the top line moves. Click one and the bottom line follows.

Every event

EventFiresPayload
changeeach item crossing the center, continuously through a drag{ index, item }
settlemotion ended{ index, item }
selectan item was chosen{ index, item }
moveevery frame of motion{ offset }
slotsthe mounted set changed{ slots }

move gives you the raw float, which is what you want for driving something alongside the track. slots fires about once per item crossing the center, not per frame, which is what lets a framework render slot contents without re-rendering on every tick.

Setting the value

select(index) is the other direction. It brings the item to the center and marks it chosen, exactly as clicking it would.

ts
picker.select(12)                    // animates there
picker.select(12, { animate: false }) // jumps, for restoring saved state

It chooses immediately rather than on arrival, so a bound value is true the moment you set it and the track is what catches up. For two-way binding in a framework, see React.