Skip to content

Commit

Permalink
Created a new HoC (GridContainer) to determinate and calculate the wi…
Browse files Browse the repository at this point in the history
…dth and other necessary measures.

Horizontal scroll is now broken but arrow navigation is in sync and perfectly working
Added a custom alignment on the storybook demo, a delete row and expanded header tooltipProps to receive PaperProps for the underlying component. Tooltips now doesn't come with arrow by default
Removed onCellClick from GridWrapper and instead we invoke directly selectCell.
useCallbacks were also removed in general where it was not needed and affecting performance
Added enter keyboard control to select checkbox
Text and Numerical editor have a resize-detector that stops editing if the target anchoring changes
Added props.width on ColumnGrid to recomputeGridSizes when the width changes
  • Loading branch information
underfisk committed Oct 14, 2020
1 parent 3b283cb commit 471eab6
Show file tree
Hide file tree
Showing 21 changed files with 977 additions and 365 deletions.
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,20 @@
"@material-ui/pickers": "^3.2.10",
"@testing-library/react-hooks": "^3.4.2",
"@types/react-virtualized": "^9.21.10",
"@xobotyi/scrollbar-width": "^1.9.5",
"babel-loader": "^8.1.0",
"babel-preset-react-app": "^9.1.2",
"clipboardy": "^2.3.0",
"clsx": "^1.1.1",
"dayjs": "^1.9.1",
"element-resize-detector": "^1.2.1",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.5",
"enzyme-to-json": "^3.6.1",
"json2csv": "^5.0.1",
"react-datepicker": "^3.2.2",
"react-virtualized": "^9.21.2",
"resize-detector": "^0.2.2",
"rxjs": "^6.6.3"
},
"devDependencies": {
Expand Down
9 changes: 5 additions & 4 deletions src/cellMeasurer/CellMeasureWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import { CellMeasurer } from 'react-virtualized'
import { CellMeasureWrapperProps } from './cellMeasureWrapperProps'
import { getMaxSum } from './utils/getMaxSum'

const CellMeasureWrapper = React.memo(
({ rowSpan, colSpan, cellRenderer, rendererProps, style, ...props }: CellMeasureWrapperProps) => {
function CellMeasureWrapper ({ rowSpan, colSpan, cellRenderer, rendererProps, style, ...props }: CellMeasureWrapperProps) {
const initializeStyles = () => {
const defaultStyle: React.CSSProperties = {
transform: 'translate3d(0, 0, 0)',
Expand Down Expand Up @@ -58,6 +57,9 @@ const CellMeasureWrapper = React.memo(
}

const spanningStyle = initializeStyles()
if (isNaN(Number(spanningStyle.width))){
console.error("WIDTH NAN AT SPANNING STYLE")
}
return (
<CellMeasurer {...props}>
{({ registerChild }) =>
Expand All @@ -69,7 +71,6 @@ const CellMeasureWrapper = React.memo(
}
</CellMeasurer>
)
},
)
}

export default CellMeasureWrapper
13 changes: 7 additions & 6 deletions src/cellMeasurer/cellMeasureWrapperProps.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import React from 'react'
import { RegisterChildFn } from '../core/interfaces/registerChildFn'
import { GetColumnWidthFn } from '../core/interfaces/getColumnWidthFn'
import { CellMeasurerCache } from 'react-virtualized'
import { GridCell } from '../types/row.interface'
import { MeasuredCellParent } from 'react-virtualized/dist/es/CellMeasurer'
import { GetColumnWidthFn } from '../gridWrapper/interfaces/getColumnWidthFn'
import { GridCell } from '../gridWrapper/interfaces/gridCell'

interface CellMeasureRendererProps {
style: React.CSSProperties
ref?: RegisterChildFn
// style: React.CSSProperties
// ref?: RegisterChildFn
}

export interface MeasurerRendererProps {
Expand All @@ -18,7 +17,9 @@ export interface MeasurerRendererProps {
getColumnWidth: GetColumnWidthFn
}

export type CellMeasureRenderer = (props: CellMeasureRendererProps) => any
export interface CellMeasureRenderer {
(props: any): unknown
}

export interface CellMeasureWrapperProps {
rowSpan?: number
Expand Down
15 changes: 11 additions & 4 deletions src/columnGrid/ColumnGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ export const ColumnGrid = React.memo(
}))
const gridRef = useRef<Grid | null>(null)

// clear cache and recompute when data changes
// clear cache and recompute when data changes OR when the container width changes
useEffect(() => {
cache?.clearAll()
cache.clearAll()
gridRef.current?.recomputeGridSize()
}, [props.data])
}, [props.data, props.width])

function getSortIndicatorComponent(order: string | undefined) {
if (!order) {
Expand All @@ -68,7 +68,7 @@ export const ColumnGrid = React.memo(
const children = renderer ? (
(renderer(cell) as any)
) : cell.tooltip ? (
<Tooltip title={title} arrow placement={'top'} {...cell.tooltipProps}>
<Tooltip title={title} placement={'top'} {...cell.tooltipProps}>
<span>{title}</span>
</Tooltip>
) : (
Expand All @@ -90,6 +90,7 @@ export const ColumnGrid = React.memo(
headerClassName = clsx(headerClassName, props.theme?.currentColumnClass)
}


return (
<div
ref={ref}
Expand Down Expand Up @@ -149,11 +150,16 @@ export const ColumnGrid = React.memo(
userSelect: 'none',
}


const rendererProps: MeasurerRendererProps = {
...args,
cell,
getColumnWidth: props.getColumnWidth,
}

if (isNaN(Number(style.width))){
console.error("WIDTH NAN AT CELL MEASURER WRAPPER STYLE")
}
return (
<CellMeasurer
cache={cache}
Expand Down Expand Up @@ -198,6 +204,7 @@ export const ColumnGrid = React.memo(
overscanColumnCount={props.overscanColumnCount ?? 2}
width={props.width}
columnWidth={props.getColumnWidth}
height={100} //Its going to be ignored due to autoHeight
autoHeight
/>
)
Expand Down
5 changes: 2 additions & 3 deletions src/columnGrid/column-grid-props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ export interface ColumnGridProps {
getColumnWidth: ({ index }: { index: number }) => number

width: number
scrollLeft: number
isScrolling: boolean
height: number
// scrollLeft: number
// isScrolling: boolean
theme?: GridTheme
coords: NavigationCoords
/** @default StretchMode.None */
Expand Down
2 changes: 2 additions & 0 deletions src/columnGrid/types/header.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react'
import { TooltipProps } from '@material-ui/core'
import { NavigationCoords } from '../../navigation/types/navigation-coords.type'
import { EditorRef } from '../../editorManager/useEditorManager'
import { PopperProps } from '@material-ui/core/Popper/Popper'

export interface CellRendererProps<TRow = unknown> {
row: TRow
Expand Down Expand Up @@ -44,6 +45,7 @@ export interface Header<Key = string> {
open?: boolean
/** @default top **/
placement?: TooltipProps['placement']
PopperProps?: Partial<PopperProps>
}
/** @default 500 **/
maxLength?: number
Expand Down
16 changes: 15 additions & 1 deletion src/editorManager/components/NumericEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import React, {
CSSProperties,
forwardRef,
useCallback,
useCallback, useEffect,
useImperativeHandle,
useMemo,
useState,
} from 'react'
import { EditorProps } from '../editorProps'
import { Popover, TextareaAutosize, TextField } from '@material-ui/core'
import { makeStyles } from '@material-ui/core/styles'
import { addListener, removeListener } from 'resize-detector'

const useStyles = makeStyles(() => ({
input: {
Expand All @@ -31,6 +32,19 @@ export const NumericEditor = forwardRef(
const [editingValue, setEditingValue] = useState<string>(
isNaN(Number(value)) ? '0' : String(value),
)

function onAnchorResize() {
stopEditing()
}

//Watch for DOM Changes on the target anchor and close editor because Popover does not change
useEffect(() => {
addListener(anchorRef, onAnchorResize)
return () => {
removeListener(anchorRef, onAnchorResize)
}
}, [])

useImperativeHandle(
componentRef,
() => ({
Expand Down
14 changes: 14 additions & 0 deletions src/editorManager/components/TextEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { NavigationKey } from '../enums/navigation-key.enum'
import { isCaretAtEndPosition } from '../utils/isCaretAtEndPosition'
import { EditorProps } from '../editorProps'
import { makeStyles } from '@material-ui/core/styles'
import { addListener, removeListener } from 'resize-detector'

const useStyles = makeStyles(() => ({
input: {
Expand All @@ -32,6 +33,19 @@ export const TextEditor = forwardRef(
({ value, stopEditing, anchorRef, maxLength, validatorHook }: EditorProps, componentRef) => {
const classes = useStyles()
const [editingValue, setEditingValue] = useState(String(value))

function onAnchorResize() {
stopEditing()
}

//Watch for DOM Changes on the target anchor and close editor because Popover does not change
useEffect(() => {
addListener(anchorRef, onAnchorResize)
return () => {
removeListener(anchorRef, onAnchorResize)
}
}, [])

useImperativeHandle(
componentRef,
() => ({
Expand Down
2 changes: 1 addition & 1 deletion src/editorManager/editorProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { StopEditingParams } from './useEditorManager'
export interface EditorProps {
value: string
stopEditing: (params?: StopEditingParams) => void
anchorRef: Element
anchorRef: HTMLElement
cellStyle?: CSSProperties
maxLength: number
validatorHook?: (value: unknown) => boolean
Expand Down
5 changes: 3 additions & 2 deletions src/editorManager/useEditorManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export interface IEditorState {
rowIndex: number
colIndex: number
initialValue: React.ReactText
targetElement: Element
targetElement: HTMLElement
validatorHook?: (value: unknown) => boolean
/**
* Useful to prevent navigation interception on second arms
Expand All @@ -46,7 +46,7 @@ export interface EditorManagerProps<TRow = unknown> {

export interface BeginEditingParams {
coords: NavigationCoords
targetElement: Element
targetElement: HTMLElement
defaultKey?: string
}

Expand All @@ -65,6 +65,7 @@ export function useEditorManager<TRow>({ getColumnAt, rows, onCellChange }: Edit
const [editorNode, setEditorNode] = useState<JSX.Element | null>(null)
const [scheduleMove, setScheduleMove] = useState<string | null>(null)


//Effect used to perform the move (keyPress) after editor closes
useEffect(() => {
if (!scheduleMove) {
Expand Down
Loading

0 comments on commit 471eab6

Please sign in to comment.