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] Introduce renderCustomToolbar, additionalDisplaySettings and allowResetButton customization options #7190

Merged
merged 25 commits into from
Sep 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e14fb4c
adding api for additional display controls on the datagrid
timductive Aug 30, 2023
488e365
[EuiDataGrid] Introduce a renderCustomToolbar render prop (#7150)
kertal Sep 1, 2023
d87d061
Refactor how `renderCustomToolbar` works
jughosta Sep 14, 2023
8302ccd
Update tests and docs
jughosta Sep 14, 2023
f81e226
Update example and docs
jughosta Sep 14, 2023
3061aef
Add a changelog
jughosta Sep 14, 2023
228220b
Merge branch 'main' into render-custom-toolbar
jughosta Sep 14, 2023
b74c6f4
Merge branch 'main' into render-custom-toolbar
jughosta Sep 19, 2023
809a229
Update changelog
jughosta Sep 19, 2023
bae0d2e
Update allowResetButton logic
jughosta Sep 19, 2023
9d93d36
Update src/components/datagrid/data_grid_types.ts
jughosta Sep 19, 2023
315cdca
Update src/components/datagrid/data_grid_types.ts
jughosta Sep 19, 2023
bbf2d18
Rename to `EuiDataGridCustomToolbarProps`
jughosta Sep 19, 2023
67d6eed
Reduce the number of available custom toolbar props
jughosta Sep 19, 2023
b7d012a
Merge branch 'render-custom-toolbar' of github.com:jughosta/eui into …
jughosta Sep 19, 2023
84eb5fd
Simplify return type of `renderCustomToolbar`
jughosta Sep 19, 2023
8500388
Add tests
jughosta Sep 20, 2023
747577a
Update docs
jughosta Sep 20, 2023
b59347e
Merge branch 'main' into render-custom-toolbar
jughosta Sep 20, 2023
29c5061
Merge branch 'main' into render-custom-toolbar
jughosta Sep 22, 2023
bb177d3
Merge remote-tracking branch 'upstream/main' into render-custom-toolbar
cee-chen Sep 24, 2023
47f061c
[PR feedback] very minor copy tweaks
cee-chen Sep 24, 2023
6643774
[display_selector] Minor test cleanup
cee-chen Sep 24, 2023
2fa8e08
[PR feedback] Move `additionalDisplaySettings` docs example from main…
cee-chen Sep 24, 2023
ab6e553
Final docs pass
cee-chen Sep 24, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading