From a769a4fc711ac1ad47a5a1cf96b58a10cfa5b2e6 Mon Sep 17 00:00:00 2001 From: Yair Even Or Date: Fri, 22 Apr 2022 18:50:43 +0300 Subject: [PATCH] - take parent `gap` style into account when container is a flexbox - more strict hiding styles for the dragged item --- dist/dragsort.css | 2 +- dist/dragsort.js | 2 +- src/dragsort.css | 8 ++++---- src/dragsort.js | 12 ++++++++---- test/test.html | 18 ++++++++++++------ 5 files changed, 26 insertions(+), 16 deletions(-) diff --git a/dist/dragsort.css b/dist/dragsort.css index 39e793a..8efaf00 100644 --- a/dist/dragsort.css +++ b/dist/dragsort.css @@ -1 +1 @@ -.dragsort--noAnim,.dragsort--noAnim~[draggable]{transition:none!important}.dragsort--dragStart .dragsort--dragElem{opacity:0}.dragsort--dragStart .dragsort--hide{width:0!important;height:0!important}.dragsort--dragStart>*{transition:.18s cubic-bezier(.6, .1, .4, 1.2)}.dragsort--dragStart>*>*{pointer-events:none} \ No newline at end of file +.dragsort--noAnim,.dragsort--noAnim~[draggable]{transition:none!important}.dragsort--dragStart .dragsort--dragElem{opacity:0}.dragsort--dragStart .dragsort--hide{width:0!important;height:0!important;padding:0!important;margin:0!important;border-width:0!important}.dragsort--dragStart>*{transition:var(--dragsort-trans-dur, .18s) cubic-bezier(.6, .1, .4, 1.2)}.dragsort--dragStart>*>*{pointer-events:none} \ No newline at end of file diff --git a/dist/dragsort.js b/dist/dragsort.js index 6a868f0..3e26e0c 100644 --- a/dist/dragsort.js +++ b/dist/dragsort.js @@ -1 +1 @@ -!function(t,e){var s=s||{};"function"==typeof s&&s.amd?s([],e):"object"==typeof exports&&"object"==typeof module?module.exports=e():"object"==typeof exports?exports.DragSort=e():t.DragSort=e()}(this,(function(){var t,e=0,s={},i={},r=(t=window.MutationObserver||window.WebKitMutationObserver,function(e,s){e&&1===e.nodeType&&(t?new t((function(t,e){s(t)})).observe(e,{childList:!0,subtree:!1}):window.addEventListener&&e.addEventListener("DOMNodeInserted",s,!1))});function a(t,e){if(!t)return this;e=e||{},this.parentElm=t,this.uid=e.uid,this.settings={selector:"*",callbacks:{}},Object.assign(this.settings,e),this.setup(),r(this.parentElm,this.setup.bind(this)),this.bindEvents()}return a.prototype={namespace:"dragsort",setup(){[...this.parentElm.childNodes].forEach((t=>{if(1!=t.nodeType)return t.parentNode.removeChild(t);t.matches(this.settings.selector)&&(t.draggable=!0)})),this.gap=this.getItemsGap(this.parentElm.firstElementChild)},throttle(t,e){var s=!1,i=this;return function(r){s||(t.call(i,r),s=!0,setTimeout((()=>s=!1),e))}},getDraggableElm(t){if(!t.closest)return null;var e=t.closest('[draggable="true"]');return this.uid==s.uid?e:null},dragstart(t,e){s=this;var i,r=this.getDraggableElm(e);r?(this.source=this.getInitialState(),this.target=this.getInitialState(),i=r.getBoundingClientRect(),this.source.elm=r,this.source.idx=this.getNodeIndex(r),this.source.size.width=i.width,this.source.size.height=i.height,t.dataTransfer.effectAllowed="move","function"==typeof this.settings.callbacks.dragStart&&this.settings.callbacks.dragStart(this.source.elm,t),setTimeout(this.afterDragStart.bind(this))):s={}},afterDragStart(){var t="vertical"==this.settings.mode?"height":"width";this.parentElm.classList.add(`${this.namespace}--dragStart`),this.source.elm.style[t]=this.source.size[t]+"px",this.source.elm.classList.add(`${this.namespace}--dragElem`)},dragover(t){t.preventDefault(),t.stopPropagation();var e=t.target;if((e=this.getDraggableElm(e))&&this.target){var s=this.target.elm,i=this.target.hoverDirection;t.dataTransfer.dropEffect="move",this.target.hoverDirection=this.getTargetDirection(t),s==e&&i==this.target.hoverDirection||this.directionAwareDragEnter(t,e)}},dragenter(t,e){(e=this.getDraggableElm(e))&&this.target&&this.isValidElm(e)&&this.source.elm!=e&&this.source.elm&&(this.target.bounding=e.getBoundingClientRect())},directionAwareDragEnter(t,e){var s;t.preventDefault(),t.stopPropagation(),t.dataTransfer.dropEffect="none",this.isValidElm(e)&&this.source.elm!=e&&this.source.elm&&(t.dataTransfer.dropEffect="move",this.cleanupLastTarget(),this.target.elm=e,this.target.idx=this.getNodeIndex(e),e.classList.add("over"),s=Math.abs(this.target.idx-this.source.idx),this.source.elm.classList.toggle(`${this.namespace}--hide`,s>0),"vertical"==this.settings.mode?this.target.elm.style[this.target.hoverDirection?"marginBottom":"marginTop"]=this.source.size.height+this.gap+"px":this.target.elm.style[this.target.hoverDirection?"marginRight":"marginLeft"]=this.source.size.width+this.gap+"px")},dragend(t){if(clearTimeout(this.dragoverTimeout),this.dragoverTimeout=null,this.parentElm.classList.remove(`${this.namespace}--dragStart`),!this.isValidElm(this.target.elm))return this.cleanup();var e=this.target.hoverDirection?this.target.elm.nextElementSibling:this.target.elm;return this.source.elm!=this.target.elm&&this.target.elm&&(this.target.elm.classList.add(`${this.namespace}--noAnim`),this.cleanup(),this.parentElm.insertBefore(this.source.elm,e)),this.source.elm&&this.source.elm.classList.remove(`${this.namespace}--dragElem`,`${this.namespace}--hide`),"function"==typeof this.settings.callbacks.dragEnd&&this.settings.callbacks.dragEnd(this.source.elm,t),this},isTargetLastChild(){return this.parentElm.lastElementChild==this.target.elm},getTargetDirection(t){if(this.target.bounding)return"vertical"==this.settings.mode?t.pageY>this.target.bounding.top+this.target.bounding.height/2?1:0:t.pageX>this.target.bounding.left+this.target.bounding.width/2?1:0},getNodeIndex(t){for(var e=0;t=t.previousSibling;)3==t.nodeType&&/^\s*$/.test(t.data)||e++;return e},isValidElm(t){return t&&t.nodeType&&t.parentNode==this.parentElm},cleanup(){s={},[...this.parentElm.children].forEach((t=>{t.removeAttribute("style"),setTimeout((()=>{t.classList.remove(`${this.namespace}--over`,`${this.namespace}--noAnim`,`${this.namespace}--dragElem`)}),50)}))},cleanupLastTarget(){this.target.elm&&(this.target.elm.classList.remove(`${this.namespace}--hide`,`${this.namespace}--over`),this.target.elm.removeAttribute("style"))},getInitialState:()=>({elm:null,size:{}}),getItemsGap(t){var e=getComputedStyle(t);return"vertical"==this.settings.mode?parseInt(e.marginTop)+parseInt(e.marginBottom):parseInt(e.marginLeft)+parseInt(e.marginRight)},bindEvents(t){for(var e in this.listeners=this.listeners||{dragstart:t=>this.dragstart(t,t.target),dragenter:t=>this.dragenter(t,t.target),dragend:t=>this.dragend(t,t.target),dragover:this.throttle(this.dragover,350)},this.listeners)this.parentElm[t?"removeEventListener":"addEventListener"](e,this.listeners[e])},destroy(){this.cleanup(),this.bindEvents(!0),delete i[this.uid]}},function(t,s){return i[++e]=t.DragSort?i[t.DragSort]:new a(t,{...s,uid:e}),t.DragSort=e,i[e]}})); \ No newline at end of file +!function(t,e){var s=s||{};"function"==typeof s&&s.amd?s([],e):"object"==typeof exports&&"object"==typeof module?module.exports=e():"object"==typeof exports?exports.DragSort=e():t.DragSort=e()}(this,(function(){var t,e=0,s={},i={},r=(t=window.MutationObserver||window.WebKitMutationObserver,function(e,s){e&&1===e.nodeType&&(t?new t((function(t,e){s(t)})).observe(e,{childList:!0,subtree:!1}):window.addEventListener&&e.addEventListener("DOMNodeInserted",s,!1))});function a(t,e){if(!t)return this;e=e||{},this.parentElm=t,this.uid=e.uid,this.settings={selector:"*",callbacks:{}},Object.assign(this.settings,e),this.setup(),r(this.parentElm,this.setup.bind(this)),this.bindEvents()}return a.prototype={namespace:"dragsort",setup(){[...this.parentElm.childNodes].forEach((t=>{if(1!=t.nodeType)return t.parentNode.removeChild(t);t.matches(this.settings.selector)&&(t.draggable=!0)})),this.gap=this.getItemsGap(this.parentElm.firstElementChild)},throttle(t,e){var s=!1,i=this;return function(r){s||(t.call(i,r),s=!0,setTimeout((()=>s=!1),e))}},getDraggableElm(t){if(!t.closest)return null;var e=t.closest('[draggable="true"]');return this.uid==s.uid?e:null},dragstart(t,e){s=this;var i,r=this.getDraggableElm(e);r?(this.source=this.getInitialState(),this.target=this.getInitialState(),i=r.getBoundingClientRect(),this.source.elm=r,this.source.idx=this.getNodeIndex(r),this.source.size.width=i.width,this.source.size.height=i.height,t.dataTransfer.effectAllowed="move",this.settings.callbacks.dragStart&&this.settings.callbacks.dragStart(this.source.elm,t),setTimeout(this.afterDragStart.bind(this))):s={}},afterDragStart(){var t="vertical"==this.settings.mode?"height":"width";this.parentElm.classList.add(`${this.namespace}--dragStart`),this.source.elm.style[t]=this.source.size[t]+"px",this.source.elm.classList.add(`${this.namespace}--dragElem`)},dragover(t){t.preventDefault(),t.stopPropagation();var e=t.target;if((e=this.getDraggableElm(e))&&this.target){var s=this.target.elm,i=this.target.hoverDirection;t.dataTransfer.dropEffect="move",this.target.hoverDirection=this.getTargetDirection(t),s==e&&i==this.target.hoverDirection||this.directionAwareDragEnter(t,e)}},dragenter(t,e){(e=this.getDraggableElm(e))&&this.target&&this.isValidElm(e)&&this.source.elm!=e&&this.source.elm&&(this.target.bounding=e.getBoundingClientRect())},directionAwareDragEnter(t,e){var s;t.preventDefault(),t.stopPropagation(),t.dataTransfer.dropEffect="none",this.isValidElm(e)&&this.source.elm!=e&&this.source.elm&&(t.dataTransfer.dropEffect="move",this.cleanupLastTarget(),this.target.elm=e,this.target.idx=this.getNodeIndex(e),e.classList.add("over"),s=Math.abs(this.target.idx-this.source.idx),this.source.elm.classList.toggle(`${this.namespace}--hide`,s>0),"vertical"==this.settings.mode?this.target.elm.style[this.target.hoverDirection?"marginBottom":"marginTop"]=this.source.size.height+this.gap+"px":this.target.elm.style[this.target.hoverDirection?"marginRight":"marginLeft"]=this.source.size.width+this.gap+"px")},dragend(t){if(clearTimeout(this.dragoverTimeout),this.dragoverTimeout=null,this.parentElm.classList.remove(`${this.namespace}--dragStart`),!this.isValidElm(this.target.elm))return this.cleanup();var e=this.target.hoverDirection?this.target.elm.nextElementSibling:this.target.elm;return this.source.elm!=this.target.elm&&this.target.elm&&(this.target.elm.classList.add(`${this.namespace}--noAnim`),this.cleanup(),this.parentElm.insertBefore(this.source.elm,e)),this.source.elm&&this.source.elm.classList.remove(`${this.namespace}--dragElem`,`${this.namespace}--hide`),this.settings.callbacks.dragEnd&&this.settings.callbacks.dragEnd(this.source.elm),this},isTargetLastChild(){return this.parentElm.lastElementChild==this.target.elm},getTargetDirection(t){if(this.target.bounding)return"vertical"==this.settings.mode?t.pageY>this.target.bounding.top+this.target.bounding.height/2?1:0:t.pageX>this.target.bounding.left+this.target.bounding.width/2?1:0},getNodeIndex(t){for(var e=0;t=t.previousSibling;)3==t.nodeType&&/^\s*$/.test(t.data)||e++;return e},isValidElm(t){return t&&t.nodeType&&t.parentNode==this.parentElm},cleanup(){s={},[...this.parentElm.children].forEach((t=>{t.removeAttribute("style"),setTimeout((()=>{t.classList.remove(`${this.namespace}--over`,`${this.namespace}--noAnim`,`${this.namespace}--dragElem`)}),50)}))},cleanupLastTarget(){this.target.elm&&(this.target.elm.classList.remove(`${this.namespace}--hide`,`${this.namespace}--over`),this.target.elm.removeAttribute("style"))},getInitialState:()=>({elm:null,size:{}}),getItemsGap(t){var e=getComputedStyle(t),s=getComputedStyle(t.parentNode),i="vertical"==this.settings.mode,r=parseInt(s.gap)||0;return parseInt(e["margin"+(i?"Top":"Left")])+parseInt(e["margin"+(i?"Bottom":"Right")])+r},bindEvents(t){for(var e in this.listeners=this.listeners||{dragstart:t=>this.dragstart(t,t.target),dragenter:t=>this.dragenter(t,t.target),dragend:t=>this.dragend(t,t.target),dragover:this.throttle(this.dragover,350)},this.listeners)this.parentElm[t?"removeEventListener":"addEventListener"](e,this.listeners[e])},destroy(){this.cleanup(),this.bindEvents(!0),delete i[this.uid]}},function(t,s){return i[++e]=t.DragSort?i[t.DragSort]:new a(t,{...s,uid:e}),t.DragSort=e,i[e]}})); \ No newline at end of file diff --git a/src/dragsort.css b/src/dragsort.css index b60814c..c75125d 100644 --- a/src/dragsort.css +++ b/src/dragsort.css @@ -10,13 +10,13 @@ .dragsort--dragStart .dragsort--hide { width: 0 !important; height: 0 !important; - /* padding: 0; - margin: 0; - border-width: 0; */ + padding: 0 !important; + margin: 0 !important; + border-width: 0 !important; } .dragsort--dragStart > *{ - transition: .18s cubic-bezier(.6, .1, .4, 1.2); + transition: var(--dragsort-trans-dur, .18s) cubic-bezier(.6, .1, .4, 1.2); } .dragsort--dragStart > * > *{ diff --git a/src/dragsort.js b/src/dragsort.js index d0ccc46..6a83500 100644 --- a/src/dragsort.js +++ b/src/dragsort.js @@ -275,10 +275,14 @@ }, getItemsGap(elm) { - var styles = getComputedStyle(elm); - return this.settings.mode == 'vertical' ? - parseInt(styles.marginTop) + parseInt(styles.marginBottom) : - parseInt(styles.marginLeft) + parseInt(styles.marginRight) + var itemStyles = getComputedStyle(elm), + parentStyles = getComputedStyle(elm.parentNode), + v = this.settings.mode == 'vertical', + gap = parseInt(parentStyles.gap) || 0, // parent might be a flexbox witha a gap + marginGap = parseInt(itemStyles[`margin${v ? 'Top' : 'Left'}`]) + + parseInt(itemStyles[`margin${v ? 'Bottom' : 'Right'}`]) + + return marginGap + gap; }, bindEvents(unbind) { diff --git a/test/test.html b/test/test.html index a7466cf..0a18265 100644 --- a/test/test.html +++ b/test/test.html @@ -52,15 +52,18 @@

Horizontal Tags - Varying Widths

} .list { + --gap: 1vw; + + display: flex; + flex-wrap: wrap; + gap: var(--gap); + padding: var(--gap); + width: 100%; max-width: 600px; margin: 2rem auto; - padding: 0; list-style-type: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; + user-select: none; overflow: hidden; } @@ -93,11 +96,14 @@

Horizontal Tags - Varying Widths

font-weight: bold; border-radius: 20px; padding: 0.3em 0.5em; - margin: 5px 0 5px 5px; white-space: nowrap; box-sizing: border-box; overflow: hidden; } + +.card.dragsort--hide { + margin: 0 calc(var(--gap)/2 * -1); +}