2023-08-22 23:12:33 +02:00
/* eslint-disable */
import { reactive , openBlock , createBlock , resolveDynamicComponent , normalizeClass , createSlots , withCtx , renderSlot , normalizeProps , guardReactiveProps , createElementBlock , createCommentVNode , renderList , TransitionGroup , h , nextTick } from '../vue/vue' ;
function mitt ( n ) { return { all : n = n || new Map , on : function ( t , e ) { var i = n . get ( t ) ; i ? i . push ( e ) : n . set ( t , [ e ] ) ; } , off : function ( t , e ) { var i = n . get ( t ) ; i && ( e ? i . splice ( i . indexOf ( e ) >>> 0 , 1 ) : n . set ( t , [ ] ) ) ; } , emit : function ( t , e ) { var i = n . get ( t ) ; i && i . slice ( ) . map ( function ( n ) { n ( e ) ; } ) , ( i = n . get ( "*" ) ) && i . slice ( ) . map ( function ( n ) { n ( t , e ) ; } ) ; } } }
2023-08-21 22:04:51 +02:00
/ * *
* This is the class of the global object that holds the state of the drag and drop during its progress . It emits events
* reporting its state evolution during the progress of the drag and drop . Its data is reactive and listeners can be
* attached to it using the method on .
* /
class DnD {
inProgress = false ;
type = null ;
data = null ;
source = null ;
top = null ;
position = null ;
eventBus = mitt ( ) ;
success = null ;
startDrag ( source , event , x , y , type , data ) {
this . type = type ;
this . data = data ;
this . source = source ;
this . position = { x , y } ;
this . top = null ;
this . inProgress = true ;
this . emit ( event , 'dragstart' ) ;
this . emit ( event , 'dragtopchanged' , { previousTop : null } ) ;
}
resetVariables ( ) {
this . inProgress = false ;
this . data = null ;
this . source = null ;
this . position = null ;
this . success = null ;
}
stopDrag ( event ) {
this . success = this . top !== null && this . top [ 'compatibleMode' ] && this . top [ 'dropAllowed' ] ;
if ( this . top !== null ) {
this . emit ( event , 'drop' ) ;
}
this . emit ( event , 'dragend' ) ;
this . resetVariables ( ) ;
}
cancelDrag ( event ) {
this . success = false ;
this . emit ( event , 'dragend' ) ;
this . resetVariables ( ) ;
}
mouseMove ( event , comp ) {
if ( this . inProgress ) {
let prevent = false ;
const previousTop = this . top ;
if ( comp === null ) {
// The mouse move event reached the top of the document without hitting a drop component.
this . top = null ;
prevent = true ;
}
else if ( comp [ 'isDropMask' ] ) {
// The mouse move event bubbled until it reached a drop mask.
this . top = null ;
prevent = true ;
}
else if ( comp [ 'candidate' ] ( this . type , this . data , this . source ) ) {
// The mouse move event bubbled until it reached a drop component that participates in the current drag operation.
this . top = comp ;
prevent = true ;
}
if ( prevent ) {
// We prevent the mouse move event from bubbling further up the tree because it reached the foremost drop component and that component is all that matters.
event . stopPropagation ( ) ;
}
if ( this . top !== previousTop ) {
this . emit ( event . detail . native , 'dragtopchanged' , { previousTop : previousTop } ) ;
}
this . position = {
x : event . detail . x ,
y : event . detail . y
} ;
this . emit ( event . detail . native , 'dragpositionchanged' ) ;
}
}
emit ( native , event , data = { } ) {
this . eventBus . emit ( event , {
type : this . type ,
data : this . data ,
top : this . top ,
source : this . source ,
position : this . position ,
success : this . success ,
native ,
... data
} ) ;
}
on ( event , callback ) {
this . eventBus . on ( event , callback ) ;
}
off ( event , callback ) {
this . eventBus . off ( event , callback ) ;
}
}
2023-08-22 23:12:33 +02:00
const dnd = reactive ( new DnD ( ) ) ;
2023-08-21 22:04:51 +02:00
var DragAwareMixin = {
data ( ) {
return {
isDropMask : false
} ;
} ,
computed : {
dragInProgress ( ) {
return dnd . inProgress ;
} ,
dragData ( ) {
return dnd . data ;
} ,
dragType ( ) {
return dnd . type ;
} ,
dragPosition ( ) {
return dnd . position ;
} ,
dragSource ( ) {
return dnd . source ;
} ,
dragTop ( ) {
return dnd . top ;
}
}
2023-08-22 23:12:33 +02:00
} ;
2023-08-21 22:04:51 +02:00
/ * *
* This files contains the primitives required to create drag images from HTML elements that serve as models . A snapshot
* of the computed styles of the model elements is taken when creating the drag image , so that it will look the same as
* the model , no matter where the drag images is grafted into the DOM .
* /
/ * *
* Creates a drag image using the given element as model .
* /
function createDragImage ( el ) {
const clone = deepClone ( el ) ;
clone . style . position = 'fixed' ;
clone . style . margin = '0' ;
clone . style [ 'z-index' ] = '1000' ;
clone . style . transition = 'opacity 0.2s' ;
return clone ;
}
/ * *
* Clones the given element and all its descendants .
* /
function deepClone ( el ) {
const clone = el . cloneNode ( true ) ;
copyStyle ( el , clone ) ;
const vSrcElements = el . getElementsByTagName ( '*' ) ;
const vDstElements = clone . getElementsByTagName ( '*' ) ;
for ( let i = vSrcElements . length ; i -- ; ) {
const vSrcElement = vSrcElements [ i ] ;
const vDstElement = vDstElements [ i ] ;
copyStyle ( vSrcElement , vDstElement ) ;
}
return clone ;
}
/ * *
* Copy the computed styles from src to destination .
* /
function copyStyle ( src , destination ) {
const computedStyle = window . getComputedStyle ( src ) ;
for ( const key of computedStyle ) {
if ( key === 'width' ) {
// IE11
const width = computedStyle . getPropertyValue ( 'box-sizing' ) === 'border-box' ?
src . clientWidth :
src . clientWidth - parseFloat ( computedStyle . paddingLeft ) - parseFloat ( computedStyle . paddingRight ) ;
destination . style . setProperty ( 'width' , width + 'px' ) ;
}
else if ( key === 'height' ) {
// IE11
const height = computedStyle . getPropertyValue ( 'box-sizing' ) === 'border-box' ?
src . clientHeight :
src . clientHeight - parseFloat ( computedStyle . paddingTop ) - parseFloat ( computedStyle . paddingBottom ) ;
destination . style . setProperty ( 'height' , height + 'px' ) ;
}
else {
destination . style . setProperty ( key , computedStyle . getPropertyValue ( key ) , computedStyle . getPropertyPriority ( key ) ) ;
}
}
destination . style . pointerEvents = 'none' ;
2023-08-22 23:12:33 +02:00
}
2023-08-21 22:04:51 +02:00
// Forked from https://gist.github.com/gre/296291b8ce0d8fe6e1c3ea4f1d1c5c3b
const regex = /(auto|scroll)/ ;
const style = ( node , prop ) =>
getComputedStyle ( node , null ) . getPropertyValue ( prop ) ;
const scroll = ( node ) =>
regex . test (
style ( node , 'overflow' ) +
style ( node , 'overflow-y' ) +
style ( node , 'overflow-x' ) ) ;
const scrollparent = ( node ) =>
! node || node === document . body
? document . body
: scroll ( node )
? node
2023-08-22 23:12:33 +02:00
: scrollparent ( node . parentNode ) ;
2023-08-21 22:04:51 +02:00
// Forked from https://github.com/bennadel/JavaScript-Demos/blob/master/demos/window-edge-scrolling/index.htm
// Code was altered to work with scrollable containers
var timer = null ;
function cancelScrollAction ( ) {
clearTimeout ( timer ) ;
}
function performEdgeScroll ( event , container , clientX , clientY , edgeSize ) {
if ( ! container || ! edgeSize ) {
cancelScrollAction ( ) ;
return false ;
}
// NOTE: Much of the information here, with regard to document dimensions,
// viewport dimensions, and window scrolling is derived from JavaScript.info.
// I am consuming it here primarily as NOTE TO SELF.
// --
// Read More: https://javascript.info/size-and-scroll-window
// --
// CAUTION: The viewport and document dimensions can all be CACHED and then
// recalculated on window-resize events (for the most part). I am keeping it
// all here in the mousemove event handler to remove as many of the moving
// parts as possible and keep the demo as simple as possible.
// Get the viewport-relative coordinates of the mousemove event.
var rect = container . getBoundingClientRect ( ) ;
var isBody = container === document . body ;
var viewportX = clientX - rect . left ;
var viewportY = clientY - rect . top ;
if ( isBody ) {
viewportX = clientX ;
viewportY = clientY ;
}
// Get the viewport dimensions.
var viewportWidth = rect . width ;
var viewportHeight = rect . height ;
if ( isBody ) {
viewportWidth = document . documentElement . clientWidth ;
viewportHeight = document . documentElement . clientHeight ;
}
// Next, we need to determine if the mouse is within the "edge" of the
// viewport, which may require scrolling the window. To do this, we need to
// calculate the boundaries of the edge in the viewport (these coordinates
// are relative to the viewport grid system).
var edgeTop = edgeSize ;
var edgeLeft = edgeSize ;
var edgeBottom = ( viewportHeight - edgeSize ) ;
var edgeRight = ( viewportWidth - edgeSize ) ;
var isInLeftEdge = ( viewportX < edgeLeft ) ;
var isInRightEdge = ( viewportX > edgeRight ) ;
var isInTopEdge = ( viewportY < edgeTop ) ;
var isInBottomEdge = ( viewportY > edgeBottom ) ;
// If the mouse is not in the viewport edge, there's no need to calculate
// anything else.
if ( ! ( isInLeftEdge || isInRightEdge || isInTopEdge || isInBottomEdge ) ) {
cancelScrollAction ( ) ;
return false ;
}
// If we made it this far, the user's mouse is located within the edge of the
// viewport. As such, we need to check to see if scrolling needs to be done.
// Get the document dimensions.
var documentWidth = Math . max (
container . scrollWidth ,
container . offsetWidth ,
container . clientWidth
) ;
var documentHeight = Math . max (
container . scrollHeight ,
container . offsetHeight ,
container . clientHeight
) ;
// Calculate the maximum scroll offset in each direction. Since you can only
// scroll the overflow portion of the document, the maximum represents the
// length of the document that is NOT in the viewport.
var maxScrollX = ( documentWidth - viewportWidth ) ;
var maxScrollY = ( documentHeight - viewportHeight ) ;
// As we examine the mousemove event, we want to adjust the window scroll in
// immediate response to the event; but, we also want to continue adjusting
// the window scroll if the user rests their mouse in the edge boundary. To
// do this, we'll invoke the adjustment logic immediately. Then, we'll setup
// a timer that continues to invoke the adjustment logic while the window can
// still be scrolled in a particular direction.
( function checkForWindowScroll ( ) {
cancelScrollAction ( ) ;
if ( adjustWindowScroll ( ) ) {
timer = setTimeout ( checkForWindowScroll , 30 ) ;
}
} ) ( ) ;
// Adjust the window scroll based on the user's mouse position. Returns True
// or False depending on whether or not the window scroll was changed.
function adjustWindowScroll ( ) {
// Get the current scroll position of the document.
var currentScrollX = container . scrollLeft ;
var currentScrollY = container . scrollTop ;
if ( isBody ) {
currentScrollX = window . pageXOffset ;
currentScrollY = window . pageYOffset ;
}
// Determine if the window can be scrolled in any particular direction.
var canScrollUp = ( currentScrollY > 0 ) ;
var canScrollDown = ( currentScrollY < maxScrollY ) ;
var canScrollLeft = ( currentScrollX > 0 ) ;
var canScrollRight = ( currentScrollX < maxScrollX ) ;
// Since we can potentially scroll in two directions at the same time,
// let's keep track of the next scroll, starting with the current scroll.
// Each of these values can then be adjusted independently in the logic
// below.
var nextScrollX = currentScrollX ;
var nextScrollY = currentScrollY ;
// As we examine the mouse position within the edge, we want to make the
// incremental scroll changes more "intense" the closer that the user
// gets the viewport edge. As such, we'll calculate the percentage that
// the user has made it "through the edge" when calculating the delta.
// Then, that use that percentage to back-off from the "max" step value.
var maxStep = 50 ;
// Should we scroll left?
if ( isInLeftEdge && canScrollLeft ) {
const intensity = ( ( edgeLeft - viewportX ) / edgeSize ) ;
nextScrollX = ( nextScrollX - ( maxStep * intensity ) ) ;
}
// Should we scroll right?
else if ( isInRightEdge && canScrollRight ) {
const intensity = ( ( viewportX - edgeRight ) / edgeSize ) ;
nextScrollX = ( nextScrollX + ( maxStep * intensity ) ) ;
}
// Should we scroll up?
if ( isInTopEdge && canScrollUp ) {
const intensity = ( ( edgeTop - viewportY ) / edgeSize ) ;
nextScrollY = ( nextScrollY - ( maxStep * intensity ) ) ;
}
// Should we scroll down?
else if ( isInBottomEdge && canScrollDown ) {
const intensity = ( ( viewportY - edgeBottom ) / edgeSize ) ;
nextScrollY = ( nextScrollY + ( maxStep * intensity ) ) ;
}
// Sanitize invalid maximums. An invalid scroll offset won't break the
// subsequent .scrollTo() call; however, it will make it harder to
// determine if the .scrollTo() method should have been called in the
// first place.
nextScrollX = Math . max ( 0 , Math . min ( maxScrollX , nextScrollX ) ) ;
nextScrollY = Math . max ( 0 , Math . min ( maxScrollY , nextScrollY ) ) ;
if (
( nextScrollX !== currentScrollX ) ||
( nextScrollY !== currentScrollY )
) {
( isBody ? window : container ) . scrollTo ( nextScrollX , nextScrollY ) ;
return true ;
}
else {
return false ;
}
}
return true ;
2023-08-22 23:12:33 +02:00
}
2023-08-21 22:04:51 +02:00
var DragMixin = {
mixins : [ DragAwareMixin ] ,
props : {
type : {
type : String ,
default : null
} ,
data : {
default : null
} ,
dragImageOpacity : {
type : Number ,
default : 0.7
} ,
disabled : {
type : Boolean ,
default : false
} ,
goBack : {
type : Boolean ,
default : false
} ,
handle : {
type : String ,
default : null
} ,
delta : {
type : Number ,
default : 0
} ,
delay : {
type : Number ,
default : 0
} ,
dragClass : {
type : String ,
default : null
} ,
vibration : {
type : Number ,
default : 0
} ,
scrollingEdgeSize : {
type : Number ,
default : 100
}
} ,
emits : [ 'dragstart' , 'dragend' , 'cut' , 'copy' ] ,
data ( ) {
return {
dragInitialised : false ,
dragStarted : false ,
ignoreNextClick : false ,
initialUserSelect : null ,
downEvent : null ,
startPosition : null ,
delayTimer : null ,
scrollContainer : null
} ;
} ,
computed : {
cssClasses ( ) {
const clazz = {
'dnd-drag' : true
} ;
if ( ! this . disabled ) {
return {
... clazz ,
'drag-source' : this . dragInProgress && this . dragSource === this ,
'drag-mode-copy' : this . currentDropMode === 'copy' ,
'drag-mode-cut' : this . currentDropMode === 'cut' ,
'drag-mode-reordering' : this . currentDropMode === 'reordering' ,
'drag-no-handle' : ! this . handle
} ;
}
else {
return clazz ;
}
} ,
currentDropMode ( ) {
if ( this . dragInProgress && this . dragSource === this ) {
if ( this . dragTop && this . dragTop [ 'dropAllowed' ] ) {
if ( this . dragTop [ 'reordering' ] ) {
return 'reordering' ;
}
else {
return this . dragTop [ 'mode' ] ;
}
}
else {
return null ;
}
}
else {
return null ;
}
}
} ,
methods : {
onSelectStart ( e ) {
e . stopPropagation ( ) ;
e . preventDefault ( ) ;
} ,
performVibration ( ) {
// If browser can perform vibration and user has defined a vibration, perform it
if ( this . vibration > 0 && window . navigator && window . navigator . vibrate ) {
window . navigator . vibrate ( this . vibration ) ;
}
} ,
onMouseDown ( e ) {
let target = null ;
let goodButton = false ;
if ( e . type === 'mousedown' ) {
const mouse = e ;
target = e . target ;
goodButton = mouse . buttons === 1 ;
}
else {
const touch = e ;
target = touch . touches [ 0 ] . target ;
goodButton = true ;
}
if ( this . disabled || this . downEvent !== null || ! goodButton ) {
return ;
}
// Check that the target element is eligible for starting a drag
// Includes checking against the handle selector
// or whether the element contains 'dnd-no-drag' class (which should disable dragging from that
// sub-element of a draggable parent)
const goodTarget = ! target . matches ( '.dnd-no-drag, .dnd-no-drag *' ) &&
(
! this . handle ||
target . matches ( this . handle + ', ' + this . handle + ' *' )
) ;
if ( ! goodTarget ) {
return ;
}
this . scrollContainer = scrollparent ( target ) ;
this . initialUserSelect = document . body . style . userSelect ;
document . documentElement . style . userSelect = 'none' ; // Permet au drag de se poursuivre normalement même
// quand on quitte un élémént avec overflow: hidden.
this . dragStarted = false ;
this . downEvent = e ;
if ( this . downEvent . type === 'mousedown' ) {
const mouse = e ;
this . startPosition = {
x : mouse . clientX ,
y : mouse . clientY
} ;
}
else {
const touch = e ;
this . startPosition = {
x : touch . touches [ 0 ] . clientX ,
y : touch . touches [ 0 ] . clientY
} ;
}
if ( this . delay ) {
this . dragInitialised = false ;
clearTimeout ( this . delayTimer ) ;
this . delayTimer = setTimeout ( ( ) => {
this . dragInitialised = true ;
this . performVibration ( ) ;
} , this . delay ) ;
}
else {
this . dragInitialised = true ;
this . performVibration ( ) ;
}
document . addEventListener ( 'click' , this . onMouseClick , true ) ;
document . addEventListener ( 'mouseup' , this . onMouseUp ) ;
document . addEventListener ( 'touchend' , this . onMouseUp ) ;
document . addEventListener ( 'selectstart' , this . onSelectStart ) ;
document . addEventListener ( 'keyup' , this . onKeyUp ) ;
setTimeout ( ( ) => {
document . addEventListener ( 'mousemove' , this . onMouseMove ) ;
document . addEventListener ( 'touchmove' , this . onMouseMove , { passive : false } ) ;
document . addEventListener ( 'easy-dnd-move' , this . onEasyDnDMove ) ;
} , 0 ) ;
// Prevents event from bubbling to ancestor drag components and initiate several drags at the same time
e . stopPropagation ( ) ;
} ,
// Prevent the user from accidentally causing a click event
// if they have just attempted a drag event
onMouseClick ( e ) {
if ( this . ignoreNextClick ) {
e . preventDefault ( ) ;
e . stopPropagation && e . stopPropagation ( ) ;
e . stopImmediatePropagation && e . stopImmediatePropagation ( ) ;
this . ignoreNextClick = false ;
return false ;
}
} ,
onMouseMove ( e ) {
// We ignore the mousemove event that follows touchend :
if ( this . downEvent === null ) return ;
// On touch devices, we ignore fake mouse events and deal with touch events only.
if ( this . downEvent . type === 'touchstart' && e . type === 'mousemove' ) return ;
// Find out event target and pointer position :
let target = null ;
let x = null ;
let y = null ;
if ( e . type === 'touchmove' ) {
const touch = e ;
x = touch . touches [ 0 ] . clientX ;
y = touch . touches [ 0 ] . clientY ;
target = document . elementFromPoint ( x , y ) ;
if ( ! target ) {
// Mouse going off screen. Ignore event.
return ;
}
}
else {
const mouse = e ;
x = mouse . clientX ;
y = mouse . clientY ;
target = mouse . target ;
}
// Distance between current event and start position :
const dist = Math . sqrt ( Math . pow ( this . startPosition . x - x , 2 ) + Math . pow ( this . startPosition . y - y , 2 ) ) ;
// If the drag has not begun yet and distance from initial point is greater than delta, we start the drag :
if ( ! this . dragStarted && dist > this . delta ) {
// If they have dragged greater than the delta before the delay period has ended,
// It means that they attempted to perform another action (such as scrolling) on the page
if ( ! this . dragInitialised ) {
clearTimeout ( this . delayTimer ) ;
}
else {
this . ignoreNextClick = true ;
this . dragStarted = true ;
dnd . startDrag ( this , this . downEvent , this . startPosition . x , this . startPosition . y , this . type , this . data ) ;
document . documentElement . classList . add ( 'drag-in-progress' ) ;
}
}
// Dispatch custom easy-dnd-move event :
if ( this . dragStarted ) {
// If cursor/touch is at edge of container, perform scroll if available
// If this.dragTop is defined, it means they are dragging on top of another DropList/EasyDnd component
// if dropTop is a DropList, use the scrollingEdgeSize of that container if it exists, otherwise use the scrollingEdgeSize of the Drag component
const currEdgeSize = this . dragTop && this . dragTop . $props . scrollingEdgeSize !== undefined ?
this . dragTop . $props . scrollingEdgeSize :
this . scrollingEdgeSize ;
if ( currEdgeSize ) {
const currScrollContainer = this . dragTop ? scrollparent ( this . dragTop . $el ) : this . scrollContainer ;
performEdgeScroll ( e , currScrollContainer , x , y , currEdgeSize ) ;
}
else {
cancelScrollAction ( ) ;
}
const custom = new CustomEvent ( 'easy-dnd-move' , {
bubbles : true ,
cancelable : true ,
detail : {
x ,
y ,
native : e
}
} ) ;
target . dispatchEvent ( custom ) ;
}
// Prevent scroll on touch devices if they were performing a drag
if ( this . dragInitialised && e . cancelable ) {
e . preventDefault ( ) ;
}
} ,
onEasyDnDMove ( e ) {
dnd . mouseMove ( e , null ) ;
} ,
onMouseUp ( e ) {
// On touch devices, we ignore fake mouse events and deal with touch events only.
if ( this . downEvent . type === 'touchstart' && e . type === 'mouseup' ) return ;
// This delay makes sure that when the click event that results from the mouseup is produced, the drag is
// still in progress. So by checking the flag dnd.inProgress, one can tell apart true clicks from drag and
// drop artefacts.
setTimeout ( ( ) => {
this . cancelDragActions ( ) ;
if ( this . dragStarted ) {
dnd . stopDrag ( e ) ;
}
this . finishDrag ( ) ;
} , 0 ) ;
} ,
onKeyUp ( e ) {
// If ESC is pressed, cancel the drag
if ( e . key === 'Escape' ) {
this . cancelDragActions ( ) ;
setTimeout ( ( ) => {
dnd . cancelDrag ( e ) ;
this . finishDrag ( ) ;
} , 0 ) ;
}
} ,
cancelDragActions ( ) {
this . dragInitialised = false ;
clearTimeout ( this . delayTimer ) ;
cancelScrollAction ( ) ;
} ,
finishDrag ( ) {
this . downEvent = null ;
this . scrollContainer = null ;
if ( this . dragStarted ) {
document . documentElement . classList . remove ( 'drag-in-progress' ) ;
}
document . removeEventListener ( 'click' , this . onMouseClick , true ) ;
document . removeEventListener ( 'mousemove' , this . onMouseMove ) ;
document . removeEventListener ( 'touchmove' , this . onMouseMove ) ;
document . removeEventListener ( 'easy-dnd-move' , this . onEasyDnDMove ) ;
document . removeEventListener ( 'mouseup' , this . onMouseUp ) ;
document . removeEventListener ( 'touchend' , this . onMouseUp ) ;
document . removeEventListener ( 'selectstart' , this . onSelectStart ) ;
document . removeEventListener ( 'keyup' , this . onKeyUp ) ;
document . documentElement . style . userSelect = this . initialUserSelect ;
} ,
dndDragStart ( ev ) {
if ( ev . source === this ) {
this . $emit ( 'dragstart' , ev ) ;
}
} ,
dndDragEnd ( ev ) {
if ( ev . source === this ) {
this . $emit ( 'dragend' , ev ) ;
}
} ,
createDragImage ( selfTransform ) {
let image ;
if ( this . $slots [ 'drag-image' ] ) {
const el = this . $refs [ 'drag-image' ] || document . createElement ( 'div' ) ;
if ( el . childElementCount !== 1 ) {
image = createDragImage ( el ) ;
}
else {
image = createDragImage ( el . children . item ( 0 ) ) ;
}
}
else {
image = createDragImage ( this . $el ) ;
image . style . transform = selfTransform ;
}
if ( this . dragClass ) {
image . classList . add ( this . dragClass ) ;
}
image . classList . add ( 'dnd-ghost' ) ;
image [ '__opacity' ] = this . dragImageOpacity ;
return image ;
}
} ,
created ( ) {
dnd . on ( 'dragstart' , this . dndDragStart ) ;
dnd . on ( 'dragend' , this . dndDragEnd ) ;
} ,
mounted ( ) {
this . $el . addEventListener ( 'mousedown' , this . onMouseDown ) ;
this . $el . addEventListener ( 'touchstart' , this . onMouseDown ) ;
} ,
beforeUnmount ( ) {
dnd . off ( 'dragstart' , this . dndDragStart ) ;
dnd . off ( 'dragend' , this . dndDragEnd ) ;
this . $el . removeEventListener ( 'mousedown' , this . onMouseDown ) ;
this . $el . removeEventListener ( 'touchstart' , this . onMouseDown ) ;
}
2023-08-22 23:12:33 +02:00
} ;
2023-08-21 22:04:51 +02:00
var script$4 = {
name : 'Drag' ,
mixins : [ DragMixin ] ,
props : {
/ * *
* Tag to be used as root of this component . Defaults to div .
* /
tag : {
type : [ String , Object , Function ] ,
default : 'div'
}
} ,
computed : {
dynamicSlots ( ) {
return Object . entries ( this . $slots ) . filter ( ( [ key ] ) => key !== 'drag-image' && key !== 'default' ) ;
}
}
2023-08-22 23:12:33 +02:00
} ;
const _hoisted _1$2 = {
key : 0 ,
ref : "drag-image" ,
class : "__drag-image"
} ;
function render$3 ( _ctx , _cache , $props , $setup , $data , $options ) {
return ( openBlock ( ) , createBlock ( resolveDynamicComponent ( $props . tag ) , {
class : normalizeClass ( _ctx . cssClasses )
} , createSlots ( {
default : withCtx ( ( ) => [
renderSlot ( _ctx . $slots , "default" , normalizeProps ( guardReactiveProps ( _ctx . $slots [ 'default' ] || { } ) ) ) ,
( _ctx . dragInitialised )
? ( openBlock ( ) , createElementBlock ( "div" , _hoisted _1$2 , [
renderSlot ( _ctx . $slots , "drag-image" )
] , 512 /* NEED_PATCH */ ) )
: createCommentVNode ( "v-if" , true )
] ) ,
_ : 2 /* DYNAMIC */
} , [
renderList ( $options . dynamicSlots , ( [ slot , args ] ) => {
return {
name : slot ,
fn : withCtx ( ( ) => [
renderSlot ( _ctx . $slots , slot , normalizeProps ( guardReactiveProps ( args ) ) )
] )
}
} )
] ) , 1032 /* PROPS, DYNAMIC_SLOTS */ , [ "class" ] ) )
}
script$4 . render = render$3 ;
script$4 . _ _scopeId = "data-v-f87407ce" ;
2023-08-21 22:04:51 +02:00
function dropAllowed ( inst ) {
if ( inst . dragInProgress && inst . typeAllowed ) {
return inst . compatibleMode && inst . effectiveAcceptsData ( inst . dragData , inst . dragType ) ;
}
return null ;
}
function doDrop ( inst , event ) {
inst . $emit ( 'drop' , event ) ;
event . source . $emit ( inst . mode , event ) ;
}
function candidate ( inst , type ) {
return inst . effectiveAcceptsType ( type ) ;
}
var DropMixin = {
mixins : [ DragAwareMixin ] ,
props : {
acceptsType : {
type : [ String , Array , Function ] ,
default : null
} ,
acceptsData : {
type : Function ,
default : ( ) => {
return true ;
}
} ,
mode : {
type : String ,
default : 'copy'
} ,
dragImageOpacity : {
type : Number ,
default : 0.7
}
} ,
emits : [ 'dragover' , 'dragenter' , 'dragleave' , 'dragend' , 'drop' ] ,
data ( ) {
return {
isDrop : true
} ;
} ,
computed : {
compatibleMode ( ) {
return this . dragInProgress ? true : null ;
} ,
dropIn ( ) {
if ( this . dragInProgress ) {
return this . dragTop === this ;
}
return null ;
} ,
typeAllowed ( ) {
if ( this . dragInProgress ) {
return this . effectiveAcceptsType ( this . dragType ) ;
}
return null ;
} ,
dropAllowed ( ) {
return dropAllowed ( this ) ;
} ,
cssClasses ( ) {
const clazz = {
'dnd-drop' : true
} ;
if ( this . dropIn !== null ) {
clazz [ 'drop-in' ] = this . dropIn ;
clazz [ 'drop-out' ] = ! this . dropIn ;
}
if ( this . typeAllowed !== null ) {
clazz [ 'type-allowed' ] = this . typeAllowed ;
clazz [ 'type-forbidden' ] = ! this . typeAllowed ;
}
if ( this . dropAllowed !== null ) {
clazz [ 'drop-allowed' ] = this . dropAllowed ;
clazz [ 'drop-forbidden' ] = ! this . dropAllowed ;
}
return clazz ;
}
} ,
methods : {
effectiveAcceptsType ( type ) {
if ( this . acceptsType === null ) {
return true ;
}
else if ( typeof ( this . acceptsType ) === 'string' || typeof ( this . acceptsType ) === 'number' ) {
return this . acceptsType === type ;
}
else if ( typeof ( this . acceptsType ) === 'object' && Array . isArray ( this . acceptsType ) ) {
return this . acceptsType . includes ( type ) ;
}
else {
return this . acceptsType ( type ) ;
}
} ,
effectiveAcceptsData ( data , type ) {
return this . acceptsData ( data , type ) ;
} ,
onDragPositionChanged ( event ) {
if ( this === event . top ) {
this . $emit ( 'dragover' , event ) ;
}
} ,
onDragTopChanged ( event ) {
if ( this === event . top ) {
this . $emit ( 'dragenter' , event ) ;
}
if ( this === event . previousTop ) {
this . $emit ( 'dragleave' , event ) ;
}
} ,
onDragEnd ( event ) {
if ( this === event . top ) {
this . $emit ( 'dragend' , event ) ;
}
} ,
onDrop ( event ) {
if ( this . dropIn && this . compatibleMode && this . dropAllowed ) {
this . doDrop ( event ) ;
}
} ,
doDrop ( event ) {
doDrop ( this , event ) ;
} ,
/ * *
* Returns true if the current drop area participates in the current drag operation .
* /
candidate ( type ) {
return candidate ( this , type ) ;
} ,
createDragImage ( ) {
let image = 'source' ;
if ( this . $refs [ 'drag-image' ] ) {
const el = this . $refs [ 'drag-image' ] ;
if ( el . childElementCount !== 1 ) {
image = createDragImage ( el ) ;
}
else {
image = createDragImage ( el . children . item ( 0 ) ) ;
}
image [ '__opacity' ] = this . dragImageOpacity ;
image . classList . add ( 'dnd-ghost' ) ;
}
return image ;
} ,
onDnDMove ( e ) {
dnd . mouseMove ( e , this ) ;
}
} ,
created ( ) {
dnd . on ( 'dragpositionchanged' , this . onDragPositionChanged ) ;
dnd . on ( 'dragtopchanged' , this . onDragTopChanged ) ;
dnd . on ( 'drop' , this . onDrop ) ;
dnd . on ( 'dragend' , this . onDragEnd ) ;
} ,
mounted ( ) {
this . $el . addEventListener ( 'easy-dnd-move' , this . onDnDMove ) ;
} ,
beforeUnmount ( ) {
this . $el . removeEventListener ( 'easy-dnd-move' , this . onDnDMove ) ;
dnd . off ( 'dragpositionchanged' , this . onDragPositionChanged ) ;
dnd . off ( 'dragtopchanged' , this . onDragTopChanged ) ;
dnd . off ( 'drop' , this . onDrop ) ;
dnd . off ( 'dragend' , this . onDragEnd ) ;
}
2023-08-22 23:12:33 +02:00
} ;
2023-08-21 22:04:51 +02:00
var script$3 = {
name : 'Drop' ,
mixins : [ DropMixin ] ,
props : {
tag : {
type : [ String , Object , Function ] ,
default : 'div'
}
} ,
computed : {
dynamicSlots ( ) {
return Object . entries ( this . $slots ) . filter ( ( [ key ] ) => key !== 'drag-image' && key !== 'default' ) ;
} ,
showDragImage ( ) {
return this . dragInProgress && this . typeAllowed && ! ! this . $slots [ 'drag-image' ] ;
}
}
2023-08-22 23:12:33 +02:00
} ;
const _hoisted _1$1 = {
key : 0 ,
ref : "drag-image" ,
class : "__drag-image"
} ;
function render$2 ( _ctx , _cache , $props , $setup , $data , $options ) {
return ( openBlock ( ) , createBlock ( resolveDynamicComponent ( $props . tag ) , {
class : normalizeClass ( _ctx . cssClasses )
} , createSlots ( {
default : withCtx ( ( ) => [
renderSlot ( _ctx . $slots , "default" , normalizeProps ( guardReactiveProps ( _ctx . $slots [ 'default' ] || { } ) ) ) ,
( $options . showDragImage )
? ( openBlock ( ) , createElementBlock ( "div" , _hoisted _1$1 , [
renderSlot ( _ctx . $slots , "drag-image" , {
type : _ctx . dragType ,
data : _ctx . dragData
} )
] , 512 /* NEED_PATCH */ ) )
: createCommentVNode ( "v-if" , true )
] ) ,
_ : 2 /* DYNAMIC */
} , [
renderList ( $options . dynamicSlots , ( [ slot , args ] ) => {
return {
name : slot ,
fn : withCtx ( ( ) => [
renderSlot ( _ctx . $slots , slot , normalizeProps ( guardReactiveProps ( args ) ) )
] )
}
} )
] ) , 1032 /* PROPS, DYNAMIC_SLOTS */ , [ "class" ] ) )
}
script$3 . render = render$2 ;
script$3 . _ _scopeId = "data-v-12a39e52" ;
2023-08-21 22:04:51 +02:00
var script$2 = {
name : 'DropMask' ,
mixins : [ DragAwareMixin ] ,
props : {
tag : {
type : [ String , Object , Function ] ,
default : 'div'
}
} ,
data ( ) {
return {
isDropMask : true
} ;
} ,
mounted ( ) {
this . $el . addEventListener ( 'easy-dnd-move' , this . onDndMove ) ;
} ,
beforeUnmount ( ) {
this . $el . removeEventListener ( 'easy-dnd-move' , this . onDndMove ) ;
} ,
methods : {
createDragImage ( ) {
return 'source' ;
} ,
onDndMove ( e ) {
dnd . mouseMove ( e , this ) ;
}
}
2023-08-22 23:12:33 +02:00
} ;
function render$1 ( _ctx , _cache , $props , $setup , $data , $options ) {
return ( openBlock ( ) , createBlock ( resolveDynamicComponent ( $props . tag ) , null , createSlots ( { _ : 2 /* DYNAMIC */ } , [
renderList ( _ctx . $slots , ( args , slot ) => {
return {
name : slot ,
fn : withCtx ( ( ) => [
renderSlot ( _ctx . $slots , slot , normalizeProps ( guardReactiveProps ( args ) ) )
] )
}
} )
] ) , 1024 /* DYNAMIC_SLOTS */ ) )
}
script$2 . render = render$1 ;
2023-08-21 22:04:51 +02:00
var script$1 = {
name : 'DragFeedback'
2023-08-22 23:12:33 +02:00
} ;
const _hoisted _1 = { class : "DragFeedback" } ;
function render ( _ctx , _cache , $props , $setup , $data , $options ) {
return ( openBlock ( ) , createElementBlock ( "div" , _hoisted _1 , [
renderSlot ( _ctx . $slots , "default" )
] ) )
}
script$1 . render = render ;
2023-08-21 22:04:51 +02:00
class Grid {
reference ;
referenceOriginalPosition ;
magnets = [ ] ;
constructor ( collection , upToIndex , direction , fromIndex ) {
this . reference = collection . item ( 0 ) . parentNode ;
this . referenceOriginalPosition = {
x : this . reference . getBoundingClientRect ( ) . left - this . reference . scrollLeft ,
y : this . reference . getBoundingClientRect ( ) . top - this . reference . scrollTop ,
} ;
let index = 0 ;
for ( const child of collection ) {
if ( index > upToIndex ) break ;
const rect = child . getBoundingClientRect ( ) ;
const hasNestedDrop = child . classList . contains ( 'dnd-drop' ) || child . getElementsByClassName ( 'dnd-drop' ) . length > 0 ;
let horizontal = false ;
if ( hasNestedDrop ) {
if ( direction === 'auto' ) {
// Auto mode not supported for now. Row or column must be defined explicitly if there are nested drop lists.
throw 'Easy-DnD error : a drop list is missing one of these attributes : \'row\' or \'column\'.' ;
}
else {
horizontal = direction === 'row' ;
}
}
if ( fromIndex === null ) {
// Inserting mode.
this . magnets . push ( hasNestedDrop ? this . before ( rect , horizontal ) : this . center ( rect ) ) ;
}
else {
// Reordering mode.
this . magnets . push ( hasNestedDrop ? (
fromIndex < index ? this . after : this . before
) ( rect , horizontal ) : this . center ( rect ) ) ;
}
// Debug : show magnets :
//document.body.insertAdjacentHTML("beforeend", "<div style='background-color: red; position: fixed; width: 1px; height: 1px; top:" + this.magnets[index].y + "px; left:" + this.magnets[index].x + "px;' ></div>")
index ++ ;
}
}
/ * *
* Returns the center of the rectangle .
* /
center ( rect ) {
return {
x : rect . left + rect . width / 2 ,
y : rect . top + rect . height / 2
} ;
}
/ * *
* When horizontal is true / false , returns middle of the left / top side of the rectangle .
* /
before ( rect , horizontal ) {
return horizontal ? {
x : rect . left ,
y : rect . top + rect . height / 2
} : {
x : rect . left + rect . width / 2 ,
y : rect . top
} ;
}
/ * *
* When horizontal is true / false , returns middle of the right / bottom side of the rectangle .
* /
after ( rect , horizontal ) {
return horizontal ? {
x : rect . left + rect . width ,
y : rect . top + rect . height / 2
} : {
x : rect . left + rect . width / 2 ,
y : rect . top + rect . height
} ;
}
/ * *
* In case the user scrolls during the drag , the position of the magnets are not what they used to be when the drag
* started . A correction must be applied that takes into account the amount of scroll . This correction is the
* difference between the current position of the parent element and its position when the drag started .
* /
correction ( ) {
return {
x : this . reference . getBoundingClientRect ( ) . left - this . reference . scrollLeft - this . referenceOriginalPosition . x ,
y : this . reference . getBoundingClientRect ( ) . top - this . reference . scrollTop - this . referenceOriginalPosition . y ,
} ;
}
closestIndex ( position ) {
const x = position . x - this . correction ( ) . x ;
const y = position . y - this . correction ( ) . y ;
let minDist = 999999 ;
let index = - 1 ;
for ( let i = 0 ; i < this . magnets . length ; i ++ ) {
const magnet = this . magnets [ i ] ;
const dist = Math . sqrt ( Math . pow ( magnet . x - x , 2 ) + Math . pow ( magnet . y - y , 2 ) ) ;
if ( dist < minDist ) {
minDist = dist ;
index = i ;
}
}
return index ;
}
2023-08-22 23:12:33 +02:00
}
2023-08-21 22:04:51 +02:00
class DnDEvent {
type ;
data ;
top ;
previousTop ;
source ;
position ;
success ;
native ;
}
class ReorderEvent {
from ;
to ;
constructor ( from , to ) {
this . from = from ;
this . to = to ;
}
apply ( array ) {
const temp = array [ this . from ] ;
array . splice ( this . from , 1 ) ;
array . splice ( this . to , 0 , temp ) ;
}
}
class InsertEvent {
type ;
data ;
index ;
constructor ( type , data , index ) {
this . type = type ;
this . data = data ;
this . index = index ;
}
2023-08-22 23:12:33 +02:00
}
2023-08-21 22:04:51 +02:00
var script = {
name : 'DropList' ,
mixins : [ DropMixin ] ,
props : {
tag : {
type : [ String , Object , Function ] ,
default : 'div'
} ,
items : {
type : Array ,
required : true
} ,
row : {
type : Boolean ,
default : false
} ,
column : {
type : Boolean ,
default : false
} ,
noAnimations : {
type : Boolean ,
default : false
} ,
scrollingEdgeSize : {
type : Number ,
default : undefined
}
} ,
emits : [ 'reorder' , 'insert' ] ,
data ( ) {
return {
grid : null ,
forbiddenKeys : [ ] ,
feedbackKey : null ,
fromIndex : null
} ;
} ,
computed : {
rootTag ( ) {
if ( this . noAnimations ) {
return this . tag ;
}
return TransitionGroup ;
} ,
rootProps ( ) {
if ( this . noAnimations ) {
return { } ;
}
return {
tag : this . tag ,
css : false
} ;
} ,
direction ( ) {
// todo - rewrite this logic
if ( this . row ) return 'row' ;
if ( this . column ) return 'column' ;
return 'auto' ;
} ,
reordering ( ) {
if ( dnd . inProgress ) {
return dnd . source . $el . parentElement === this . $el ;
}
return null ;
} ,
closestIndex ( ) {
if ( this . grid ) {
return this . grid . closestIndex ( dnd . position ) ;
}
return null ;
} ,
dropAllowed ( ) {
if ( this . dragInProgress ) {
if ( this . reordering ) {
return this . items . length > 1 ;
}
else {
// todo - eventually refactor so that this isn't necessary
if ( ! dropAllowed ( this ) ) {
return false ;
}
if ( this . forbiddenKeys !== null && this . feedbackKey !== null ) {
return ! this . forbiddenKeys . includes ( this . feedbackKey ) ;
}
return true ;
}
}
return null ;
} ,
itemsBeforeFeedback ( ) {
if ( this . closestIndex === 0 ) {
return [ ] ;
}
return this . items . slice ( 0 , this . closestIndex ) ;
} ,
itemsAfterFeedback ( ) {
if ( this . closestIndex === this . items . length ) {
return [ ] ;
}
return this . items . slice ( this . closestIndex ) ;
} ,
itemsBeforeReorderingFeedback ( ) {
if ( this . closestIndex <= this . fromIndex ) {
return this . items . slice ( 0 , this . closestIndex ) ;
}
return this . items . slice ( 0 , this . closestIndex + 1 ) ;
} ,
itemsAfterReorderingFeedback ( ) {
if ( this . closestIndex <= this . fromIndex ) {
return this . items . slice ( this . closestIndex ) ;
}
return this . items . slice ( this . closestIndex + 1 ) ;
} ,
reorderedItems ( ) {
const toIndex = this . closestIndex ;
const reordered = [ ... this . items ] ;
const temp = reordered [ this . fromIndex ] ;
reordered . splice ( this . fromIndex , 1 ) ;
reordered . splice ( toIndex , 0 , temp ) ;
return reordered ;
} ,
clazz ( ) {
return {
'drop-list' : true ,
'reordering' : this . reordering === true ,
'inserting' : this . reordering === false ,
... ( this . reordering === false ? this . cssClasses : { 'dnd-drop' : true } )
} ;
} ,
showDragFeedback ( ) {
return this . dragInProgress && this . typeAllowed && ! this . reordering ;
} ,
showInsertingDragImage ( ) {
return this . dragInProgress && this . typeAllowed && ! this . reordering && ! ! this . $slots [ 'drag-image' ] ;
} ,
showReorderingDragImage ( ) {
return this . dragInProgress && this . reordering && ! ! this . $slots [ 'reordering-drag-image' ] ;
} ,
hasReorderingFeedback ( ) {
return ! ! this . $slots [ 'reordering-feedback' ] ;
} ,
hasEmptySlot ( ) {
return ! ! this . $slots [ 'empty' ] ;
}
} ,
created ( ) {
dnd . on ( 'dragstart' , this . onDragStart ) ;
dnd . on ( 'dragend' , this . onDragEnd ) ;
} ,
beforeUnmount ( ) {
dnd . off ( 'dragstart' , this . onDragStart ) ;
dnd . off ( 'dragend' , this . onDragEnd ) ;
} ,
methods : {
// Presence of feedback node in the DOM and of keys in the virtual DOM required => delayed until what
// depends on drag data has been processed.
refresh ( ) {
this . $nextTick ( ( ) => {
this . grid = this . computeInsertingGrid ( ) ;
this . feedbackKey = this . computeFeedbackKey ( ) ;
this . forbiddenKeys = this . computeForbiddenKeys ( ) ;
} ) ;
} ,
onDragStart ( event ) {
if ( this . candidate ( dnd . type ) ) {
if ( this . reordering ) {
this . fromIndex = Array . prototype . indexOf . call ( event . source . $el . parentElement . children , event . source . $el ) ;
this . grid = this . computeReorderingGrid ( ) ;
}
else {
this . refresh ( ) ;
}
}
} ,
onDragEnd ( ) {
this . fromIndex = null ;
this . feedbackKey = null ;
this . forbiddenKeys = null ;
this . grid = null ;
} ,
doDrop ( event ) {
if ( this . reordering ) {
if ( this . fromIndex !== this . closestIndex ) {
this . $emit ( 'reorder' , new ReorderEvent (
this . fromIndex ,
this . closestIndex
) ) ;
}
}
else {
// todo - eventually remove the need for this
doDrop ( this , event ) ;
this . $emit ( 'insert' , new InsertEvent (
event . type ,
event . data ,
this . closestIndex
) ) ;
}
} ,
candidate ( type ) {
return candidate ( this , type ) || this . reordering ;
} ,
computeForbiddenKeys ( ) {
return ( this . noAnimations ? [ ] : this . $refs . component . $slots [ 'default' ] ( ) )
. map ( vn => vn . key )
. filter ( k => ! ! k && k !== 'drag-image' && k !== 'drag-feedback' ) ;
} ,
computeFeedbackKey ( ) {
return this . $refs [ 'feedback' ] [ '$slots' ] [ 'default' ] ( ) [ 0 ] [ 'key' ] ;
} ,
computeInsertingGrid ( ) {
if ( this . $refs . feedback . $el . children . length < 1 ) {
return null ;
}
const feedback = this . $refs . feedback . $el . children [ 0 ] ;
const clone = feedback . cloneNode ( true ) ;
const tg = this . $el ;
if ( tg . children . length > this . items . length ) {
tg . insertBefore ( clone , tg . children [ this . items . length ] ) ;
}
else {
tg . appendChild ( clone ) ;
}
const grid = new Grid ( tg . children , this . items . length , this . direction , null ) ;
tg . removeChild ( clone ) ;
return grid ;
} ,
computeReorderingGrid ( ) {
return new Grid ( this . $el . children , this . items . length - 1 , this . direction , this . fromIndex ) ;
} ,
createDragImage ( ) {
let image ;
if ( this . $refs [ 'drag-image' ] ) {
const el = this . $refs [ 'drag-image' ] ;
let model ;
if ( el . childElementCount !== 1 ) {
model = el ;
}
else {
model = el . children . item ( 0 ) ;
}
const clone = model . cloneNode ( true ) ;
const tg = this . $el ;
tg . appendChild ( clone ) ;
image = createDragImage ( clone ) ;
tg . removeChild ( clone ) ;
image [ '__opacity' ] = this . dragImageOpacity ;
image . classList . add ( 'dnd-ghost' ) ;
}
else {
image = 'source' ;
}
return image ;
}
} ,
render ( ) {
if ( ! this . $slots [ 'item' ] ) {
throw 'The "Item" slot must be defined to use DropList' ;
}
if ( ! this . $slots [ 'feedback' ] ) {
throw 'The "Feedback" slot must be defined to use DropList' ;
}
let defaultArr = [ ] ;
if ( this . dropIn && this . dropAllowed ) {
if ( this . reordering ) {
if ( this . hasReorderingFeedback ) {
const itemsReorderingBefore = this . itemsBeforeReorderingFeedback . map ( ( item , index ) => {
return this . $slots [ 'item' ] ( {
item : item ,
index : index ,
reorder : false
} ) [ 0 ] ;
} ) ;
if ( itemsReorderingBefore . length > 0 ) {
defaultArr = defaultArr . concat ( itemsReorderingBefore ) ;
}
defaultArr . push ( this . $slots [ 'reordering-feedback' ] ( {
key : 'reordering-feedback' ,
item : this . items [ this . fromIndex ]
} ) [ 0 ] ) ;
const itemsReorderingAfter = this . itemsAfterReorderingFeedback . map ( ( item , index ) => {
return this . $slots [ 'item' ] ( {
item : item ,
index : this . itemsBeforeReorderingFeedback . length + index ,
reorder : false
} ) [ 0 ] ;
} ) ;
if ( itemsReorderingAfter . length > 0 ) {
defaultArr = defaultArr . concat ( itemsReorderingAfter ) ;
}
}
else {
const reorderedItems = this . reorderedItems . map ( ( item , index ) => {
return this . $slots [ 'item' ] ( {
item : item ,
index : index ,
reorder : index === this . closestIndex
} ) [ 0 ] ;
} ) ;
if ( reorderedItems . length > 0 ) {
defaultArr = defaultArr . concat ( reorderedItems ) ;
}
}
}
else {
const itemsBefore = this . itemsBeforeFeedback . map ( ( item , index ) => {
return this . $slots [ 'item' ] ( {
item : item ,
index : index ,
reorder : false
} ) [ 0 ] ;
} ) ;
if ( itemsBefore . length > 0 ) {
defaultArr = defaultArr . concat ( itemsBefore ) ;
}
defaultArr . push ( this . $slots [ 'feedback' ] ( {
key : 'drag-feedback' ,
data : this . dragData ,
type : this . dragType
} ) [ 0 ] ) ;
const itemsAfter = this . itemsAfterFeedback . map ( ( item , index ) => {
return this . $slots [ 'item' ] ( {
item : item ,
index : this . itemsBeforeFeedback . length + index ,
reorder : false
} ) [ 0 ] ;
} ) ;
if ( itemsAfter . length > 0 ) {
defaultArr = defaultArr . concat ( itemsAfter ) ;
}
}
}
else {
const defaultItems = this . items . map ( ( item , index ) => {
return this . $slots [ 'item' ] ( {
item : item ,
index : index ,
reorder : false
} ) [ 0 ] ;
} ) ;
if ( defaultItems . length > 0 ) {
defaultArr = defaultArr . concat ( defaultItems ) ;
}
else if ( this . hasEmptySlot ) {
defaultArr . push ( this . $slots [ 'empty' ] ( ) [ 0 ] ) ;
}
}
if ( this . showDragFeedback ) {
defaultArr . push ( h (
script$1 ,
{
class : '__feedback' ,
ref : 'feedback' ,
key : 'drag-feedback'
} ,
{
default : ( ) => this . $slots [ 'feedback' ] ( {
type : this . dragType ,
data : this . dragData
} ) [ 0 ]
}
) ) ;
}
if ( this . showReorderingDragImage ) {
defaultArr . push ( h (
'div' ,
{
class : '__drag-image' ,
ref : 'drag-image' ,
key : 'reordering-drag-image'
} ,
{
default : ( ) => this . $slots [ 'reordering-drag-image' ] ( {
item : this . items [ this . fromIndex ]
} ) [ 0 ]
}
) ) ;
}
if ( this . showInsertingDragImage ) {
defaultArr . push ( h (
'div' ,
{
class : '__drag-image' ,
ref : 'drag-image' ,
key : 'inserting-drag-image'
} ,
{
default : ( ) => this . $slots [ 'drag-image' ] ( {
type : this . dragType ,
data : this . dragData
} ) [ 0 ]
}
) ) ;
}
return h (
this . rootTag ,
{
ref : 'component' ,
class : this . clazz ,
... this . rootProps
} ,
{
default : ( ) => defaultArr
}
) ;
}
2023-08-22 23:12:33 +02:00
} ;
script . _ _scopeId = "data-v-230f65e3" ;
2023-08-21 22:04:51 +02:00
/ * *
* This class reacts to drag events emitted by the dnd object to manage a sequence of drag images and fade from one to the
* other as the drag progresses .
* /
class DragImagesManager {
selfTransform = null ;
clones = null ;
source = null ;
sourcePos = null ;
sourceClone = null ;
constructor ( ) {
dnd . on ( 'dragstart' , this . onDragStart . bind ( this ) ) ;
dnd . on ( 'dragtopchanged' , this . onDragTopChanged . bind ( this ) ) ;
dnd . on ( 'dragpositionchanged' , this . onDragPositionChanged . bind ( this ) ) ;
dnd . on ( 'dragend' , this . onDragEnd . bind ( this ) ) ;
}
onDragStart ( event ) {
// If go-back=true and it is still animating while they attempt another drag,
// it will bug out. Best to clean up any existing elements on the page before
// attempting to start the next animation
this . cleanUp ( ) ;
this . sourcePos = {
x : event . source . $el . getBoundingClientRect ( ) . left ,
y : event . source . $el . getBoundingClientRect ( ) . top
} ;
this . selfTransform = 'translate(-' + ( event . position . x - this . sourcePos . x ) + 'px, -' + ( event . position . y - this . sourcePos . y ) + 'px)' ;
this . clones = new Map ( ) ;
this . source = event . source ;
}
onDragEnd ( event ) {
nextTick ( )
. then ( ( ) => {
if ( ! event . success && this . source && this . source [ 'goBack' ] ) {
// Restore the drag image that is active when hovering outside any drop zone :
const img = this . switch ( null ) ;
// Move it back to its original place :
window . requestAnimationFrame ( ( ) => {
img . style . transition = 'all 0.5s' ;
window . requestAnimationFrame ( ( ) => {
img . style . left = this . sourcePos . x + 'px' ;
img . style . top = this . sourcePos . y + 'px' ;
img . style . transform = 'translate(0,0)' ;
const handler = ( ) => {
this . cleanUp ( ) ;
img . removeEventListener ( 'transitionend' , handler ) ;
} ;
img . addEventListener ( 'transitionend' , handler ) ;
} ) ;
} ) ;
}
else {
this . cleanUp ( ) ;
}
} ) ;
}
cleanUp ( ) {
if ( this . clones ) {
this . clones . forEach ( ( clone ) => {
if ( clone . parentNode === document . body ) {
document . body . removeChild ( clone ) ;
}
} ) ;
}
if ( this . sourceClone !== null ) {
if ( this . sourceClone . parentNode === document . body ) {
document . body . removeChild ( this . sourceClone ) ;
}
}
this . selfTransform = null ;
this . clones = null ;
this . source = null ;
this . sourceClone = null ;
this . sourcePos = null ;
}
onDragTopChanged ( event ) {
this . switch ( event . top ) ;
}
switch ( top ) {
this . clones . forEach ( clone => {
clone . style . opacity = '0' ;
} ) ;
if ( this . sourceClone ) {
this . sourceClone . style . opacity = '0' ;
}
let activeClone ;
if ( top === null ) {
activeClone = this . getSourceClone ( ) ;
}
else {
if ( ! this . clones . has ( top ) ) {
let clone = top [ 'createDragImage' ] ( this . selfTransform ) ;
if ( clone === 'source' ) {
clone = this . getSourceClone ( ) ;
}
else if ( clone !== null ) {
clone . style . opacity = '0' ;
document . body . appendChild ( clone ) ;
}
this . clones . set ( top , clone ) ;
}
activeClone = this . clones . get ( top ) ;
}
if ( activeClone !== null ) {
activeClone . offsetWidth ; // Forces browser reflow
activeClone . style . opacity = activeClone [ '__opacity' ] ;
activeClone . style . visibility = 'visible' ;
}
return activeClone ;
}
getSourceClone ( ) {
if ( this . sourceClone === null ) {
this . sourceClone = this . source [ 'createDragImage' ] ( this . selfTransform ) ;
this . sourceClone . style . opacity = '0' ;
document . body . appendChild ( this . sourceClone ) ;
}
return this . sourceClone ;
}
onDragPositionChanged ( ) {
this . clones . forEach ( ( clone ) => {
clone . style . left = dnd . position . x + 'px' ;
clone . style . top = dnd . position . y + 'px' ;
} ) ;
if ( this . sourceClone ) {
this . sourceClone . style . left = dnd . position . x + 'px' ;
this . sourceClone . style . top = dnd . position . y + 'px' ;
}
}
}
2023-08-22 23:12:33 +02:00
new DragImagesManager ( ) ;
export { DnDEvent , script$4 as Drag , DragAwareMixin , script$1 as DragFeedback , DragImagesManager , DragMixin , script$3 as Drop , script as DropList , script$2 as DropMask , DropMixin , InsertEvent , ReorderEvent , createDragImage , dnd } ;