JSFiddle - React, Tailwind, and code Playground
by John Doe
HTML
<div class="container">
<div>
<h3>Sortable List 1</h3>
<ul id="list-1" class="sortable">
<li id="item-1">Item 01 - <a href="#1">Link 01</a></li>
<li id="item-2">Item 02 - <a href="#2">Link 02</a></li>
<li id="item-3">Item 03 - <a href="#3">Link 03</a></li>
<li id="item-4">Item 04 - <a href="#4">Link 04</a></li>
<li id="item-5">Item 05 - <a href="#5">Link 05</a></li>
<li id="item-6">Item 06 - <a href="#6">Link 06</a></li>
</ul>
</div>
<div>
<h3>Sortable List 2</h3>
<ul id="list-2" class="sortable">
<li id="item-7">Item 07 - <a href="#7">Link 07</a></li>
<li id="item-8">Item 08 - <a href="#8">Link 08</a></li>
<li id="item-9">Item 09 - <a href="#9">Link 09</a></li>
<li id="item-10">Item 10 - <a href="#10">Link 10</a></li>
<li id="item-11">Item 11 - <a href="#11">Link 11</a></li>
<li id="item-12">Item 12 - <a href="#12">Link 12</a></li>
</ul>
</div>
</div>
SCSS
*, *:before, *:after {
box-sizing: border-box;
transition:
background-color 400ms ease-out,
border-color 400ms ease-out,
color 400ms ease-out;
}
html, body {
display: block;
height: 100%;
}
body {
overflow: hidden;
overflow-y: scroll;
font-family: Arial, sans-serif;
background: rgb(252,255,244);
background: radial-gradient( ellipse at center, rgba(252,255,244,1) 0%,rgba(223,229,215,1) 50%,rgba(179,190,173,1) 100% );
}
.container {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-around;
width: 100%;
height: 100%;
max-width: 800px;
margin: 0 auto;
div {
flex-basis: 40%;
h3 {
font-weight: bold;
font-size: 150%;
line-height: 1em;
}
}
}
ul.sortable {
display: block;
list-style: none;
background: #e0e0e0;
border-radius: 4px;
box-shadow: 0 0 40px rgba(0,0,0,0.4);
margin: 20px 0;
padding: 5px;
& > li {
display: block;
margin: 1px;
padding: 10px;
border-radius: 4px;
cursor: move;
background: #fff;
&:hover {
background: #ffffe0;
}
&.active {
background: #ccc;
}
&.dragging {
background: #e0ffff;
box-shadow: 0 4px 20px rgba(0,0,0,0.5);
opacity: 0.5;
}
}
}
JavaScript
(function( name, factory ) {
if( typeof window === "object" ) {
// add to window
window[ name ] = factory();
// add jquery plugin, if available
if( typeof jQuery === "object" ) {
jQuery.fn[ name ] = function( options ) {
return this.each( function() {
new window[ name ]( this, options );
});
};
}
}
})( "Sortable", function() {
var _w = window,
_b = document.body,
_d = document.documentElement;
// get position of mouse/touch in relation to viewport
var getPoint = function( e )
{
var scrollX = Math.max( 0, _w.pageXOffset || _d.scrollLeft || _b.scrollLeft || 0 ) - ( _d.clientLeft || 0 ),
scrollY = Math.max( 0, _w.pageYOffset || _d.scrollTop || _b.scrollTop || 0 ) - ( _d.clientTop || 0 ),
pointX = e ? ( Math.max( 0, e.pageX || e.clientX || 0 ) - scrollX ) : 0,
pointY = e ? ( Math.max( 0, e.pageY || e.clientY || 0 ) - scrollY ) : 0;
return { x: pointX, y: pointY };
};
// class constructor
var Factory = function( container, options )
{
if( container && container instanceof Element )
{
this._container = container;
this._options = options || {}; /* nothing atm */
this._clickItem = null;
this._dragItem = null;
this._hovItem = null;
this._sortLists = [];
this._click = {};
this._dragging = false;
this._container.setAttribute( "data-is-sortable", 1 );
this._container.style["position"] = "static";
window.addEventListener( "mousedown", this._onPress.bind( this ), true );
window.addEventListener( "touchstart", this._onPress.bind( this ), true );
window.addEventListener( "mouseup", this._onRelease.bind( this ), true );
window.addEventListener( "touchend", this._onRelease.bind( this ), true...