Skip to content

Commit

Permalink
[EuiDataGrid] Add new beta rowHeightsOptions.autoBelowLineCount fea…
Browse files Browse the repository at this point in the history
…ture flag (#8096)
  • Loading branch information
cee-chen authored Oct 25, 2024
1 parent 25edfb7 commit 040bf9a
Show file tree
Hide file tree
Showing 16 changed files with 219 additions and 34 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions packages/eui/changelogs/upcoming/8096.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Updated `EuiDataGrid` with a beta `rowHeightsOptions.autoBelowLineCount` feature flag
Original file line number Diff line number Diff line change
Expand Up @@ -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(
<EuiDataGridCell
{...requiredProps}
rowHeightsOptions={{
autoBelowLineCount: true,
defaultHeight: { lineCount: 3 },
}}
setRowHeight={setRowHeight}
/>
);

callMethod(component);
expect(setRowHeight).not.toHaveBeenCalled();

mockRowHeightUtils.isAutoBelowLineCount.mockRestore();
});
});
});

Expand Down Expand Up @@ -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(
<EuiDataGridCell
{...props}
rowHeightsOptions={{
autoBelowLineCount: true,
defaultHeight: { lineCount: 3 },
}}
/>
);

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`
Expand Down
34 changes: 22 additions & 12 deletions packages/eui/src/components/datagrid/body/cell/data_grid_cell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const EuiDataGridCellContent: FunctionComponent<
setCellContentsRef,
rowIndex,
colIndex,
rowHeight,
rowHeightsOptions,
rowHeightUtils,
isControlColumn,
...rest
Expand All @@ -78,11 +78,18 @@ const EuiDataGridCellContent: FunctionComponent<
const CellElement =
renderCellValue as JSXElementConstructor<EuiDataGridCellValueElementProps>;

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(
Expand All @@ -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,
]),
Expand All @@ -113,7 +120,9 @@ const EuiDataGridCellContent: FunctionComponent<
return (
<RenderTruncatedCellContent
hasLineCountTruncation={
cellHeightType === 'lineCount' && !isControlColumn
(cellHeightType === 'lineCount' ||
cellHeightType === 'autoBelowLineCount') &&
!isControlColumn
}
rowHeight={rowHeight}
>
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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({
Expand Down Expand Up @@ -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}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,7 @@ export const EuiDataGridBodyCustomRender: FunctionComponent<EuiDataGridBodyProps
/**
* Row heights
*/
const rowHeightUtils = useRowHeightUtils({
rowHeightsOptions,
gridStyles,
columns,
});
const rowHeightUtils = useRowHeightUtils({ rowHeightsOptions, columns });

const { setRowHeight, getRowHeight } = useDefaultRowHeight({
rowHeightsOptions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,6 @@ export const EuiDataGridBodyVirtualized: FunctionComponent<EuiDataGridBodyProps>
gridItemsRenderedRef: gridItemsRendered,
},
rowHeightsOptions,
gridStyles,
columns,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
<MockComponent rowHeightsOptions={{ autoBelowLineCount: true }} />
);
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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ const RowHeightControl = ({
rowHeightsOptions: EuiDataGridRowHeightsOptions;
onChange: Function;
}) => {
const { autoBelowLineCount } = rowHeightsOptions;

const [lineCountInput, setLineCountInput] = useState(1);
const setLineCountHeight = useCallback(
(event: ChangeEvent<HTMLInputElement>) => {
Expand Down Expand Up @@ -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[]) => (
<EuiFormRow label={rowHeightLabel} display="columnCompressed">
<EuiFlexGroup gutterSize="s" responsive={false}>
<EuiButtonGroup
Expand All @@ -240,7 +243,10 @@ const RowHeightControl = ({
isFullWidth
options={[
{ id: rowHeightSelectionOptions[0], label: labelAuto },
{ id: rowHeightSelectionOptions[1], label: labelStatic },
{
id: rowHeightSelectionOptions[1],
label: autoBelowLineCount ? labelMax : labelStatic,
},
]}
onChange={setRowHeight}
idSelected={rowHeightSelection}
Expand Down
3 changes: 2 additions & 1 deletion packages/eui/src/components/datagrid/data_grid.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ export const euiDataGridStyles = (euiThemeContext: UseEuiTheme) => {
}
/* 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',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) => (
<StatefulDataGrid
{...storyArgs}
rowHeightsOptions={rowHeightsOptions}
renderCellValue={({ rowIndex }) => loremData[rowIndex]}
columns={[{ id: 'name' }, { id: 'location' }]}
/>
),
};

export const StaticHeight: Story = {
args: {
defaultHeight: { height: 48 },
Expand Down
8 changes: 8 additions & 0 deletions packages/eui/src/components/datagrid/data_grid_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export const useUnconstrainedHeight = ({
rowHeightOption,
defaultRowHeight,
correctRowIndex,
rowHeightUtils.isRowHeightOverride(correctRowIndex, rowHeightsOptions)
rowHeightsOptions
);
}
}
Expand Down
Loading

0 comments on commit 040bf9a

Please sign in to comment.