diff --git a/.npmrc b/.npmrc new file mode 100644 index 000000000..c483022c0 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +shamefully-hoist=true \ No newline at end of file diff --git a/docs/examples/stickyHeader.tsx b/docs/examples/stickyHeader.tsx index 817ff86bc..52f285675 100644 --- a/docs/examples/stickyHeader.tsx +++ b/docs/examples/stickyHeader.tsx @@ -2,7 +2,7 @@ import React, { useRef } from 'react'; import Table from 'rc-table'; import '../../assets/index.less'; -import type { ColumnType } from '@/interface'; +import type { ColumnType, ColumnsType } from '@/interface'; interface RecordType { a?: string; @@ -79,6 +79,41 @@ const columns: ColumnType[] = [ }, ]; +const columnsWithWidth: ColumnType[] = [ + { title: 'title1', dataIndex: 'a', key: 'a', width: 100 }, + { title: 'title2', dataIndex: 'b', key: 'b', width: 100 }, + { title: 'title3', dataIndex: 'c', key: 'c', width: 200 }, + { title: 'title4', dataIndex: 'd', key: 'd', width: 100 }, +]; + +const columnsGrouped: ColumnsType = [ + { + title: '', + dataIndex: 'productType', + key: 'productType', + rowSpan: 2, + rowScope: 'row', + }, + { + title: 'Mars', + dataIndex: 'mars', + key: 'mars', + children: [ + { title: 'ProducedProducedProduced', dataIndex: 'producedMars', key: 'producedMars' }, + { title: 'Sold', dataIndex: 'soldMars', key: 'soldMars' }, + ], + }, + { + title: 'Venus', + dataIndex: 'venus', + key: 'venus', + children: [ + { title: 'Produced Produced', dataIndex: 'producedVenus', key: 'producedVenus' }, + { title: 'Sold Sold Sold Sold', dataIndex: 'soldVenus', key: 'soldVenus' }, + ], + }, +]; + const data = [ { a: '123', key: '1' }, { a: 'cdd', b: 'edd', key: '2' }, @@ -105,11 +140,7 @@ const data = [ const Demo = () => { const container = useRef(); return ( -
+

Sticky

columns={columns} @@ -212,6 +243,79 @@ const Demo = () => { suscipit asperiores, id ullam in iste soluta dignissimos vero incidunt, rem ex consectetur beatae totam aperiam. Sunt, laudantium?
+ +

Sticky header with empty data

+ +
+
+
+
+
+
+
+
+
+
({ ...column, width: undefined }))} + data={[]} + scroll={{ + x: 'max-content', + }} + sticky + /> +
+
({ ...column, width: undefined }))} + data={[{}]} + scroll={{ + x: 'max-content', + }} + sticky + /> +
+
); }; diff --git a/package.json b/package.json index ed4cad18d..252cdc2fc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@rc-component/table", - "version": "1.5.2", + "version": "1.5.3", "description": "table ui component for react", "engines": { "node": ">=8.x" diff --git a/src/Body/MeasureCell.tsx b/src/Body/MeasureCell.tsx index b3015c5f2..3cb7fee7a 100644 --- a/src/Body/MeasureCell.tsx +++ b/src/Body/MeasureCell.tsx @@ -1,13 +1,15 @@ import * as React from 'react'; import ResizeObserver from '@rc-component/resize-observer'; import useLayoutEffect from '@rc-component/util/lib/hooks/useLayoutEffect'; +import type { ColumnType } from '../interface'; export interface MeasureCellProps { columnKey: React.Key; onColumnResize: (key: React.Key, width: number) => void; + column?: ColumnType; } -export default function MeasureCell({ columnKey, onColumnResize }: MeasureCellProps) { +export default function MeasureCell({ columnKey, onColumnResize, column }: MeasureCellProps) { const cellRef = React.useRef(); useLayoutEffect(() => { @@ -18,8 +20,13 @@ export default function MeasureCell({ columnKey, onColumnResize }: MeasureCellPr return ( - ); diff --git a/src/Body/MeasureRow.tsx b/src/Body/MeasureRow.tsx index d5b38b0e0..ea9c55ce5 100644 --- a/src/Body/MeasureRow.tsx +++ b/src/Body/MeasureRow.tsx @@ -2,23 +2,25 @@ import * as React from 'react'; import ResizeObserver from '@rc-component/resize-observer'; import MeasureCell from './MeasureCell'; import isVisible from '@rc-component/util/lib/Dom/isVisible'; +import type { ColumnType } from '../interface'; -export interface MeasureCellProps { +export interface MeasureRowProps { prefixCls: string; onColumnResize: (key: React.Key, width: number) => void; columnsKey: React.Key[]; + columns: readonly ColumnType[]; } -export default function MeasureRow({ prefixCls, columnsKey, onColumnResize }: MeasureCellProps) { +export default function MeasureRow({ + prefixCls, + columnsKey, + onColumnResize, + columns, +}: MeasureRowProps) { const ref = React.useRef(null); return ( - + { if (isVisible(ref.current)) { @@ -28,9 +30,17 @@ export default function MeasureRow({ prefixCls, columnsKey, onColumnResize }: Me } }} > - {columnsKey.map(columnKey => ( - - ))} + {columnsKey.map(columnKey => { + const column = columns.find(col => col.key === columnKey); + return ( + + ); + })} ); diff --git a/src/Body/index.tsx b/src/Body/index.tsx index 58453439c..a33a9cdac 100644 --- a/src/Body/index.tsx +++ b/src/Body/index.tsx @@ -146,6 +146,7 @@ function Body(props: BodyProps) { prefixCls={prefixCls} columnsKey={columnsKey} onColumnResize={onColumnResize} + columns={flattenColumns} /> )} diff --git a/src/ColGroup.tsx b/src/ColGroup.tsx index a20e58c28..6c49f304f 100644 --- a/src/ColGroup.tsx +++ b/src/ColGroup.tsx @@ -22,7 +22,7 @@ function ColGroup({ colWidths, columns, columCount }: ColGroupProps< for (let i = len - 1; i >= 0; i -= 1) { const width = colWidths[i]; const column = columns && columns[i]; - let additionalProps; + let additionalProps: Record; let minWidth: number; if (column) { additionalProps = column[INTERNAL_COL_DEFINE]; diff --git a/src/FixedHolder/index.tsx b/src/FixedHolder/index.tsx index a4c8e32c8..814c188fe 100644 --- a/src/FixedHolder/index.tsx +++ b/src/FixedHolder/index.tsx @@ -7,7 +7,7 @@ import ColGroup from '../ColGroup'; import TableContext from '../context/TableContext'; import type { HeaderProps } from '../Header/Header'; import devRenderTimes from '../hooks/useRenderTimes'; -import type { ColumnsType, ColumnType, Direction } from '../interface'; +import type { ColumnsType, ColumnType, Direction, TableLayout } from '../interface'; function useColumnWidth(colWidths: readonly number[], columCount: number) { return useMemo(() => { @@ -36,6 +36,8 @@ export interface FixedHeaderProps extends HeaderProps { stickyTopOffset?: number; stickyBottomOffset?: number; stickyClassName?: string; + scrollTableStyle?: React.CSSProperties; + tableLayout?: TableLayout; onScroll: (info: { currentTarget: HTMLDivElement; scrollLeft?: number }) => void; children: (info: HeaderProps) => React.ReactNode; } @@ -59,6 +61,8 @@ const FixedHolder = React.forwardRef>((pro stickyTopOffset, stickyBottomOffset, stickyClassName, + scrollTableStyle, + tableLayout = 'fixed', onScroll, maxContentScroll, children, @@ -115,12 +119,6 @@ const FixedHolder = React.forwardRef>((pro }; }, []); - // Check if all flattenColumns has width - const allFlattenColumnsWithWidth = React.useMemo( - () => flattenColumns.every(column => column.width), - [flattenColumns], - ); - // Add scrollbar column const lastColumn = flattenColumns[flattenColumns.length - 1]; const ScrollBarColumn: ColumnType & { scrollbar: true } = { @@ -158,6 +156,32 @@ const FixedHolder = React.forwardRef>((pro const mergedColumnWidth = useColumnWidth(colWidths, columCount); + const colGroupNode = useMemo(() => { + // use original ColGroup if no data or no calculated column width, otherwise use calculated column width + // Return original colGroup if no data, or mergedColumnWidth is empty, or all widths are falsy + if ( + noData || + !mergedColumnWidth || + mergedColumnWidth.length === 0 || + mergedColumnWidth.every(width => !width) + ) { + return ColGroup; + } + return ( + + ); + }, [ + noData, + mergedColumnWidth, + combinationScrollBarSize, + columCount, + flattenColumnsWithScrollbar, + ]); + return (
>((pro > - {(!noData || !maxContentScroll || allFlattenColumnsWithWidth) && ( -
- )} + {colGroupNode} {children({ ...restProps, stickyOffsets: headerStickyOffsets, diff --git a/src/Table.tsx b/src/Table.tsx index d2e3d5c73..0dc33e98e 100644 --- a/src/Table.tsx +++ b/src/Table.tsx @@ -719,6 +719,8 @@ function Table( ...columnContext, direction, stickyClassName, + scrollTableStyle, + tableLayout: mergedTableLayout, onScroll: onInternalScroll, }; diff --git a/tests/__snapshots__/ExpandRow.spec.jsx.snap b/tests/__snapshots__/ExpandRow.spec.jsx.snap index bedeb127d..51d854a1f 100644 --- a/tests/__snapshots__/ExpandRow.spec.jsx.snap +++ b/tests/__snapshots__/ExpandRow.spec.jsx.snap @@ -158,42 +158,42 @@ exports[`Table.Expand > does not crash if scroll is not set 1`] = ` @@ -313,42 +313,42 @@ exports[`Table.Expand > does not crash if scroll is not set 2`] = ` @@ -557,42 +557,42 @@ exports[`Table.Expand > renders fixed column correctly > work 1`] = ` @@ -1023,42 +1023,42 @@ exports[`Table.Expand > work in expandable fix 1`] = ` @@ -1181,40 +1181,40 @@ exports[`Table.Expand > work in expandable fix 2`] = ` @@ -917,114 +917,114 @@ exports[`Table.FixedColumn > renders correctly > scrollX - with data 1`] = ` @@ -1706,114 +1706,114 @@ exports[`Table.FixedColumn > renders correctly > scrollX - without data 1`] = ` @@ -1851,7 +1851,7 @@ exports[`Table.FixedColumn > renders correctly > scrollXY - with data 1`] = ` style="overflow: hidden;" >
-
 
+
+
+ {column?.title || '\xa0'} +
renders correctly > scrollXY - with data 1`] = ` @@ -2694,49 +2694,8 @@ exports[`Table.FixedColumn > renders correctly > scrollXY - without data 1`] = ` style="overflow: hidden;" >
- - - - - - - - - - - - - - - @@ -2862,114 +2821,114 @@ exports[`Table.FixedColumn > renders correctly > scrollXY - without data 1`] = ` diff --git a/tests/__snapshots__/Table.spec.jsx.snap b/tests/__snapshots__/Table.spec.jsx.snap index 29c6638b5..5fd5ed333 100644 --- a/tests/__snapshots__/Table.spec.jsx.snap +++ b/tests/__snapshots__/Table.spec.jsx.snap @@ -86,22 +86,8 @@ exports[`Table.Basic > custom components > renders fixed column and header corre style="overflow: hidden;" >
- - - - - - custom components > renders fixed column and header corre @@ -232,7 +218,7 @@ exports[`Table.Basic > custom components > scroll content > with scroll 1`] = ` style="overflow: hidden;" >