+ {cell}
+ {cellInspect && isHovered && (
+
+ {
+ setContextMenuProps({
+ value: String(value ?? ''),
+ mode:
+ cellType === TableCellDisplayMode.JSONView
+ ? TableCellInspectorMode.code
+ : TableCellInspectorMode.text,
+ });
+ setIsInspecting(true);
+ }}
+ />
+
+ )}
+
+ );
+}
+
+const getStyles = (theme: GrafanaTheme2, isRightAligned: boolean, color: CellColors) => ({
+ cell: css({
+ height: '100%',
+ alignContent: 'center',
+ paddingInline: '8px',
+ // TODO: follow-up on this: change styles on hover on table row level
+ background: color.bgColor || 'none',
+ color: color.textColor,
+ '&:hover': { background: color.bgHoverColor },
+ }),
+ cellActions: css({
+ display: 'flex',
+ position: 'absolute',
+ top: '1px',
+ left: isRightAligned ? 0 : undefined,
+ right: isRightAligned ? undefined : 0,
+ margin: 'auto',
+ height: '100%',
+ background: theme.colors.background.secondary,
+ color: theme.colors.text.primary,
+ padding: '4px 0px 4px 4px',
+ }),
+});
diff --git a/packages/grafana-ui/src/components/Table/TableNG/Filter/Filter.tsx b/packages/grafana-ui/src/components/Table/TableNG/Filter/Filter.tsx
new file mode 100644
index 00000000000..dfbda8354fe
--- /dev/null
+++ b/packages/grafana-ui/src/components/Table/TableNG/Filter/Filter.tsx
@@ -0,0 +1,99 @@
+import { css, cx } from '@emotion/css';
+import { useCallback, useMemo, useRef, useState } from 'react';
+
+import { Field, GrafanaTheme2, SelectableValue } from '@grafana/data';
+
+import { useStyles2 } from '../../../../themes';
+import { Icon } from '../../../Icon/Icon';
+import { Popover } from '../../../Tooltip/Popover';
+import { TableRow } from '../types';
+
+import { REGEX_OPERATOR } from './FilterList';
+import { FilterPopup } from './FilterPopup';
+
+interface Props {
+ name: string;
+ rows: any[];
+ filter: any;
+ setFilter: (value: any) => void;
+ field?: Field;
+ crossFilterOrder: string[];
+ crossFilterRows: { [key: string]: TableRow[] };
+}
+
+export const Filter = ({ name, rows, filter, setFilter, field, crossFilterOrder, crossFilterRows }: Props) => {
+ const filterValue = filter[name]?.filtered;
+
+ // get rows for cross filtering
+ const filterIndex = crossFilterOrder.indexOf(name);
+ let filteredRows: TableRow[];
+ if (filterIndex > 0) {
+ // current filter list should be based on the previous filter list
+ const previousFilterName = crossFilterOrder[filterIndex - 1];
+ filteredRows = crossFilterRows[previousFilterName];
+ } else if (filterIndex === -1 && crossFilterOrder.length > 0) {
+ // current filter list should be based on the last filter list
+ const previousFilterName = crossFilterOrder[crossFilterOrder.length - 1];
+ filteredRows = crossFilterRows[previousFilterName];
+ } else {
+ filteredRows = rows;
+ }
+
+ const ref = useRef