Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EuiDataGrid] Display selector / toolbar control enhancements #8080

Merged
merged 11 commits into from
Oct 23, 2024
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.
3 changes: 3 additions & 0 deletions packages/eui/changelogs/upcoming/8080.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- `EuiDataGrid` now supports a new `toolbarVisibility.showDisplaySelector.customRender` function that allows completely customizing the rendering of the display selector popover
- `EuiDataGrid`'s row height/lines per row setting has been streamlined in both UI and UX
- `EuiDataGrid` now accepts consumer-passed display setting updates even after users have changed their display preferences via UI
15 changes: 9 additions & 6 deletions packages/eui/src-docs/src/views/datagrid/toolbar/_props.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@ import { DataGridPropsTable } from '../_props_table';
/* eslint-disable local/css-logical-properties */
const gridSnippets = {
showColumnSelector: `showColumnSelector: {
allowHide: false;
allowReorder: false;
allowHide: false,
allowReorder: false,
}`,
showDisplaySelector: `showDisplaySelector: {
allowDensity: false;
allowRowHeight: false;
allowResetButton: false;
additionalDisplaySettings: <EuiButtonEmpty size="xs" />;
allowDensity: false,
allowRowHeight: false,
allowResetButton: false,
additionalDisplaySettings: <EuiButtonEmpty size="xs" />,
customRender: ({ densityControl, rowHeightControl, resetButton, additionalDisplaySettings }) => (
<>Completely custom display settings</>
),
}`,
showSortSelector: 'showSortSelector: false',
showFullScreenSelector: 'showFullScreenSelector: false',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import {
EuiContextMenuItem,
EuiContextMenuPanel,
EuiPopover,
EuiFormRow,
EuiRange,
EuiDataGridPaginationProps,
RenderCellValue,
} from '../../../../../src';
Expand Down Expand Up @@ -54,6 +56,29 @@ for (let i = 1; i < 20; i++) {
const renderCellValue: RenderCellValue = ({ rowIndex, columnId }) =>
data[rowIndex][columnId];

// Some additional custom settings to show in the Display popover
const AdditionalDisplaySettings = () => {
const [exampleSettingValue, setExampleSettingValue] = useState<number>(10);

return (
<EuiFormRow label="Example additional setting" display="columnCompressed">
<EuiRange
compressed
fullWidth
showInput
min={1}
max={100}
step={1}
value={exampleSettingValue}
data-test-subj="exampleAdditionalSetting"
onChange={(event) => {
setExampleSettingValue(Number(event.currentTarget.value));
}}
/>
</EuiFormRow>
);
};

export default () => {
const [pagination, setPagination] = useState({ pageIndex: 0 });
const [isFlyoutVisible, setIsFlyoutVisible] = useState(false);
Expand Down Expand Up @@ -209,6 +234,10 @@ export default () => {
</Fragment>
),
},
showDisplaySelector: {
allowResetButton: false,
additionalDisplaySettings: <AdditionalDisplaySettings />,
},
}}
/>
{flyout}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,60 +34,64 @@ const controlsSnippet = `<EuiDataGrid
columnVisibility={{ visibleColumns, setVisibleColumns }}
rowCount={rowCount}
toolbarVisibility={{
// Use of a fragment for multiple items will insure proper margins
additionalControls: {
left: {
prepend: (
<>
<EuiButtonEmpty
size="xs"
onClick={() => {}}>
New button
</EuiButtonEmpty>
<EuiButtonEmpty
size="xs"
onClick={() => {}}>
Another button
</EuiButtonEmpty>
</>
),
append: (
// Use of a fragment for multiple items will insure proper margins
additionalControls: {
left: {
prepend: (
<>
<EuiButtonEmpty
size="xs"
onClick={() => {}}>
New button
</EuiButtonEmpty>
<EuiButtonEmpty
size="xs"
onClick={() => {}}>
Another button
</EuiButtonEmpty>
</>
),
append: (
<>
<EuiButtonEmpty
size="xs"
onClick={() => {}}>
New button
</EuiButtonEmpty>
<EuiButtonEmpty
size="xs"
onClick={() => {}}>
Another button
</EuiButtonEmpty>
</>
),
},
right: (
<>
<EuiButtonEmpty
size="xs"
onClick={() => {}}>
New button
</EuiButtonEmpty>
<EuiButtonEmpty
size="xs"
onClick={() => {}}>
Another button
</EuiButtonEmpty>
<EuiToolTip content="Right-side button">
<EuiButtonIcon
aria-label="Right-side button"
size="xs"
iconType="refresh"
onClick={() => {}}
/>
</EuiToolTip>
<EuiToolTip content="Another right-side button">
<EuiButtonIcon
aria-label="Another right-side button"
size="xs"
iconType="inspect"
onClick={() => {}}
/>
</EuiToolTip>
</>
),
},
right: (
<>
<EuiToolTip content="Right-side button">
<EuiButtonIcon
aria-label="Right-side button"
size="xs"
iconType="refresh"
onClick={() => {}}
/>
</EuiToolTip>
<EuiToolTip content="Another right-side button">
<EuiButtonIcon
aria-label="Another right-side button"
size="xs"
iconType="inspect"
onClick={() => {}}
/>
</EuiToolTip>
</>
)
}
}}
// Additional controls can also be passed to the display settings popover
showDisplaySelector: {
additionalDisplaySettings: <div>Custom settings content</div>,
},
}}
/>
`;

