diff --git a/src-docs/src/views/datagrid/datagrid.js b/src-docs/src/views/datagrid/datagrid.js
index d2780c5d3b5..b3d4d3a83b2 100644
--- a/src-docs/src/views/datagrid/datagrid.js
+++ b/src-docs/src/views/datagrid/datagrid.js
@@ -1,7 +1,6 @@
import React, {
Fragment,
useCallback,
- useEffect,
useMemo,
useState,
createContext,
@@ -366,23 +365,8 @@ export default () => {
); // initialize to the full set of columns
const renderCellValue = useMemo(() => {
- return ({ rowIndex, columnId, setCellProps }) => {
+ return ({ rowIndex, columnId, CellProps }) => {
const data = useContext(DataContext);
- useEffect(() => {
- if (columnId === 'amount') {
- if (data.hasOwnProperty(rowIndex)) {
- const numeric = parseFloat(
- data[rowIndex][columnId].match(/\d+\.\d+/)[0],
- 10
- );
- setCellProps({
- style: {
- backgroundColor: `rgba(0, 255, 0, ${numeric * 0.0002})`,
- },
- });
- }
- }
- }, [rowIndex, columnId, setCellProps, data]);
function getFormatted() {
return data[rowIndex][columnId].formatted
@@ -390,9 +374,31 @@ export default () => {
: data[rowIndex][columnId];
}
- return data.hasOwnProperty(rowIndex)
+ const content = data.hasOwnProperty(rowIndex)
? getFormatted(rowIndex, columnId)
: null;
+
+ // Apply custom background color to cells in the `amount` columns
+ let cellProps = undefined;
+ if (columnId === 'amount') {
+ const numeric = parseFloat(content.match(/\d+\.\d+/)[0], 10);
+ cellProps = (
+
+ );
+ }
+
+ return (
+ <>
+ {content}
+ {cellProps}
+ >
+ );
};
}, []);
diff --git a/src/components/datagrid/body/__snapshots__/data_grid_cell.test.tsx.snap b/src/components/datagrid/body/__snapshots__/data_grid_cell.test.tsx.snap
index 3f57f59cf0a..d2cd2c8d1c4 100644
--- a/src/components/datagrid/body/__snapshots__/data_grid_cell.test.tsx.snap
+++ b/src/components/datagrid/body/__snapshots__/data_grid_cell.test.tsx.snap
@@ -1,5 +1,39 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
+exports[`EuiDataGridCell componentDidUpdate handles the cell popover by forwarding the cell's DOM node and contents to the parent popover context 1`] = `
+Array [
+
+
+
+
+
+
,
+ ,
+]
+`;
+
exports[`EuiDataGridCell renders 1`] = `
`;
-
-exports[`EuiDataGridCell componentDidUpdate handles the cell popover by forwarding the cell's DOM node and contents to the parent popover context 1`] = `
-Array [
-
-
-
-
-
-
,
- ,
-]
-`;
diff --git a/src/components/datagrid/body/data_grid_cell.tsx b/src/components/datagrid/body/data_grid_cell.tsx
index 4826891a3fa..812333d2f59 100644
--- a/src/components/datagrid/body/data_grid_cell.tsx
+++ b/src/components/datagrid/body/data_grid_cell.tsx
@@ -9,6 +9,7 @@
import classNames from 'classnames';
import React, {
Component,
+ createContext,
createRef,
FocusEvent,
FunctionComponent,
@@ -17,6 +18,8 @@ import React, {
KeyboardEvent,
memo,
MutableRefObject,
+ useContext,
+ useEffect,
} from 'react';
import { createPortal } from 'react-dom';
import tabbable from 'tabbable';
@@ -41,6 +44,7 @@ import { IS_JEST_ENVIRONMENT } from '../../../test';
const EuiDataGridCellContent: FunctionComponent<
EuiDataGridCellValueProps & {
setCellProps: EuiDataGridCellValueElementProps['setCellProps'];
+ CellProps: typeof CellProps;
setCellContentsRef: EuiDataGridCell['setCellContentsRef'];
isExpanded: boolean;
isDefinedHeight: boolean;
@@ -99,6 +103,22 @@ const EuiDataGridCellContent: FunctionComponent<
}
);
+const CellPropsContext = createContext<{
+ setCellProps: (props: HTMLAttributes) => void;
+}>({
+ setCellProps: () => {},
+});
+
+export const CellProps: FunctionComponent<{
+ props: HTMLAttributes;
+}> = ({ props }) => {
+ const { setCellProps } = useContext(CellPropsContext);
+ useEffect(() => {
+ setCellProps(props);
+ }, [setCellProps, props]);
+ return null;
+};
+
export class EuiDataGridCell extends Component<
EuiDataGridCellProps,
EuiDataGridCellState
@@ -469,6 +489,7 @@ export class EuiDataGridCell extends Component<
isExpandable={true}
isExpanded={true}
setCellProps={this.setCellProps}
+ CellProps={CellProps}
isDetails={true}
/>
@@ -599,6 +620,7 @@ export class EuiDataGridCell extends Component<
const cellContentProps = {
...rest,
setCellProps: this.setCellProps,
+ CellProps,
column,
columnType: columnType,
isExpandable,
@@ -668,32 +690,34 @@ export class EuiDataGridCell extends Component<
}
const content = (
- {
- this.setState({ enableInteractions: true });
- }}
- onMouseLeave={() => {
- this.setState({ enableInteractions: false });
- }}
- onBlur={this.onBlur}
- >
- {innerContent}
-
+
+ {
+ this.setState({ enableInteractions: true });
+ }}
+ onMouseLeave={() => {
+ this.setState({ enableInteractions: false });
+ }}
+ onBlur={this.onBlur}
+ >
+ {innerContent}
+
+
);
return rowManager && !IS_JEST_ENVIRONMENT
diff --git a/src/components/datagrid/data_grid_types.ts b/src/components/datagrid/data_grid_types.ts
index a84d03a0ead..eebf53eb94f 100644
--- a/src/components/datagrid/data_grid_types.ts
+++ b/src/components/datagrid/data_grid_types.ts
@@ -18,6 +18,7 @@ import {
Dispatch,
SetStateAction,
MutableRefObject,
+ FunctionComponent,
} from 'react';
import {
VariableSizeGridProps,
@@ -389,6 +390,10 @@ export interface EuiDataGridCellValueElementProps {
* it's best to wrap calls to `setCellProps` in a `useEffect` hook
*/
setCellProps: (props: CommonProps & HTMLAttributes) => void;
+ /**
+ * React component that can be used to specific custom props & attributes on the cell's wrapping `div` element
+ */
+ CellProps: FunctionComponent<{ props: HTMLAttributes }>;
/**
* whether or not the cell is expandable, comes from the #EuiDataGridColumn `isExpandable` which defaults to `true`
*/
diff --git a/src/components/datagrid/utils/in_memory.tsx b/src/components/datagrid/utils/in_memory.tsx
index ef979fa2cb0..0522344cba6 100644
--- a/src/components/datagrid/utils/in_memory.tsx
+++ b/src/components/datagrid/utils/in_memory.tsx
@@ -24,6 +24,7 @@ import {
EuiDataGridInMemoryRendererProps,
EuiDataGridCellValueElementProps,
} from '../data_grid_types';
+import { CellProps } from '../body/data_grid_cell';
/**
* inMemory values hook
@@ -124,6 +125,7 @@ export const EuiDataGridInMemoryRenderer: FunctionComponent