Skip to content

Commit 488e365

Browse files
kertaltimductive
authored andcommitted
[EuiDataGrid] Introduce a renderCustomToolbar render prop (#7150)
1 parent e14fb4c commit 488e365

5 files changed

Lines changed: 371 additions & 142 deletions

File tree

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
import React, { useCallback, useState } from 'react';
2+
import { faker } from '@faker-js/faker';
3+
4+
import {
5+
EuiDataGrid,
6+
EuiDataGridColumnCellActionProps,
7+
EuiButtonIcon,
8+
EuiDataGridPaginationProps,
9+
EuiDataGridSorting,
10+
EuiDataGridColumnSortingConfig,
11+
EuiPopover,
12+
EuiDataGridCustomToolbarProps,
13+
EuiFormRow,
14+
EuiRange,
15+
} from '../../../../../src';
16+
17+
const raw_data: Array<{ [key: string]: string }> = [];
18+
for (let i = 1; i < 100; i++) {
19+
raw_data.push({
20+
name: `${faker.name.lastName()}, ${faker.name.firstName()}`,
21+
email: faker.internet.email(),
22+
location: `${faker.address.city()}, ${faker.address.country()}`,
23+
date: `${faker.date.past()}`,
24+
amount: faker.commerce.price(1, 1000, 2, '$'),
25+
});
26+
}
27+
28+
const columns = [
29+
{
30+
id: 'name',
31+
displayAsText: 'Name',
32+
cellActions: [
33+
({ Component }: EuiDataGridColumnCellActionProps) => (
34+
<Component
35+
onClick={() => alert('action')}
36+
iconType="faceHappy"
37+
aria-label="Some action"
38+
>
39+
Some action
40+
</Component>
41+
),
42+
],
43+
},
44+
{
45+
id: 'email',
46+
displayAsText: 'Email address',
47+
initialWidth: 130,
48+
},
49+
{
50+
id: 'location',
51+
displayAsText: 'Location',
52+
},
53+
{
54+
id: 'date',
55+
displayAsText: 'Date',
56+
},
57+
{
58+
id: 'amount',
59+
displayAsText: 'Amount',
60+
},
61+
];
62+
63+
export default () => {
64+
// Column visibility
65+
const [visibleColumns, setVisibleColumns] = useState(() =>
66+
columns.map(({ id }) => id)
67+
);
68+
69+
// Pagination
70+
const [pagination, setPagination] = useState({ pageIndex: 0 });
71+
const onChangePage = useCallback<EuiDataGridPaginationProps['onChangePage']>(
72+
(pageIndex) => {
73+
setPagination((pagination) => ({ ...pagination, pageIndex }));
74+
},
75+
[]
76+
);
77+
const onChangePageSize = useCallback<
78+
EuiDataGridPaginationProps['onChangeItemsPerPage']
79+
>((pageSize) => {
80+
setPagination((pagination) => ({ ...pagination, pageSize }));
81+
}, []);
82+
83+
// Sorting
84+
const [sortingColumns, setSortingColumns] = useState<
85+
EuiDataGridColumnSortingConfig[]
86+
>([]);
87+
const onSort = useCallback<EuiDataGridSorting['onSort']>((sortingColumns) => {
88+
setSortingColumns(sortingColumns);
89+
}, []);
90+
const [isDisplaySelectorOpen, setIsDisplaySelectorOpen] = useState(false);
91+
92+
// Custom toolbar body renderer
93+
const RenderCustomToolbar = ({
94+
fullScreenSelector,
95+
keyboardShortcuts,
96+
rowHeightsControls,
97+
densityControls,
98+
columnSelector,
99+
columnSorting,
100+
}: EuiDataGridCustomToolbarProps) => {
101+
return (
102+
<div className="euiDataGrid__controls" data-test-subj="dataGridControls">
103+
<div className="euiDataGrid__leftControls">
104+
Always look at the left side of grid!
105+
</div>
106+
<div className="euiDataGrid__rightControls">
107+
{fullScreenSelector}
108+
{keyboardShortcuts}
109+
<EuiPopover
110+
button={
111+
<EuiButtonIcon
112+
iconType="controlsHorizontal"
113+
aria-label="Custom grid controls"
114+
onClick={() => setIsDisplaySelectorOpen(true)}
115+
/>
116+
}
117+
isOpen={isDisplaySelectorOpen}
118+
data-test-subj="dataGridDisplaySelectorPopover"
119+
closePopover={() => setIsDisplaySelectorOpen(false)}
120+
anchorPosition="downRight"
121+
panelPaddingSize="s"
122+
panelClassName="euiDataGrid__displayPopoverPanel"
123+
>
124+
{rowHeightsControls}
125+
{densityControls}
126+
127+
<EuiFormRow label="Random Sample Size" display="columnCompressed">
128+
<EuiRange
129+
compressed
130+
fullWidth
131+
showInput
132+
min={1}
133+
max={100}
134+
step={1}
135+
value={10}
136+
data-test-subj="randomSampleSize"
137+
/>
138+
</EuiFormRow>
139+
</EuiPopover>
140+
{columnSorting}
141+
{columnSelector}
142+
</div>
143+
</div>
144+
);
145+
};
146+
147+
return (
148+
<>
149+
<EuiDataGrid
150+
aria-label="Data grid custom body renderer demo"
151+
columns={columns}
152+
columnVisibility={{ visibleColumns, setVisibleColumns }}
153+
sorting={{ columns: sortingColumns, onSort }}
154+
inMemory={{ level: 'sorting' }}
155+
pagination={{
156+
...pagination,
157+
onChangePage: onChangePage,
158+
onChangeItemsPerPage: onChangePageSize,
159+
}}
160+
rowCount={raw_data.length}
161+
renderCellValue={({ rowIndex, columnId }) =>
162+
raw_data[rowIndex][columnId]
163+
}
164+
renderCustomToolbar={RenderCustomToolbar}
165+
height={undefined}
166+
gridStyle={{ border: 'none', header: 'underline' }}
167+
/>
168+
</>
169+
);
170+
};

src-docs/src/views/datagrid/advanced/datagrid_advanced_example.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
EuiCallOut,
99
EuiTitle,
1010
EuiLink,
11+
EuiDataGridCustomToolbarProps,
1112
} from '../../../../../src/components';
1213

