-
Notifications
You must be signed in to change notification settings - Fork 8.3k
/
cell_value.tsx
87 lines (82 loc) · 3.3 KB
/
cell_value.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React, { useContext, useEffect } from 'react';
import { EuiDataGridCellValueElementProps } from '@elastic/eui';
import { IUiSettingsClient } from 'kibana/public';
import classNames from 'classnames';
import type { FormatFactory } from '../../../common';
import { getOriginalId } from '../../../common/expressions';
import type { ColumnConfig } from '../../../common/expressions';
import type { DataContextType } from './types';
import { getContrastColor, getNumericValue } from '../../shared_components/coloring/utils';
export const createGridCell = (
formatters: Record<string, ReturnType<FormatFactory>>,
columnConfig: ColumnConfig,
DataContext: React.Context<DataContextType>,
uiSettings: IUiSettingsClient,
fitRowToContent?: boolean
) => {
// Changing theme requires a full reload of the page, so we can cache here
const IS_DARK_THEME = uiSettings.get('theme:darkMode');
return ({ rowIndex, columnId, setCellProps }: EuiDataGridCellValueElementProps) => {
const { table, alignments, minMaxByColumnId, getColorForValue } = useContext(DataContext);
const rowValue = table?.rows[rowIndex]?.[columnId];
const content = formatters[columnId]?.convert(rowValue, 'html');
const currentAlignment = alignments && alignments[columnId];
const alignmentClassName = `lnsTableCell--${currentAlignment}`;
const className = classNames(alignmentClassName, {
lnsTableCell: !fitRowToContent,
});
const { colorMode, palette } =
columnConfig.columns.find(({ columnId: id }) => id === columnId) || {};
useEffect(() => {
const originalId = getOriginalId(columnId);
if (minMaxByColumnId?.[originalId]) {
if (colorMode !== 'none' && palette?.params && getColorForValue) {
// workout the bucket the value belongs to
const color = getColorForValue(
getNumericValue(rowValue),
palette.params,
minMaxByColumnId[originalId]
);
if (color) {
const style = { [colorMode === 'cell' ? 'backgroundColor' : 'color']: color };
if (colorMode === 'cell' && color) {
style.color = getContrastColor(color, IS_DARK_THEME);
}
setCellProps({
style,
});
}
}
}
// make sure to clean it up when something change
// this avoids cell's styling to stick forever
return () => {
if (minMaxByColumnId?.[originalId]) {
setCellProps({
style: {
backgroundColor: undefined,
color: undefined,
},
});
}
};
}, [rowValue, columnId, setCellProps, colorMode, palette, minMaxByColumnId, getColorForValue]);
return (
<div
/*
* dangerouslySetInnerHTML is necessary because the field formatter might produce HTML markup
* which is produced in a safe way.
*/
dangerouslySetInnerHTML={{ __html: content }} // eslint-disable-line react/no-danger
data-test-subj="lnsTableCellContent"
className={className}
/>
);
};
};