Expand Down Expand Up @@ -246,8 +250,7 @@ export const DataGridToolbarExample = {
renderCustomToolbar={({ displayControl }) => <div>Custom toolbar content {displayControl}</div>}
toolbarVisibility={{
showDisplaySelector: {
allowResetButton: false,
additionalDisplaySettings: <div>Custom settings content</div>
customRender: ({ densityControl }) => <div>Custom display selector {densityControl}</div>
}
}}
/>`,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback, useState } from 'react';
import React, { useCallback, useMemo, useState } from 'react';
import { css } from '@emotion/react';
import { faker } from '@faker-js/faker';

Expand All @@ -8,12 +8,18 @@ import {
EuiDataGridColumnSortingConfig,
EuiDataGridToolbarProps,
EuiDataGridToolbarControl,
EuiDataGridStyle,
EuiDataGridStyleBorders,
EuiDataGridDisplaySelectorCustomRender,
EuiSpacer,
EuiHorizontalRule,
EuiFormRow,
EuiRange,
EuiButtonGroup,
EuiFlexGroup,
EuiFlexItem,
euiScreenReaderOnly,
RenderCellValue,
EuiSwitch,
} from '../../../../../src';

const raw_data: Array<{ [key: string]: string }> = [];
Expand Down Expand Up @@ -57,6 +63,7 @@ const renderCustomToolbar: EuiDataGridToolbarProps['renderCustomToolbar'] = ({
justifyContent="spaceBetween"
alignItems="center"
css={mobileStyles}
className="euiDataGrid__controls"
>
<EuiFlexItem grow={false}>
{hasRoomForGridControls && (
Expand Down Expand Up @@ -86,29 +93,6 @@ const renderCustomToolbar: EuiDataGridToolbarProps['renderCustomToolbar'] = ({
const renderCellValue: RenderCellValue = ({ rowIndex, columnId }) =>
raw_data[rowIndex][columnId];

// Some additional custom settings to show in the Display popover
const AdditionalDisplaySettings = () => {
const [exampleSettingValue, setExampleSettingValue] = useState<number>(10);

return (
<EuiFormRow label="Example additional setting" display="columnCompressed">
<EuiRange
compressed
fullWidth
showInput
min={1}
max={100}
step={1}
value={exampleSettingValue}
data-test-subj="exampleAdditionalSetting"
onChange={(event) => {
setExampleSettingValue(Number(event.currentTarget.value));
}}
/>
</EuiFormRow>
);
};

export default () => {
// Column visibility
const [visibleColumns, setVisibleColumns] = useState(() =>
Expand All @@ -123,6 +107,51 @@ export default () => {
setSortingColumns(sortingColumns);
}, []);

// Custom display settings
const [borders, setGridBorders] = useState<EuiDataGridStyleBorders>('none');
const [rowStripes, setRowStripes] = useState(false);
const gridStyle: EuiDataGridStyle = useMemo(
() => ({
border: borders,
header: borders === 'none' ? 'underline' : 'shade',
stripes: rowStripes,
}),
[borders, rowStripes]
);
const customDisplayControls: EuiDataGridDisplaySelectorCustomRender =
useCallback(
({ densityControl, rowHeightControl }) => {
return (
<>
<EuiSpacer size="xs" />
<EuiSwitch
label="Show row stripes"
checked={rowStripes}
onChange={() => setRowStripes(!rowStripes)}
/>
<EuiHorizontalRule margin="s" />
{densityControl}
<EuiFormRow label="Border" display="columnCompressed">
<EuiButtonGroup
isFullWidth
buttonSize="compressed"
legend="Border"
options={[
{ id: 'all', label: 'All' },
{ id: 'horizontal', label: 'Horizontal only' },
{ id: 'none', label: 'None' },
]}
idSelected={borders}
onChange={(id) => setGridBorders(id as EuiDataGridStyleBorders)}
/>
</EuiFormRow>
{rowHeightControl}
</>
);
},
[borders, rowStripes]
);

return (
<EuiDataGrid
aria-label="Data grid custom toolbar demo"
Expand All @@ -131,12 +160,12 @@ export default () => {
sorting={{ columns: sortingColumns, onSort }}
rowCount={raw_data.length}
renderCellValue={renderCellValue}
gridStyle={{ border: 'none', header: 'underline' }}
gridStyle={gridStyle}
renderCustomToolbar={renderCustomToolbar}
toolbarVisibility={{
showDisplaySelector: {
allowResetButton: false,
additionalDisplaySettings: <AdditionalDisplaySettings />,
customRender: customDisplayControls,
},
}}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ describe('EuiDataGridBodyCustomRender', () => {
cy.get('[role="gridcell"]').first().invoke('outerHeight').should('eq', 36);

cy.get('[data-test-subj="dataGridDisplaySelectorButton"]').click();
cy.contains('Auto fit').click();
cy.contains('Auto').click();

cy.get('[role="gridcell"]')
.first()
Expand Down
Loading
Loading