Skip to content

Commit

Permalink
[EuiDataGrid] Introduce renderCustomToolbar, `additionalDisplaySett…
Browse files Browse the repository at this point in the history
…ings` and `allowResetButton` customization options (#7190)

Co-authored-by: Tim Schnell <[email protected]>
Co-authored-by: Matthias Wilhelm <[email protected]>
Co-authored-by: Cee Chen <[email protected]>
Co-authored-by: Cee Chen <[email protected]>
  • Loading branch information
5 people authored Sep 25, 2023
1 parent 3a653d4 commit 7767b10
Show file tree
Hide file tree
Showing 14 changed files with 497 additions and 88 deletions.
43 changes: 39 additions & 4 deletions src-docs/src/views/datagrid/toolbar/_grid.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import React, { useState, useCallback, useMemo } from 'react';
import { faker } from '@faker-js/faker';

import { EuiDataGrid, EuiAvatar } from '../../../../../src/components';
import {
EuiDataGrid,
EuiAvatar,
EuiFormRow,
EuiRange,
} from '../../../../../src/components';

const columns = [
{
Expand Down Expand Up @@ -52,6 +57,8 @@ const DataGridStyle = ({
showFullScreenSelector,
allowDensity,
allowRowHeight,
allowResetButton,
additionalDisplaySettings,
allowHideColumns,
allowOrderingColumns,
}) => {
Expand Down Expand Up @@ -98,13 +105,41 @@ const DataGridStyle = ({
const toggleDisplaySelector = useMemo(() => {
if (
showDisplaySelector === true &&
(allowDensity === false || allowRowHeight === false)
(allowDensity === false ||
allowRowHeight === false ||
allowResetButton === false ||
additionalDisplaySettings)
) {
return { allowDensity, allowRowHeight };
const customDisplaySetting = additionalDisplaySettings && (
<EuiFormRow label="Random Sample Size" display="columnCompressed">
<EuiRange
compressed
fullWidth
showInput
min={1}
max={100}
step={1}
value={10}
data-test-subj="randomSampleSize"
/>
</EuiFormRow>
);
return {
allowDensity,
allowRowHeight,
allowResetButton,
additionalDisplaySettings: customDisplaySetting,
};
} else {
return showDisplaySelector;
}
}, [showDisplaySelector, allowDensity, allowRowHeight]);
}, [
showDisplaySelector,
allowDensity,
allowRowHeight,
allowResetButton,
additionalDisplaySettings,
]);

const toolbarVisibilityOptions = {
showColumnSelector: toggleColumnSelector,
Expand Down
2 changes: 2 additions & 0 deletions src-docs/src/views/datagrid/toolbar/_props.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ const gridSnippets = {
showDisplaySelector: `showDisplaySelector: {
allowDensity: false;
allowRowHeight: false;
allowResetButton: false;
additionalDisplaySettings: <EuiButtonEmpty size="xs" />;
}`,
showSortSelector: 'showSortSelector: false',
showFullScreenSelector: 'showFullScreenSelector: false',
Expand Down
53 changes: 53 additions & 0 deletions src-docs/src/views/datagrid/toolbar/datagrid_toolbar_example.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ const dataGridToolbarVisibilitySource = require('!!raw-loader!./_grid');
import DataGridControls from './additional_controls';
const dataGridControlsSource = require('!!raw-loader!./additional_controls');

import DataGridCustomToolbar from './render_custom_toolbar';
const dataGridCustomToolbarSource = require('!!raw-loader!./render_custom_toolbar');

import ToolbarPropsTable from './_props';

import {
Expand All @@ -17,6 +20,7 @@ import {
EuiDataGridToolBarVisibilityColumnSelectorOptions,
EuiDataGridToolBarVisibilityDisplaySelectorOptions,
EuiDataGridToolBarAdditionalControlsLeftOptions,
EuiDataGridCustomToolbarProps,
} from '!!prop-loader!../../../../../src/components/datagrid/data_grid_types';

/* eslint-disable local/css-logical-properties */
Expand Down Expand Up @@ -185,6 +189,55 @@ export const DataGridToolbarExample = {
},
demo: <DataGridControls />,
},
{
title: 'Completely custom toolbar rendering',
source: [
{
type: GuideSectionTypes.TSX,
code: dataGridCustomToolbarSource,
},
],
text: (
<>
<p>
If more customized control over the toolbar is required than{' '}
<EuiCode>toolbarVisibility</EuiCode> or{' '}
<EuiCode>additionalControls</EuiCode> allows, you can use the{' '}
<EuiCode>renderCustomToolbar</EuiCode> prop to pass a component. The
default datagrid controls are passed back as parameters for optional
usage.
</p>
<p>
<EuiCode>renderCustomToolbar</EuiCode> should only be used when a
very custom layout (e.g. moving default buttons between sides,
interspering custom controls between default controls, custom
responsive behavior, etc.) is required. We would caution you to keep
consistency in mind also when customizing the toolbar: if using
multiple datagrid instances across your app, users will typically
want to reach for the same controls for each grid. Changing the
available controls inconsistently across your app may result in user
frustration.
</p>
</>
),
demo: <DataGridCustomToolbar />,
props: {
EuiDataGridCustomToolbarProps,
},
snippet: `<EuiDataGrid
aria-label="Data grid with a custom toolbar and additional content in the display settings popover "
columns={columns}
columnVisibility={{ visibleColumns, setVisibleColumns }}
rowCount={rowCount}
renderCustomToolbar={({ displayControl }) => <div>Custom toolbar content {displayControl}</div>}
toolbarVisibility={{
showDisplaySelector: {
allowResetButton: false,
additionalDisplaySettings: <div>Custom settings content</div>
}
}}
/>`,
},
{
title: 'Toolbar props',
text: (
Expand Down
136 changes: 136 additions & 0 deletions src-docs/src/views/datagrid/toolbar/render_custom_toolbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import React, { useCallback, useState } from 'react';
import { css } from '@emotion/react';
import { faker } from '@faker-js/faker';

import {
EuiDataGrid,
EuiDataGridSorting,
EuiDataGridColumnSortingConfig,
EuiDataGridToolbarProps,
EuiButtonEmpty,
EuiFormRow,
EuiRange,
EuiFlexGroup,
EuiFlexItem,
euiScreenReaderOnly,
} from '../../../../../src';

const raw_data: Array<{ [key: string]: string }> = [];
for (let i = 0; i < 5; i++) {
raw_data.push({
name: `${faker.person.lastName()}, ${faker.person.firstName()}`,
email: faker.internet.email(),
location: `${faker.location.city()}, ${faker.location.country()}`,
date: `${faker.date.past()}`,
amount: faker.commerce.price({ min: 1, max: 1000, dec: 2, symbol: '$' }),
});
}
const columns = [
{ id: 'name', displayAsText: 'Name' },
{ id: 'email', displayAsText: 'Email address' },
{ id: 'location', displayAsText: 'Location' },
{ id: 'date', displayAsText: 'Date' },
{ id: 'amount', displayAsText: 'Amount' },
];

// Custom toolbar renderer
const renderCustomToolbar: EuiDataGridToolbarProps['renderCustomToolbar'] = ({
hasRoomForGridControls,
columnControl,
columnSortingControl,
displayControl,
fullScreenControl,
keyboardShortcutsControl,
}) => {
const mobileStyles =
!hasRoomForGridControls &&
css`
.euiDataGrid__controlBtn .euiButtonEmpty__text {
${euiScreenReaderOnly()}
}
`;
return (
<EuiFlexGroup
responsive={false}
gutterSize="s"
justifyContent="spaceBetween"
alignItems="center"
css={mobileStyles}
>
<EuiFlexItem grow={false}>
{hasRoomForGridControls && (
<EuiButtonEmpty size="xs" color="primary">
Custom left side
</EuiButtonEmpty>
)}
</EuiFlexItem>

<EuiFlexItem grow={false}>
<EuiFlexGroup responsive={false} gutterSize="s" alignItems="center">
<EuiFlexItem grow={false}>{columnControl}</EuiFlexItem>
<EuiFlexItem grow={false}>{columnSortingControl}</EuiFlexItem>
<EuiFlexItem grow={false}>{keyboardShortcutsControl}</EuiFlexItem>
<EuiFlexItem grow={false}>{displayControl}</EuiFlexItem>
<EuiFlexItem grow={false}>{fullScreenControl}</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
);
};

// 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(() =>
columns.map(({ id }) => id)
);

// Sorting
const [sortingColumns, setSortingColumns] = useState<
EuiDataGridColumnSortingConfig[]
>([]);
const onSort = useCallback<EuiDataGridSorting['onSort']>((sortingColumns) => {
setSortingColumns(sortingColumns);
}, []);

return (
<EuiDataGrid
aria-label="Data grid custom toolbar demo"
columns={columns}
columnVisibility={{ visibleColumns, setVisibleColumns }}
sorting={{ columns: sortingColumns, onSort }}
rowCount={raw_data.length}
renderCellValue={({ rowIndex, columnId }) => raw_data[rowIndex][columnId]}
gridStyle={{ border: 'none', header: 'underline' }}
renderCustomToolbar={renderCustomToolbar}
toolbarVisibility={{
showDisplaySelector: {
allowResetButton: false,
additionalDisplaySettings: <AdditionalDisplaySettings />,
},
}}
/>
);
};
43 changes: 40 additions & 3 deletions src-docs/src/views/datagrid/toolbar/visibility.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ const DataGrid = () => {
const [showDisplaySelector, setShowDisplaySelector] = useState(true);
const [allowDensity, setAllowDensity] = useState(true);
const [allowRowHeight, setAllowRowHeight] = useState(true);
const [allowResetButton, setAllowResetButton] = useState(true);
const [additionalDisplaySettings, setAdditionalDisplaySettings] =
useState(false);
const [showColumnSelector, setShowColumnSelector] = useState(true);
const [allowHideColumns, setAllowHideColumns] = useState(true);
const [allowOrderingColumns, setAllowOrderingColumns] = useState(true);
Expand Down Expand Up @@ -76,6 +79,12 @@ const DataGrid = () => {
const onAllowRowHeightChange = (optionId) => {
setAllowRowHeight(optionId === 'true');
};
const onAllowResetButtonChange = (optionId) => {
setAllowResetButton(optionId === 'true');
};
const onAdditionalDisplaySettingsChange = (optionId) => {
setAdditionalDisplaySettings(optionId === 'true');
};

const onShowKeyboardShortcutsChange = (optionId) => {
setShowKeyboardShortcuts(optionId === 'true');
Expand Down Expand Up @@ -125,13 +134,27 @@ const DataGrid = () => {
const toggleDisplaySelector = useMemo(() => {
if (
showDisplaySelector === true &&
(allowDensity === false || allowRowHeight === false)
(allowDensity === false ||
allowRowHeight === false ||
allowResetButton === false ||
additionalDisplaySettings)
) {
return { allowDensity, allowRowHeight };
return {
allowDensity,
allowRowHeight,
allowResetButton,
additionalDisplaySettings,
};
} else {
return showDisplaySelector;
}
}, [showDisplaySelector, allowDensity, allowRowHeight]);
}, [
showDisplaySelector,
allowDensity,
allowRowHeight,
allowResetButton,
additionalDisplaySettings,
]);

const createItem = (name, buttonProps = {}) => {
return (
Expand Down Expand Up @@ -234,6 +257,18 @@ const DataGrid = () => {
onChange: onAllowRowHeightChange,
})}
</li>
<li>
{createItem('Show reset button', {
idSelected: allowResetButton.toString(),
onChange: onAllowResetButtonChange,
})}
</li>
<li>
{createItem('Additional display settings', {
idSelected: additionalDisplaySettings.toString(),
onChange: onAdditionalDisplaySettingsChange,
})}
</li>
</ul>
)}

Expand Down Expand Up @@ -266,6 +301,8 @@ const DataGrid = () => {
showFullScreenSelector={showFullScreenSelector}
allowDensity={allowDensity}
allowRowHeight={allowRowHeight}
allowResetButton={allowResetButton}
additionalDisplaySettings={additionalDisplaySettings}
allowHideColumns={allowHideColumns}
allowOrderingColumns={allowOrderingColumns}
/>
Expand Down
Loading

0 comments on commit 7767b10

Please sign in to comment.