From 040bf9a8ff09b30a8fb06828a02efe785b2ba2de Mon Sep 17 00:00:00 2001 From: Cee Chen <549407+cee-chen@users.noreply.github.com> Date: Fri, 25 Oct 2024 12:02:19 -0700 Subject: [PATCH] [EuiDataGrid] Add new beta `rowHeightsOptions.autoBelowLineCount` feature flag (#8096) --- ...ghtsOptions_prop_Auto_Below_Line_Count.png | Bin 0 -> 24843 bytes ...ghtsOptions_prop_Auto_Below_Line_Count.png | Bin 0 -> 43063 bytes packages/eui/changelogs/upcoming/8096.md | 1 + .../body/cell/data_grid_cell.test.tsx | 44 ++++++++++ .../datagrid/body/cell/data_grid_cell.tsx | 34 ++++--- .../datagrid/body/data_grid_body_custom.tsx | 6 +- .../body/data_grid_body_virtualized.tsx | 1 - .../controls/display_selector.test.tsx | 10 +++ .../datagrid/controls/display_selector.tsx | 12 ++- .../components/datagrid/data_grid.styles.ts | 3 +- .../data_grid_row_heights.stories.tsx | 21 +++++ .../components/datagrid/data_grid_types.ts | 8 ++ .../datagrid/utils/__mocks__/row_heights.ts | 1 + .../datagrid/utils/grid_height_width.ts | 2 +- .../datagrid/utils/row_heights.test.ts | 83 ++++++++++++++++-- .../components/datagrid/utils/row_heights.ts | 27 ++++-- 16 files changed, 219 insertions(+), 34 deletions(-) create mode 100644 packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_rowHeightsOptions_prop_Auto_Below_Line_Count.png create mode 100644 packages/eui/.loki/reference/chrome_mobile_Tabular_Content_EuiDataGrid_rowHeightsOptions_prop_Auto_Below_Line_Count.png create mode 100644 packages/eui/changelogs/upcoming/8096.md diff --git a/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_rowHeightsOptions_prop_Auto_Below_Line_Count.png b/packages/eui/.loki/reference/chrome_desktop_Tabular_Content_EuiDataGrid_rowHeightsOptions_prop_Auto_Below_Line_Count.png new file mode 100644 index 0000000000000000000000000000000000000000..092ccb900cb7272314f49458d38be204a2d6b88e GIT binary patch literal 24843 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 h129g*95ZbZTZ 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 aU+Q|Jr9&0Xv!JjD2D^CvGA>WkHsD`#tS%$~ literal 0 HcmV?d00001 diff --git a/packages/eui/changelogs/upcoming/8096.md b/packages/eui/changelogs/upcoming/8096.md new file mode 100644 index 00000000000..57f9615617b --- /dev/null +++ b/packages/eui/changelogs/upcoming/8096.md @@ -0,0 +1 @@ +- Updated `EuiDataGrid` with a beta `rowHeightsOptions.autoBelowLineCount` feature flag diff --git a/packages/eui/src/components/datagrid/body/cell/data_grid_cell.test.tsx b/packages/eui/src/components/datagrid/body/cell/data_grid_cell.test.tsx index b12992b8494..841f347407b 100644 --- a/packages/eui/src/components/datagrid/body/cell/data_grid_cell.test.tsx +++ b/packages/eui/src/components/datagrid/body/cell/data_grid_cell.test.tsx @@ -757,6 +757,26 @@ describe('EuiDataGridCell', () => { callMethod(component); expect(setRowHeight).not.toHaveBeenCalled(); }); + + it('does nothing if cell height is auto or autoBelowLineCount', () => { + mockRowHeightUtils.isAutoBelowLineCount.mockReturnValue(true); + + const component = mount( + + ); + + callMethod(component); + expect(setRowHeight).not.toHaveBeenCalled(); + + mockRowHeightUtils.isAutoBelowLineCount.mockRestore(); + }); }); }); @@ -816,6 +836,30 @@ describe('EuiDataGridCell', () => { expect(component.find('.eui-textBreakWord').exists()).toBe(true); expect(component.find('.euiTextBlockTruncate').exists()).toBe(true); }); + + test('autoBelowLineCount', () => { + mockRowHeightUtils.isAutoBelowLineCount.mockReturnValue(true); + + const component = mount( + + ); + + expect( + component + .find('div.euiDataGridRowCell__content--autoBelowLineCountHeight') + .hasClass(/autoHeight/) + ).toBe(true); + expect(component.find('.eui-textBreakWord').exists()).toBe(true); + expect(component.find('.euiTextBlockTruncate').exists()).toBe(true); + + mockRowHeightUtils.isAutoBelowLineCount.mockRestore(); + }); }); // Note: Tests for cell interactivity (focus, tabbing, etc) are in `focus_utils.spec.tsx` diff --git a/packages/eui/src/components/datagrid/body/cell/data_grid_cell.tsx b/packages/eui/src/components/datagrid/body/cell/data_grid_cell.tsx index 57592f9c0e8..013e4ccf17b 100644 --- a/packages/eui/src/components/datagrid/body/cell/data_grid_cell.tsx +++ b/packages/eui/src/components/datagrid/body/cell/data_grid_cell.tsx @@ -69,7 +69,7 @@ const EuiDataGridCellContent: FunctionComponent< setCellContentsRef, rowIndex, colIndex, - rowHeight, + rowHeightsOptions, rowHeightUtils, isControlColumn, ...rest @@ -78,11 +78,18 @@ const EuiDataGridCellContent: FunctionComponent< const CellElement = renderCellValue as JSXElementConstructor; - const cellHeightType = useMemo( - () => rowHeightUtils?.getHeightType(rowHeight) || 'default', - [rowHeightUtils, rowHeight] + // Cell height type + const rowHeight = rowHeightUtils?.getRowHeightOption( + rowIndex, + rowHeightsOptions ); + const cellHeightType = useMemo(() => { + return rowHeightUtils?.isAutoBelowLineCount(rowHeightsOptions, rowHeight) + ? 'autoBelowLineCount' + : rowHeightUtils?.getHeightType(rowHeight) || 'default'; + }, [rowHeightUtils, rowHeight, rowHeightsOptions]); + // Classes and styles const classes = useMemo( () => classNames( @@ -104,7 +111,7 @@ const EuiDataGridCellContent: FunctionComponent< : [ // Regular data cells should always inherit height from the row wrapper, // except for auto height - cellHeightType === 'auto' + cellHeightType === 'auto' || cellHeightType === 'autoBelowLineCount' ? styles.content.autoHeight : styles.content.defaultHeight, ]), @@ -113,7 +120,9 @@ const EuiDataGridCellContent: FunctionComponent< return ( @@ -201,6 +210,12 @@ export class EuiDataGridCell extends Component< rowIndex, rowHeightsOptions ); + if ( + rowHeightUtils?.isAutoBelowLineCount(rowHeightsOptions, rowHeightOption) + ) { + return; // Using auto height instead + } + const isSingleLine = rowHeightOption == null; // Undefined rowHeightsOptions default to a single line const lineCount = isSingleLine ? 1 @@ -585,11 +600,6 @@ export class EuiDataGridCell extends Component< ...cellPropsStyle, // apply anything from setCellProps({ style }) }; - const rowHeight = rowHeightUtils?.getRowHeightOption( - rowIndex, - rowHeightsOptions - ); - const row = rowManager && !IS_JEST_ENVIRONMENT ? rowManager.getRow({ @@ -628,7 +638,7 @@ export class EuiDataGridCell extends Component< isExpandable={isExpandable} isExpanded={popoverIsOpen} setCellContentsRef={this.setCellContentsRef} - rowHeight={rowHeight} + rowHeightsOptions={rowHeightsOptions} rowHeightUtils={rowHeightUtils} isControlColumn={isControlColumn} rowIndex={rowIndex} diff --git a/packages/eui/src/components/datagrid/body/data_grid_body_custom.tsx b/packages/eui/src/components/datagrid/body/data_grid_body_custom.tsx index 3093b852ad5..3b93a598a35 100644 --- a/packages/eui/src/components/datagrid/body/data_grid_body_custom.tsx +++ b/packages/eui/src/components/datagrid/body/data_grid_body_custom.tsx @@ -84,11 +84,7 @@ export const EuiDataGridBodyCustomRender: FunctionComponent gridItemsRenderedRef: gridItemsRendered, }, rowHeightsOptions, - gridStyles, columns, }); diff --git a/packages/eui/src/components/datagrid/controls/display_selector.test.tsx b/packages/eui/src/components/datagrid/controls/display_selector.test.tsx index d6b0374ab80..964af8eb30e 100644 --- a/packages/eui/src/components/datagrid/controls/display_selector.test.tsx +++ b/packages/eui/src/components/datagrid/controls/display_selector.test.tsx @@ -266,9 +266,19 @@ describe('useDataGridDisplaySelector', () => { expect(getSelection(baseElement, 'rowHeightButtonGroup')).toEqual( 'static' ); + expect(getByTestSubject('static')).toHaveTextContent('Static'); expect(getByTestSubject('lineCountNumber')).toHaveValue(1); }); + it('renders a "Max" label instead of "Static" if autoBelowLineCount is true', async () => { + const { container, getByTestSubject } = render( + + ); + openPopover(container); + + expect(getByTestSubject('static')).toHaveTextContent('Max'); + }); + it('calls the rowHeightsOptions.onChange callback on user change', async () => { const onRowHeightChange = jest.fn(); const { container, baseElement, getByTestSubject } = render( diff --git a/packages/eui/src/components/datagrid/controls/display_selector.tsx b/packages/eui/src/components/datagrid/controls/display_selector.tsx index 9016dd7af39..34f028950b5 100644 --- a/packages/eui/src/components/datagrid/controls/display_selector.tsx +++ b/packages/eui/src/components/datagrid/controls/display_selector.tsx @@ -162,6 +162,8 @@ const RowHeightControl = ({ rowHeightsOptions: EuiDataGridRowHeightsOptions; onChange: Function; }) => { + const { autoBelowLineCount } = rowHeightsOptions; + const [lineCountInput, setLineCountInput] = useState(1); const setLineCountHeight = useCallback( (event: ChangeEvent) => { @@ -227,10 +229,11 @@ const RowHeightControl = ({ 'euiDisplaySelector.rowHeightLabel', 'euiDisplaySelector.labelAuto', 'euiDisplaySelector.labelStatic', + 'euiDisplaySelector.labelMax', ]} - defaults={['Lines per row', 'Auto', 'Static']} + defaults={['Lines per row', 'Auto', 'Static', 'Max']} > - {([rowHeightLabel, labelAuto, labelStatic]: string[]) => ( + {([rowHeightLabel, labelAuto, labelStatic, labelMax]: string[]) => ( { } /* Workaround to trim line-clamp and padding - @see https://github.com/elastic/eui/issues/7780 */ - .euiDataGridRowCell__content--lineCountHeight { + .euiDataGridRowCell__content--lineCountHeight, + .euiDataGridRowCell__content--autoBelowLineCountHeight { ${logicalCSS('padding-bottom', 0)} ${logicalCSS( 'border-bottom', diff --git a/packages/eui/src/components/datagrid/data_grid_row_heights.stories.tsx b/packages/eui/src/components/datagrid/data_grid_row_heights.stories.tsx index 4b69a84b8d3..5100b100c95 100644 --- a/packages/eui/src/components/datagrid/data_grid_row_heights.stories.tsx +++ b/packages/eui/src/components/datagrid/data_grid_row_heights.stories.tsx @@ -80,6 +80,27 @@ export const LineCount1: Story = { ), }; +import { faker } from '@faker-js/faker'; +faker.seed(42); +const loremData = Array.from({ length: 5 }).map((_, i) => + faker.lorem.lines(i % 2 === 0 ? 1 : 20) +); + +export const AutoBelowLineCount: Story = { + args: { + autoBelowLineCount: true, + defaultHeight: { lineCount: 3 }, + }, + render: (rowHeightsOptions) => ( + loremData[rowIndex]} + columns={[{ id: 'name' }, { id: 'location' }]} + /> + ), +}; + export const StaticHeight: Story = { args: { defaultHeight: { height: 48 }, diff --git a/packages/eui/src/components/datagrid/data_grid_types.ts b/packages/eui/src/components/datagrid/data_grid_types.ts index 34f7921bd54..acac707bf34 100644 --- a/packages/eui/src/components/datagrid/data_grid_types.ts +++ b/packages/eui/src/components/datagrid/data_grid_types.ts @@ -1108,6 +1108,14 @@ export interface EuiDataGridRowHeightsOptions { * Defines the default size for all rows. It can be line count or just height. */ defaultHeight?: EuiDataGridRowHeightOption; + /** + * Feature flag for custom `lineCount` behavior, where `lineCount` acts like a + * *max* number of lines (instead of a set number of lines for all rows). + * + * This functionality is in beta and has performance implications; + * we do not yet fully recommend/support it for heavy production usage. + */ + autoBelowLineCount?: boolean; /** * Defines the height for a specific row. It can be line count or just height. * diff --git a/packages/eui/src/components/datagrid/utils/__mocks__/row_heights.ts b/packages/eui/src/components/datagrid/utils/__mocks__/row_heights.ts index 2fef7caa05b..3ff7283eca0 100644 --- a/packages/eui/src/components/datagrid/utils/__mocks__/row_heights.ts +++ b/packages/eui/src/components/datagrid/utils/__mocks__/row_heights.ts @@ -24,6 +24,7 @@ export const RowHeightUtils = jest.fn().mockImplementation(() => { const rowHeightUtilsMock: RowHeightUtilsPublicAPI = { getHeightType: jest.fn(rowHeightUtils.getHeightType), + isAutoBelowLineCount: jest.fn(() => false), isAutoHeight: jest.fn(() => false), setRowHeight: jest.fn(), pruneHiddenColumnHeights: jest.fn(), diff --git a/packages/eui/src/components/datagrid/utils/grid_height_width.ts b/packages/eui/src/components/datagrid/utils/grid_height_width.ts index 7c66fe64d90..686acc38323 100644 --- a/packages/eui/src/components/datagrid/utils/grid_height_width.ts +++ b/packages/eui/src/components/datagrid/utils/grid_height_width.ts @@ -141,7 +141,7 @@ export const useUnconstrainedHeight = ({ rowHeightOption, defaultRowHeight, correctRowIndex, - rowHeightUtils.isRowHeightOverride(correctRowIndex, rowHeightsOptions) + rowHeightsOptions ); } } diff --git a/packages/eui/src/components/datagrid/utils/row_heights.test.ts b/packages/eui/src/components/datagrid/utils/row_heights.test.ts index 988c71edc78..5ee8e2b71bf 100644 --- a/packages/eui/src/components/datagrid/utils/row_heights.test.ts +++ b/packages/eui/src/components/datagrid/utils/row_heights.test.ts @@ -9,7 +9,6 @@ import type { MutableRefObject } from 'react'; import { act } from '@testing-library/react'; import { renderHook } from '../../../test/rtl'; -import { startingStyles } from '../controls'; import type { ImperativeGridApi } from '../data_grid_types'; import { RowHeightUtils, @@ -108,6 +107,23 @@ describe('RowHeightUtils', () => { }); }); + describe('autoBelowLineCount', () => { + it('uses the auto height cache', () => { + const rowIndex = 3; + const autoRowHeight = 100; + rowHeightUtils.setRowHeight(rowIndex, 'a', autoRowHeight, 0); + + expect( + rowHeightUtils.getCalculatedHeight( + { lineCount: 10 }, + 34, + rowIndex, + { rowHeights: { [rowIndex]: autoRowHeight } } + ) + ).toEqual(autoRowHeight); + }); + }); + describe('row-specific overrides', () => { it('returns the height set in the cache', () => { const rowIndex = 5; @@ -119,7 +135,7 @@ describe('RowHeightUtils', () => { { lineCount: 10 }, 34, rowIndex, - true + { rowHeights: { [rowIndex]: rowHeightOverride } } ) ).toEqual(rowHeightOverride); }); @@ -223,6 +239,56 @@ describe('RowHeightUtils', () => { ); // 5 * 24 + 6 + 6 }); }); + + describe('isAutoBelowLineCount', () => { + it('returns true when the feature flag is enabled and a lineCount above 1 exists', () => { + expect( + rowHeightUtils.isAutoBelowLineCount( + { autoBelowLineCount: true }, + { lineCount: 3 } + ) + ).toEqual(true); + }); + + it('returns false if the feature flag is not enabled', () => { + expect( + rowHeightUtils.isAutoBelowLineCount( + { autoBelowLineCount: false }, + { lineCount: 3 } + ) + ).toEqual(false); + expect( + rowHeightUtils.isAutoBelowLineCount(undefined, { lineCount: 3 }) + ).toEqual(false); + }); + + it('returns false if height type is not lineCount', () => { + expect( + rowHeightUtils.isAutoBelowLineCount({ autoBelowLineCount: true }, 50) + ).toEqual(false); + expect( + rowHeightUtils.isAutoBelowLineCount( + { autoBelowLineCount: true }, + 'auto' + ) + ).toEqual(false); + }); + + it('returns false if lineCount is 1 (treated as single line/undefined)', () => { + expect( + rowHeightUtils.isAutoBelowLineCount( + { autoBelowLineCount: true }, + { lineCount: 1 } + ) + ).toEqual(false); + expect( + rowHeightUtils.isAutoBelowLineCount( + { autoBelowLineCount: true }, + undefined + ) + ).toEqual(false); + }); + }); }); describe('auto height utils', () => { @@ -240,6 +306,15 @@ describe('RowHeightUtils', () => { ).toEqual(true); }); + it('returns true if the conditions for `.isAutoBelowLineCount` are met', () => { + expect( + rowHeightUtils.isAutoHeight(1, { + autoBelowLineCount: true, + defaultHeight: { lineCount: 2 }, + }) + ).toEqual(true); + }); + it('returns false otherwise', () => { expect( rowHeightUtils.isAutoHeight(1, { @@ -539,10 +614,8 @@ describe('RowHeightVirtualizationUtils', () => { }); describe('useRowHeightUtils', () => { - const mockArgs = { - gridStyles: startingStyles, + const mockArgs: Parameters[0] = { columns: [{ id: 'A' }, { id: 'B' }], - rowHeightOptions: undefined, }; const mockVirtualizationArgs = { ...mockArgs, diff --git a/packages/eui/src/components/datagrid/utils/row_heights.ts b/packages/eui/src/components/datagrid/utils/row_heights.ts index 57f415e11e4..aa02bd8a5ab 100644 --- a/packages/eui/src/components/datagrid/utils/row_heights.ts +++ b/packages/eui/src/components/datagrid/utils/row_heights.ts @@ -22,7 +22,6 @@ import { EuiDataGridRowHeightOption, EuiDataGridRowHeightsOptions, EuiDataGridScrollAnchorRow, - EuiDataGridStyle, ImperativeGridApi, } from '../data_grid_types'; import { DataGridSortedContext } from './sorting'; @@ -54,7 +53,7 @@ export class RowHeightUtils { heightOption: EuiDataGridRowHeightOption, defaultHeight: number, rowIndex?: number, - isRowHeightOverride?: boolean + rowHeightsOptions?: EuiDataGridRowHeightsOptions ) { if (isObject(heightOption) && heightOption.height) { return Math.max(heightOption.height, defaultHeight); @@ -65,8 +64,13 @@ export class RowHeightUtils { } if (isObject(heightOption) && heightOption.lineCount) { - if (isRowHeightOverride) { - return this.getRowHeight(rowIndex!) || defaultHeight; // lineCount overrides are stored in the heights cache + const { autoBelowLineCount } = rowHeightsOptions || {}; // uses auto height cache + const isRowHeightOverride = // lineCount overrides are stored in the heights cache + rowIndex != null && + this.isRowHeightOverride(rowIndex, rowHeightsOptions); + + if (autoBelowLineCount || isRowHeightOverride) { + return this.getRowHeight(rowIndex!) || defaultHeight; } else { return defaultHeight; // default lineCount height is set in minRowHeight state in grid_row_body } @@ -115,6 +119,15 @@ export class RowHeightUtils { return contentHeight + padding * 2; } + isAutoBelowLineCount( + options?: EuiDataGridRowHeightsOptions, + option?: EuiDataGridRowHeightOption + ) { + if (!options?.autoBelowLineCount) return false; + if ((this.getLineCount(option) ?? 0) > 1) return true; + return false; + } + /** * Auto height utils */ @@ -128,6 +141,9 @@ export class RowHeightUtils { if (height === AUTO_HEIGHT) { return true; } + if (this.isAutoBelowLineCount(rowHeightsOptions, height)) { + return true; + } return false; } @@ -310,7 +326,6 @@ export const useRowHeightUtils = ({ gridItemsRenderedRef: MutableRefObject; }; rowHeightsOptions?: EuiDataGridRowHeightsOptions; - gridStyles: EuiDataGridStyle; columns: EuiDataGridColumn[]; }) => { const forceRenderRef = useLatest(useForceRender()); @@ -393,7 +408,7 @@ export const useDefaultRowHeight = ({ rowHeightOption, minRowHeight, correctRowIndex, - rowHeightUtils.isRowHeightOverride(correctRowIndex, rowHeightsOptions) + rowHeightsOptions ); }