JSFiddle - React, Tailwind, and code Playground
by Daedalus
HTML
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
<div class="row">
<div class="col-2">
<div class="row" :style="squareParent.style" v-for="(squareParent, i) in squareParents" ref="titles">
<div class="col m-0" style="height: 20px; border: 1px solid transparent;">
{{squareParent.title}}
</div>
<div class="col" :style="{backgroundColor: squareParent.color, width: '20px', height: '20px', margin: '2px'}"></div>
</div>
</div>
<div class="col-4 position-relative">
<div v-for="(squareParent, i) in squareParents">
<div :style="{backgroundColor: squareParent.color, width: '20px', height: '20px', margin: '2px', float: 'left', position: 'relative'}" v-for="(square, square_i) in squareParent.squares" ref="squares"></div>
</div>
</div>
</div>
JavaScript
new Vue({
el: '#app',
data: {
squareParents: [{
title: 'test1',
squares: 1,
color: 'red',
style: {}
}, {
title: 'test2',
squares: 1,
color: 'green',
style: {}
}, {
title: 'test3',
squares: 1,
color: 'blue',
style: {}
}, {
title: 'test4',
squares: 24,
color: 'red',
style: {}
}, {
title: 'test5',
squares: 21,
color: 'green',
style: {}
}, {
title: 'test6',
squares: 23,
color: 'blue',
style: {}
}]
},
methods: {
async styleTitles() {
let squareIdx = 0;
for (let [idx, squareParent] of this.squareParents.entries()) {
let spacing;
if (idx > 0) {
let square = this.$refs.squares[squareIdx],
title = this.$refs.titles[idx],
priorTitle = this.$refs.titles[idx - 1],
sTop = square.getBoundingClientRect().top,
tTop = title.getBoundingClientRect().top,
pTTop = priorTitle.getBoundingClientRect().top;
if (tTop < sTop) {
spacing = (sTop - pTTop) - square.getBoundingClientRect().height - 6;
}
}
if (!isNaN(spacing)) {
squareParent.style = {
marginTop: spacing + 'px'
};
await this.$nextTick();
}
squareIdx += squareParent.squares;
}
}
},
mounted() {
this.styleTitles();
}
});