Skip to content

Commit

Permalink
refactor catalog-item.tsx and extract catalog tile, refactor cell.tsx…
Browse files Browse the repository at this point in the history
… to use padding instead of subtracting the height width to create spacing
  • Loading branch information
sahil143 committed Jul 7, 2020
1 parent 150685a commit 2e77f80
Show file tree
Hide file tree
Showing 12 changed files with 172 additions and 196 deletions.
Original file line number Diff line number Diff line change
@@ -1,34 +1,27 @@
import * as React from 'react';
import { CellMeasurer } from 'react-virtualized';
import { RenderCell, RenderHeader, GridChildrenProps, Item, CellItem } from './types';
import { getHeightAndWidthOfCell, CellMeasurementContext } from './utils';
import { CellMeasurementContext } from './utils';

type CellProps = {
renderCell: RenderCell;
renderHeader?: RenderHeader;
} & GridChildrenProps;

const Cell: React.FC<CellProps> = ({ data, columnCount, items, renderCell, renderHeader }) => {
const Cell: React.FC<CellProps> = ({
data,
columnCount,
items,
rowCount,
renderCell,
renderHeader,
}) => {
const { cache, cellMargin } = React.useContext(CellMeasurementContext);
const {
key,
style: { height: cellHeight, width: cellWidth, left, top, ...style },
columnIndex,
rowIndex,
parent,
} = data;
const { key, style: cellStyle, columnIndex, rowIndex, parent } = data;
const index = rowIndex * columnCount + columnIndex;
const item: CellItem = items[index];
const isItemString = typeof item === 'string';

const { width, height } = getHeightAndWidthOfCell(cellHeight, cellWidth, item);
const wrapperStyles = {
...style,
height,
width,
left: Number(left) + cellMargin,
top: Number(top) + cellMargin,
};
return item ? (
<CellMeasurer
cache={cache}
Expand All @@ -37,7 +30,14 @@ const Cell: React.FC<CellProps> = ({ data, columnCount, items, renderCell, rende
parent={parent}
rowIndex={rowIndex}
>
<div style={wrapperStyles}>
<div
style={{
...cellStyle,
padding: `${cellMargin}px ${cellMargin}px ${
rowIndex === rowCount - 1 ? `${cellMargin}px` : 0
} ${cellMargin}px`,
}}
>
{isItemString ? renderHeader(item as string) : renderCell(item as Item)}
</div>
</CellMeasurer>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as React from 'react';
import { Grid as GridComponent, GridCellProps } from 'react-virtualized';
import { CELL_PADDING } from './const';
import { Item, GridChildrenProps } from './types';
import { CellMeasurementContext } from './utils';
import './Grid.scss';
Expand All @@ -14,23 +13,24 @@ type GridProps = {
};

const Grid: React.FC<GridProps> = ({ height, width, scrollTop, items, children }) => {
const { cache, cellWidth, cellMargin, overscanRowCount } = React.useContext(
const { cache, cellWidth, cellMargin, overscanRowCount, estimatedCellHeight } = React.useContext(
CellMeasurementContext,
);
const itemCount = items.length;
const idealItemWidth = cellWidth + cellMargin;
const columnCountEstimate = Math.max(1, Math.floor(width / idealItemWidth));
const rowCount = Math.ceil(itemCount / columnCountEstimate);
const columnCount = Math.max(1, itemCount && Math.ceil(itemCount / rowCount));
const cellRenderer = (data: GridCellProps) => children({ data, columnCount, items });
const cellRenderer = (data: GridCellProps) => children({ data, columnCount, items, rowCount });
return (
<GridComponent
className="ocs-grid"
autoHeight
height={height ?? 0}
width={width}
scrollTop={scrollTop}
rowHeight={(params) => cache.rowHeight(params) + CELL_PADDING}
rowHeight={(params) => cache.rowHeight(params)}
estimatedRowSize={estimatedCellHeight}
deferredMeasurementCache={cache}
columnWidth={idealItemWidth}
rowCount={rowCount}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as React from 'react';
import { Grid as GridComponent, GridCellProps } from 'react-virtualized';
import { CELL_PADDING } from './const';
import { getItemsAndRowCount, CellMeasurementContext } from './utils';
import { Params, GroupedItems, GridChildrenProps } from './types';
import './Grid.scss';
Expand All @@ -20,22 +19,27 @@ const GroupByFilterGrid: React.FC<GroupByFilterGridProps> = ({
items: groupedItems,
children,
}) => {
const { cache, cellWidth, cellMargin, overscanRowCount, headerHeight } = React.useContext(
CellMeasurementContext,
);
const {
cache,
cellWidth,
cellMargin,
overscanRowCount,
headerHeight,
estimatedCellHeight,
} = React.useContext(CellMeasurementContext);
const idealItemWidth = cellWidth + cellMargin;
const columnCountEstimate = Math.max(1, Math.floor(width / idealItemWidth));
const { items, rowCount, columnCount, headerRows } = getItemsAndRowCount(
groupedItems,
columnCountEstimate,
);
const cellRenderer = (data: GridCellProps) => children({ data, columnCount, items });
const cellRenderer = (data: GridCellProps) => children({ data, columnCount, items, rowCount });
const getRowHeight = React.useCallback(
({ index }: Params): number => {
if (headerRows.includes(index)) {
return headerHeight;
}
return cache.rowHeight({ index }) + CELL_PADDING;
return cache.rowHeight({ index });
},
[cache, headerHeight, headerRows],
);
Expand All @@ -53,6 +57,7 @@ const GroupByFilterGrid: React.FC<GroupByFilterGridProps> = ({
columnCount={columnCount}
cellRenderer={cellRenderer}
overscanRowCount={overscanRowCount}
estimatedRowSize={estimatedCellHeight}
/>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
DEFAULT_CELL_HEIGHT,
OVERSCAN_ROW_COUNT,
HEADER_FIXED_HEIGHT,
ESTIMATED_ROW_SIZE,
} from './const';
import { CellMeasurementContext } from './utils';

Expand All @@ -31,6 +32,7 @@ type VirtualizedGridProps = {
celldefaultHeight?: number;
overscanRowCount?: number;
headerHeight?: number;
estimatedCellHeight?: number;
};

const VirtualizedGrid: React.FC<VirtualizedGridProps> = ({
Expand All @@ -43,6 +45,7 @@ const VirtualizedGrid: React.FC<VirtualizedGridProps> = ({
celldefaultHeight = DEFAULT_CELL_HEIGHT,
overscanRowCount = OVERSCAN_ROW_COUNT,
headerHeight = HEADER_FIXED_HEIGHT,
estimatedCellHeight = ESTIMATED_ROW_SIZE,
}) => {
const cache: CellMeasurerCache = new CellMeasurerCache({
defaultHeight: celldefaultHeight,
Expand All @@ -51,7 +54,7 @@ const VirtualizedGrid: React.FC<VirtualizedGridProps> = ({
});
return (
<CellMeasurementContext.Provider
value={{ cache, cellMargin, cellWidth, overscanRowCount, headerHeight }}
value={{ cache, cellMargin, cellWidth, overscanRowCount, headerHeight, estimatedCellHeight }}
>
<WithScrollContainer>
{(scrollElement) => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ describe('Grid-cell', () => {

it('should return null when item is null', () => {
const wrapper = shallow(
<Cell data={data} renderCell={renderCell} columnCount={1} items={[null]} />,
<Cell data={data} renderCell={renderCell} columnCount={1} rowCount={2} items={[null]} />,
);
expect(wrapper.isEmptyRender()).toBeTruthy();
});

it('should render cellMeasurer when item is not null', () => {
const wrapper = shallow(
<Cell data={data} renderCell={renderCell} columnCount={1} items={[{}]} />,
<Cell data={data} renderCell={renderCell} columnCount={1} rowCount={2} items={[{}]} />,
);
expect(wrapper.find(CellMeasurer)).toHaveLength(1);
});
Expand All @@ -50,6 +50,7 @@ describe('Grid-cell', () => {
data={data}
renderCell={renderCell}
columnCount={1}
rowCount={2}
items={['string']}
renderHeader={renderHeader}
/>,
Expand All @@ -63,7 +64,7 @@ describe('Grid-cell', () => {
it('should render Cell and not the Header when item is neither string nor null and height should be changed', () => {
const item = { id: 1 };
const wrapper = shallow(
<Cell data={data} renderCell={renderCell} columnCount={1} items={[item]} />,
<Cell data={data} renderCell={renderCell} columnCount={1} rowCount={2} items={[item]} />,
);
expect(wrapper.find('div').prop('style').height).toBe(50 - IDEAL_SPACE_BW_TILES);
expect(wrapper.find('div').prop('style').width).toBe(50 - IDEAL_SPACE_BW_TILES);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ export const IDEAL_CELL_WIDTH = 260;
export const IDEAL_SPACE_BW_TILES = 25;
export const HEADER_FIXED_HEIGHT = 30;
export const OVERSCAN_ROW_COUNT = 6;
export const CELL_PADDING = 24;
export const DEFAULT_CELL_HEIGHT = 250;
export const ESTIMATED_ROW_SIZE = 270;
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export type GridChildrenProps = {
data: GridCellProps;
columnCount: number;
items: CellItem[];
rowCount: number;
};

export type CellSize = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { useCallback, createContext } from 'react';
import { defaultOverscanIndicesGetter, CellMeasurerCache } from 'react-virtualized';
import { GroupedItems, CellItem, CellSize } from './types';
import { IDEAL_SPACE_BW_TILES } from './const';
import { createContext } from 'react';
import { CellMeasurerCache } from 'react-virtualized';
import { GroupedItems, CellItem } from './types';

/**
*
Expand Down Expand Up @@ -85,63 +84,13 @@ export const getItemsAndRowCount = (
},
);

/**
*
* @param h height provided by cell renderer style prop
* @param w width provided by cell renderer style prop
* @param item item to render in cell
*
* calculate the height and width of rendered cell
*/
export const getHeightAndWidthOfCell = (
h: string | number,
w: string | number,
item: CellItem,
): CellSize => {
let height: string | number;
let width: string | number;
if (!item) return { height, width };
const isItemString = typeof item === 'string';

if (Number.isNaN(Number(h))) {
height = h;
} else {
height = isItemString ? h : Number(h) - IDEAL_SPACE_BW_TILES;
}

if (Number.isNaN(Number(w))) {
width = w;
} else {
width = isItemString ? '100%' : Number(w) - IDEAL_SPACE_BW_TILES;
}
return { height, width };
};

export const useOverScanIndicesGetter = () =>
useCallback((args) => {
const { scrollDirection, cellCount } = args;
const {
overscanStartIndex: startIndex,
overscanStopIndex: stopIndex,
} = defaultOverscanIndicesGetter(args);
return {
overscanStartIndex:
scrollDirection === 1 ? (startIndex === 0 ? 0 : startIndex - 1) : startIndex,
overscanStopIndex:
scrollDirection === -1
? stopIndex === cellCount - 1
? stopIndex
: stopIndex + 1
: stopIndex,
};
}, []);

type CellMeasurementContextType = {
cache?: CellMeasurerCache;
cellWidth?: number;
cellMargin?: number;
overscanRowCount?: number;
headerHeight?: number;
estimatedCellHeight?: number;
};

export const CellMeasurementContext = createContext<CellMeasurementContextType>({});

0 comments on commit 2e77f80

Please sign in to comment.