The shortest path: a container, items, zones. onSort may be asynchronous and may fail โ a rejection
puts the card back, the library never assumes the host accepted the filing. The fourth zone below is
free: dropping a card on it files nothing, it asks the host what to put there.
import { Deck } from '@trieur/core';
import '@trieur/core/trieur.css';
new Deck(document.querySelector('#sorter'), {
touchPreview: false,
items: links,
zones: [
{ id: 'dev', label: 'dev', icon: 'โ' },
{ id: 'ai', label: 'ai', icon: 'โ' },
null, // free zone: dropping calls onAssign
{ id: 'home', label: 'home', icon: 'โ' },
],
renderCard: (link, el) => { el.innerHTML = template(link); },
onSort: (link, zone) => fetch('/file', { method: 'POST', body: JSON.stringify({ link, zone }) }),
onUndo: (link, zone) => fetch('/unfile', { method: 'POST', body: JSON.stringify({ link, zone }) }),
onAssign: (index) => console.log('free zone', index),
});