microsoft / fluentui

Fluent UI web represents a collection of utilities, React components, and web components for building web applications.
https://react.fluentui.dev
Other
18.53k stars 2.74k forks source link

[Bug]: DataGrid, virtualized with resizable columns, does not scroll header horizontally #27805

Closed logicaloud closed 10 months ago

logicaloud commented 1 year ago

Library

React Components / v9 (@fluentui/react-components)

System Info

Edge: Spartan (44.22621.1555.0), Chromium (112.0.1722.64)

"@fluentui/react-components": "^9.18.9"

Are you reporting Accessibility issue?

no

Reproduction

https://codesandbox.io/s/young-cherry-bpfrx7

Bug Description

Actual Behavior

When scrolling the data grid horizontally, the header cells remain fixed.

fluent-headerscroll

Expected Behavior

The header cells should scroll horizontally with the data grid body.

Logs

No response

Requested priority

Normal

Products/sites affected

No response

Are you willing to submit a PR to fix?

no

Validations

FengQiMS commented 1 year ago

Any ETA when this sticky header will be fixed?

FengQiMS commented 1 year ago

Got this fixed with the solution answered in this issue The fix is to add a wrapper div at header, and make it overflow: hidden, bundle scroll bar horizontal event of the child List component of DataGridBody(target element is the one with the overflow:auto): to make both header and body scroll horizontally using scrollTo() API

    const headerContainer: React.Ref<HTMLDivElement> = React.useRef(null);
    const bodyContainer: React.Ref<HTMLDivElement> = React.useRef(null);

    const scrollToLeft = (scrollLeft: number) => {
        headerContainer && (headerContainer?.current as HTMLElement).scrollTo({ left: scrollLeft});
        const bodyChildren = bodyContainer && bodyContainer?.current?.children;
        if( bodyChildren) {
            (Array.from(bodyChildren)[0] as HTMLElement).scrollTo({ left: scrollLeft });
        }
    }

    // bundle scroll bar horizontal of the child List component of DataGridBody: to make both header and body scroll horizontally
    React.useEffect(() => {
        const bodyChildren = bodyContainer && bodyContainer?.current?.children;
        if( bodyChildren) {
            const handleScroll = (event) => {
                scrollToLeft((Array.from(bodyChildren)[0] as HTMLElement).scrollLeft);
            }

            (Array.from(bodyChildren)[0] as HTMLElement).addEventListener('scroll', handleScroll);
        }
    }, []);
 <DataGrid
            {...props}
            items={items}
  >
            <div role='grid' className={styles.tableHeader} ref={headerContainer}>
                <DataGridHeader style={{ paddingRight: scrollbarWidth }}>
                    <DataGridRow>
                        {({ columnId, renderHeaderCell }, tableFeaturesState) => {
                            return (
                                <RichDataGridHeaderCell>
                                    {renderHeaderCell()}
                                </RichDataGridHeaderCell>
                            );
                        }}
                    </DataGridRow>
                </DataGridHeader>
            </div>
            <DataGridBody<Item> itemSize={getRowHeight(richSize)} height={height} ref={bodyContainer}>
                {renderRow}
            </DataGridBody>
        </DataGrid>

After fix: fixHeaderStickyscrollHorizontal

Reference code: https://github.com/Autodesk/react-base-table/blob/master/src/GridTable.js#L51-L54 https://autodesk.github.io/react-base-table/examples/fixed.

ling1726 commented 1 year ago

@FengQiMS your fix makes sense, feel free to contribute it to the virtualized DataGrid package https://github.com/microsoft/fluentui-contrib

microsoft-github-policy-service[bot] commented 10 months ago

Because this issue has not had activity for over 150 days, we're automatically closing it for house-keeping purposes.

Still require assistance? Please, create a new issue with up-to date details.