JSFiddle - React, Tailwind, and code Playground
HTML
<div class='boxImage' data-name='one' data-step=30 data-minWidth=180 data-maxWidth=300>
<span class='counter'></span>
<img class='image' src='http://s-engineer.ru/wp-content/uploads/2013/07/js.png'/>
<button class='addButton'>Добавить статью</button>
</div>
<div data-name='parent-one'>
<article class='myArticle' data-target='one'><p>Это первая статья из первого модуля</p></article>
</div>
<div class='boxImage' data-name='two' data-step=20 data-minWidth=180 data-maxWidth=300>
<span class='counter'></span>
<img class='image' src='http://s-engineer.ru/wp-content/uploads/2013/07/js.png'/>
<button class='addButton'>Добавить статью</button>
</div>
<div data-name='parent-two'>
<article class='myArticle' data-target='two'><p>Это первая статья из второго модуля</p></article>
</div>
CSS
.boxImage {
position:relative;
}
.counter{
position:absolute;
top:0;
right:0;
background:white;
font-style:bold;
font-size:16px;
padding:5px;
}
JavaScript
var boxes = document.querySelectorAll('.boxImage');
for (var i=0; i < boxes.length; i++) {
var attr = boxes[i].getAttribute('data-name'),
parent = document.querySelector('div[data-name="parent-'+attr+'"]'),
articles = document.querySelectorAll('.myArticle[data-target="'+attr+'"]'),
length = articles.length,
config = {
step: +(boxes[i].getAttribute('data-step')),
minWidth: +(boxes[i].getAttribute('data-minWidth')),
maxWidth: +(boxes[i].getAttribute('data-maxWidth'))
};
var resultWidth = config.step*length+config.minWidth;
resultWidth > config.maxWidth && (resultWidth= config.maxWidth);
boxes[i].querySelectorAll('.counter')[0].innerHTML = articles.length;
boxes[i].querySelectorAll('.image')[0].style.cssText="width:"+resultWidth+'px;'+""
//events
boxes[i].querySelectorAll('.addButton')[0].onclick = eventHandler.bind(null, boxes[i], config.step, config.minWidth, config.maxWidth, parent)
}
function eventHandler(elem, step, minWidth, maxWidth, parent) {
var count = elem.querySelector('.counter').innerHTML = +(elem.querySelector('.counter').innerHTML)+1,
resultWidth = step*count+minWidth;
resultWidth > maxWidth && (resultWidth= maxWidth);
elem.querySelector('.image').style.cssText="width:"+resultWidth+'px;'+""
var el = document.createElement('article');
el.setAttribute('data-target',elem.getAttribute('data-name'));
el.innerHTML = 'Новая статья';
parent.appendChild(el);
}