JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://cdn.jsdelivr.net/gh/ionstage/jcore@master/jcore.js"></script>
<div class="rect"></div>
<div class="rect"></div>

CSS

.rect {
  background-color: orange;
  position: absolute;
}

JavaScript

class Rect extends jCore.Component {
  constructor(el, x, y, width, height) {
    super(el);
    this.x = this.prop(x);
    this.y = this.prop(y);
    this.width = this.prop(width);
    this.height = this.prop(height);
    this.draggable = new RectDraggable(this);

    this.draggable.enable();
    this.markDirty();
  }

  onredraw() {
    this.redrawBy('x', 'y', (x, y) => {
      this.el.style.transform = 'translate(' + x + 'px, ' + y + 'px)';
    });
    this.redrawBy('width', width => {
      this.el.style.width = width + 'px';
    });
    this.redrawBy('height', height => {
      this.el.style.height = height + 'px';
    });
  }
}

class RectRelation extends jCore.Relation {
  constructor(relatedRect, offsetX, offsetY) {
    super();
    this.relatedRect = relatedRect;
    this.offsetX = offsetX;
    this.offsetY = offsetY;
  }

  update(rect) {
    this.relatedRect.x(rect.x() + this.offsetX);
    this.relatedRect.y(rect.y() + this.offsetY);
  }
}

class RectDraggable extends jCore.Draggable {
  onstart(rect, x, y, event, context) {
    event.preventDefault();
    context.x = rect.x();
    context.y = rect.y();
  }

  onmove(rect, dx, dy, event, context) {
    rect.x(context.x + dx);
    rect.y(context.y + dy);
  }
}

const elements = document.querySelectorAll('.rect');
const first = new Rect(elements[0], 0, 0, 100, 50);
const second = new Rect(elements[1], 0, 0, 100, 50);

first.addRelation(new RectRelation(second, 100, 100));
second.addRelation(new RectRelation(first, -100, -100));