From 1481096e506452a144713621468620eea77ca6f2 Mon Sep 17 00:00:00 2001 From: jingzouzou <827088092@qq.com> Date: Fri, 1 Nov 2024 22:11:12 +0800 Subject: [PATCH 1/7] fix: gab fixed columns have no shadow --- src/Body/BodyRow.tsx | 1 + src/Cell/index.tsx | 36 ++++++++++++++++++++++++++++-------- src/Header/HeaderRow.tsx | 8 +++++++- src/Table.tsx | 11 +++++++++++ src/context/TableContext.tsx | 3 ++- 5 files changed, 49 insertions(+), 10 deletions(-) diff --git a/src/Body/BodyRow.tsx b/src/Body/BodyRow.tsx index d33cf38dc..51ce174e2 100644 --- a/src/Body/BodyRow.tsx +++ b/src/Body/BodyRow.tsx @@ -167,6 +167,7 @@ function BodyRow( key={key} record={record} index={index} + colIndex={colIndex} renderIndex={renderIndex} dataIndex={dataIndex} render={render} diff --git a/src/Cell/index.tsx b/src/Cell/index.tsx index 90bb04a48..07d3db822 100644 --- a/src/Cell/index.tsx +++ b/src/Cell/index.tsx @@ -22,6 +22,8 @@ export interface CellProps { record?: RecordType; /** `column` index is the real show rowIndex */ index?: number; + /** the column index which cell in */ + colIndex: number; /** the index of the record. For the render(value, record, renderIndex) */ renderIndex?: number; dataIndex?: DataIndex; @@ -53,6 +55,7 @@ export interface CellProps { rowType?: 'header' | 'body' | 'footer'; isSticky?: boolean; + setRef?: React.Ref; } const getTitleFromCellRenderChildren = ({ @@ -99,6 +102,9 @@ function Cell(props: CellProps) { index, rowType, + // Col, + colIndex, + // Span colSpan, rowSpan, @@ -115,14 +121,18 @@ function Cell(props: CellProps) { appendNode, additionalProps = {}, isSticky, + setRef, } = props; const cellPrefixCls = `${prefixCls}-cell`; - const { supportSticky, allColumnsFixedLeft, rowHoverable } = useContext(TableContext, [ - 'supportSticky', - 'allColumnsFixedLeft', - 'rowHoverable', - ]); + const { supportSticky, allColumnsFixedLeft, rowHoverable, bodyScrollLeft, headerCellRefs } = + useContext(TableContext, [ + 'supportSticky', + 'allColumnsFixedLeft', + 'rowHoverable', + 'bodyScrollLeft', + 'headerCellRefs', + ]); // ====================== Value ======================= const [childNode, legacyCellProps] = useCellRender( @@ -171,6 +181,15 @@ function Cell(props: CellProps) { additionalProps?.onMouseLeave?.(event); }); + let mergedLastFixLeft = lastFixLeft; + if (lastFixLeft) { + const { current } = headerCellRefs; + const dom = current[colIndex]; + + // should not be tagged as lastFixLeft if cell is not stickying; + mergedLastFixLeft = + dom && typeof fixLeft === 'number' && dom.offsetLeft === fixLeft + bodyScrollLeft + 1; + } // ====================== Render ====================== if (mergedColSpan === 0 || mergedRowSpan === 0) { return null; @@ -192,8 +211,8 @@ function Cell(props: CellProps) { { [`${cellPrefixCls}-fix-left`]: isFixLeft && supportSticky, [`${cellPrefixCls}-fix-left-first`]: firstFixLeft && supportSticky, - [`${cellPrefixCls}-fix-left-last`]: lastFixLeft && supportSticky, - [`${cellPrefixCls}-fix-left-all`]: lastFixLeft && allColumnsFixedLeft && supportSticky, + [`${cellPrefixCls}-fix-left-last`]: mergedLastFixLeft && supportSticky, + [`${cellPrefixCls}-fix-left-all`]: mergedLastFixLeft && allColumnsFixedLeft && supportSticky, [`${cellPrefixCls}-fix-right`]: isFixRight && supportSticky, [`${cellPrefixCls}-fix-right-first`]: firstFixRight && supportSticky, [`${cellPrefixCls}-fix-right-last`]: lastFixRight && supportSticky, @@ -237,6 +256,7 @@ function Cell(props: CellProps) { return ( (props: CellProps) { ); } -export default React.memo(Cell) as typeof Cell; +export default React.memo(React.forwardRef(Cell)) as typeof Cell; diff --git a/src/Header/HeaderRow.tsx b/src/Header/HeaderRow.tsx index fe7629c64..7d8e010b8 100644 --- a/src/Header/HeaderRow.tsx +++ b/src/Header/HeaderRow.tsx @@ -32,7 +32,11 @@ const HeaderRow = (props: RowProps) => { onHeaderRow, index, } = props; - const { prefixCls, direction } = useContext(TableContext, ['prefixCls', 'direction']); + const { prefixCls, direction, headerCellRefs } = useContext(TableContext, [ + 'prefixCls', + 'direction', + 'headerCellRefs', + ]); let rowProps: React.HTMLAttributes; if (onHeaderRow) { rowProps = onHeaderRow( @@ -62,6 +66,8 @@ const HeaderRow = (props: RowProps) => { return ( (headerCellRefs.current[cellIndex] = headerCellRef)} {...cell} scope={column.title ? (cell.colSpan > 1 ? 'colgroup' : 'col') : null} ellipsis={column.ellipsis} diff --git a/src/Table.tsx b/src/Table.tsx index a1db3de5b..efb25dad2 100644 --- a/src/Table.tsx +++ b/src/Table.tsx @@ -441,6 +441,7 @@ function Table( const isRTL = direction === 'rtl'; const mergedScrollLeft = typeof scrollLeft === 'number' ? scrollLeft : currentTarget.scrollLeft; + console.log('mergedScrollLeft: ', mergedScrollLeft); const compareTarget = currentTarget || EMPTY_SCROLL_TARGET; if (!getScrollTarget() || getScrollTarget() === compareTarget) { @@ -477,9 +478,14 @@ function Table( }, ); + const [bodyScrollLeft, setBodyScrollLeft] = React.useState(); const onBodyScroll = useEvent((e: React.UIEvent) => { onInternalScroll(e); onScroll?.(e); + + const { scrollLeft } = e.currentTarget; + + setBodyScrollLeft(scrollLeft); }); const triggerOnScroll = () => { @@ -796,6 +802,7 @@ function Table( const fixedInfoList = useFixedInfo(flattenColumns, stickyOffsets, direction); + const headerCellRefs = React.useRef([]); const TableContextValue = React.useMemo( () => ({ // Scroll @@ -846,6 +853,8 @@ function Table( childrenColumnName: mergedChildrenColumnName, rowHoverable, + bodyScrollLeft, + headerCellRefs, }), [ // Scroll @@ -895,6 +904,8 @@ function Table( mergedChildrenColumnName, rowHoverable, + bodyScrollLeft, + headerCellRefs, ], ); diff --git a/src/context/TableContext.tsx b/src/context/TableContext.tsx index f566c84f0..70b079266 100644 --- a/src/context/TableContext.tsx +++ b/src/context/TableContext.tsx @@ -66,8 +66,9 @@ export interface TableContextProps { expandedKeys: Set; getRowKey: GetRowKey; childrenColumnName: string; - + headerCellRefs: React.MutableRefObject; rowHoverable?: boolean; + bodyScrollLeft?: number; } const TableContext = createContext(); From 0263215cdacd1356da47cac2ff5f386f77095b01 Mon Sep 17 00:00:00 2001 From: jingzouzou <827088092@qq.com> Date: Fri, 1 Nov 2024 22:12:59 +0800 Subject: [PATCH 2/7] fix: supplement styles changes --- assets/index.less | 6 ------ 1 file changed, 6 deletions(-) diff --git a/assets/index.less b/assets/index.less index bfa245b03..f6c23c50a 100644 --- a/assets/index.less +++ b/assets/index.less @@ -56,12 +56,6 @@ } // ================== Cell ================== - &-fixed-column-gapped { - .@{tablePrefixCls}-cell-fix-left-last::after, - .@{tablePrefixCls}-cell-fix-right-first::after { - display: none !important; - } - } &-cell { background: #f4f4f4; From 28351f0e928d41d937096b4873048394c297765b Mon Sep 17 00:00:00 2001 From: jingzouzou <827088092@qq.com> Date: Mon, 4 Nov 2024 23:25:52 +0800 Subject: [PATCH 3/7] feat: use `getBoundingClientRect` to calculate dom whether is sticky --- src/Cell/index.tsx | 21 ++++++++++++--------- src/Header/HeaderRow.tsx | 2 +- src/Table.tsx | 8 ++------ 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/Cell/index.tsx b/src/Cell/index.tsx index 07d3db822..cf148cb44 100644 --- a/src/Cell/index.tsx +++ b/src/Cell/index.tsx @@ -75,7 +75,10 @@ const getTitleFromCellRenderChildren = ({ return title; }; -function Cell(props: CellProps) { +function Cell( + props: CellProps, + ref: React.ForwardedRef, +) { if (process.env.NODE_ENV !== 'production') { devRenderTimes(props); } @@ -121,7 +124,6 @@ function Cell(props: CellProps) { appendNode, additionalProps = {}, isSticky, - setRef, } = props; const cellPrefixCls = `${prefixCls}-cell`; @@ -182,13 +184,14 @@ function Cell(props: CellProps) { }); let mergedLastFixLeft = lastFixLeft; - if (lastFixLeft) { - const { current } = headerCellRefs; - const dom = current[colIndex]; + const { current } = headerCellRefs; + const dom = current[colIndex]; + if (lastFixLeft && dom) { + const offsetLeft = + dom.getBoundingClientRect().x - dom.parentElement.getBoundingClientRect().x || 0; // should not be tagged as lastFixLeft if cell is not stickying; - mergedLastFixLeft = - dom && typeof fixLeft === 'number' && dom.offsetLeft === fixLeft + bodyScrollLeft + 1; + mergedLastFixLeft = typeof fixLeft === 'number' && offsetLeft === fixLeft + bodyScrollLeft; } // ====================== Render ====================== if (mergedColSpan === 0 || mergedRowSpan === 0) { @@ -256,7 +259,7 @@ function Cell(props: CellProps) { return ( (props: CellProps) { ); } -export default React.memo(React.forwardRef(Cell)) as typeof Cell; +export default React.memo(React.forwardRef(Cell)); diff --git a/src/Header/HeaderRow.tsx b/src/Header/HeaderRow.tsx index 7d8e010b8..15ba25369 100644 --- a/src/Header/HeaderRow.tsx +++ b/src/Header/HeaderRow.tsx @@ -67,7 +67,7 @@ const HeaderRow = (props: RowProps) => { return ( (headerCellRefs.current[cellIndex] = headerCellRef)} + ref={headerCellRef => (headerCellRefs.current[cellIndex] = headerCellRef)} {...cell} scope={column.title ? (cell.colSpan > 1 ? 'colgroup' : 'col') : null} ellipsis={column.ellipsis} diff --git a/src/Table.tsx b/src/Table.tsx index efb25dad2..ce1df4675 100644 --- a/src/Table.tsx +++ b/src/Table.tsx @@ -435,13 +435,14 @@ function Table( } } } + const [bodyScrollLeft, setBodyScrollLeft] = React.useState(0); const onInternalScroll = useEvent( ({ currentTarget, scrollLeft }: { currentTarget: HTMLElement; scrollLeft?: number }) => { const isRTL = direction === 'rtl'; const mergedScrollLeft = typeof scrollLeft === 'number' ? scrollLeft : currentTarget.scrollLeft; - console.log('mergedScrollLeft: ', mergedScrollLeft); + setBodyScrollLeft(mergedScrollLeft); const compareTarget = currentTarget || EMPTY_SCROLL_TARGET; if (!getScrollTarget() || getScrollTarget() === compareTarget) { @@ -478,14 +479,9 @@ function Table( }, ); - const [bodyScrollLeft, setBodyScrollLeft] = React.useState(); const onBodyScroll = useEvent((e: React.UIEvent) => { onInternalScroll(e); onScroll?.(e); - - const { scrollLeft } = e.currentTarget; - - setBodyScrollLeft(scrollLeft); }); const triggerOnScroll = () => { From e3d328745f7d045c48bcc8510d830b98a4bbef6a Mon Sep 17 00:00:00 2001 From: jingzouzou <827088092@qq.com> Date: Thu, 7 Nov 2024 00:14:05 +0800 Subject: [PATCH 4/7] fix: add `getBoundingClientRect` spy to pass tests --- tests/FixedColumn.spec.tsx | 39 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/tests/FixedColumn.spec.tsx b/tests/FixedColumn.spec.tsx index 50a21baf9..c4a3b9fa8 100644 --- a/tests/FixedColumn.spec.tsx +++ b/tests/FixedColumn.spec.tsx @@ -25,6 +25,31 @@ describe('Table.FixedColumn', () => { offsetWidth: { get: () => 1000, }, + getBoundingClientRect() { + if (this.tagName === 'TR') { + return { + x: 0, + y: 0, + width: 1000, + height: 105, + }; + } + if (this.textContent === 'title2') { + return { + x: 93, + y: 0, + width: 93, + height: 105, + }; + } + + return { + x: 0, + y: 0, + width: 100, + height: 100, + }; + }, }); }); @@ -249,6 +274,20 @@ describe('Table.FixedColumn', () => { it('when all columns fixed left,cell should has classname rc-table-cell-fix-left-all', async () => { const wrapper = mount(); + + // make `mergedLastFixLeft`'s calculation work. + act(() => { + wrapper + .find(RcResizeObserver.Collection) + .first() + .props() + .onBatchResize([ + { + data: wrapper.find('table ResizeObserver').first().props().data, + size: { width: 93, offsetWidth: 93 }, + } as any, + ]); + }); await safeAct(wrapper); expect(wrapper.find('.rc-table-cell-fix-left-all')).toHaveLength(10); }); From 04091fcdb31a32d6c04ffb0b28337ee37c2f36a4 Mon Sep 17 00:00:00 2001 From: jingzouzou <827088092@qq.com> Date: Fri, 8 Nov 2024 00:22:30 +0800 Subject: [PATCH 5/7] fix: tsc check error --- src/Cell/index.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Cell/index.tsx b/src/Cell/index.tsx index cf148cb44..e7cde3c70 100644 --- a/src/Cell/index.tsx +++ b/src/Cell/index.tsx @@ -23,7 +23,7 @@ export interface CellProps { /** `column` index is the real show rowIndex */ index?: number; /** the column index which cell in */ - colIndex: number; + colIndex?: number; /** the index of the record. For the render(value, record, renderIndex) */ renderIndex?: number; dataIndex?: DataIndex; @@ -55,7 +55,6 @@ export interface CellProps { rowType?: 'header' | 'body' | 'footer'; isSticky?: boolean; - setRef?: React.Ref; } const getTitleFromCellRenderChildren = ({ @@ -280,4 +279,6 @@ function Cell( ); } -export default React.memo(React.forwardRef(Cell)); +export default React.memo(React.forwardRef(Cell)) as ( + props: CellProps & { ref?: React.ForwardedRef }, +) => React.JSX.Element; From 99b1309d5e1bb0c35c6ce5a314175a6670ed08d1 Mon Sep 17 00:00:00 2001 From: jingzouzou <827088092@qq.com> Date: Fri, 8 Nov 2024 20:51:37 +0800 Subject: [PATCH 6/7] chore: optimize codes logic --- src/Cell/index.tsx | 23 +++++++++++++---------- src/Header/HeaderRow.tsx | 7 ++++++- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/Cell/index.tsx b/src/Cell/index.tsx index e7cde3c70..da21a2f91 100644 --- a/src/Cell/index.tsx +++ b/src/Cell/index.tsx @@ -182,16 +182,19 @@ function Cell( additionalProps?.onMouseLeave?.(event); }); - let mergedLastFixLeft = lastFixLeft; - const { current } = headerCellRefs; - const dom = current[colIndex]; - if (lastFixLeft && dom) { - const offsetLeft = - dom.getBoundingClientRect().x - dom.parentElement.getBoundingClientRect().x || 0; - - // should not be tagged as lastFixLeft if cell is not stickying; - mergedLastFixLeft = typeof fixLeft === 'number' && offsetLeft === fixLeft + bodyScrollLeft; - } + const mergedLastFixLeft = React.useMemo(() => { + const { current } = headerCellRefs; + const dom = current[colIndex]; + + if (lastFixLeft && dom && typeof fixLeft === 'number') { + const offsetLeft = + dom.getBoundingClientRect().x - dom.parentElement.getBoundingClientRect().x || 0; + + // should not be tagged as lastFixLeft if cell is not stickying; + return offsetLeft === fixLeft + bodyScrollLeft; + } + return lastFixLeft; + }, [bodyScrollLeft, colIndex, fixLeft, headerCellRefs, lastFixLeft]); // ====================== Render ====================== if (mergedColSpan === 0 || mergedRowSpan === 0) { return null; diff --git a/src/Header/HeaderRow.tsx b/src/Header/HeaderRow.tsx index 15ba25369..45e4dec78 100644 --- a/src/Header/HeaderRow.tsx +++ b/src/Header/HeaderRow.tsx @@ -47,6 +47,11 @@ const HeaderRow = (props: RowProps) => { const columnsKey = getColumnsKey(cells.map(cell => cell.column)); + const handleHeaderCellRef = + (cellIndex: number) => (headerCellRef: HTMLTableCellElement | null) => { + headerCellRefs.current[cellIndex] = headerCellRef; + }; + return ( {cells.map((cell: CellType, cellIndex) => { @@ -67,7 +72,7 @@ const HeaderRow = (props: RowProps) => { return ( (headerCellRefs.current[cellIndex] = headerCellRef)} + ref={handleHeaderCellRef(cellIndex)} {...cell} scope={column.title ? (cell.colSpan > 1 ? 'colgroup' : 'col') : null} ellipsis={column.ellipsis} From e862c63b3a35d5d83484298b4cf0d3be29ea4799 Mon Sep 17 00:00:00 2001 From: jingzouzou <827088092@qq.com> Date: Fri, 8 Nov 2024 22:03:01 +0800 Subject: [PATCH 7/7] feat: add test case for fixed gap columns scrolling --- tests/Scroll.spec.jsx | 241 ++++++++++++++++++++++++++++++------------ 1 file changed, 174 insertions(+), 67 deletions(-) diff --git a/tests/Scroll.spec.jsx b/tests/Scroll.spec.jsx index 387e6cd5f..8e726972c 100644 --- a/tests/Scroll.spec.jsx +++ b/tests/Scroll.spec.jsx @@ -3,6 +3,7 @@ import { spyElementPrototypes } from 'rc-util/lib/test/domHook'; import React from 'react'; import { act } from 'react-dom/test-utils'; import Table from '../src'; +import { safeAct } from './utils'; describe('Table.Scroll', () => { const data = [ @@ -49,10 +50,10 @@ describe('Table.Scroll', () => { expect(wrapper.find('.rc-table-body').props().style.overflowY).toEqual('scroll'); }); - it('fire scroll event', () => { - vi.useFakeTimers(); + describe('scroll', () => { let scrollLeft = 0; let scrollTop = 0; + let domSpy; const setScrollLeft = vi.fn((_, val) => { scrollLeft = val; @@ -60,80 +61,186 @@ describe('Table.Scroll', () => { const setScrollTop = vi.fn((_, val) => { scrollTop = val; }); + beforeEach(() => { + vi.useFakeTimers(); + domSpy = spyElementPrototypes(HTMLElement, { + scrollLeft: { + get: () => scrollLeft, + set: setScrollLeft, + }, + scrollTop: { + get: () => scrollTop, + set: setScrollTop, + }, + scrollWidth: { + get: () => 200, + }, + clientWidth: { + get: () => 100, + }, + offsetWidth: { + get: () => 200, + }, + getBoundingClientRect() { + if (this.tagName === 'TR') { + return { + x: 0, + y: 0, + width: 1000, + height: 105, + }; + } + if (this.textContent === 'title3') { + return { + x: 400, + y: 0, + width: 100, + height: 105, + }; + } - const domSpy = spyElementPrototypes(HTMLDivElement, { - scrollLeft: { - get: () => scrollLeft, - set: setScrollLeft, - }, - scrollTop: { - get: () => scrollTop, - set: setScrollTop, - }, - scrollWidth: { - get: () => 200, - }, - clientWidth: { - get: () => 100, - }, + return { + x: 0, + y: 0, + width: 100, + height: 100, + }; + }, + }); }); - const newColumns = [ - { title: 'title1', dataIndex: 'a', key: 'a', width: 100, fixed: 'left' }, - { title: 'title2', dataIndex: 'b', key: 'b' }, - { title: 'title3', dataIndex: 'c', key: 'c' }, - { title: 'title4', dataIndex: 'd', key: 'd', width: 100, fixed: 'right' }, - ]; - const newData = [ - { a: '123', b: 'xxxxxxxx', c: 3, d: 'hehe', key: '1' }, - { a: 'cdd', b: 'edd12221', c: 3, d: 'haha', key: '2' }, - ]; - const wrapper = mount( -
, - ); - - vi.runAllTimers(); - // Use `onScroll` directly since simulate not support `currentTarget` - act(() => { - const headerDiv = wrapper.find('div.rc-table-header').instance(); - - const wheelEvent = new WheelEvent('wheel'); - Object.defineProperty(wheelEvent, 'deltaX', { - get: () => 10, - }); + afterEach(() => { + setScrollLeft.mockReset(); - headerDiv.dispatchEvent(wheelEvent); - vi.runAllTimers(); + domSpy.mockRestore(); + vi.useRealTimers(); }); - expect(setScrollLeft).toHaveBeenCalledWith(undefined, 10); - setScrollLeft.mockReset(); - - act(() => { - wrapper - .find('.rc-table-body') - .props() - .onScroll({ - currentTarget: { - scrollLeft: 33, - scrollWidth: 200, - clientWidth: 100, - }, + it('scroll event', () => { + const newColumns = [ + { title: 'title1', dataIndex: 'a', key: 'a', width: 100, fixed: 'left' }, + { title: 'title2', dataIndex: 'b', key: 'b' }, + { title: 'title3', dataIndex: 'c', key: 'c' }, + { title: 'title4', dataIndex: 'd', key: 'd', width: 100, fixed: 'right' }, + ]; + const newData = [ + { a: '123', b: 'xxxxxxxx', c: 3, d: 'hehe', key: '1' }, + { a: 'cdd', b: 'edd12221', c: 3, d: 'haha', key: '2' }, + ]; + const wrapper = mount( +
, + ); + + vi.runAllTimers(); + // Use `onScroll` directly since simulate not support `currentTarget` + act(() => { + const headerDiv = wrapper.find('div.rc-table-header').instance(); + + const wheelEvent = new WheelEvent('wheel'); + Object.defineProperty(wheelEvent, 'deltaX', { + get: () => 10, }); + + headerDiv.dispatchEvent(wheelEvent); + vi.runAllTimers(); + }); + + expect(setScrollLeft).toHaveBeenCalledWith(undefined, 10); + setScrollLeft.mockReset(); + + act(() => { + wrapper + .find('.rc-table-body') + .props() + .onScroll({ + currentTarget: { + scrollLeft: 33, + scrollWidth: 200, + clientWidth: 100, + }, + }); + }); + vi.runAllTimers(); + expect(setScrollLeft).toHaveBeenCalledWith(undefined, 33); }); - vi.runAllTimers(); - expect(setScrollLeft).toHaveBeenCalledWith(undefined, 33); - setScrollLeft.mockReset(); - domSpy.mockRestore(); - vi.useRealTimers(); + it('cell should have not have classname `rc-table-cell-fix-left-last` before being sticky', async () => { + // const cellSpy = spyElementPrototypes(HTMLElement, { + // offsetParent: { + // get: () => ({}), + // }, + + // }); + + const newColumns = [ + { title: 'title1', dataIndex: 'a', key: 'a', width: 100, fixed: 'left' }, + { + title: 'title2', + dataIndex: 'b', + key: 'b', + width: 100, + render: () => 1111, + }, + { title: 'title3', dataIndex: 'c', key: 'c', width: 100, fixed: 'left' }, + { title: 'title4', dataIndex: 'b', key: 'd' }, + { title: 'title5', dataIndex: 'b', key: 'e' }, + { title: 'title6', dataIndex: 'b', key: 'f' }, + { title: 'title7', dataIndex: 'b', key: 'g' }, + { title: 'title8', dataIndex: 'b', key: 'h' }, + { title: 'title9', dataIndex: 'b', key: 'i' }, + { title: 'title10', dataIndex: 'b', key: 'j' }, + { title: 'title11', dataIndex: 'b', key: 'k' }, + { title: 'title12', dataIndex: 'b', key: 'l', width: 100, fixed: 'right' }, + ]; + const data = [ + { a: '123', b: 'xxxxxxxx', d: 3, key: '1' }, + { a: 'cdd', b: 'edd12221', d: 3, key: '2' }, + { a: '133', c: 'edd12221', d: 2, key: '3' }, + { a: '133', c: 'edd12221', d: 2, key: '4' }, + { a: '133', c: 'edd12221', d: 2, key: '5' }, + { a: '133', c: 'edd12221', d: 2, key: '6' }, + { a: '133', c: 'edd12221', d: 2, key: '7' }, + { a: '133', c: 'edd12221', d: 2, key: '8' }, + { a: '133', c: 'edd12221', d: 2, key: '9' }, + ]; + const wrapper = mount( +
, + ); + + vi.runAllTimers(); + await safeAct(wrapper); + console.log(wrapper.find('th').first(), wrapper.find('th').at(2)); + + expect(wrapper.find('th').first().props().className).toContain('rc-table-cell-fix-left-last'); + expect(wrapper.find('th').at(2).props().className).not.toContain( + 'rc-table-cell-fix-left-last', + ); + + act(() => { + wrapper + .find('.rc-table-body') + .props() + .onScroll({ + currentTarget: { + scrollLeft: 200, + scrollWidth: 200, + clientWidth: 100, + }, + }); + }); + vi.runAllTimers(); + setScrollLeft.mockReset(); + await safeAct(wrapper); + + expect(wrapper.find('th').at(2).props().className).toContain('rc-table-cell-fix-left-last'); + }); }); it('trigger inner scrollTo when set `top` 0 after render', () => {