0

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>
    );
};

0

Browse other questions tagged or ask your own question.