JSFiddle - React, Tailwind, and code Playground

by isochronous

HTML

<script src="http://rawgithub.com/j-ulrich/jquery-simulate-ext/master/libs/jquery.simulate.js"></script>
<script src="http://rawgithub.com/j-ulrich/jquery-simulate-ext/master/src/jquery.simulate.ext.js"></script>
<script src="http://rawgithub.com/j-ulrich/jquery-simulate-ext/master/src/jquery.simulate.drag-n-drop.js"></script>
<div id="container">
<ul style='display:inline-block; width: 33%;'>
    <li>
        <div><span class="handle"></span><span class="text">List One Item 1</span></div>
    </li>
    <li>
        <div><span class="handle"></span><span class="text">List One Item 2</span></div>
    </li>
    <li>
        <div><span class="handle"></span><span class="text">List One Item 3</span></div>
    </li>
    <li>
        <div><span class="handle"></span><span class="text">List One Item 4</span></div>
    </li>
    <li>
        <div><span class="handle"></span><span class="text">List One Item 5</span></div>
    </li>
</ul>

<ul style='display:inline-block; width: 33%;'>
    <li>
        <div><span class="handle"></span><span class="text">List Two Item 1</span></div>
    </li>
    <li>
        <div><span class="handle"></span><span class="text">List Two Item 2</span></div>
    </li>
    <li>
        <div><span class="handle"></span><span class="text">List Two Item 3</span></div>
    </li>
    <li>
        <div><span class="handle"></span><span class="text">List Two Item 4</span></div>
    </li>
    <li>
        <div><span class="handle"></span><span class="text">List Two Item 5</span></div>
    </li>
</ul>
</div>

CSS

span.handle{
    display: inline-block;
    width: 33px;
    height: 1em;
    background-color: #444466;
}

li {
    box-sizing: border-box;
    margin: 5px 0 30px 0;
    min-height: 1.2em;
    border: 1px solid green;
}

li div {
    border: 1px solid #eee;
    list-style: none;
}

.is-drop { background-color: blue; }
.is-swap { background-color: red; }
.is-drop-target { border: 3px dashed black }

JavaScript

$(function() {
    
    /**
     * @class $.triton.dragswap
     * @alias module:widgets/jquery.ui.dragswap
     */
    $.widget('triton.dragswap', 
        
        /** @lends $.triton.dragswap.prototype */
        {

            version: '0.3.0',
    
            options: {
                debug: false,
                debugVerbosity: 3,
                draggableOptions: {
                    handle: '.handle',
                    revertDuration: 200,
                    scope: 'dragswap',
                    zIndex: 999
                },
                droppableOptions: {
                    scope: 'dragswap'
                },
                logger: console,
                makeDraggable: 'li div',
                makeDroppable: 'li'
            },
            
            requiredDraggableOptions: {
                helper: 'clone',
                revert: false,
            },
            
            requiredDroppableOptions: {
                              
            },
            
            _create: function () {
                this.nodes = {};
                this.nodes.root = this.element.addClass('triton-dragswap');
            },
    
            _init: function () {
                var n = this.nodes,
                    o = this.options;

                this.nodes.draggables = $();
                this.nodes.droppables = $();
                
                this.swapping = false;
    
                this._log('initializing dragswap widget');
                
                n.draggables = n.root.find(o.makeDraggable).draggable($.extend({}, o.draggableOptions, this.requiredDraggableOptions));
                n.droppables = n.root.find(o.makeDroppable).droppable($.extend({}, o.droppableOptions, this.requiredDroppableOptions));
                
                this._log('made draggables out of %o', n.draggables);
                this._log('made droppables out of %o', n.droppables);
    
                this._off(n.draggables, 'dragstart...