Get started
Install loopem and mount your first picker.
Loopem has no dependencies. One package covers every framework, and the adapters are subpaths of it.
Your first picker
Give it an element, a list, and a way to build one item. Everything else has a default.
The element is one empty div. You never write the items into your markup: loopem creates them, and keeps only the ones on screen.
<div id="colors"></div>The items can be anything. Loopem never looks inside one, and renderItem
decides what it looks like.
import { createPicker } from 'loopem'
const colors = [
{ name: 'Ember', hex: '#e8574a' },
{ name: 'Amber', hex: '#e0a33a' },
{ name: 'Fern', hex: '#7cc44f' },
// …twenty in all
]
const picker = createPicker(document.getElementById('colors'), {
items: colors,
renderItem: (color) => {
const button = document.createElement('button')
button.style.background = color.hex
button.setAttribute('aria-label', color.name)
return button
},
fade: 100,
})fade dissolves the last 100px at each end, so the track runs out of the frame
instead of stopping at a hard edge. Everything else here is a default.
That is a working picker. It drags, flicks with momentum, never rests between two items, answers to the keyboard, and announces itself to a screen reader.
Sizing it
Loopem positions items; it never sizes them. The container needs a height, and each item needs whatever size you want it to be. Both are ordinary CSS.
#colors {
height: 240px;
}
#colors button {
width: 56px;
height: 56px;
border: 0;
border-radius: 20px;
}Reading what was picked
Nothing happens in your app until you ask.
picker.on('select', ({ index, item }) => {
console.log('Picked', item, 'at', index)
}, { immediate: true })immediate: true also runs the listener once on subscribe, so one line fills
your view and keeps it up to date. select fires when the track settles, so it
is where anything expensive belongs. There is a full account in
Read the selection.
Cleaning up
destroy() removes the listeners, the slots, and the rAF loop. In a framework,
the adapters do it for you.
picker.destroy()Where to go next
- Options lists every option, with a picker you can change them on.
- Line & arc covers the two built-in shapes.
- React, Vue and Svelte each have a first-party adapter.