Skip to content

Commit 4cab7dc

Browse files
committed
Add docs example + copy
1 parent ad95e85 commit 4cab7dc

5 files changed

Lines changed: 151 additions & 0 deletions

File tree

src-docs/src/views/datagrid/_props_table.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,19 @@ export const DataGridPropsTable: FunctionComponent<{
2929
.filter((i) => !exclude?.includes(i))
3030
.sort();
3131

32+
// Manually move the cellContext prop after renderCellValue
33+
const cellContext = gridPropsKeys.splice(
34+
gridPropsKeys.findIndex((prop) => prop === 'cellContext'),
35+
1
36+
)[0];
37+
if (cellContext) {
38+
gridPropsKeys.splice(
39+
gridPropsKeys.findIndex((prop) => prop === 'renderCellValue') + 1,
40+
0,
41+
cellContext
42+
);
43+
}
44+
3245
const items: BasicItem[] = gridPropsKeys.map((prop) => {
3346
return {
3447
id: prop,

src-docs/src/views/datagrid/_snippets.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ inMemory={{ level: 'sorting' }}`,
5353
},
5454
]}`,
5555
renderCellValue: 'renderCellValue={({ rowIndex, columnId }) => {}}',
56+
cellContext: `cellContext={{
57+
// Will be passed to your \`renderCellValue\` function/component as a prop
58+
yourData,
59+
}}
60+
renderCellValue={({ rowIndex, columnId, yourData }) => {}}`,
5661
renderCellPopover: `renderCellPopover={({ children, cellActions }) => (
5762
<>
5863
<EuiPopoverTitle>I'm a custom popover!</EuiPopoverTitle>

src-docs/src/views/datagrid/basics/_props.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const gridLinks = {
2424
ref: '/tabular-content/data-grid-advanced#ref-methods',
2525
renderCustomGridBody:
2626
'/tabular-content/data-grid-advanced#custom-body-renderer',
27+
cellContext: '/tabular-content/data-grid-cells-popovers#cell-context',
2728
};
2829

2930
export const DataGridTopProps = () => {
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import React, { useState, useEffect, useCallback, ReactNode } from 'react';
2+
import { faker } from '@faker-js/faker';
3+
4+
import {
5+
EuiDataGrid,
6+
EuiDataGridColumn,
7+
type RenderCellValue,
8+
EuiButton,
9+
EuiSpacer,
10+
EuiSkeletonText,
11+
} from '../../../../../src';
12+
13+
type DataType = Array<{ [key: string]: ReactNode }>;
14+
15+
const columns: EuiDataGridColumn[] = [
16+
{ id: 'firstName' },
17+
{ id: 'lastName' },
18+
{ id: 'suffix' },
19+
{ id: 'boolean' },
20+
];
21+
22+
const CellValue: RenderCellValue = ({
23+
rowIndex,
24+
columnId,
25+
// Props from cellContext
26+
data,
27+
isLoading,
28+
}) => {
29+
if (isLoading) {
30+
return <EuiSkeletonText lines={1} />;
31+
}
32+
33+
const value = data[rowIndex][columnId];
34+
return value;
35+
};
36+
37+
export default () => {
38+
const [visibleColumns, setVisibleColumns] = useState(
39+
columns.map(({ id }) => id)
40+
);
41+
42+
const [data, setData] = useState<DataType>([]);
43+
const [cellContext, setCellContext] = useState({
44+
data,
45+
isLoading: false,
46+
});
47+
48+
// Mock fetching data from an async API
49+
const mockLoading = useCallback(() => {
50+
setCellContext((context) => ({
51+
...context,
52+
isLoading: true,
53+
}));
54+
55+
// End the loading state after 3 seconds
56+
const timeout = setTimeout(() => {
57+
setCellContext((context) => ({
58+
...context,
59+
isLoading: false,
60+
}));
61+
}, 3000);
62+
return () => clearTimeout(timeout);
63+
}, []);
64+
65+
const fetchData = useCallback(() => {
66+
mockLoading();
67+
68+
const data: DataType = [];
69+
for (let i = 1; i < 5; i++) {
70+
data.push({
71+
firstName: faker.person.firstName(),
72+
lastName: faker.person.lastName(),
73+
suffix: faker.person.suffix(),
74+
boolean: `${faker.datatype.boolean()}`,
75+
});
76+
}
77+
setData(data);
78+
setCellContext((context) => ({ ...context, data }));
79+
}, [mockLoading]);
80+
81+
// Fetch data on page load
82+
useEffect(() => {
83+
fetchData();
84+
}, [fetchData]);
85+
86+
return (
87+
<>
88+
<EuiButton size="s" onClick={fetchData}>
89+
Fetch grid data
90+
</EuiButton>
91+
<EuiSpacer size="s" />
92+
<EuiDataGrid
93+
aria-label="Data grid example of cellContext"
94+
columns={columns}
95+
columnVisibility={{ visibleColumns, setVisibleColumns }}
96+
rowCount={data.length}
97+
renderCellValue={CellValue}
98+
cellContext={cellContext}
99+
/>
100+
</>
101+
);
102+
};

src-docs/src/views/datagrid/cells_popovers/datagrid_cells_example.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ import { DataGridCellPopoverExample } from './datagrid_cell_popover_example';
2121
import DataGridFocus from './focus';
2222
const dataGridFocusSource = require('!!raw-loader!./focus');
2323

24+
import CellContext from './cell_context';
25+
const cellContextSource = require('!!raw-loader!./cell_context');
26+
2427
import {
2528
EuiDataGridColumn,
2629
EuiDataGridColumnCellAction,
@@ -218,5 +221,32 @@ export const DataGridCellsExample = {
218221
),
219222
demo: <DataGridFocus />,
220223
},
224+
{
225+
title: 'Cell context',
226+
source: [
227+
{
228+
type: GuideSectionTypes.TSX,
229+
code: cellContextSource,
230+
},
231+
],
232+
text: (
233+
<>
234+
<p>
235+
The <EuiCode>cellContext</EuiCode> prop is an easy way of passing
236+
your custom data or context from the top level of{' '}
237+
<strong>EuiDataGrid</strong> down to the cell content rendered by
238+
your <EuiCode>renderCellValue</EuiCode> function component.
239+
</p>
240+
<p>
241+
The primary use of the cell context API is performance: if your data
242+
relies on state from your app, it allows you to more easily define
243+
your <EuiCode>renderCellValue</EuiCode> function statically, instead
244+
of within your app, which in turn reduces the number of rerenders
245+
within your data grid.
246+
</p>
247+
</>
248+
),
249+
demo: <CellContext />,
250+
},
221251
],
222252
};

0 commit comments

Comments
 (0)