Add your own controls

Prev and next buttons, jumping, and driving the track from code.

The handle has the same moves a drag does. Wire them to your own buttons and the picker behaves exactly as if someone had dragged it.

controls.jsts
previous.addEventListener('click', () => picker.previous())
next.addEventListener('click', () => picker.next())
first.addEventListener('click', () => picker.scrollTo(0))
Those three lines, wired to those three buttons.

Moving it

MethodWhat it does
next() / previous()Step one item from the commanded target.
scrollTo(index, { animate })Move there without choosing.
select(index, { animate })Move there and choose, as a click would.
seek(offset)Put the track at a continuous position, 2.5 included.

scrollTo and select differ only in whether they commit. Reach for select when you are setting a value and scrollTo when you are only repositioning.

Jumping without animating

{ animate: false } puts the track there in one frame. That is what you want when restoring state on load: nobody wants to watch the picker scroll to item 340 while the page settles.

ts
picker.select(saved.index, { animate: false })

Swapping the list

ts
picker.update(nextItems)

It keeps the centered position where the new length allows and rebinds content through the slot pool, so nothing is torn down and rebuilt. Note that it resets the selection to the centered item, so if you are holding a value externally, re-assert it after.

In React and Vue there is no update, because the items option drives it. Svelte has one, because its options are read once.

Cleaning up

ts
picker.destroy()

Removes every listener, the slots, and the rAF loop. The adapters call it for you on unmount.

Reading state without subscribing

getCount(), getActiveIndex(), getSelectedItem() and friends are all synchronous. Useful inside a handler; not a substitute for on(...), which is how you find out that something changed.