@bluecateng/smooth-reorder
Version:
Smooth list reordering in vanilla JS
2 lines (1 loc) • 4.14 kB
JavaScript
import ce from"@bluecateng/nano-spring";var fe=(n,P)=>{let I=Math.abs,M="transform .2s cubic-bezier(0.3, 0, 0, 1)",re=205,o,l,R,F,T,B,d,p,U,z,q,u,L=!1,x=!1,v,m,K=()=>Array.prototype.indexOf.call(o.parentNode.childNodes,o),le=(e,t)=>{for(;e!==document.body&&!/(auto|scroll)/.test(getComputedStyle(e)[t]);)e=e.parentNode;return e},{horizontal:N,selector:S=".draggable",onStart:ie,onMove:O,onFinish:j,onCancel:G}=P,H=P.handleSelector||S,X=P.focusSelector||H,i=le(n,N?"overflowX":"overflowY"),y=i.getBoundingClientRect(),E=e=>{(S!==X&&e.querySelector(X)||e).focus()},W=()=>{m&&(cancelAnimationFrame(m),m=0)},b=(e,t,s,c,a)=>{let g=o.getBoundingClientRect(),r,f=g,h=o[e],w=[];for(;h&&s(r=h.getBoundingClientRect());)h.style.transition=M,h.style.transform=c(r,f),w.push(h),f=r,h=h[e];if(w.length){x=!0,a&&(o.style.transition=M,o.style.transform=a(g,f));let A=o;setTimeout(()=>{for(let D of w)D.style.transition="",D.style.transform="";if(w[w.length-1].insertAdjacentElement(t,A),a&&(A.style.transition="",A.style.transform="",E(A)),x=!1,v){let D=v;v=null,D()}},re)}},C=(e,t)=>`translate(${t.right-e.right}px,${t.bottom-e.bottom}px)`,$=(e,t)=>`translate(${t.left-e.left}px,${t.top-e.top}px)`,J=e=>b("previousSibling","beforebegin",t=>e<t.right+5,C),Q=e=>b("nextSibling","afterend",t=>e>t.left-5,$),V=e=>b("previousSibling","beforebegin",t=>e<t.bottom+5,C),Z=e=>b("nextSibling","afterend",t=>e>t.top-5,$),_=(e,t)=>{if(N){let s=e+T;e>d?Q(s):e<d&&J(s)}else{let s=t+B;t>p?Z(s):t<p&&V(s)}d=e,p=t},ee=e=>{e.preventDefault();let t=e.clientX-U,s=e.clientY-z;if(L)if(l.style.transform=`translate(${t}px,${s}px)`,x?v=()=>_(t,s):_(t,s),W(),N){let c=t+T,a=t-y.left,g=t+R-y.right;if(a<0){let r=()=>{i.scrollLeft>0&&(i.scrollLeft+=a,J(c),m=requestAnimationFrame(r))};r()}else if(g>0){let r=i.scrollWidth-y.width,f=()=>{i.scrollLeft<r&&(i.scrollLeft+=g,Q(c),m=requestAnimationFrame(f))};f()}}else{let c=s+B,a=s-y.top,g=s+F-y.bottom;if(a<0){let r=()=>{i.scrollTop>0&&(i.scrollTop+=a,V(c),m=requestAnimationFrame(r))};r()}else if(g>0){let r=i.scrollHeight-y.height,f=()=>{i.scrollTop<r&&(i.scrollTop+=g,Z(c),m=requestAnimationFrame(f))};f()}}else I(t-d)+I(s-p)>2&&(L=!0,o.classList.add("placeholder"),l.classList.add("dragging"),l.classList.add("clone"),l.style.transform=`translate(${t}px,${s}px)`,document.body.appendChild(l),E(l))},te=e=>{let t;if(!o&&e.button===0&&(t=e.target.closest(H))){e.preventDefault(),o=t.closest(S);let s=o.getBoundingClientRect();R=s.width,F=s.height,T=R/2,B=F/2,d=s.left,p=s.top,U=e.clientX-d,z=e.clientY-p,n.setPointerCapture(e.pointerId),n.addEventListener("pointermove",ee,!0),E(o),l=o.cloneNode(!0),l.style.width=`${s.width}px`,l.style.height=`${s.height}px`}},oe=e=>{n.releasePointerCapture(e.pointerId),L&&e.preventDefault()},se=()=>{if(n.removeEventListener("pointermove",ee,!0),L){L=!1,W();let e=o.getBoundingClientRect(),t=e.left-d,s=e.top-p;ce(250,30,c=>{l.style.transform=`translate(${d+c*t}px,${p+c*s}px)`},()=>{document.body.removeChild(l),o.classList.remove("placeholder"),E(o),j(o),o=null})}},k=(e,t)=>{if(x)v=()=>k(e,t);else{let s=K()-e;s>0?b("previousSibling","beforebegin",()=>s--!==0,C,$,t):b("nextSibling","afterend",()=>s++!==0,$,C,t),t&&(v=()=>(G(o),o=null))}},Y=e=>{switch(e.preventDefault(),e.stopPropagation(),e.key){case"Escape":o.classList.remove("dragging"),document.removeEventListener("keydown",Y,!0),u===q?(G(o),o=null):k(q,!0);break;case" ":o.classList.remove("dragging"),document.removeEventListener("keydown",Y,!0),j(o),o=null;break;case"ArrowLeft":case"ArrowUp":{o.previousSibling&&(k(--u),O(o,u));break}case"ArrowRight":case"ArrowDown":{o.nextSibling&&(k(++u),O(o,u));break}}},ne=e=>{if(e.key===" "){let t=e.target;t.matches(X)&&(e.preventDefault(),document.addEventListener("keydown",Y,!0),o=t.closest(S),o.classList.add("dragging"),u=q=K(),ie(o,u))}};return n.addEventListener("pointerdown",te),n.addEventListener("pointerup",oe),n.addEventListener("lostpointercapture",se),n.addEventListener("keydown",ne),()=>{n.removeEventListener("pointerdown",te),n.removeEventListener("pointerup",oe),n.removeEventListener("lostpointercapture",se),n.removeEventListener("keydown",ne)}};export{fe as default};