diff --git a/docs/demo/virtual-columns.md b/docs/demo/virtual-columns.md new file mode 100644 index 000000000..c8637675e --- /dev/null +++ b/docs/demo/virtual-columns.md @@ -0,0 +1,8 @@ +--- +title: Virtual Columns +nav: + title: Demo + path: /demo +--- + + diff --git a/docs/examples/fixedColumns.tsx b/docs/examples/fixedColumns.tsx index ee8dea7e6..fb1df6711 100644 --- a/docs/examples/fixedColumns.tsx +++ b/docs/examples/fixedColumns.tsx @@ -1,7 +1,7 @@ -import React from 'react'; +import type { ColumnType } from 'rc-table'; import Table from 'rc-table'; -import { ColumnType } from 'rc-table/lib/interface'; -import './assets/index.less'; +import React from 'react'; +import '../../assets/index.less'; interface RecordType { a: string; diff --git a/docs/examples/virtual-columns.tsx b/docs/examples/virtual-columns.tsx new file mode 100644 index 000000000..b762ed4d7 --- /dev/null +++ b/docs/examples/virtual-columns.tsx @@ -0,0 +1,66 @@ +import React from 'react'; +import '../../assets/index.less'; +import { VirtualTable } from '../../src'; +import type { ColumnsType } from '../../src/interface'; + +interface RecordType { + a: string; + b?: string; + c?: string; +} + +const columns1: ColumnsType = [ + { title: 'title1', dataIndex: 'a', width: 100 }, + { title: 'title2', dataIndex: 'b', width: 100 }, + { + title: 'title13', + dataIndex: 'c', + }, +]; + +const columns2: ColumnsType = [ + { title: 'title1', dataIndex: 'a', width: 100 }, + { title: 'title2', dataIndex: 'b', width: 100 }, +]; + +const columns3: ColumnsType = [ + { title: 'title1', dataIndex: 'a', width: 500 }, + { title: 'title2', dataIndex: 'b', width: 500 }, +]; + +const data: RecordType[] = new Array(4 * 10000).fill(null).map((_, index) => ({ + a: `a${index}`, + b: `b${index}`, + c: `c${index}`, +})); + +const Demo = () => { + const [columns, setColumns] = React.useState(columns1); + + return ( +
+ + + + + w - 1} + columns={columns} + scroll={{ y: 200 }} + data={data} + rowKey="a" + /> +
+ ); +}; + +export default Demo; diff --git a/src/hooks/useColumns/useWidthColumns.tsx b/src/hooks/useColumns/useWidthColumns.tsx index eb108da53..fb5f2d885 100644 --- a/src/hooks/useColumns/useWidthColumns.tsx +++ b/src/hooks/useColumns/useWidthColumns.tsx @@ -38,7 +38,8 @@ export default function useWidthColumns( }); // Fill width - let restWidth = Math.max(scrollWidth - totalWidth, missWidthCount); + const maxFitWidth = Math.max(scrollWidth, clientWidth); + let restWidth = Math.max(maxFitWidth - totalWidth, missWidthCount); let restCount = missWidthCount; const avgWidth = restWidth / missWidthCount; @@ -67,8 +68,6 @@ export default function useWidthColumns( return clone; }); - const maxFitWidth = Math.max(scrollWidth, clientWidth); - // If realTotal is less than clientWidth, // We need extend column width if (realTotal < maxFitWidth) { diff --git a/src/index.ts b/src/index.ts index dd67c0309..a1c42ecbe 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ import { EXPAND_COLUMN, INTERNAL_HOOKS } from './constant'; import { FooterComponents as Summary } from './Footer'; -import type { Reference } from './interface'; +import type { ColumnType, Reference } from './interface'; import Column from './sugar/Column'; import ColumnGroup from './sugar/ColumnGroup'; import type { TableProps } from './Table'; @@ -22,6 +22,7 @@ export { genVirtualTable, type VirtualTableProps, type Reference, + type ColumnType, }; export default Table; diff --git a/tests/Virtual.spec.tsx b/tests/Virtual.spec.tsx index d6557dd13..f2ad1398b 100644 --- a/tests/Virtual.spec.tsx +++ b/tests/Virtual.spec.tsx @@ -323,4 +323,77 @@ describe('Table.Virtual', () => { index: 99, }); }); + + describe('auto width', () => { + async function prepareTable(columns: any[]) { + const { container } = getTable({ + getContainerWidth: () => 300, + columns: columns, + }); + + resize(container.querySelector('.rc-table')!); + await waitFakeTimer(); + + return container; + } + + it('fill rest', async () => { + const container = await prepareTable([ + { + dataIndex: 'name', + width: 100, + }, + { + dataIndex: 'age', + }, + ]); + + expect(container.querySelectorAll('col')[0]).toHaveStyle({ + width: '100px', + }); + expect(container.querySelectorAll('col')[1]).toHaveStyle({ + width: '200px', + }); + }); + + it('stretch', async () => { + const container = await prepareTable([ + { + dataIndex: 'name', + width: 100, + }, + { + dataIndex: 'age', + width: 100, + }, + ]); + + expect(container.querySelectorAll('col')[0]).toHaveStyle({ + width: '150px', + }); + expect(container.querySelectorAll('col')[1]).toHaveStyle({ + width: '150px', + }); + }); + + it('exceed', async () => { + const container = await prepareTable([ + { + dataIndex: 'name', + width: 500, + }, + { + dataIndex: 'age', + width: 600, + }, + ]); + + expect(container.querySelectorAll('col')[0]).toHaveStyle({ + width: '500px', + }); + expect(container.querySelectorAll('col')[1]).toHaveStyle({ + width: '600px', + }); + }); + }); });