I want to add pinnablecolumns feature for MUI datagrid myself. I wrote the following component for this, but as soon as I call it, I get the error in the title.
I completely removed the scroll synchronization feature, leaving only the columns and render() function, but it still didn't work.
I want to use Datagrid Pinnable feature without DatagridPro.
Here is my code:
import * as React from 'react';
import { DataGrid, DataGridProps } from '@mui/x-data-grid';
import { styled } from '@mui/material/styles';
import { useMemo, useRef, useEffect } from 'react';
const Container = styled('div')({
display: 'flex',
alignItems: 'flex-start',
overflowX: 'hidden',
});
const DataGridFixed = styled(DataGrid)({
'& .MuiDataGrid-viewport': {
overflow: 'hidden',
},
});
const DataGridScrollable = styled(DataGrid)({
'& .MuiDataGrid-viewport': {
overflowX: 'auto',
},
});
interface GridPinnedColumnFields {
left?: string[]; // Optional field names to pin to the left
right?: string[]; // Optional field names to pin to the right
}
interface PinnedColumnsGridProps extends DataGridProps {
pinnedColumns?: GridPinnedColumnFields;
}
export const CustomDataGridPro: React.FC<PinnedColumnsGridProps> = ({
pinnedColumns = {},
columns,
...rest
}) => {
const fixedLeftGridRef = useRef<HTMLDivElement>(null);
const scrollableGridRef = useRef<HTMLDivElement>(null);
const fixedRightGridRef = useRef<HTMLDivElement>(null);
const handleScroll = (event: Event) => {
const scrollTop = (event.target as HTMLElement).scrollTop;
if (fixedLeftGridRef.current) {
fixedLeftGridRef.current.scrollTop = scrollTop;
}
if (fixedRightGridRef.current) {
fixedRightGridRef.current.scrollTop = scrollTop;
}
};
useEffect(() => {
const scrollableGridElement = scrollableGridRef.current;
if (scrollableGridElement) {
scrollableGridElement.addEventListener('scroll', handleScroll);
return () => {
scrollableGridElement.removeEventListener('scroll', handleScroll);
};
}
}, []);
const leftPinnedColumns = useMemo(() => {
return columns.filter((column) =>
pinnedColumns.left?.includes(column.field)
);
}, [columns, pinnedColumns.left]);
const rightPinnedColumns = useMemo(() => {
return columns.filter((column) =>
pinnedColumns.right?.includes(column.field)
);
}, [columns, pinnedColumns.right]);
const otherColumns = useMemo(() => {
return columns.filter(
(column) =>
!pinnedColumns.left?.includes(column.field) &&
!pinnedColumns.right?.includes(column.field)
);
}, [columns, pinnedColumns.left, pinnedColumns.right]);
return (
<Container>
{leftPinnedColumns.length > 0 && (
<div style={{ overflow: 'hidden' }} ref={fixedLeftGridRef}>
<DataGridFixed columns={leftPinnedColumns} {...rest} />
</div>
)}
<div style={{ overflow: 'auto' }} ref={scrollableGridRef}>
<DataGridScrollable columns={otherColumns} {...rest} />
</div>
{rightPinnedColumns.length > 0 && (
<div style={{ overflow: 'hidden' }} ref={fixedRightGridRef}>
<DataGridFixed columns={rightPinnedColumns} {...rest} />
</div>
)}
</Container>
);
};