1314
import {
@@ -36,7 +37,9 @@ dataGridRef.current.closeCellPopover();
3637
`;
3738

3839
import CustomRenderer from './custom_renderer';
40+
import CustomToolbarRenderer from './custom_toolbar';
3941
const customRendererSource = require('!!raw-loader!./custom_renderer');
42+
const customToolbarSource = require('!!raw-loader!./custom_toolbar');
4043
const customRendererSnippet = `const CustomGridBody = ({ visibleColumns, visibleRowData, Cell }) => {
4144
const visibleRows = raw_data.slice(
4245
visibleRowData.startRow,
@@ -253,5 +256,26 @@ export const DataGridAdvancedExample = {
253256
snippet: customRendererSnippet,
254257
props: { EuiDataGridCustomBodyProps },
255258
},
259+
{
260+
title: 'Custom toolbar renderer',
261+
source: [
262+
{
263+
type: GuideSectionTypes.TSX,
264+
code: customToolbarSource,
265+
},
266+
],
267+
text: (
268+
<>
269+
<p>
270+
For advanced use cases, the <EuiCode>renderCustomToolbar</EuiCode>{' '}
271+
prop may be used to take complete control over rendering the
272+
toolbar. This may be useful where custom row layouts (e.g., all
273+
button on the right side) are required.
274+
</p>
275+
</>
276+
),
277+
demo: <CustomToolbarRenderer />,
278+
props: { EuiDataGridCustomToolbarProps },
279+
},
256280
],
257281
};

0 commit comments

Comments
 (0)