[Discover] Update colors for in-table search highlights (#209564)

- Closes https://github.com/elastic/kibana/issues/208944

## Summary

This PR updates colors for Borealis theme while keeping previous colors
for Amsterdam theme.

Borealis:
<img width="1103" alt="Screenshot 2025-02-05 at 10 26 24"
src="https://github.com/user-attachments/assets/94594b5e-bf94-4c03-8fcf-ae9e7470aea6"
/>
<img width="1100" alt="Screenshot 2025-02-05 at 10 26 55"
src="https://github.com/user-attachments/assets/9a075506-6984-44ba-8d19-be68f910ad8c"
/>

Amsterdam:
<img width="1028" alt="Screenshot 2025-02-05 at 10 18 37"
src="https://github.com/user-attachments/assets/b7a432ae-be1c-4eb3-beca-bb198f1b58df"
/>
<img width="1029" alt="Screenshot 2025-02-05 at 10 18 05"
src="https://github.com/user-attachments/assets/100a90f7-b680-4d91-8b83-9526d3266d21"
/>
This commit is contained in:
Julia Rechkunova 2025-02-06 09:53:20 +01:00 committed by GitHub
parent 931c34e219
commit ad7a9a90b1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 130 additions and 71 deletions

View file

@ -9,8 +9,6 @@
export const CELL_MATCH_INDEX_ATTRIBUTE = 'data-match-index';
export const HIGHLIGHT_CLASS_NAME = 'dataGridInTableSearch__match';
export const HIGHLIGHT_COLOR = '#e5ffc0'; // TODO: Use a named color token
export const ACTIVE_HIGHLIGHT_COLOR = '#ffc30e'; // TODO: Use a named color token
export const BUTTON_TEST_SUBJ = 'startInTableSearchButton';
export const INPUT_TEST_SUBJ = 'inTableSearchInput';

View file

@ -0,0 +1,34 @@
/*
* 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/
import { EuiThemeComputed } from '@elastic/eui';
const AMSTERDAM_HIGHLIGHT_COLOR = '#e5ffc0';
const AMSTERDAM_ACTIVE_HIGHLIGHT_COLOR = '#ffc30e';
export const getHighlightColors = (euiTheme: EuiThemeComputed<{}>) => {
// FIXME: remove once Amsterdam theme is removed
const isAmsterdamTheme = euiTheme.themeName.toLowerCase().includes('amsterdam');
return {
highlightColor: isAmsterdamTheme ? euiTheme.colors.plainDark : euiTheme.colors.textAccent,
highlightBackgroundColor: isAmsterdamTheme
? AMSTERDAM_HIGHLIGHT_COLOR
: euiTheme.colors.backgroundLightAccent,
activeHighlightColor: isAmsterdamTheme
? euiTheme.colors.plainDark
: euiTheme.colors.textInverse,
activeHighlightBackgroundColor: isAmsterdamTheme
? AMSTERDAM_ACTIVE_HIGHLIGHT_COLOR
: euiTheme.colors.backgroundFilledAccent,
activeHighlightBorderColor: isAmsterdamTheme
? AMSTERDAM_ACTIVE_HIGHLIGHT_COLOR
: euiTheme.colors.borderStrongAccent,
};
};

View file

@ -34,15 +34,18 @@ describe('InTableSearchControl', () => {
const visibleColumns = Array.from({ length: 2 }, (_, i) => `column${i}`);
const getColumnIndexFromId = (columnId: string) => parseInt(columnId.replace('column', ''), 10);
const getRenderCellValueWrappedMock = (data: string[][]) =>
jest.fn(
wrapRenderCellValueWithInTableSearchSupport(getRenderCellValueMock(data), 'black', 'green')
);
it('should update correctly when deps change', async () => {
const initialProps: InTableSearchControlProps = {
inTableSearchTerm: 'a',
pageSize: 10,
visibleColumns,
rows: testData,
renderCellValue: jest.fn(
wrapRenderCellValueWithInTableSearchSupport(getRenderCellValueMock(testData))
),
renderCellValue: getRenderCellValueWrappedMock(testData),
getColumnIndexFromId: jest.fn(getColumnIndexFromId),
scrollToCell: jest.fn(),
shouldOverrideCmdF: jest.fn(),
@ -87,9 +90,7 @@ describe('InTableSearchControl', () => {
<InTableSearchControl
{...initialProps}
rows={testData2}
renderCellValue={jest.fn(
wrapRenderCellValueWithInTableSearchSupport(getRenderCellValueMock(testData2))
)}
renderCellValue={getRenderCellValueWrappedMock(testData2)}
/>
);
@ -130,9 +131,7 @@ describe('InTableSearchControl', () => {
pageSize: null,
visibleColumns,
rows: testData,
renderCellValue: jest.fn(
wrapRenderCellValueWithInTableSearchSupport(getRenderCellValueMock(testData))
),
renderCellValue: getRenderCellValueWrappedMock(testData),
getColumnIndexFromId: jest.fn(getColumnIndexFromId),
scrollToCell: jest.fn(),
shouldOverrideCmdF: jest.fn(),
@ -160,9 +159,7 @@ describe('InTableSearchControl', () => {
pageSize: 2,
visibleColumns,
rows: testData,
renderCellValue: jest.fn(
wrapRenderCellValueWithInTableSearchSupport(getRenderCellValueMock(testData))
),
renderCellValue: getRenderCellValueWrappedMock(testData),
getColumnIndexFromId: jest.fn(getColumnIndexFromId),
scrollToCell: jest.fn(),
shouldOverrideCmdF: jest.fn(),
@ -216,9 +213,7 @@ describe('InTableSearchControl', () => {
pageSize: 2,
visibleColumns,
rows: testData,
renderCellValue: jest.fn(
wrapRenderCellValueWithInTableSearchSupport(getRenderCellValueMock(testData))
),
renderCellValue: getRenderCellValueWrappedMock(testData),
getColumnIndexFromId: jest.fn(getColumnIndexFromId),
scrollToCell: jest.fn(),
shouldOverrideCmdF: jest.fn(),
@ -328,9 +323,7 @@ describe('InTableSearchControl', () => {
pageSize: null,
visibleColumns,
rows: testData,
renderCellValue: jest.fn(
wrapRenderCellValueWithInTableSearchSupport(getRenderCellValueMock(testData))
),
renderCellValue: getRenderCellValueWrappedMock(testData),
getColumnIndexFromId: jest.fn(getColumnIndexFromId),
scrollToCell: jest.fn(),
shouldOverrideCmdF: jest.fn(),
@ -358,9 +351,7 @@ describe('InTableSearchControl', () => {
pageSize: null,
visibleColumns: [visibleColumns[0]],
rows: testData,
renderCellValue: jest.fn(
wrapRenderCellValueWithInTableSearchSupport(getRenderCellValueMock(testData))
),
renderCellValue: getRenderCellValueWrappedMock(testData),
getColumnIndexFromId: jest.fn(getColumnIndexFromId),
scrollToCell: jest.fn(),
shouldOverrideCmdF: jest.fn(),

View file

@ -7,7 +7,7 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
import React, { useCallback, useState, useEffect, useRef } from 'react';
import React, { useCallback, useState, useEffect, useRef, useMemo } from 'react';
import { EuiButtonIcon, EuiToolTip, useEuiTheme } from '@elastic/eui';
import useEvent from 'react-use/lib/useEvent';
import { i18n } from '@kbn/i18n';
@ -16,12 +16,12 @@ import { useFindMatches } from './matches/use_find_matches';
import { InTableSearchInput } from './in_table_search_input';
import { UseFindMatchesProps } from './types';
import {
ACTIVE_HIGHLIGHT_COLOR,
CELL_MATCH_INDEX_ATTRIBUTE,
HIGHLIGHT_CLASS_NAME,
BUTTON_TEST_SUBJ,
INPUT_TEST_SUBJ,
} from './constants';
import { getHighlightColors } from './get_highlight_colors';
const innerCss = css`
.dataGridInTableSearch__matchesCounter {
@ -69,6 +69,7 @@ export const InTableSearchControl: React.FC<InTableSearchControlProps> = ({
...props
}) => {
const { euiTheme } = useEuiTheme();
const colors = useMemo(() => getHighlightColors(euiTheme), [euiTheme]);
const containerRef = useRef<HTMLDivElement | null>(null);
const buttonRef = useRef<HTMLButtonElement | null>(null);
const shouldReturnFocusToButtonRef = useRef<boolean>(false);
@ -81,7 +82,8 @@ export const InTableSearchControl: React.FC<InTableSearchControlProps> = ({
onChangeToExpectedPage(expectedPageIndex);
}
// The cell border is useful when the active match is not visible due to the limited cell height.
// Defines highlight styles for the active match.
// The cell border is useful when the active match is not visible due to the limited cell boundaries.
onChangeCss(css`
.euiDataGridRowCell[data-gridcell-row-index='${rowIndex}'][data-gridcell-column-id='${columnId}'] {
&:after {
@ -90,11 +92,12 @@ export const InTableSearchControl: React.FC<InTableSearchControlProps> = ({
pointer-events: none;
position: absolute;
inset: 0;
border: 2px solid ${ACTIVE_HIGHLIGHT_COLOR} !important;
border: 2px solid ${colors.activeHighlightBorderColor} !important;
border-radius: 3px;
}
.${HIGHLIGHT_CLASS_NAME}[${CELL_MATCH_INDEX_ATTRIBUTE}='${matchIndexWithinCell}'] {
background-color: ${ACTIVE_HIGHLIGHT_COLOR} !important;
color: ${colors.activeHighlightColor} !important;
background-color: ${colors.activeHighlightBackgroundColor} !important;
}
}
`);
@ -108,7 +111,7 @@ export const InTableSearchControl: React.FC<InTableSearchControlProps> = ({
align: 'center',
});
},
[getColumnIndexFromId, scrollToCell, onChangeCss, onChangeToExpectedPage, pageSize]
[getColumnIndexFromId, scrollToCell, onChangeCss, onChangeToExpectedPage, pageSize, colors]
);
const {

View file

@ -11,11 +11,16 @@ import React from 'react';
import { InTableSearchHighlightsWrapper } from './in_table_search_highlights_wrapper';
import { render, waitFor, screen } from '@testing-library/react';
const colors = {
highlightColor: 'black',
highlightBackgroundColor: 'green',
};
describe('InTableSearchHighlightsWrapper', () => {
describe('modifies the DOM and adds search highlights', () => {
it('with matches', async () => {
const { container } = render(
<InTableSearchHighlightsWrapper inTableSearchTerm="test">
<InTableSearchHighlightsWrapper inTableSearchTerm="test" {...colors}>
<div>
Some text here with test and test and even more Test to be sure
<div>test</div>
@ -31,13 +36,13 @@ describe('InTableSearchHighlightsWrapper', () => {
});
expect(container.innerHTML).toMatchInlineSnapshot(
`"<div><div>Some text here with <mark style=\\"background-color: rgb(229, 255, 192);\\" class=\\"dataGridInTableSearch__match\\" data-match-index=\\"0\\">test</mark> and <mark style=\\"background-color: rgb(229, 255, 192);\\" class=\\"dataGridInTableSearch__match\\" data-match-index=\\"1\\">test</mark> and even more <mark style=\\"background-color: rgb(229, 255, 192);\\" class=\\"dataGridInTableSearch__match\\" data-match-index=\\"2\\">Test</mark> to be sure<div><mark style=\\"background-color: rgb(229, 255, 192);\\" class=\\"dataGridInTableSearch__match\\" data-match-index=\\"3\\">test</mark></div><div>this</div><img src=\\"https://test.com\\" alt=\\"not for test\\"></div></div>"`
`"<div><div>Some text here with <mark style=\\"color: black; background-color: green;\\" class=\\"dataGridInTableSearch__match\\" data-match-index=\\"0\\">test</mark> and <mark style=\\"color: black; background-color: green;\\" class=\\"dataGridInTableSearch__match\\" data-match-index=\\"1\\">test</mark> and even more <mark style=\\"color: black; background-color: green;\\" class=\\"dataGridInTableSearch__match\\" data-match-index=\\"2\\">Test</mark> to be sure<div><mark style=\\"color: black; background-color: green;\\" class=\\"dataGridInTableSearch__match\\" data-match-index=\\"3\\">test</mark></div><div>this</div><img src=\\"https://test.com\\" alt=\\"not for test\\"></div></div>"`
);
});
it('with single match', async () => {
const { container } = render(
<InTableSearchHighlightsWrapper inTableSearchTerm="test2">
<InTableSearchHighlightsWrapper inTableSearchTerm="test2" {...colors}>
<div>test2</div>
</InTableSearchHighlightsWrapper>
);
@ -47,13 +52,13 @@ describe('InTableSearchHighlightsWrapper', () => {
});
expect(container.innerHTML).toMatchInlineSnapshot(
`"<div><div><mark style=\\"background-color: rgb(229, 255, 192);\\" class=\\"dataGridInTableSearch__match\\" data-match-index=\\"0\\">test2</mark></div></div>"`
`"<div><div><mark style=\\"color: black; background-color: green;\\" class=\\"dataGridInTableSearch__match\\" data-match-index=\\"0\\">test2</mark></div></div>"`
);
});
it('with no matches', async () => {
const { container } = render(
<InTableSearchHighlightsWrapper inTableSearchTerm="test3">
<InTableSearchHighlightsWrapper inTableSearchTerm="test3" {...colors}>
<div>test2</div>
</InTableSearchHighlightsWrapper>
);
@ -63,7 +68,7 @@ describe('InTableSearchHighlightsWrapper', () => {
it('escape the input with tags', async () => {
const { container } = render(
<InTableSearchHighlightsWrapper inTableSearchTerm="<hr />">
<InTableSearchHighlightsWrapper inTableSearchTerm="<hr />" {...colors}>
<div>
<hr />
<div>test</div>
@ -77,13 +82,13 @@ describe('InTableSearchHighlightsWrapper', () => {
});
expect(container.innerHTML).toMatchInlineSnapshot(
`"<div><div><hr><div>test</div><div>this <mark style=\\"background-color: rgb(229, 255, 192);\\" class=\\"dataGridInTableSearch__match\\" data-match-index=\\"0\\">&lt;hr /&gt;</mark></div></div></div>"`
`"<div><div><hr><div>test</div><div>this <mark style=\\"color: black; background-color: green;\\" class=\\"dataGridInTableSearch__match\\" data-match-index=\\"0\\">&lt;hr /&gt;</mark></div></div></div>"`
);
});
it('escape the input with regex', async () => {
const { container } = render(
<InTableSearchHighlightsWrapper inTableSearchTerm=".">
<InTableSearchHighlightsWrapper inTableSearchTerm="." {...colors}>
<div>test this now.</div>
</InTableSearchHighlightsWrapper>
);
@ -93,13 +98,13 @@ describe('InTableSearchHighlightsWrapper', () => {
});
expect(container.innerHTML).toMatchInlineSnapshot(
`"<div><div>test this now<mark style=\\"background-color: rgb(229, 255, 192);\\" class=\\"dataGridInTableSearch__match\\" data-match-index=\\"0\\">.</mark></div></div>"`
`"<div><div>test this now<mark style=\\"color: black; background-color: green;\\" class=\\"dataGridInTableSearch__match\\" data-match-index=\\"0\\">.</mark></div></div>"`
);
});
it('with no search term', async () => {
const { container } = render(
<InTableSearchHighlightsWrapper>
<InTableSearchHighlightsWrapper {...colors}>
<div>test</div>
</InTableSearchHighlightsWrapper>
);
@ -115,6 +120,7 @@ describe('InTableSearchHighlightsWrapper', () => {
<InTableSearchHighlightsWrapper
inTableSearchTerm="test"
onHighlightsCountFound={onHighlightsCountFound}
{...colors}
>
<div>
Some text here with test and test and even more Test to be sure
@ -141,6 +147,7 @@ describe('InTableSearchHighlightsWrapper', () => {
<InTableSearchHighlightsWrapper
inTableSearchTerm="test2"
onHighlightsCountFound={onHighlightsCountFound}
{...colors}
>
<div>test2</div>
</InTableSearchHighlightsWrapper>
@ -159,6 +166,7 @@ describe('InTableSearchHighlightsWrapper', () => {
<InTableSearchHighlightsWrapper
inTableSearchTerm="test3"
onHighlightsCountFound={onHighlightsCountFound}
{...colors}
>
<div>test2</div>
</InTableSearchHighlightsWrapper>
@ -174,7 +182,7 @@ describe('InTableSearchHighlightsWrapper', () => {
it('with no search term', async () => {
const onHighlightsCountFound = jest.fn();
const { container } = render(
<InTableSearchHighlightsWrapper onHighlightsCountFound={onHighlightsCountFound}>
<InTableSearchHighlightsWrapper onHighlightsCountFound={onHighlightsCountFound} {...colors}>
<div>test</div>
</InTableSearchHighlightsWrapper>
);

View file

@ -9,7 +9,7 @@
import React, { useEffect, useRef } from 'react';
import { escapeRegExp } from 'lodash';
import { HIGHLIGHT_COLOR, HIGHLIGHT_CLASS_NAME, CELL_MATCH_INDEX_ATTRIBUTE } from './constants';
import { HIGHLIGHT_CLASS_NAME, CELL_MATCH_INDEX_ATTRIBUTE } from './constants';
import { InTableSearchHighlightsWrapperProps } from './types';
/**
@ -17,6 +17,8 @@ import { InTableSearchHighlightsWrapperProps } from './types';
*/
export const InTableSearchHighlightsWrapper: React.FC<InTableSearchHighlightsWrapperProps> = ({
inTableSearchTerm,
highlightColor,
highlightBackgroundColor,
onHighlightsCountFound,
children,
}) => {
@ -31,7 +33,13 @@ export const InTableSearchHighlightsWrapper: React.FC<InTableSearchHighlightsWra
const cellNode = cellValueRef.current;
const searchForMatches = () => {
const count = modifyDOMAndAddSearchHighlights(cellNode, inTableSearchTerm, dryRun);
const count = modifyDOMAndAddSearchHighlights(
cellNode,
inTableSearchTerm,
highlightColor,
highlightBackgroundColor,
dryRun
);
if (shouldCallCallbackRef.current) {
shouldCallCallbackRef.current = false;
onHighlightsCountFound?.(count);
@ -44,7 +52,14 @@ export const InTableSearchHighlightsWrapper: React.FC<InTableSearchHighlightsWra
timerRef.current = setTimeout(searchForMatches, 0);
}
}, [dryRun, inTableSearchTerm, children, onHighlightsCountFound]);
}, [
dryRun,
inTableSearchTerm,
highlightColor,
highlightBackgroundColor,
children,
onHighlightsCountFound,
]);
return <div ref={cellValueRef}>{children}</div>;
};
@ -68,6 +83,8 @@ export const clearSearchTermRegExpCache = () => {
function modifyDOMAndAddSearchHighlights(
originalNode: Node,
inTableSearchTerm: string,
highlightColor: string,
highlightBackgroundColor: string,
dryRun: boolean
): number {
let matchIndex = 0;
@ -98,7 +115,8 @@ function modifyDOMAndAddSearchHighlights(
if (searchTermRegExp.test(part)) {
const mark = document.createElement('mark');
mark.textContent = part;
mark.style.backgroundColor = HIGHLIGHT_COLOR;
mark.style.color = highlightColor;
mark.style.backgroundColor = highlightBackgroundColor;
mark.setAttribute('class', HIGHLIGHT_CLASS_NAME);
mark.setAttribute(CELL_MATCH_INDEX_ATTRIBUTE, `${matchIndex++}`);
nodeWithHighlights.appendChild(mark);

View file

@ -17,6 +17,8 @@ describe('AllCellsRenderer', () => {
const testData = generateMockData(100, 2);
const originalRenderCellValue = jest.fn(getRenderCellValueMock(testData));
const getRenderCellValueWrappedMock = () =>
jest.fn(wrapRenderCellValueWithInTableSearchSupport(originalRenderCellValue, 'black', 'green'));
beforeEach(() => {
originalRenderCellValue.mockClear();
@ -24,9 +26,7 @@ describe('AllCellsRenderer', () => {
it('processes all cells in all rows', async () => {
const onFinish = jest.fn();
const renderCellValue = jest.fn(
wrapRenderCellValueWithInTableSearchSupport(originalRenderCellValue)
);
const renderCellValue = getRenderCellValueWrappedMock();
const visibleColumns = ['columnA', 'columnB'];
const inTableSearchTerm = 'cell';
@ -54,9 +54,7 @@ describe('AllCellsRenderer', () => {
it('counts multiple matches correctly', async () => {
const onFinish = jest.fn();
const renderCellValue = jest.fn(
wrapRenderCellValueWithInTableSearchSupport(originalRenderCellValue)
);
const renderCellValue = getRenderCellValueWrappedMock();
const visibleColumns = ['columnA', 'columnB'];
const inTableSearchTerm = '-';
@ -84,9 +82,7 @@ describe('AllCellsRenderer', () => {
it('counts a single match correctly', async () => {
const onFinish = jest.fn();
const renderCellValue = jest.fn(
wrapRenderCellValueWithInTableSearchSupport(originalRenderCellValue)
);
const renderCellValue = getRenderCellValueWrappedMock();
const visibleColumns = ['columnA', 'columnB'];
const inTableSearchTerm = 'cell-in-row-10-col-0';
@ -122,9 +118,7 @@ describe('AllCellsRenderer', () => {
it('skips cells which create exceptions', async () => {
const onFinish = jest.fn();
const renderCellValue = jest.fn(
wrapRenderCellValueWithInTableSearchSupport(originalRenderCellValue)
);
const renderCellValue = getRenderCellValueWrappedMock();
const visibleColumns = ['columnA', 'columnB'];
const inTableSearchTerm = '50';

View file

@ -21,15 +21,16 @@ describe('RowCellsRenderer', () => {
const originalRenderCellValue = jest.fn(getRenderCellValueMock(testData));
const getRenderCellValueWrappedMock = () =>
jest.fn(wrapRenderCellValueWithInTableSearchSupport(originalRenderCellValue, 'black', 'green'));
beforeEach(() => {
originalRenderCellValue.mockClear();
});
it('renders cells in row 0', async () => {
const onRowProcessed = jest.fn();
const renderCellValue = jest.fn(
wrapRenderCellValueWithInTableSearchSupport(originalRenderCellValue)
);
const renderCellValue = getRenderCellValueWrappedMock();
const visibleColumns = ['columnA', 'columnB'];
const rowIndex = 0;
const inTableSearchTerm = 'a';
@ -61,9 +62,7 @@ describe('RowCellsRenderer', () => {
it('renders cells in row 1', async () => {
const onRowProcessed = jest.fn();
const renderCellValue = jest.fn(
wrapRenderCellValueWithInTableSearchSupport(originalRenderCellValue)
);
const renderCellValue = getRenderCellValueWrappedMock();
const visibleColumns = ['columnA', 'columnB'];
const rowIndex = 1;
const inTableSearchTerm = 'bb';
@ -96,9 +95,7 @@ describe('RowCellsRenderer', () => {
it('should call onRowProcessed even in case of errors', async () => {
const onRowProcessed = jest.fn();
const renderCellValue = jest.fn(
wrapRenderCellValueWithInTableSearchSupport(originalRenderCellValue)
);
const renderCellValue = getRenderCellValueWrappedMock();
const visibleColumns = ['columnA', 'columnB'];
const rowIndex = 3;
const inTableSearchTerm = 'test';

View file

@ -24,6 +24,8 @@ export interface ActiveMatch {
export interface InTableSearchHighlightsWrapperProps {
inTableSearchTerm?: string;
highlightColor: string;
highlightBackgroundColor: string;
onHighlightsCountFound?: (count: number) => void;
children: ReactNode;
}

View file

@ -65,6 +65,8 @@ describe('useDataGridInTableSearch', () => {
} as RenderCellValuePropsWithInTableSearch)
).toMatchInlineSnapshot(`
<InTableSearchHighlightsWrapper
highlightBackgroundColor="#e5ffc0"
highlightColor="#000000"
inTableSearchTerm="test"
>
<OriginalRenderCellValue

View file

@ -9,11 +9,12 @@
import React, { useEffect, useMemo, useRef, useState } from 'react';
import type { SerializedStyles } from '@emotion/react';
import type { EuiDataGridProps, EuiDataGridRefProps } from '@elastic/eui';
import { EuiDataGridProps, EuiDataGridRefProps, useEuiTheme } from '@elastic/eui';
import { InTableSearchControl, InTableSearchControlProps } from './in_table_search_control';
import { RenderCellValueWrapper } from './types';
import { wrapRenderCellValueWithInTableSearchSupport } from './wrap_render_cell_value';
import { clearSearchTermRegExpCache } from './in_table_search_highlights_wrapper';
import { getHighlightColors } from './get_highlight_colors';
export interface UseDataGridInTableSearchProps
extends Pick<InTableSearchControlProps, 'rows' | 'visibleColumns'> {
@ -50,16 +51,23 @@ export const useDataGridInTableSearch = (
pagination,
cellContext,
} = props;
const { euiTheme } = useEuiTheme();
const isPaginationEnabled = Boolean(pagination);
const pageSize = (isPaginationEnabled && pagination?.pageSize) || null;
const onChangePage = pagination?.onChangePage;
const pageIndexRef = useRef<number>();
pageIndexRef.current = pagination?.pageIndex ?? 0;
const renderCellValueWithInTableSearchSupport = useMemo(
() => wrapRenderCellValueWithInTableSearchSupport(renderCellValue),
[renderCellValue]
);
const renderCellValueWithInTableSearchSupport = useMemo(() => {
const colors = getHighlightColors(euiTheme);
return wrapRenderCellValueWithInTableSearchSupport(
renderCellValue,
// defines colors for the highlights
colors.highlightColor,
colors.highlightBackgroundColor
);
}, [renderCellValue, euiTheme]);
const [{ inTableSearchTerm, inTableSearchTermCss }, setInTableSearchState] =
useState<UseDataGridInTableSearchState>(() => ({ inTableSearchTerm: '' }));

View file

@ -13,7 +13,9 @@ import { InTableSearchHighlightsWrapper } from './in_table_search_highlights_wra
import type { RenderCellValuePropsWithInTableSearch, RenderCellValueWrapper } from './types';
export const wrapRenderCellValueWithInTableSearchSupport = (
renderCellValue: EuiDataGridProps['renderCellValue']
renderCellValue: EuiDataGridProps['renderCellValue'],
highlightColor: string,
highlightBackgroundColor: string
): RenderCellValueWrapper => {
const RenderCellValue = renderCellValue;
@ -27,6 +29,8 @@ export const wrapRenderCellValueWithInTableSearchSupport = (
// it's very important to have a unique key for each inTableSearchTerm change so it can add the highlights again
key={`cell-${inTableSearchTerm || ''}`}
inTableSearchTerm={inTableSearchTerm}
highlightColor={highlightColor}
highlightBackgroundColor={highlightBackgroundColor}
onHighlightsCountFound={onHighlightsCountFound}
>
<RenderCellValue {...props} />