JSFiddle - React, Tailwind, and code Playground

HTML

<div class="container">
    <div class="item item-1">1</div>
    <div class="item item-2">2</div>
    <div class="item item-3">3</div>
    <div class="item item-4">4</div>
    <div class="item item-5">5</div>
    <div class="item item-6">6</div>
</div>

CSS

.container {
    display: flex;
    justify-content: space-between;
    width: 700px;
}
.item {
    font-size: 40px;
    width: 100px;
    height: 100px;
    outline: 1px solid #ccc;
    text-align: center;
    line-height: 100px;
    cursor: pointer;
    transition: background-color 0.5s ease;
    background-color: yellow;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
.item:hover {
    background-color: lightblue;
}
.item.active {
    outline: 2px solid red;
}

Babel + JSX

const active = [];
const items  = Array.from(document.querySelectorAll('.item'));

function activateRow (item1, item2) {
	const a = items.indexOf(item1);
	const b = items.indexOf(item2);

  items
  	.slice( Math.min(a,b), Math.max(a,b)+1 )
  	.map( addActive );
}

function activateSingle (item, isForced) {
  const isActive = active.indexOf( item ) >= 0;
  
  if (isForced) deactivateAll();
  
  isActive
    ? removeActive( item )
  	: addActive( item );
}

function addActive (item, isActive) {
	item.classList.add('active');
  active.push(item);
}

function removeActive (item) {
	item.classList.remove('active');
  active.splice( active.indexOf(item), 1 );
}

function deactivateAll () {
	active.map( item => item.classList.remove('active') );
	active.length = 0;
}

items.map(item => {
  item.addEventListener('click', event => {
    if (event.shiftKey && items.length) {
      activateRow( active[active.length - 1], item );
    } else {
    	activateSingle( item, !event.ctrlKey );
    }
  });

});