diff --git a/docs/examples/fixedColumnsAndHeader.tsx b/docs/examples/fixedColumnsAndHeader.tsx index 4b79ba878..b8692b47e 100644 --- a/docs/examples/fixedColumnsAndHeader.tsx +++ b/docs/examples/fixedColumnsAndHeader.tsx @@ -4,141 +4,68 @@ import '../../assets/index.less'; import { ColumnsType } from '@/interface'; import { useCheckbox } from './utils/useInput'; -interface RecordType { - a: string; - b?: string; - c: string; - d: number; - key: string; -} - -const originData: RecordType[] = [ - { a: 'aaa', b: 'bbb', c: '内容内容内容内容内容', d: 3, key: '1' }, - { a: 'aaa', b: 'bbb', c: '内容内容内容内容内容', d: 3, key: '2' }, - { a: 'aaa', c: '内容内容内容内容内容', d: 2, key: '3' }, - { a: 'aaa', c: '内容内容内容内容内容', d: 2, key: '4' }, - { a: 'aaa', c: '内容内容内容内容内容', d: 2, key: '5' }, - { a: 'aaa', c: '内容内容内容内容内容', d: 2, key: '6' }, - { a: 'aaa', c: '内容内容内容内容内容', d: 2, key: '7' }, - { a: 'aaa', c: '内容内容内容内容内容', d: 2, key: '8' }, - { a: 'aaa', c: '内容内容内容内容内容', d: 2, key: '9' }, +const columns = [ + { + title: 'Full Name', + width: 100, + dataIndex: 'name', + key: 'name', + }, + { + title: 'Age', + dataIndex: 'age', + key: 'age', + }, + { + title: 'Column 1', + dataIndex: 'address', + key: '1', + }, + { + title: 'Column 2', + dataIndex: 'address', + key: '2', + }, + { + title: 'Column 3', + dataIndex: 'address', + key: '3', + width: 150, + }, + { + title: 'Column 4', + dataIndex: 'address', + key: '4', + }, + { + title: 'Column 5', + dataIndex: 'address', + key: '5', + }, + { + title: 'Column 6', + dataIndex: 'address', + key: '6', + }, + { + title: 'Column 7', + dataIndex: 'address', + key: '7', + }, + { title: 'Column 8', dataIndex: 'address', key: '8' }, + { + title: 'Action', + key: 'operation', + fixed: 'right', + render: () => action, + }, ]; -const longTextData: RecordType[] = [...originData]; -longTextData[0] = { - ...longTextData[0], - a: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', -}; - -const useColumn = ( - fixLeft: boolean, - fixTitle: boolean, - fixRight: boolean, - ellipsis: boolean, - percentage: boolean, -) => { - const columns: ColumnsType = React.useMemo( - () => [ - { - title: 'title1', - dataIndex: 'a', - key: 'a', - width: percentage ? '10%' : 80, - fixed: fixLeft ? 'left' : null, - ellipsis, - }, - { title: 'title2', dataIndex: 'b', key: 'b', width: 80, fixed: fixLeft ? 'left' : null }, - { - title: 'title3', - fixed: fixLeft && fixTitle ? 'left' : null, - children: [ - { title: 'title4', dataIndex: 'c', key: 'd', width: 100 }, - { title: 'title5', dataIndex: 'c', key: 'e', width: 100 }, - ], - }, - { title: 'title6', dataIndex: 'c', key: 'f' }, - { title: 'title7', dataIndex: 'c', key: 'g' }, - { title: 'title8', dataIndex: 'c', key: 'h' }, - { title: 'title9', dataIndex: 'b', key: 'i' }, - { title: 'title10', dataIndex: 'b', key: 'j' }, - { title: 'title11', dataIndex: 'b', key: 'k', width: 100, fixed: fixRight ? 'right' : null }, - { title: 'title12', dataIndex: 'b', key: 'l', width: 80, fixed: fixRight ? 'right' : null }, - ], - [fixLeft, fixTitle, fixRight, ellipsis, percentage], - ); - - return columns; -}; - const Demo = () => { - const [autoWidth, autoWidthProps] = useCheckbox(false); - const [longText, longTextProps] = useCheckbox(false); - const [fixHeader, fixHeaderProps] = useCheckbox(true); - const [fixLeft, fixLeftProps] = useCheckbox(true); - const [fixRight, fixRightProps] = useCheckbox(true); - const [fixTitle3, fixTitle3Props] = useCheckbox(false); - const [ellipsis, ellipsisProps] = useCheckbox(false); - const [percentage, percentageProps] = useCheckbox(false); - const [empty, emptyProps] = useCheckbox(false); - const columns = useColumn(fixLeft, fixTitle3, fixRight, ellipsis, percentage); - - let mergedData: RecordType[]; - if (empty) { - mergedData = null; - } else if (longText) { - mergedData = longTextData; - } else { - mergedData = originData; - } - return (
-

Fixed columns and header

- - - - - - - - - - - - - columns={columns} - scroll={{ x: 1650, y: fixHeader ? 300 : null }} - data={mergedData} - style={{ width: autoWidth ? null : 800 }} - /> + ); diff --git a/src/Header/FixedHeader.tsx b/src/Header/FixedHeader.tsx index 3055e7e1b..d83e8f13b 100644 --- a/src/Header/FixedHeader.tsx +++ b/src/Header/FixedHeader.tsx @@ -2,9 +2,10 @@ import * as React from 'react'; import { useMemo } from 'react'; import classNames from 'classnames'; import { fillRef } from 'rc-util/lib/ref'; -import Header, { HeaderProps } from './Header'; +import type { HeaderProps } from './Header'; +import Header from './Header'; import ColGroup from '../ColGroup'; -import { ColumnsType, ColumnType } from '../interface'; +import type { ColumnsType, ColumnType } from '../interface'; import TableContext from '../context/TableContext'; function useColumnWidth(colWidths: readonly number[], columCount: number) { @@ -78,6 +79,12 @@ const FixedHeader = React.forwardRef>( }; }, []); + // Check if all flattenColumns has width + const allFlattenColumnsWithWidth = React.useMemo( + () => flattenColumns.every(column => column.width >= 0), + [flattenColumns], + ); + // Add scrollbar column const lastColumn = flattenColumns[flattenColumns.length - 1]; const ScrollBarColumn: ColumnType = { @@ -131,11 +138,13 @@ const FixedHeader = React.forwardRef>( visibility: noData || mergedColumnWidth ? null : 'hidden', }} > - + {(!noData || allFlattenColumnsWithWidth) && ( + + )}
(props: TableProps { const colWidth = index === columns.length - 1 ? (width as number) - scrollbarSize : width; if (typeof colWidth === 'number' && !Number.isNaN(colWidth)) { diff --git a/tests/FixedColumn.spec.js b/tests/FixedColumn.spec.js index 6ec93163c..e0bff211e 100644 --- a/tests/FixedColumn.spec.js +++ b/tests/FixedColumn.spec.js @@ -49,29 +49,45 @@ describe('Table.FixedColumn', () => { { scrollName: 'scrollX', scroll: { x: 1200 } }, { scrollName: 'scrollXY', scroll: { x: 1200, y: 100 } }, ].forEach(({ scrollName, scroll }) => { - [{ name: 'with data', data }, { name: 'without data', data: [] }].forEach( - ({ name, data: testData }) => { - it(`${scrollName} - ${name}`, async () => { - jest.useFakeTimers(); - const wrapper = mount(
); - - act(() => { - wrapper - .find('table ResizeObserver') - .first() - .props() - .onResize({ width: 93, offsetWidth: 93 }); - }); - await act(async () => { - jest.runAllTimers(); - await Promise.resolve(); - wrapper.update(); - }); - expect(wrapper.render()).toMatchSnapshot(); - jest.useRealTimers(); + [ + { name: 'with data', data }, + { name: 'without data', data: [] }, + ].forEach(({ name, data: testData }) => { + it(`${scrollName} - ${name}`, async () => { + jest.useFakeTimers(); + const wrapper = mount(
); + + act(() => { + wrapper + .find('table ResizeObserver') + .first() + .props() + .onResize({ width: 93, offsetWidth: 93 }); }); - }, + await act(async () => { + jest.runAllTimers(); + await Promise.resolve(); + wrapper.update(); + }); + expect(wrapper.render()).toMatchSnapshot(); + jest.useRealTimers(); + }); + }); + }); + + it('all column has width should use it', () => { + const wrapper = mount( +
, ); + + expect(wrapper.find('colgroup').render()).toMatchSnapshot(); }); }); diff --git a/tests/__snapshots__/FixedColumn.spec.js.snap b/tests/__snapshots__/FixedColumn.spec.js.snap index ff835cedb..b0b7529ce 100644 --- a/tests/__snapshots__/FixedColumn.spec.js.snap +++ b/tests/__snapshots__/FixedColumn.spec.js.snap @@ -695,6 +695,17 @@ exports[`Table.FixedColumn fixed column renders correctly RTL 1`] = ` `; +exports[`Table.FixedColumn renders correctly all column has width should use it 1`] = ` ++ + + +`; + exports[`Table.FixedColumn renders correctly scrollX - with data 1`] = `
-
- - - - - - - - - - - - - -