JSFiddle - React, Tailwind, and code Playground

HTML

<div class='widget' id='a'>Drag A</div>
<div class='widget' id='b'>Drag B</div>
<div class='widget' id='c'>Drag C</div>
<div class='widget' id='d'>Drag D</div>

CSS

.widget {
    position: absolute;
    width: 80px;
    height: 80px;
    background: lightgrey;
    margin: 5px;
    padding: 10px;
    text-align:center;
    cursor:move;
}
#b {
    top: 120px
}
#c {
    left: 120px
}
#d {
    top: 120px;
    left:120px
}
.selected {
    background-color: #4af;
}

JavaScript

var selectedWidgets, GRID = 10,
    prevOffsetLeft = 0,
    prevOffsetTop = 0;
var draggableOptions = {
    grid: [GRID, GRID],
    start: function (event, ui) {
        // Get all selected widgets
        selectedWidgets = $('.widget.selected').filter('[id!=' + $(this).attr('id') + ']');
    },
    drag: function (event, ui) {
        var currentPos = $(this).position();
        var originalPos = ui.originalPosition;

        var offsetLeft = roundM(currentPos.left - originalPos.left, GRID);
        var offsetTop = roundM(currentPos.top - originalPos.top, GRID);

        if (offsetLeft !== prevOffsetLeft || offsetTop !== prevOffsetTop) {
            console.log(offsetLeft, offsetTop);
            moveSelectedWidgets(offsetLeft - prevOffsetLeft, offsetTop - prevOffsetTop);
            prevOffsetLeft = offsetLeft;
            prevOffsetTop = offsetTop;
        }
    },
    stop: function (event, ui) {
        prevOffsetLeft = 0;
        prevOffsetTop = 0;
    }
};

$('.widget').draggable(draggableOptions).click(function () {
    $(this).toggleClass('selected');
});

function moveSelectedWidgets(offsetLeft, offsetTop) {
    selectedWidgets.each(function () {
        var $this = $(this);
        var pos = $this.position();
        var posLeft = pos.left;
        var posTop = pos.top;

        $this.css('left', posLeft + offsetLeft);
        $this.css('top', posTop + offsetTop);
    });
}

function roundM(number, multiple) {
    return Math.round(number / multiple) * multiple;
}