Skip to content

Commit

Permalink
Improvements over the types/props
Browse files Browse the repository at this point in the history
Removed debouncing on recomputing and made it instantly
Added a debugger for column grid
  • Loading branch information
underfisk committed Apr 14, 2021
1 parent 92ffd2b commit 8ac98fd
Show file tree
Hide file tree
Showing 11 changed files with 200 additions and 198 deletions.
11 changes: 5 additions & 6 deletions src/ApolloSpreadsheet.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { forwardRef, useCallback, useEffect, useRef, useState } from 'react'
import React, { forwardRef, useCallback, useRef, useState } from 'react'
import GridWrapper from './gridWrapper/GridWrapper'
import ColumnGrid from './columnGrid/ColumnGrid'
import { NavigationCoords, useKeyboard } from './keyboard'
import { Row, StretchMode } from './types'
import { useKeyboard } from './keyboard'
import { StretchMode } from './types'
import { useMergeCells } from './mergeCells'
import { useHeaders } from './columnGrid'
import { useData } from './data'
Expand Down Expand Up @@ -36,7 +36,6 @@ const useStyles = makeStyles(() => ({
height: '100%',
width: '100%',
},
fixedBottomContainer: {},
}))

export const ApolloSpreadSheet: React.FC<ApolloSpreadsheetProps> = forwardRef(
Expand Down Expand Up @@ -179,7 +178,7 @@ export const ApolloSpreadSheet: React.FC<ApolloSpreadsheetProps> = forwardRef(
coords={coords}
columns={columns}
width={width}
defaultColumnWidth={minColumnWidth}
minColumnWidth={minColumnWidth}
getColumnWidth={getColumnWidth}
minRowHeight={props.minColumnHeight ?? 50}
scrollLeft={scrollLeft}
Expand All @@ -192,7 +191,7 @@ export const ApolloSpreadSheet: React.FC<ApolloSpreadsheetProps> = forwardRef(
rows={rows}
data={cells}
coords={coords}
defaultColumnWidth={minColumnWidth}
minColumnWidth={minColumnWidth}
width={width}
getColumnWidth={getColumnWidth}
minRowHeight={props.minRowHeight ?? 50}
Expand Down
119 changes: 101 additions & 18 deletions src/ApolloSpreadsheetProps.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,123 @@
import { DisableSortFilterParam, GridWrapperCommonProps } from './gridWrapper'
import { DisableSortFilter, ICellChangeEvent, OutsideClickDeselect } from './gridWrapper'
import { GridContainerCommonProps } from './gridContainer'
import { GridTheme, Row, StretchMode } from './types'
import { KeyDownEventParams, NavigationCoords } from './keyboard'
import { SelectionProps } from './rowSelection'
import { ApiRef } from './api'
import { NestedRowsProps } from './nestedRows'
import { Column, NestedHeader } from './columnGrid'
import { MergeCell } from './mergeCells'
import { Alignment } from 'react-virtualized'

export interface ApolloSpreadsheetProps
extends GridWrapperCommonProps,
GridContainerCommonProps,
NestedRowsProps {
theme?: GridTheme
/** @default { rowIndex: 0, colIndex: 0} **/
defaultCoords?: NavigationCoords
/**
* Main grid body (rows and cells) class name
*/
className?: string
rows: Row[]
export interface ApolloCrudProps {
onCreateRow?: (coords: NavigationCoords) => void
onCellChange?: ICellChangeEvent<any>
}

export interface ApolloColumnRowSizeProps {
/** @default 50 **/
minRowHeight?: number
/** @default 50 **/
minColumnHeight?: number
/** @default 30 **/
minColumnWidth?: number
/** @default StretchMode.None */
stretchMode?: StretchMode
/**
* Whether CellMeasurer will set a fixed or dynamic width
* By enabling this, CellMeasurer will be ignored therefore it results in faster performance
* when you can predict a fixed size
* @default true
*/
fixedRowWidth?: boolean
/**
* Whether CellMeasurer will set a fixed or dynamic row height
* By enabling this, CellMeasurer will be ignored therefore it results in faster performance
* when you can predict a fixed size
* @default false
*/
fixedRowHeight?: boolean
/**
* Provides a constant row height or conditionally
* @description This requires fixedRowHeight to be enabled and set to true. This is preferable when you can predict
* the size therefore it would result in faster measurements
* @default dynamic
*/
rowHeight?: number
}

export interface ApolloDataProps {
rows: Row[]
columns: Column[]
nestedHeaders?: Array<NestedHeader[]>
mergeCells?: MergeCell[]
}

export interface ApolloNavigationProps {
/** @default { rowIndex: 0, colIndex: 0} **/
defaultCoords?: NavigationCoords
onKeyDown?: (params: KeyDownEventParams) => void
selection?: SelectionProps
onCreateRow?: (coords: NavigationCoords) => void
/** @default false **/
suppressNavigation?: boolean
}

export interface ApolloSortProps {
/**
* Indicates if the sort is disabled globally or on a specific column
* @default true **/
disableSort?: boolean | DisableSortFilterParam
disableSort?: DisableSortFilter
}

export interface ApolloLayoutProps {
/** @default StretchMode.None */
stretchMode?: StretchMode
theme?: GridTheme
/**
* Border for highlighted cell
*/
highlightBorderColor?: string
/**
* Main grid body (rows and cells) class name
*/
className?: string
selection?: SelectionProps
/** @default false **/
outsideClickDeselects?: OutsideClickDeselect
/**
* Controls scroll-to-cell behavior of the Grid.
* The default ("auto") scrolls the least amount possible to ensure that the specified cell is fully visible.
* Use "start" to align cells to the top/left of the Grid and "end" to align bottom/right.
*/
scrollToAlignment?: Alignment
}

export interface ApolloCoreProps {
/**
* Providing a custom ApiRef will override internal ref by allowing the exposure of grid methods
*/
apiRef?: ApiRef
}

export interface ApolloVirtualizedProps {
/**
* Overscan count buffer for react-virtualized
* @description Keep in mind a lower value
* @default 2
*/
overscanRowCount?: number
/**
* Overscan count buffer for react-virtualized
* @description Keep in mind a lower value
* @default 2
*/
overscanColumnCount?: number
}

export type ApolloSpreadsheetProps = ApolloCoreProps &
GridContainerCommonProps &
NestedRowsProps &
ApolloCrudProps &
ApolloColumnRowSizeProps &
ApolloSortProps &
ApolloNavigationProps &
ApolloLayoutProps &
ApolloDataProps &
ApolloVirtualizedProps
46 changes: 25 additions & 21 deletions src/columnGrid/ColumnGrid.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useRef, useEffect, useMemo, useCallback, CSSProperties } from 'react'
import { Grid, CellMeasurerCache } from 'react-virtualized'
import { Grid, CellMeasurerCache, CellMeasurerCacheParams } from 'react-virtualized'
import CellMeasurer from '../cellMeasurer/CellMeasureWrapper'
import { GridHeader } from './types'
import clsx from 'clsx'
Expand All @@ -13,6 +13,7 @@ import { makeStyles } from '@material-ui/core/styles'
import { isFunctionType } from '../helpers'
import flattenDeep from 'lodash/flattenDeep'
import { createCellQueryProperties } from '../keyboard/utils'
import { useLogger } from '../logger'

type SortDisabled = boolean
const useStyles = makeStyles(() => ({
Expand Down Expand Up @@ -53,21 +54,33 @@ const useStyles = makeStyles(() => ({
}))
export const ColumnGrid: React.FC<ColumnGridProps> = React.memo(props => {
const classes = useStyles()
const cache = useRef(
new CellMeasurerCache({
defaultWidth: props.defaultColumnWidth,
const logger = useLogger('ColumnGrid')
const cache: CellMeasurerCache = useMemo(() => {
const options: CellMeasurerCacheParams = {
defaultWidth: props.minColumnWidth,
defaultHeight: props.minRowHeight,
//Width and height are fixed
//Width is calculated on useHeaders hook
//Height is never going to expand to avoid conflicts
fixedWidth: true,
fixedHeight: true,
minHeight: props.minRowHeight,
minWidth: props.defaultColumnWidth,
}),
).current
const recomputingTimeout = useRef<NodeJS.Timeout | undefined>(undefined)
minWidth: props.minColumnWidth,
}
return new CellMeasurerCache(options)
}, [props.minColumnWidth, props.minRowHeight])

const gridRef = useRef<Grid | null>(null)
const cacheRef = useRef<CellMeasurerCache>(cache)
const loggerRef = useRef(logger)

useEffect(() => {
loggerRef.current = logger
}, [logger])

useEffect(() => {
cacheRef.current = cache
}, [cache])

//Stores the headers sort configuration (whether they have sort disabled or not)
const headersSortDisabledMap = useMemo(() => {
Expand All @@ -89,23 +102,14 @@ export const ColumnGrid: React.FC<ColumnGridProps> = React.memo(props => {

// clear cache and recompute when data changes OR when the container width changes
const recomputeSizes = useCallback(() => {
cache.clearAll()
loggerRef.current.debug('Recomputing Sizes')
cacheRef.current?.clearAll()
gridRef.current?.recomputeGridSize()
}, [cache])

function recomputingCleanup() {
if (recomputingTimeout.current) {
clearTimeout(recomputingTimeout.current)
}
}
}, [])

// clear cache and recompute when data changes
useEffect(() => {
if (recomputingTimeout.current) {
clearTimeout(recomputingTimeout.current)
}
recomputingTimeout.current = setTimeout(recomputeSizes, 100)
return recomputingCleanup
recomputeSizes()
}, [props.data, props.width, recomputeSizes])

function getSortIndicatorComponent(order: string | undefined) {
Expand Down
5 changes: 3 additions & 2 deletions src/columnGrid/__tests__/ColumnGrid.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ describe('<ColumnGrid />', () => {
],
data: [],
minRowHeight: 10,
defaultColumnWidth: 10,
minColumnWidth: 10,
getColumnWidth: ({ index }: { index: number }) => 0,
width: 100,
scrollLeft: 0,
coords: { rowIndex: 0, colIndex: 0 },
apiRef: apiRefMock
apiRef: apiRefMock,
nestedRowsEnabled: false
}
const grid = shallow(<ColumnGrid {...props} />)

Expand Down
46 changes: 17 additions & 29 deletions src/columnGrid/column-grid-props.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,27 @@
import { StretchMode } from '../types'
import { GridHeader, Column, NestedHeader } from './types'
import { NavigationCoords } from '../keyboard/types'
import { DisableSortFilterParam } from '../gridWrapper'
import { ApiRef } from '../api'
import { GridHeader } from './types'
import { NavigationCoords } from '../keyboard'
import { SortState } from '../sort/useSort'
import {
ApolloColumnRowSizeProps,
ApolloCoreProps,
ApolloDataProps,
ApolloLayoutProps,
ApolloSortProps,
ApolloVirtualizedProps,
} from '../ApolloSpreadsheetProps'

export interface ColumnGridProps {
/**
* Indicates if the sort is disabled globally or on a specific column
* @default true **/
disableSort?: boolean | DisableSortFilterParam
apiRef: ApiRef
export interface ColumnGridProps
extends ApolloVirtualizedProps,
Pick<ApolloLayoutProps, 'stretchMode'>,
Pick<ApolloDataProps, 'columns' | 'nestedHeaders'>,
ApolloSortProps,
Required<ApolloCoreProps>,
Pick<ApolloColumnRowSizeProps, 'minRowHeight' | 'minColumnWidth'> {
data: Array<GridHeader[]>
columns: Column[]
nestedHeaders?: Array<NestedHeader[]>
minRowHeight: number
coords: NavigationCoords
defaultColumnWidth: number
getColumnWidth: ({ index }: { index: number }) => number
sort: SortState | null
width: number
scrollLeft: number
/** @default StretchMode.None */
stretchMode?: StretchMode
/**
* Overscan count buffer for react-virtualized
* @description Keep in mind a lower value
* @default 2
*/
overscanRowCount?: number
/**
* Overscan count buffer for react-virtualized
* @description Keep in mind a lower value
* @default 2
*/
overscanColumnCount?: number
nestedRowsEnabled: boolean
}
20 changes: 12 additions & 8 deletions src/gridContainer/GridContainerProps.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import React from 'react'
import { OnScrollParams } from 'react-virtualized'
import { Column } from '../columnGrid/types'
import { StretchMode } from '../types'
import { ApiRef } from '../api/types'
import {
ApolloColumnRowSizeProps,
ApolloCoreProps,
ApolloDataProps,
ApolloLayoutProps,
} from '../ApolloSpreadsheetProps'

export interface GridContainerChildrenProps {
width: number
Expand All @@ -18,10 +21,11 @@ export interface GridContainerCommonProps {
containerClassName?: string
}

export interface GridContainerProps extends GridContainerCommonProps {
columns: Column[]
minColumnWidth: number
stretchMode: StretchMode
export interface GridContainerProps
extends GridContainerCommonProps,
Required<ApolloCoreProps>,
Required<Pick<ApolloLayoutProps, 'stretchMode'>>,
Required<Pick<ApolloColumnRowSizeProps, 'minColumnWidth'>>,
Pick<ApolloDataProps, 'columns'> {
children: (props: GridContainerChildrenProps) => unknown
apiRef: ApiRef
}
Loading

0 comments on commit 8ac98fd

Please sign in to comment.