diff --git a/package.json b/package.json index 1068603c4..7cc645baa 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "dependencies": { "@babel/runtime": "^7.10.1", "classnames": "^2.2.5", - "rc-resize-observer": "^1.0.0", + "rc-resize-observer": "^1.1.0", "rc-util": "^5.14.0", "shallowequal": "^1.1.0" }, diff --git a/src/Body/MeasureCell.tsx b/src/Body/MeasureCell.tsx index b20de4062..1fc8d9cdf 100644 --- a/src/Body/MeasureCell.tsx +++ b/src/Body/MeasureCell.tsx @@ -7,7 +7,7 @@ export interface MeasureCellProps { } export default function MeasureCell({ columnKey, onColumnResize }: MeasureCellProps) { - const cellRef = React.useRef(); + const cellRef = React.useRef(); React.useEffect(() => { if (cellRef.current) { @@ -16,11 +16,7 @@ export default function MeasureCell({ columnKey, onColumnResize }: MeasureCellPr }, []); return ( - { - onColumnResize(columnKey, offsetWidth); - }} - > +
 
diff --git a/src/Body/MeasureRow.tsx b/src/Body/MeasureRow.tsx new file mode 100644 index 000000000..be468f2ec --- /dev/null +++ b/src/Body/MeasureRow.tsx @@ -0,0 +1,54 @@ +import * as React from 'react'; +import ResizeObserver from 'rc-resize-observer'; +import MeasureCell from './MeasureCell'; +import raf from 'rc-util/lib/raf'; + +export interface MeasureCellProps { + prefixCls: string; + onColumnResize: (key: React.Key, width: number) => void; + columnsKey: React.Key[]; +} + +export default function MeasureRow({ prefixCls, columnsKey, onColumnResize }: MeasureCellProps) { + // delay state update while resize continuously, e.g. window resize + const resizedColumnsRef = React.useRef(new Map()); + const rafIdRef = React.useRef(null); + + const delayOnColumnResize = () => { + if (rafIdRef.current === null) { + rafIdRef.current = raf(() => { + resizedColumnsRef.current.forEach((width, columnKey) => { + onColumnResize(columnKey, width); + }); + resizedColumnsRef.current.clear(); + rafIdRef.current = null; + }, 2); + } + }; + + React.useEffect(() => { + return () => { + raf.cancel(rafIdRef.current); + }; + }, []); + return ( + + { + infoList.forEach(({ data: columnKey, size }) => { + resizedColumnsRef.current.set(columnKey, size.offsetWidth); + }); + delayOnColumnResize(); + }} + > + {columnsKey.map(columnKey => ( + + ))} + + + ); +} diff --git a/src/Body/index.tsx b/src/Body/index.tsx index b8049690e..8d070f1d3 100644 --- a/src/Body/index.tsx +++ b/src/Body/index.tsx @@ -5,10 +5,10 @@ import ExpandedRow from './ExpandedRow'; import BodyContext from '../context/BodyContext'; import { getColumnsKey } from '../utils/valueUtil'; import ResizeContext from '../context/ResizeContext'; -import MeasureCell from './MeasureCell'; import BodyRow from './BodyRow'; import useFlattenRecords from '../hooks/useFlattenRecords'; import HoverContext from '../context/HoverContext'; +import MeasureRow from './MeasureRow'; export interface BodyProps { data: readonly RecordType[]; @@ -102,19 +102,11 @@ function Body({ {/* Measure body column width with additional hidden col */} {measureColumnWidth && ( - - {columnsKey.map(columnKey => ( - - ))} - + )} {rows} diff --git a/tests/FixedColumn-IE.spec.js b/tests/FixedColumn-IE.spec.js index 90b9bb653..8d74411ff 100644 --- a/tests/FixedColumn-IE.spec.js +++ b/tests/FixedColumn-IE.spec.js @@ -5,6 +5,7 @@ import { spyElementPrototype } from 'rc-util/lib/test/domHook'; // eslint-disable-next-line @typescript-eslint/no-unused-vars import { isStyleSupport } from 'rc-util/lib/Dom/styleChecker'; import Table from '../src'; +import RcResizeObserver from 'rc-resize-observer'; jest.mock('rc-util/lib/Dom/styleChecker', () => { return { @@ -46,7 +47,16 @@ describe('Table.FixedColumn', () => { const wrapper = mount(); act(() => { - wrapper.find('table ResizeObserver').first().props().onResize({ width: 93, offsetWidth: 93 }); + wrapper + .find(RcResizeObserver.Collection) + .first() + .props() + .onBatchResize([ + { + data: wrapper.find('table ResizeObserver').first().props().data, + size: { width: 93, offsetWidth: 93 }, + }, + ]); }); await act(async () => { diff --git a/tests/FixedColumn.spec.js b/tests/FixedColumn.spec.js index e0bff211e..eb53648bb 100644 --- a/tests/FixedColumn.spec.js +++ b/tests/FixedColumn.spec.js @@ -4,6 +4,7 @@ import { act } from 'react-dom/test-utils'; import { resetWarned } from 'rc-util/lib/warning'; import { spyElementPrototype } from 'rc-util/lib/test/domHook'; import Table from '../src'; +import RcResizeObserver from 'rc-resize-observer'; describe('Table.FixedColumn', () => { let domSpy; @@ -59,10 +60,15 @@ describe('Table.FixedColumn', () => { act(() => { wrapper - .find('table ResizeObserver') + .find(RcResizeObserver.Collection) .first() .props() - .onResize({ width: 93, offsetWidth: 93 }); + .onBatchResize([ + { + data: wrapper.find('table ResizeObserver').first().props().data, + size: { width: 93, offsetWidth: 93 }, + }, + ]); }); await act(async () => { jest.runAllTimers(); diff --git a/tests/FixedHeader.spec.js b/tests/FixedHeader.spec.js index 5fa158837..00e1919b6 100644 --- a/tests/FixedHeader.spec.js +++ b/tests/FixedHeader.spec.js @@ -3,6 +3,7 @@ import { mount } from 'enzyme'; import { act } from 'react-dom/test-utils'; import { spyElementPrototype } from 'rc-util/lib/test/domHook'; import Table, { INTERNAL_COL_DEFINE } from '../src'; +import RcResizeObserver from 'rc-resize-observer'; describe('Table.FixedHeader', () => { let domSpy; @@ -35,9 +36,24 @@ describe('Table.FixedHeader', () => { />, ); - wrapper.find('ResizeObserver').at(0).props().onResize({ width: 100, offsetWidth: 100 }); - wrapper.find('ResizeObserver').at(1).props().onResize({ width: 200, offsetWidth: 200 }); - wrapper.find('ResizeObserver').at(2).props().onResize({ width: 0, offsetWidth: 0 }); + wrapper + .find(RcResizeObserver.Collection) + .first() + .props() + .onBatchResize([ + { + data: wrapper.find('ResizeObserver').at(0).props().data, + size: { width: 100, offsetWidth: 100 }, + }, + { + data: wrapper.find('ResizeObserver').at(1).props().data, + size: { width: 200, offsetWidth: 200 }, + }, + { + data: wrapper.find('ResizeObserver').at(2).props().data, + size: { width: 0, offsetWidth: 0 }, + }, + ]); await act(async () => { jest.runAllTimers(); @@ -147,7 +163,16 @@ describe('Table.FixedHeader', () => { />, ); - wrapper.find('ResizeObserver').at(0).props().onResize({ width: 93, offsetWidth: 93 }); + wrapper + .find(RcResizeObserver.Collection) + .first() + .props() + .onBatchResize([ + { + data: wrapper.find('ResizeObserver').at(0).props().data, + size: { width: 93, offsetWidth: 93 }, + }, + ]); await act(async () => { jest.runAllTimers(); await Promise.resolve(); @@ -161,7 +186,17 @@ describe('Table.FixedHeader', () => { // Hide Table should not modify column width visible = false; - wrapper.find('ResizeObserver').at(0).props().onResize({ width: 0, offsetWidth: 0 }); + wrapper + .find(RcResizeObserver.Collection) + .first() + .props() + .onBatchResize([ + { + data: wrapper.find('ResizeObserver').at(0).props().data, + size: { width: 0, offsetWidth: 0 }, + }, + ]); + act(() => { jest.runAllTimers(); wrapper.update();