Skip to content

Commit 79a62b3

Browse files
feat: adding option to add arbitrary content inside the scroll container
1 parent 3dbab32 commit 79a62b3

File tree

7 files changed

+150
-3
lines changed

7 files changed

+150
-3
lines changed

packages/material-react-table/src/components/head/MRT_TableHead.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
} from '../../types';
88
import { parseFromValuesOrFunc } from '../../utils/utils';
99
import { MRT_ToolbarAlertBanner } from '../toolbar/MRT_ToolbarAlertBanner';
10+
import { getCommonToolbarStyles } from '../../utils/style.utils';
1011

1112
export interface MRT_TableHeadProps<TData extends MRT_RowData>
1213
extends TableHeadProps {
@@ -23,6 +24,7 @@ export const MRT_TableHead = <TData extends MRT_RowData>({
2324
getState,
2425
options: {
2526
enableStickyHeader,
27+
enableTopContent,
2628
layoutMode,
2729
muiTableHeadProps,
2830
positionToolbarAlertBanner,
@@ -52,7 +54,12 @@ export const MRT_TableHead = <TData extends MRT_RowData>({
5254
display: layoutMode?.startsWith('grid') ? 'grid' : undefined,
5355
opacity: 0.97,
5456
position: stickyHeader ? 'sticky' : 'relative',
55-
top: stickyHeader && layoutMode?.startsWith('grid') ? 0 : undefined,
57+
top:
58+
stickyHeader && layoutMode?.startsWith('grid')
59+
? 0
60+
: enableStickyHeader && enableTopContent
61+
? getCommonToolbarStyles({ table, theme }).minHeight
62+
: undefined,
5663
zIndex: stickyHeader ? 2 : undefined,
5764
...(parseFromValuesOrFunc(tableHeadProps?.sx, theme) as any),
5865
})}

packages/material-react-table/src/components/table/MRT_TableContainer.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { type MRT_RowData, type MRT_TableInstance } from '../../types';
88
import { parseFromValuesOrFunc } from '../../utils/utils';
99
import { MRT_CellActionMenu } from '../menus/MRT_CellActionMenu';
1010
import { MRT_EditRowModal } from '../modals/MRT_EditRowModal';
11+
import { MRT_TopContent } from '../toolbar/MRT_TopContent';
1112

1213
const useIsomorphicLayoutEffect =
1314
typeof window !== 'undefined' ? useLayoutEffect : useEffect;
@@ -29,6 +30,7 @@ export const MRT_TableContainer = <TData extends MRT_RowData>({
2930
enableCellActions,
3031
enableStickyHeader,
3132
muiTableContainerProps,
33+
enableTopContent,
3234
},
3335
refs: { bottomToolbarRef, tableContainerRef, topToolbarRef },
3436
} = table;
@@ -101,6 +103,7 @@ export const MRT_TableContainer = <TData extends MRT_RowData>({
101103
})}
102104
>
103105
{loading ? <MRT_TableLoadingOverlay table={table} /> : null}
106+
{enableTopContent ? <MRT_TopContent table={table} /> : null}
104107
<MRT_Table table={table} />
105108
{(createModalOpen || editModalOpen) && (
106109
<MRT_EditRowModal open table={table} />

packages/material-react-table/src/components/table/MRT_TablePaper.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export const MRT_TablePaper = <TData extends MRT_RowData>({
1919
getState,
2020
options: {
2121
enableBottomToolbar,
22+
enableTopContent,
2223
enableTopToolbar,
2324
mrtTheme: { baseBackgroundColor },
2425
muiTablePaperProps,
@@ -76,6 +77,7 @@ export const MRT_TablePaper = <TData extends MRT_RowData>({
7677
})}
7778
>
7879
{enableTopToolbar &&
80+
!enableTopContent &&
7981
(parseFromValuesOrFunc(renderTopToolbar, { table }) ?? (
8082
<MRT_TopToolbar table={table} />
8183
))}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import Box from '@mui/material/Box';
2+
import { parseFromValuesOrFunc } from '../../utils/utils';
3+
import { MRT_TopToolbar } from './MRT_TopToolbar';
4+
import type { MRT_RowData, MRT_TableInstance } from '../../types';
5+
6+
export interface MRT_TopContentProps<TData extends MRT_RowData> {
7+
table: MRT_TableInstance<TData>;
8+
}
9+
10+
export const MRT_TopContent = <TData extends MRT_RowData>({
11+
table,
12+
}: MRT_TopContentProps<TData>) => {
13+
const {
14+
options: { renderTopContent },
15+
} = table;
16+
return (
17+
<>
18+
<Box
19+
sx={() => ({
20+
position: 'sticky',
21+
insetInlineStart: 0,
22+
})}
23+
>
24+
{parseFromValuesOrFunc(renderTopContent, { table })}
25+
</Box>
26+
<MRT_TopToolbar table={table} />
27+
</>
28+
);
29+
};

packages/material-react-table/src/components/toolbar/MRT_TopToolbar.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export const MRT_TopToolbar = <TData extends MRT_RowData>({
2222
options: {
2323
enableGlobalFilter,
2424
enablePagination,
25+
enableTopContent,
2526
enableToolbarInternalActions,
2627
muiTopToolbarProps,
2728
positionGlobalFilter,
@@ -66,9 +67,11 @@ export const MRT_TopToolbar = <TData extends MRT_RowData>({
6667
}}
6768
sx={(theme) => ({
6869
...getCommonToolbarStyles({ table, theme }),
69-
position: isFullScreen ? 'sticky' : 'relative',
70-
top: isFullScreen ? '0' : undefined,
70+
position: isFullScreen || enableTopContent ? 'sticky' : 'relative',
71+
top: isFullScreen || enableTopContent ? '0' : undefined,
7172
...(parseFromValuesOrFunc(toolbarProps?.sx, theme) as any),
73+
insetInlineStart: enableTopContent ? 0 : undefined,
74+
zIndex: enableTopContent ? 3 : undefined,
7275
})}
7376
>
7477
{positionToolbarAlertBanner === 'top' && (

packages/material-react-table/src/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,7 @@ export interface MRT_TableOptions<TData extends MRT_RowData>
883883
enableTableFooter?: boolean;
884884
enableTableHead?: boolean;
885885
enableToolbarInternalActions?: boolean;
886+
enableTopContent?: boolean;
886887
enableTopToolbar?: boolean;
887888
expandRowsFn?: (dataRow: TData) => TData[];
888889
getRowId?: (
@@ -1258,6 +1259,9 @@ export interface MRT_TableOptions<TData extends MRT_RowData>
12581259
renderToolbarInternalActions?: (props: {
12591260
table: MRT_TableInstance<TData>;
12601261
}) => ReactNode;
1262+
renderTopContent?:
1263+
| ((props: { table: MRT_TableInstance<TData> }) => ReactNode)
1264+
| ReactNode;
12611265
renderTopToolbar?:
12621266
| ((props: { table: MRT_TableInstance<TData> }) => ReactNode)
12631267
| ReactNode;
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import { type MRT_ColumnDef, MaterialReactTable } from '../../src';
2+
import { faker } from '@faker-js/faker';
3+
import { type Meta } from '@storybook/react';
4+
import Paper from '@mui/material/Paper';
5+
6+
const meta: Meta = {
7+
parameters: {
8+
status: {
9+
type: 'stable',
10+
},
11+
},
12+
title: 'Styling/Top Content Examples',
13+
};
14+
15+
export default meta;
16+
17+
const columns: MRT_ColumnDef<(typeof data)[0]>[] = [
18+
{
19+
accessorKey: 'firstName',
20+
header: 'First Name',
21+
},
22+
{
23+
accessorKey: 'lastName',
24+
header: 'Last Name',
25+
},
26+
{
27+
accessorKey: 'address',
28+
header: 'Address',
29+
},
30+
{
31+
accessorKey: 'state',
32+
header: 'State',
33+
},
34+
{
35+
accessorKey: 'phoneNumber',
36+
header: 'Phone Number',
37+
},
38+
];
39+
40+
const data = [...Array(88)].map(() => ({
41+
address: faker.location.streetAddress(),
42+
firstName: faker.person.firstName(),
43+
lastName: faker.person.lastName(),
44+
phoneNumber: faker.phone.number(),
45+
state: faker.location.state(),
46+
}));
47+
48+
export const TopContentWithStaticHeader = () => (
49+
<MaterialReactTable
50+
columns={columns}
51+
data={data}
52+
initialState={{ pagination: { pageIndex: 0, pageSize: 25 } }}
53+
enableTopContent={true}
54+
renderTopContent={({ table }) => (
55+
<Paper elevation={3} sx={{ padding: '0.5rem', margin: '0.5rem' }}>
56+
<h2 style={{ margin: '2rem', textAlign: 'center' }}>
57+
Total rows: {table.getRowCount()}
58+
</h2>
59+
</Paper>
60+
)}
61+
/>
62+
);
63+
64+
export const TopContentWithStickyHeader = () => (
65+
<MaterialReactTable
66+
columns={columns}
67+
data={data}
68+
enableStickyHeader
69+
initialState={{ pagination: { pageIndex: 0, pageSize: 25 } }}
70+
enableTopContent={true}
71+
renderTopContent={({ table }) => (
72+
<Paper elevation={3} sx={{ padding: '0.5rem', margin: '0.5rem' }}>
73+
<h2 style={{ margin: '2rem', textAlign: 'center' }}>
74+
Total rows: {table.getRowCount()}
75+
</h2>
76+
</Paper>
77+
)}
78+
/>
79+
);
80+
81+
export const TopContentWithStickyHeaderShorterTable = () => (
82+
<MaterialReactTable
83+
columns={columns}
84+
data={data}
85+
enableColumnPinning
86+
enableRowSelection
87+
enableStickyHeader
88+
initialState={{ pagination: { pageIndex: 0, pageSize: 25 } }}
89+
muiTableContainerProps={{ sx: { maxHeight: 400 } }}
90+
enableTopContent={true}
91+
renderTopContent={({ table }) => (
92+
<Paper elevation={3} sx={{ padding: '0.5rem', margin: '0.5rem' }}>
93+
<h2 style={{ margin: '2rem', textAlign: 'center' }}>
94+
Total rows: {table.getRowCount()}
95+
</h2>
96+
</Paper>
97+
)}
98+
/>
99+
);

0 commit comments

Comments
 (0)