From e7394d4df167f9a307842d69ed7a6b53e20f6e64 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Tue, 18 May 2021 14:12:02 +0100 Subject: [PATCH] Allow nullish values on Columns --- src/Cell.tsx | 2 +- src/DataGrid.tsx | 9 ++--- src/editors/EditorContainer.tsx | 2 +- src/hooks/useCalculatedColumns.ts | 2 +- src/types.ts | 56 ++++++++++++++++--------------- src/utils/colSpanUtils.ts | 4 +-- 6 files changed, 39 insertions(+), 36 deletions(-) diff --git a/src/Cell.tsx b/src/Cell.tsx index 0d7bd4f546..9c7e6e4bc3 100644 --- a/src/Cell.tsx +++ b/src/Cell.tsx @@ -72,7 +72,7 @@ function Cell( className ); - function selectCellWrapper(openEditor?: boolean) { + function selectCellWrapper(openEditor?: boolean | null) { selectCell({ idx: column.idx, rowIdx }, openEditor); } diff --git a/src/DataGrid.tsx b/src/DataGrid.tsx index 6e9e69f2be..3ec11f61de 100644 --- a/src/DataGrid.tsx +++ b/src/DataGrid.tsx @@ -51,7 +51,8 @@ import type { PasteEvent, CellNavigationMode, SortDirection, - RowHeightArgs + RowHeightArgs, + SelectCellFn } from './types'; interface SelectCellState extends Position { @@ -83,7 +84,7 @@ export interface DataGridHandle { element: HTMLDivElement | null; scrollToColumn: (colIdx: number) => void; scrollToRow: (rowIdx: number) => void; - selectCell: (position: Position, openEditor?: boolean) => void; + selectCell: SelectCellFn; } type SharedDivProps = Pick< @@ -577,7 +578,7 @@ function DataGrid( function commitEditorChanges() { if ( - columns[selectedPosition.idx]?.editor === undefined || + columns[selectedPosition.idx]?.editor == null || selectedPosition.mode === 'SELECT' || selectedPosition.row === selectedPosition.originalRow ) { @@ -746,7 +747,7 @@ function DataGrid( ); } - function selectCell(position: Position, enableEditor = false): void { + function selectCell(position: Position, enableEditor?: boolean | null): void { if (!isCellWithinBounds(position)) return; commitEditorChanges(); diff --git a/src/editors/EditorContainer.tsx b/src/editors/EditorContainer.tsx index 1de2290af8..2abaa57030 100644 --- a/src/editors/EditorContainer.tsx +++ b/src/editors/EditorContainer.tsx @@ -17,7 +17,7 @@ export default function EditorContainer({ ...props }: EditorProps) { const onClickCapture = useClickOutside(() => onRowChange(row, true)); - if (column.editor === undefined) return null; + if (column.editor == null) return null; const editor = (
diff --git a/src/hooks/useCalculatedColumns.ts b/src/hooks/useCalculatedColumns.ts index 7d8a911542..68c99e6fff 100644 --- a/src/hooks/useCalculatedColumns.ts +++ b/src/hooks/useCalculatedColumns.ts @@ -94,7 +94,7 @@ export function useCalculatedColumns({ groupBy.push(column.key); } - if (column.colSpan !== undefined) { + if (column.colSpan != null) { colSpanColumns.push(column); } }); diff --git a/src/types.ts b/src/types.ts index 37e9875a43..0d4646dfd9 100644 --- a/src/types.ts +++ b/src/types.ts @@ -9,51 +9,51 @@ export interface Column { /** A unique key to distinguish each column */ key: string; /** Column width. If not specified, it will be determined automatically based on grid width and specified widths of other columns */ - width?: number | string; + width?: number | string | null; /** Minimum column width in px. */ - minWidth?: number; + minWidth?: number | null; /** Maximum column width in px. */ - maxWidth?: number; - cellClass?: string | ((row: TRow) => string | undefined); - headerCellClass?: string; - summaryCellClass?: string | ((row: TSummaryRow) => string); + maxWidth?: number | null; + cellClass?: string | ((row: TRow) => string | undefined | null) | null; + headerCellClass?: string | null; + summaryCellClass?: string | ((row: TSummaryRow) => string) | null; /** Formatter to be used to render the cell content */ - formatter?: React.ComponentType>; + formatter?: React.ComponentType> | null; /** Formatter to be used to render the summary cell content */ - summaryFormatter?: React.ComponentType>; + summaryFormatter?: React.ComponentType> | null; /** Formatter to be used to render the group cell content */ - groupFormatter?: React.ComponentType>; + groupFormatter?: React.ComponentType> | null; /** Enables cell editing. If set and no editor property specified, then a textinput will be used as the cell editor */ - editable?: boolean | ((row: TRow) => boolean); - colSpan?: (args: ColSpanArgs) => number | undefined; + editable?: boolean | ((row: TRow) => boolean) | null; + colSpan?: ((args: ColSpanArgs) => number | undefined | null) | null; /** Determines whether column is frozen or not */ - frozen?: boolean; + frozen?: boolean | null; /** Enable resizing of a column */ - resizable?: boolean; + resizable?: boolean | null; /** Enable sorting of a column */ - sortable?: boolean; + sortable?: boolean | null; /** Sets the column sort order to be descending instead of ascending the first time the column is sorted */ - sortDescendingFirst?: boolean; + sortDescendingFirst?: boolean | null; /** Editor to be rendered when cell of column is being edited. If set, then the column is automatically set to be editable */ - editor?: React.ComponentType>; + editor?: React.ComponentType> | null; editorOptions?: { /** @default false */ - createPortal?: boolean; + createPortal?: boolean | null; /** @default false */ - editOnClick?: boolean; + editOnClick?: boolean | null; /** Prevent default to cancel editing */ - onCellKeyDown?: (event: React.KeyboardEvent) => void; + onCellKeyDown?: ((event: React.KeyboardEvent) => void) | null; /** Control the default cell navigation behavior while the editor is open */ - onNavigation?: (event: React.KeyboardEvent) => boolean; + onNavigation?: ((event: React.KeyboardEvent) => boolean) | null; // TODO: Do we need these options - // editOnDoubleClick?: boolean; + // editOnDoubleClick?: boolean | null; /** @default false */ - // commitOnScroll?: boolean; - }; + // commitOnScroll?: boolean | null; + } | null; /** Header renderer for each header cell */ - headerRenderer?: React.ComponentType>; + headerRenderer?: React.ComponentType> | null; /** Component to be used to filter the data of the column */ - filterRenderer?: React.ComponentType>; + filterRenderer?: React.ComponentType> | null; } export interface CalculatedColumn extends Column { @@ -141,6 +141,8 @@ export interface SelectedCellProps extends SelectedCellPropsBase { | undefined; } +export type SelectCellFn = (position: Position, enableEditor?: boolean | null) => void; + export interface CellRendererProps extends Omit, 'style' | 'children'> { rowIdx: number; @@ -158,7 +160,7 @@ export interface CellRendererProps | ((rowIdx: number, row: TRow, column: CalculatedColumn) => void) | undefined | null; - selectCell: (position: Position, enableEditor?: boolean) => void; + selectCell: SelectCellFn; } export interface RowRendererProps @@ -181,7 +183,7 @@ export interface RowRendererProps | null; rowClass: ((row: TRow) => string | undefined | null) | undefined | null; setDraggedOverRowIdx: ((overRowIdx: number) => void) | undefined; - selectCell: (position: Position, enableEditor?: boolean) => void; + selectCell: SelectCellFn; } export interface FilterRendererProps { diff --git a/src/utils/colSpanUtils.ts b/src/utils/colSpanUtils.ts index 82e72b3398..e986ba90b3 100644 --- a/src/utils/colSpanUtils.ts +++ b/src/utils/colSpanUtils.ts @@ -4,7 +4,7 @@ export function getColSpan( column: CalculatedColumn, lastFrozenColumnIndex: number, args: ColSpanArgs -) { +): number | undefined { const colSpan = typeof column.colSpan === 'function' ? column.colSpan(args) : 1; if ( Number.isInteger(colSpan) && @@ -12,7 +12,7 @@ export function getColSpan( // ignore colSpan if it spans over both frozen and regular columns (!column.frozen || column.idx + colSpan! - 1 <= lastFrozenColumnIndex) ) { - return colSpan; + return colSpan!; } return undefined; }