loopem
v0.1.0
Published
A picker for lists of any length. Line, arc, wheel, or a layout you write. Virtualized, keyboard-accessible, and it works with any framework.
Maintainers
Readme
Loopem
A picker in any shape you want.
Documentation · Get started · Options
A framework-agnostic library for building pickers: date wheels, color swatches, photo carousels, anything where someone drags through options and lands on one. You pick the shape, from a straight line to an arc, a wheel, or a layout you write yourself.
Drag it, flick it, or use the arrow keys, and it always lands on an item instead of resting between two. Only the items on screen are in the DOM, so the length of your list stops mattering.
No dependencies.
Install
npm install loopemUse
The container is one empty element. Loopem creates the items inside it, and keeps only the ones on screen.
<div id="colors"></div>import { createPicker } from 'loopem'
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
},
})
picker.on('select', ({ item }) => {
console.log('Picked', item)
})Loopem positions items but never sizes them. Give the container a height and each item a size, in ordinary CSS.
Shapes
line and arc are built in. Four more ship as presets in loopem/layouts,
each one line:
import { coverflow } from 'loopem/layouts'
createPicker(el, { items, renderItem, ...coverflow() })| Preset | Shape |
| --- | --- |
| wheel | A vertical drum, like an iOS date picker. |
| coverflow | Cards turning away into real perspective. |
| fan | A hand of cards, or a paint deck. |
| stack | A wallet you flick through. |
A layout is just a function from distance-to-center to a position, so writing your own is a few lines of arithmetic.
Frameworks
Works with any framework. React, Vue and Svelte also get an adapter, so it feels native there.
import { usePicker } from 'loopem/react'
const { containerRef, selectedItem, renderSlots } = usePicker({ items, layout: 'arc' })- React
- Vue
- Svelte
- Everything else, including Solid, Lit and Angular
Accessibility
The container is a listbox and each item an option. Arrow keys step, Page
Up and Page Down jump five, Home and End reach the ends, Enter and Space choose.
A horizontal track claims one gesture axis only, so a thumb dragged up the page
over it still scrolls the page. Autoplay never starts under
prefers-reduced-motion.
License
MIT © Taha Shashtari
