mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Table: Optimization - render icons on hover (#76906)
* only render icons on hover * Table: Optimization - remove plaintext cell wrapper (#76916) * remove inner wrapper div from plain text cells * reuse result of typeof value === 'string' --------- Co-authored-by: Galen <galen.kistler@grafana.com> --------- Co-authored-by: Leon Sorokin <leeoniya@gmail.com>
This commit is contained in:
parent
3a9eb33b14
commit
88957c7f44
@ -1,5 +1,5 @@
|
|||||||
import { cx } from '@emotion/css';
|
import { cx } from '@emotion/css';
|
||||||
import React, { ReactElement } from 'react';
|
import React, { ReactElement, useState } from 'react';
|
||||||
import tinycolor from 'tinycolor2';
|
import tinycolor from 'tinycolor2';
|
||||||
|
|
||||||
import { DisplayValue, formattedValueToString } from '@grafana/data';
|
import { DisplayValue, formattedValueToString } from '@grafana/data';
|
||||||
@ -24,11 +24,18 @@ export const DefaultCell = (props: TableCellProps) => {
|
|||||||
const showFilters = props.onCellFilterAdded && field.config.filterable;
|
const showFilters = props.onCellFilterAdded && field.config.filterable;
|
||||||
const showActions = (showFilters && cell.value !== undefined) || inspectEnabled;
|
const showActions = (showFilters && cell.value !== undefined) || inspectEnabled;
|
||||||
const cellOptions = getCellOptions(field);
|
const cellOptions = getCellOptions(field);
|
||||||
const cellStyle = getCellStyle(tableStyles, cellOptions, displayValue, inspectEnabled);
|
|
||||||
const hasLinks = Boolean(getCellLinks(field, row)?.length);
|
const hasLinks = Boolean(getCellLinks(field, row)?.length);
|
||||||
const clearButtonStyle = useStyles2(clearLinkButtonStyles);
|
const clearButtonStyle = useStyles2(clearLinkButtonStyles);
|
||||||
|
const [hover, setHover] = useState(false);
|
||||||
let value: string | ReactElement;
|
let value: string | ReactElement;
|
||||||
|
|
||||||
|
const onMouseLeave = () => {
|
||||||
|
setHover(false);
|
||||||
|
};
|
||||||
|
const onMouseEnter = () => {
|
||||||
|
setHover(true);
|
||||||
|
};
|
||||||
|
|
||||||
if (cellOptions.type === TableCellDisplayMode.Custom) {
|
if (cellOptions.type === TableCellDisplayMode.Custom) {
|
||||||
const CustomCellComponent: React.ComponentType<CustomCellRendererProps> = cellOptions.cellComponent;
|
const CustomCellComponent: React.ComponentType<CustomCellRendererProps> = cellOptions.cellComponent;
|
||||||
value = <CustomCellComponent field={field} value={cell.value} rowIndex={row.index} frame={frame} />;
|
value = <CustomCellComponent field={field} value={cell.value} rowIndex={row.index} frame={frame} />;
|
||||||
@ -40,9 +47,22 @@ export const DefaultCell = (props: TableCellProps) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isStringValue = typeof value === 'string';
|
||||||
|
|
||||||
|
const cellStyle = getCellStyle(tableStyles, cellOptions, displayValue, inspectEnabled, isStringValue);
|
||||||
|
|
||||||
|
if (isStringValue && cellProps.style?.justifyContent === 'flex-end') {
|
||||||
|
cellProps.style!.textAlign = 'right';
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div {...cellProps} className={cellStyle}>
|
<div
|
||||||
{!hasLinks && <div className={tableStyles.cellText}>{value}</div>}
|
{...cellProps}
|
||||||
|
onMouseEnter={showActions ? onMouseEnter : undefined}
|
||||||
|
onMouseLeave={showActions ? onMouseLeave : undefined}
|
||||||
|
className={cellStyle}
|
||||||
|
>
|
||||||
|
{!hasLinks && (isStringValue ? `${value}` : <div className={tableStyles.cellText}>{value}</div>)}
|
||||||
|
|
||||||
{hasLinks && (
|
{hasLinks && (
|
||||||
<DataLinksContextMenu links={() => getCellLinks(field, row) || []}>
|
<DataLinksContextMenu links={() => getCellLinks(field, row) || []}>
|
||||||
@ -63,7 +83,7 @@ export const DefaultCell = (props: TableCellProps) => {
|
|||||||
</DataLinksContextMenu>
|
</DataLinksContextMenu>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{showActions && <CellActions {...props} previewMode="text" showFilters={showFilters} />}
|
{hover && showActions && <CellActions {...props} previewMode="text" showFilters={showFilters} />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -72,7 +92,8 @@ function getCellStyle(
|
|||||||
tableStyles: TableStyles,
|
tableStyles: TableStyles,
|
||||||
cellOptions: TableCellOptions,
|
cellOptions: TableCellOptions,
|
||||||
displayValue: DisplayValue,
|
displayValue: DisplayValue,
|
||||||
disableOverflowOnHover = false
|
disableOverflowOnHover = false,
|
||||||
|
isStringValue = false
|
||||||
) {
|
) {
|
||||||
// How much to darken elements depends upon if we're in dark mode
|
// How much to darken elements depends upon if we're in dark mode
|
||||||
const darkeningFactor = tableStyles.theme.isDark ? 1 : -0.7;
|
const darkeningFactor = tableStyles.theme.isDark ? 1 : -0.7;
|
||||||
@ -101,10 +122,14 @@ function getCellStyle(
|
|||||||
// If we have definied colors return those styles
|
// If we have definied colors return those styles
|
||||||
// Otherwise we return default styles
|
// Otherwise we return default styles
|
||||||
if (textColor !== undefined || bgColor !== undefined) {
|
if (textColor !== undefined || bgColor !== undefined) {
|
||||||
return tableStyles.buildCellContainerStyle(textColor, bgColor, !disableOverflowOnHover);
|
return tableStyles.buildCellContainerStyle(textColor, bgColor, !disableOverflowOnHover, isStringValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
return disableOverflowOnHover ? tableStyles.cellContainerNoOverflow : tableStyles.cellContainer;
|
if (isStringValue) {
|
||||||
|
return disableOverflowOnHover ? tableStyles.cellContainerTextNoOverflow : tableStyles.cellContainerText;
|
||||||
|
} else {
|
||||||
|
return disableOverflowOnHover ? tableStyles.cellContainerNoOverflow : tableStyles.cellContainer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLinkStyle(tableStyles: TableStyles, cellOptions: TableCellOptions, targetClassName: string | undefined) {
|
function getLinkStyle(tableStyles: TableStyles, cellOptions: TableCellOptions, targetClassName: string | undefined) {
|
||||||
|
@ -11,14 +11,30 @@ export function useTableStyles(theme: GrafanaTheme2, cellHeightOption: TableCell
|
|||||||
const rowHeight = cellHeight + 2;
|
const rowHeight = cellHeight + 2;
|
||||||
const headerHeight = 28;
|
const headerHeight = 28;
|
||||||
|
|
||||||
const buildCellContainerStyle = (color?: string, background?: string, overflowOnHover?: boolean) => {
|
const buildCellContainerStyle = (
|
||||||
|
color?: string,
|
||||||
|
background?: string,
|
||||||
|
overflowOnHover?: boolean,
|
||||||
|
asCellText?: boolean
|
||||||
|
) => {
|
||||||
return css({
|
return css({
|
||||||
label: overflowOnHover ? 'cellContainerOverflow' : 'cellContainerNoOverflow',
|
label: overflowOnHover ? 'cellContainerOverflow' : 'cellContainerNoOverflow',
|
||||||
padding: `${cellPadding}px`,
|
padding: `${cellPadding}px`,
|
||||||
width: '100%',
|
width: '100%',
|
||||||
// Cell height need to account for row border
|
// Cell height need to account for row border
|
||||||
height: `${rowHeight - 1}px`,
|
height: `${rowHeight - 1}px`,
|
||||||
display: 'flex',
|
|
||||||
|
display: asCellText ? 'block' : 'flex',
|
||||||
|
|
||||||
|
...(asCellText
|
||||||
|
? {
|
||||||
|
overflow: 'hidden',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
userSelect: 'text',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
|
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
borderRight: `1px solid ${borderColor}`,
|
borderRight: `1px solid ${borderColor}`,
|
||||||
|
|
||||||
@ -141,8 +157,11 @@ export function useTableStyles(theme: GrafanaTheme2, cellHeightOption: TableCell
|
|||||||
color: theme.colors.text.link,
|
color: theme.colors.text.link,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
cellContainer: buildCellContainerStyle(undefined, undefined, true),
|
cellContainerText: buildCellContainerStyle(undefined, undefined, true, true),
|
||||||
cellContainerNoOverflow: buildCellContainerStyle(undefined, undefined, false),
|
cellContainerTextNoOverflow: buildCellContainerStyle(undefined, undefined, false, true),
|
||||||
|
|
||||||
|
cellContainer: buildCellContainerStyle(undefined, undefined, true, false),
|
||||||
|
cellContainerNoOverflow: buildCellContainerStyle(undefined, undefined, false, false),
|
||||||
cellText: css({
|
cellText: css({
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
textOverflow: 'ellipsis',
|
textOverflow: 'ellipsis',
|
||||||
|
Loading…
Reference in New Issue
Block a user