React-virtualized scrollsync issue

Demo for Issue http://stackoverflow.com/questions/41956669/unable-to-scroll-past-the-last-child-with-scrollsync-with-multiple-grids-and-col

by mauron85

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.js"></script>
<script src="https://npmcdn.com/react@latest/dist/react-with-addons.js"></script>
<script src="https://npmcdn.com/react-dom@latest/dist/react-dom.js"></script>
<link rel="stylesheet" href="https://unpkg.com/react-virtualized/styles.css">
<script src="https://facebook.github.io/react/js/jsfiddle-integration-babel.js"></script>
<script src="https://unpkg.com/react/dist/react-with-addons.min.js"></script>
<script src="https://unpkg.com/react-dom/dist/react-dom.min.js"></script>
<script src="https://rawgit.com/mauron85/6e13b39ad5a822590b43da3a57e6da26/raw/81f9b7d7a0952474c3be27ad6b01a7cd4559feaf/react-virtualized.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/classnames/2.2.5/index.min.js"></script>

<div id="example">
  <!-- This element's contents will be replaced with your code... -->
</div>

CSS

html, body {
  font-family: Verdana, Geneva, sans-serif;
  font-weight: normal;
  padding: 0;
  margin: 0;
}

.icon {
	height: 1.5em;
	align-self: center;
	margin-right: .5em;
}

.GridRow {
  position: relative;
  display: flex;
  flex-direction: row;
}

.GridColumn {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
}

.LeftSideGridContainer {
  flex: 0 0 75px;
  z-index: 10;
}

.LeftSideGrid {
  overflow: hidden !important;
  background: #fff;
}

.HeaderGrid {
  width: 100%;
  overflow: hidden !important;
  background-color: #fff;
  font-size: .8em;
}

.Body {
  position: relative;  
}

.BodyPart {
  position: absolute;
  top: 0;
  left: 0;
}

.BodyGrid {
  width: 100%;
}

.evenRow {
  background-color: #fff;
}

.oddRow {
  background-color: #e5e2de;
}

.cell,
.headerCell,
.leftCell {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  padding: 0 .5em;
}

.headerCell,
.leftCell {
  font-weight: bold;
}

.Calendar {
  color: silver;
}

.Routes {
  width: 100%;
}

.route {
  height: 100%;
  border: 1px solid #fff;
  cursor: move;
  background-color: green;
}

.routeHightlight {
  background-color: yellow;
}

.delivery {
  background-color: silver;
  cursor: move;
}

.workingHourCell {
  background-color: green;
}

JavaScript 1.7

const { calculateSizeAndPositionData, defaultCellRangeRenderer, List, Grid, Collection, ScrollSync, AutoSizer } = ReactVirtualized;
const cn = classNames;
const HOUR_IN_MILLIS = 60 * 60 * 1000;

function defaultCellGroupRenderer ({
  cellCache,
  cellRenderer,
  cellSizeAndPositionGetter,
  indices,
  isScrolling
}) {
  return indices
    .map((index) => {
      const cellMetadata = cellSizeAndPositionGetter({ index })

      let cellRendererProps = {
        index,
        isScrolling,
        key: index,
        style: {
          height: cellMetadata.height,
          left: cellMetadata.x,
          position: 'absolute',
          top: cellMetadata.y,
          width: cellMetadata.width
        }
      }

      // Avoid re-creating cells while scrolling.
      // This can lead to the same cell being created many times and can cause performance issues for "heavy" cells.
      // If a scroll is in progress- cache and reuse cells.
      // This cache will be thrown away once scrolling complets.
      if (isScrolling) {
        if (!(index in cellCache)) {
          cellCache[index] = cellRenderer(cellRendererProps)
        }

        return cellCache[index]
      } else {
        return cellRenderer(cellRendererProps)
      }
    })
    .filter((renderedCell) => !!renderedCell)
}

function getHoursBetween(startDate, endDate) {
  return Math.ceil(moment(endDate).diff(moment(startDate), 'hours', true));
}

function getCouriers(count) {
  const couriers = {};
  for (let i = 1; i <= count; i++) {
    couriers[i] = { id: i, username: `courier${i}` };
  }
  return couriers;
}

function getRoutes(couriers, startDate, endDate, routeMinDurationInHours = 1) {
  const routes = [];
  const hours = moment(endDate).diff(moment(startDate), 'hours');
  const hoursPerCourier = hours / couriers.length;
  const routesPerCourier = Math.floor(hoursPerCourier / routeMinDurationInHours) || 1;
  const routeDuration = 2 * hoursPerCourier / routesPerCourier;

  console.log(`Total ${hours}...