diff --git a/README.md b/README.md index c597742a28..568fcf4b58 100644 --- a/README.md +++ b/README.md @@ -234,6 +234,10 @@ function MyGrid() { ###### `rowClass?: Maybe<(row: R) => Maybe>` +###### `rowStyle?: Maybe<(row: R) => Maybe>` + +This property sets the passed JSX style to the row. + ##### `direction?: Maybe<'ltr' | 'rtl'>` This property sets the text direction of the grid, it defaults to `'ltr'` (left-to-right). Setting `direction` to `'rtl'` has the following effects: diff --git a/src/Cell.tsx b/src/Cell.tsx index 7e376254b7..21c8be297f 100644 --- a/src/Cell.tsx +++ b/src/Cell.tsx @@ -37,7 +37,7 @@ function Cell({ }: CellRendererProps) { const { ref, tabIndex, onFocus } = useRovingCellRef(isCellSelected); - const { cellClass } = column; + const { cellClass, cellStyle } = column; const className = getCellClassname( column, { @@ -46,6 +46,7 @@ function Cell({ }, typeof cellClass === 'function' ? cellClass(row) : cellClass ); + const style = typeof cellStyle === 'function' ? cellStyle(row) : cellStyle; function selectCellWrapper(openEditor?: boolean | null) { selectCell(row, column, openEditor); @@ -79,7 +80,7 @@ function Cell({ ref={ref} tabIndex={tabIndex} className={className} - style={getCellStyle(column, colSpan)} + style={getCellStyle(column, colSpan, style)} onClick={handleClick} onDoubleClick={handleDoubleClick} onContextMenu={handleContextMenu} diff --git a/src/DataGrid.tsx b/src/DataGrid.tsx index 69381d0384..15d41690f7 100644 --- a/src/DataGrid.tsx +++ b/src/DataGrid.tsx @@ -1,5 +1,5 @@ import { forwardRef, useState, useRef, useImperativeHandle, useCallback, useMemo } from 'react'; -import type { Key, RefAttributes } from 'react'; +import type { Key, RefAttributes, CSSProperties } from 'react'; import clsx from 'clsx'; import { @@ -175,6 +175,7 @@ export interface DataGridProps extends Sha */ renderers?: Maybe>; rowClass?: Maybe<(row: R) => Maybe>; + rowStyle?: Maybe Maybe)>; direction?: Maybe; 'data-testid'?: Maybe; } @@ -224,6 +225,7 @@ function DataGrid( className, style, rowClass, + rowStyle, direction, // ARIA 'aria-label': ariaLabel, @@ -1070,6 +1072,7 @@ function DataGrid( onRowClick, onRowDoubleClick, rowClass, + rowStyle, gridRowStart, height: getRowHeight(rowIdx), copiedCellIdx: diff --git a/src/EditCell.tsx b/src/EditCell.tsx index 2d9a340c2e..6faf53eab5 100644 --- a/src/EditCell.tsx +++ b/src/EditCell.tsx @@ -95,13 +95,14 @@ export default function EditCell({ } } - const { cellClass } = column; + const { cellClass, cellStyle } = column; const className = getCellClassname( column, 'rdg-editor-container', !column.editorOptions?.renderFormatter && cellEditing, typeof cellClass === 'function' ? cellClass(row) : cellClass ); + const style = typeof cellStyle === 'function' ? cellStyle(row) : cellStyle; return (
({ aria-colspan={colSpan} aria-selected className={className} - style={getCellStyle(column, colSpan)} + style={getCellStyle(column, colSpan, style)} onKeyDown={onKeyDown} onMouseDownCapture={commitOnOutsideClick ? cancelFrameRequest : undefined} > diff --git a/src/HeaderCell.tsx b/src/HeaderCell.tsx index 343297cb3f..9f53cbbbd2 100644 --- a/src/HeaderCell.tsx +++ b/src/HeaderCell.tsx @@ -174,7 +174,7 @@ export default function HeaderCell({ tabIndex={shouldFocusGrid ? 0 : tabIndex} className={className} style={{ - ...getCellStyle(column, colSpan), + ...getCellStyle(column, colSpan, column.headerCellStyle), minWidth: column.minWidth, maxWidth: column.maxWidth ?? undefined }} diff --git a/src/Row.tsx b/src/Row.tsx index f18e252fb0..f86299a18b 100644 --- a/src/Row.tsx +++ b/src/Row.tsx @@ -26,6 +26,7 @@ function Row( onRowClick, onRowDoubleClick, rowClass, + rowStyle, setDraggedOverRowIdx, onMouseEnter, onRowChange, @@ -53,6 +54,8 @@ function Row( className ); + rowStyle = typeof rowStyle === 'function' ? rowStyle(row) : rowStyle; + const cells = []; for (let index = 0; index < viewportColumns.length; index++) { @@ -94,7 +97,7 @@ function Row( ref={ref} className={className} onMouseEnter={handleDragEnter} - style={getRowStyle(gridRowStart, height)} + style={getRowStyle(gridRowStart, height, rowStyle)} {...props} > {cells} diff --git a/src/SummaryCell.tsx b/src/SummaryCell.tsx index 3fe6d0ffaf..5cac03d84d 100644 --- a/src/SummaryCell.tsx +++ b/src/SummaryCell.tsx @@ -27,12 +27,13 @@ function SummaryCell({ selectCell }: SummaryCellProps) { const { ref, tabIndex, onFocus } = useRovingCellRef(isCellSelected); - const { summaryCellClass } = column; + const { summaryCellClass, summaryCellStyle } = column; const className = getCellClassname( column, summaryCellClassname, typeof summaryCellClass === 'function' ? summaryCellClass(row) : summaryCellClass ); + const style = typeof summaryCellStyle === 'function' ? summaryCellStyle(row) : summaryCellStyle; function onClick() { selectCell(row, column); @@ -47,7 +48,7 @@ function SummaryCell({ ref={ref} tabIndex={tabIndex} className={className} - style={getCellStyle(column, colSpan)} + style={getCellStyle(column, colSpan, style)} onClick={onClick} onFocus={onFocus} > diff --git a/src/types.ts b/src/types.ts index 6f82a1298c..d351b61432 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,4 @@ -import type { Key, ReactElement, ReactNode, RefObject } from 'react'; +import type { Key, ReactElement, ReactNode, RefObject, CSSProperties } from 'react'; export type Omit = Pick>; @@ -15,9 +15,14 @@ export interface Column { readonly minWidth?: Maybe; /** Maximum column width in px. */ readonly maxWidth?: Maybe; + /** Standard, header and summary cell style */ readonly cellClass?: Maybe Maybe)>; readonly headerCellClass?: Maybe; readonly summaryCellClass?: Maybe Maybe)>; + /** Standard, header and summary cell style */ + readonly cellStyle?: Maybe Maybe)>; + readonly headerCellStyle?: Maybe; + readonly summaryCellStyle?: Maybe Maybe)>; /** Formatter to be used to render the cell content */ readonly formatter?: Maybe<(props: FormatterProps) => ReactNode>; /** Formatter to be used to render the summary cell content */ @@ -143,6 +148,7 @@ export interface RowRendererProps onRowClick: Maybe<(row: TRow, column: CalculatedColumn) => void>; onRowDoubleClick: Maybe<(row: TRow, column: CalculatedColumn) => void>; rowClass: Maybe<(row: TRow) => Maybe>; + rowStyle: Maybe Maybe)>; setDraggedOverRowIdx: ((overRowIdx: number) => void) | undefined; selectCell: ( row: TRow, diff --git a/src/utils/styleUtils.ts b/src/utils/styleUtils.ts index 5afa2596f0..3e3bcd6f06 100644 --- a/src/utils/styleUtils.ts +++ b/src/utils/styleUtils.ts @@ -1,14 +1,19 @@ import type { CSSProperties } from 'react'; import clsx from 'clsx'; -import type { CalculatedColumn } from '../types'; +import type { Maybe, CalculatedColumn } from '../types'; import { cellClassname, cellFrozenClassname, cellFrozenLastClassname } from '../style'; -export function getRowStyle(rowIdx: number, height?: number): CSSProperties { +export function getRowStyle( + rowIdx: number, + height?: number, + extraStyles?: Maybe +): CSSProperties { if (height !== undefined) { return { '--rdg-grid-row-start': rowIdx, - '--rdg-row-height': `${height}px` + '--rdg-row-height': `${height}px`, + ...extraStyles } as unknown as CSSProperties; } return { '--rdg-grid-row-start': rowIdx } as unknown as CSSProperties; @@ -16,12 +21,14 @@ export function getRowStyle(rowIdx: number, height?: number): CSSProperties { export function getCellStyle( column: CalculatedColumn, - colSpan?: number + colSpan?: number, + extraStyles?: Maybe ): React.CSSProperties { return { gridColumnStart: column.idx + 1, gridColumnEnd: colSpan !== undefined ? `span ${colSpan}` : undefined, - insetInlineStart: column.frozen ? `var(--rdg-frozen-left-${column.idx})` : undefined + insetInlineStart: column.frozen ? `var(--rdg-frozen-left-${column.idx})` : undefined, + ...extraStyles }; }