JSFiddle - React, Tailwind, and code Playground

HTML

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

CSS

.box {
  background-color: white;
  border: 1px solid #333;
  position: absolute;
}

JavaScript

class Box 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 BoxDraggable(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 BoxDraggable extends jCore.Draggable {
  onstart(box, x, y, event, context) {
    event.preventDefault();
    context.x = box.x();
    context.y = box.y();
  }

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

class BoxRelation extends jCore.Relation {
  constructor(parent, child) {
    super();
    this.parent = parent;
    this.child = child;
  }

  update() {
    const p = this.parent;
    const c = this.child;
    c.x(this.clamp(c.x(), p.x(), p.x() + p.width() - c.width()));
    c.y(this.clamp(c.y(), p.y(), p.y() + p.height() - c.height()));
  }

  clamp(v, low, high) {
    return Math.min(Math.max(v, low), high);
  }
}

const elements = document.querySelectorAll('.box');

const boxes = {
  parent: new Box(elements[0], 0, 0, 300, 300),
  child: new Box(elements[1], 30, 30, 200, 200),
  grandchild: new Box(elements[2], 60, 60, 100, 100),
};

const relations = {
  'parent-child': new BoxRelation(boxes.parent, boxes.child),
  'child-grandchild': new BoxRelation(boxes.child, boxes.grandchild),
};

boxes.parent.addRelation(relations['parent-child']);
boxes.child.addRelation(relations['parent-child']);
boxes.child.addRelation(relations['child-grandchild']);
boxes.grandchild.addRelation(relations['child-grandchild']);