@neodrag/svelte
Version:
Svelte Action to add dragging to your apps 😉
3 lines • 5 kB
JavaScript
var e={dragStart:!0},t={delay:0,distance:3};var n=(e,t,n)=>Math.min(Math.max(e,t),n),r=e=>"string"==typeof e,o=([e,t],n,r)=>{const o=(e,t)=>0===t?0:Math.ceil(e/t)*t;return[o(n,e),o(r,t)]};var a=(e,t)=>e.some((e=>t.some((t=>e.contains(t)))));function i(e,t){if(void 0===e)return;if(l(e))return e.getBoundingClientRect();if("object"==typeof e){const{top:t=0,left:n=0,right:r=0,bottom:o=0}=e;return{top:t,right:window.innerWidth-r,bottom:window.innerHeight-o,left:n}}if("parent"===e)return t.parentNode.getBoundingClientRect();const n=document.querySelector(e);if(null===n)throw new Error("The selector provided for bound doesn't exists in the document.");return n.getBoundingClientRect()}var s=(e,t,n)=>e.style.setProperty(t,n),l=e=>e instanceof HTMLElement,d=function(d,c={}){let u,f,{bounds:g,axis:h="both",gpuAcceleration:p=!0,legacyTranslate:m=!1,transform:y,applyUserSelectHack:w=!0,disabled:b=!1,ignoreMultitouch:v=!1,recomputeBounds:x=e,grid:E,threshold:S=t,position:A,cancel:C,handle:D,defaultClass:N="neodrag",defaultClassDragging:M="neodrag-dragging",defaultClassDragged:B="neodrag-dragged",defaultPosition:R={x:0,y:0},onDragStart:$,onDrag:X,onDragEnd:Y}=c,q=!1,H=!1,P=0,T=!1,k=!1,L=0,z=0,I=0,U=0,W=0,j=0,{x:F,y:G}=A?{x:A?.x??0,y:A?.y??0}:R;oe(F,G);let J,K,O,Q,V,Z="",_=!!A;x={...e,...x},S={...t,...S??{}};let ee=new Set;function te(e){q&&!H&&k&&T&&V&&(H=!0,function(e){ae("neodrag:start",$,e)}(e),re.add(M),w&&(Z=ne.userSelect,ne.userSelect="none"))}const ne=document.body.style,re=d.classList;function oe(e=L,t=z){if(!y){if(m){let n=`${+e}px, ${+t}px`;return s(d,"transform",p?`translate3d(${n}, 0)`:`translate(${n})`)}return s(d,"translate",`${+e}px ${+t}px`)}const n=y({offsetX:e,offsetY:t,rootNode:d});r(n)&&s(d,"transform",n)}function ae(e,t,n){const r=function(e){return{offsetX:L,offsetY:z,rootNode:d,currentNode:V,event:e}}(n);d.dispatchEvent(new CustomEvent(e,{detail:r})),t?.(r)}const ie=addEventListener,se=new AbortController,le={signal:se.signal,capture:!1};function de(){let e=d.offsetWidth/K.width;return isNaN(e)&&(e=1),e}return s(d,"touch-action","none"),ie("pointerdown",(e=>{if(b)return;if(2===e.button)return;if(ee.add(e.pointerId),v&&ee.size>1)return e.preventDefault();if(x.dragStart&&(J=i(g,d)),r(D)&&r(C)&&D===C)throw new Error("`handle` selector can't be same as `cancel` selector");if(re.add(N),O=function(e,t){if(!e)return[t];if(l(e))return[e];if(Array.isArray(e))return e;const n=t.querySelectorAll(e);if(null===n)throw new Error("Selector passed for `handle` option should be child of the element on which the action is applied");return Array.from(n.values())}(D,d),Q=function(e,t){if(!e)return[];if(l(e))return[e];if(Array.isArray(e))return e;const n=t.querySelectorAll(e);if(null===n)throw new Error("Selector passed for `cancel` option should be child of the element on which the action is applied");return Array.from(n.values())}(C,d),u=/(both|x)/.test(h),f=/(both|y)/.test(h),a(Q,O))throw new Error("Element being dragged can't be a child of the element on which `cancel` is applied");const t=e.composedPath()[0];if(!O.some((e=>e.contains(t)||e.shadowRoot?.contains(t)))||a(Q,[t]))return;V=1===O.length?d:O.find((e=>e.contains(t))),q=!0,P=Date.now(),S.delay||(T=!0),K=d.getBoundingClientRect();const{clientX:n,clientY:o}=e,s=de();u&&(I=n-F/s),f&&(U=o-G/s),J&&(W=n-K.left,j=o-K.top)}),le),ie("pointermove",(e=>{if(!q||v&&ee.size>1)return;if(!H){if(!T){Date.now()-P>=S.delay&&(T=!0,te(e))}if(!k){const t=e.clientX-I,n=e.clientY-U;Math.sqrt(t**2+n**2)>=S.distance&&(k=!0,te(e))}if(!H)return}x.drag&&(J=i(g,d)),e.preventDefault(),K=d.getBoundingClientRect();let t=e.clientX,r=e.clientY;const a=de();if(J){const e={left:J.left+W,top:J.top+j,right:J.right+W-K.width,bottom:J.bottom+j-K.height};t=n(t,e.left,e.right),r=n(r,e.top,e.bottom)}if(Array.isArray(E)){let[e,n]=E;if(isNaN(+e)||e<0)throw new Error("1st argument of `grid` must be a valid positive number");if(isNaN(+n)||n<0)throw new Error("2nd argument of `grid` must be a valid positive number");let i=t-I,s=r-U;[i,s]=o([e/a,n/a],i,s),t=I+i,r=U+s}u&&(L=Math.round((t-I)*a)),f&&(z=Math.round((r-U)*a)),F=L,G=z,ae("neodrag",X,e),oe()}),le),ie("pointerup",(e=>{(ee.delete(e.pointerId),q)&&(H&&(ie("click",(e=>e.stopPropagation()),{once:!0,signal:se.signal,capture:!0}),x.dragEnd&&(J=i(g,d)),re.remove(M),re.add(B),w&&(ne.userSelect=Z),ae("neodrag:end",Y,e),u&&(I=L),f&&(U=z)),q=!1,H=!1,T=!1,k=!1)}),le),{destroy:()=>se.abort(),update:n=>{h=n.axis||"both",b=n.disabled??!1,v=n.ignoreMultitouch??!1,D=n.handle,g=n.bounds,x=n.recomputeBounds??e,C=n.cancel,w=n.applyUserSelectHack??!0,E=n.grid,p=n.gpuAcceleration??!0,m=n.legacyTranslate??!1,y=n.transform,S={...t,...n.threshold??{}};const r=re.contains(B);re.remove(N,B),N=n.defaultClass??"neodrag",M=n.defaultClassDragging??"neodrag-dragging",B=n.defaultClassDragged??"neodrag-dragged",re.add(N),r&&re.add(B),_&&(F=L=n.position?.x??L,G=z=n.position?.y??z,oe())}}};
//!THIS IS HACK, WE WANNA IMPORT THE TYPE WHEN THE ISSUE IS FIXED LATER
export{d as draggable};