From 13fc0cc8ffb61d8f184707feed1f9010798c45f1 Mon Sep 17 00:00:00 2001
From: eug-vs <eug-vs@keemail.me>
Date: Fri, 18 Sep 2020 22:20:29 +0300
Subject: feat!: allow dynamic item height in PollsList

---
 src/components/PollsList/PollsList.tsx  | 14 +++++++++++---
 src/components/PollsList/RenderItem.tsx | 22 ++++++++++++++++------
 2 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/src/components/PollsList/PollsList.tsx b/src/components/PollsList/PollsList.tsx
index 039639d..bf2079a 100644
--- a/src/components/PollsList/PollsList.tsx
+++ b/src/components/PollsList/PollsList.tsx
@@ -3,7 +3,8 @@ import {
   WindowScroller,
   AutoSizer,
   List,
-  InfiniteLoader
+  InfiniteLoader,
+  CellMeasurerCache
 } from 'react-virtualized';
 import _ from 'lodash';
 import { Poll } from 'which-types';
@@ -15,17 +16,23 @@ interface PropTypes {
   mutate: (polls: Poll[], refetch: boolean) => void;
 }
 
+const cache = new CellMeasurerCache({
+  fixedWidth: true,
+});
+
 const PAGE_SIZE = 10;
 
 const PollsList: React.FC<PropTypes> = ({ polls, mutate }) => {
   const [displayCount, setDisplayCount] = useState<number>(PAGE_SIZE);
 
-  const rowRenderer = useCallback(({ index, style, key }) => (
+  const rowRenderer = useCallback(({ index, style, key, parent }) => (
     <RenderItem
       polls={polls}
       mutate={mutate}
       index={index}
       style={style}
+      cache={cache}
+      parent={parent}
       key={key}
       _key={key}
     />
@@ -68,7 +75,7 @@ const PollsList: React.FC<PropTypes> = ({ polls, mutate }) => {
                     isScrolling={isScrolling}
                     onScroll={onChildScroll}
                     rowCount={rowCount}
-                    rowHeight={550}
+                    rowHeight={cache.rowHeight}
                     rowRenderer={rowRenderer}
                     scrollTop={scrollTop}
                     width={width}
@@ -76,6 +83,7 @@ const PollsList: React.FC<PropTypes> = ({ polls, mutate }) => {
                     overscanRowCount={2}
                     onRowsRendered={onRowsRendered}
                     ref={ref}
+                    deferredMeasurementCache={cache}
                   />
                 )}
               </InfiniteLoader>
diff --git a/src/components/PollsList/RenderItem.tsx b/src/components/PollsList/RenderItem.tsx
index beed259..ce6f0c9 100644
--- a/src/components/PollsList/RenderItem.tsx
+++ b/src/components/PollsList/RenderItem.tsx
@@ -1,6 +1,7 @@
 import React, { useCallback } from 'react';
 import { Poll } from 'which-types';
 import PollCard from '../PollCard/PollCard';
+import { CellMeasurer, CellMeasurerCache, List } from 'react-virtualized';
 
 
 interface PropTypes {
@@ -8,6 +9,8 @@ interface PropTypes {
   mutate: (polls: Poll[], refetch: boolean) => void;
   index: number;
   style: React.CSSProperties;
+  cache: CellMeasurerCache;
+  parent: List;
   _key: string; // https://reactjs.org/warnings/special-props.html
 }
 
@@ -15,13 +18,13 @@ const compareProps = (oldProps: PropTypes, newProps: PropTypes) => {
   if (oldProps._key !== newProps._key) return false;
   if (oldProps.index !== newProps.index) return false;
   if (oldProps.polls !== newProps.polls) return false;
-  // TODO: uncomment line below to listen to style updates
-  // if (JSON.stringify(oldProps.style)!== JSON.stringify(newProps.style)) return false;
+  // Only listen for height changes in style
+  if (oldProps.style.height !== newProps.style.height) return false;
   return true;
 };
 
 const RenderItem: React.FC<PropTypes> = React.memo(({
-  polls, mutate, index, style, _key
+  polls, mutate, index, style, cache, parent, _key
 }) => {
   const poll = polls[index];
 
@@ -35,9 +38,16 @@ const RenderItem: React.FC<PropTypes> = React.memo(({
   }, [mutate, index, polls]);
 
   return (
-    <div key={`${_key}-${poll._id}`} style={style}>
-      <PollCard poll={poll} setPoll={setPoll} />
-    </div>
+    <CellMeasurer
+      cache={cache}
+      columnIndex={0}
+      rowIndex={index}
+      parent={parent}
+    >
+      <div key={`${_key}-${poll._id}`} style={{...style, paddingBottom: '40px' }}>
+        <PollCard poll={poll} setPoll={setPoll} />
+      </div>
+    </CellMeasurer>
   );
 }, compareProps);
 
-- 
cgit v1.2.3