diff --git a/assets/index.less b/assets/index.less index 3115f72a3..510ec4f1a 100644 --- a/assets/index.less +++ b/assets/index.less @@ -281,4 +281,10 @@ border-top: 0; padding: @cell-padding; } + + tfoot { + td { + background: #fff; + } + } } diff --git a/examples/fixedColumns.tsx b/examples/fixedColumns.tsx index 88f86989c..d16faa21b 100644 --- a/examples/fixedColumns.tsx +++ b/examples/fixedColumns.tsx @@ -63,6 +63,20 @@ const Demo = () => ( expandedRowRender={({ b, c }) => b || c} scroll={{ x: 1200 }} data={data} + summary={() => ( + <> + + + + Summary + + + Content + + Right + + + )} /> ); diff --git a/src/Body/BodyRow.tsx b/src/Body/BodyRow.tsx index ba2b3615b..412172393 100644 --- a/src/Body/BodyRow.tsx +++ b/src/Body/BodyRow.tsx @@ -4,15 +4,7 @@ import Cell from '../Cell'; import TableContext from '../context/TableContext'; import BodyContext from '../context/BodyContext'; import { getColumnsKey } from '../utils/valueUtil'; -import { - ColumnType, - StickyOffsets, - CustomizeComponent, - GetComponentProps, - Key, - GetRowKey, -} from '../interface'; -import { getCellFixedInfo } from '../utils/fixUtil'; +import { ColumnType, CustomizeComponent, GetComponentProps, Key, GetRowKey } from '../interface'; import ExpandedRow from './ExpandedRow'; export interface BodyRowProps { @@ -20,7 +12,6 @@ export interface BodyRowProps { index: number; className?: string; style?: React.CSSProperties; - stickyOffsets: StickyOffsets; recordKey: Key; expandedKeys: Set; rowComponent: CustomizeComponent; @@ -37,19 +28,19 @@ function BodyRow(props: BodyRowP const { className, style, - stickyOffsets, record, index, rowKey, getRowKey, rowExpandable, + expandedKeys, onRow, indent = 0, rowComponent: RowComponent, cellComponent, childrenColumnName, } = props; - const { prefixCls, direction } = React.useContext(TableContext); + const { prefixCls, fixedInfoList } = React.useContext(TableContext); const { fixHeader, fixColumn, @@ -68,7 +59,7 @@ function BodyRow(props: BodyRowP } = React.useContext(BodyContext); const [expandRended, setExpandRended] = React.useState(false); - const expanded = props.expandedKeys.has(props.recordKey); + const expanded = expandedKeys && expandedKeys.has(props.recordKey); React.useEffect(() => { if (expanded) { @@ -76,15 +67,11 @@ function BodyRow(props: BodyRowP } }, [expanded]); - // Move to Body to enhance performance - const fixedInfoList = flattenColumns.map((column, colIndex) => - getCellFixedInfo(colIndex, colIndex, flattenColumns, stickyOffsets, direction), - ); - const rowSupportExpand = expandableType === 'row' && (!rowExpandable || rowExpandable(record)); // Only when row is not expandable and `children` exist in record const nestExpandable = expandableType === 'nest'; - const hasNestChildren = childrenColumnName in record && record[childrenColumnName]; + const hasNestChildren = + childrenColumnName && childrenColumnName in record && record[childrenColumnName]; const mergedExpandable = rowSupportExpand || nestExpandable; // =========================== onRow =========================== diff --git a/src/Body/index.tsx b/src/Body/index.tsx index 96cf62994..140b438c9 100644 --- a/src/Body/index.tsx +++ b/src/Body/index.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import ResizeObserver from 'rc-resize-observer'; import BodyRow from './BodyRow'; import TableContext from '../context/TableContext'; -import { GetRowKey, StickyOffsets, Key, GetComponentProps } from '../interface'; +import { GetRowKey, Key, GetComponentProps } from '../interface'; import ExpandedRow from './ExpandedRow'; import BodyContext from '../context/BodyContext'; import { getColumnsKey } from '../utils/valueUtil'; @@ -12,7 +12,6 @@ export interface BodyProps { data: RecordType[]; getRowKey: GetRowKey; measureColumnWidth: boolean; - stickyOffsets: StickyOffsets; expandedKeys: Set; onRow: GetComponentProps; rowExpandable: (record: RecordType) => boolean; @@ -24,7 +23,6 @@ function Body({ data, getRowKey, measureColumnWidth, - stickyOffsets, expandedKeys, onRow, rowExpandable, @@ -56,7 +54,6 @@ function Body({ index={index} rowComponent={trComponent} cellComponent={tdComponent} - stickyOffsets={stickyOffsets} expandedKeys={expandedKeys} onRow={onRow} getRowKey={getRowKey} @@ -112,7 +109,6 @@ function Body({ prefixCls, onRow, measureColumnWidth, - stickyOffsets, expandedKeys, getRowKey, getComponent, diff --git a/src/Footer/Cell.tsx b/src/Footer/Cell.tsx new file mode 100644 index 000000000..f85dd55e6 --- /dev/null +++ b/src/Footer/Cell.tsx @@ -0,0 +1,42 @@ +import * as React from 'react'; +import Cell from '../Cell'; +import TableContext from '../context/TableContext'; + +export interface SummaryCellProps { + className?: string; + children?: React.ReactNode; + index: number; + colSpan?: number; + rowSpan?: number; +} + +export default function SummaryCell({ + className, + index, + children, + colSpan, + rowSpan, +}: SummaryCellProps) { + const { prefixCls, fixedInfoList } = React.useContext(TableContext); + + const fixedInfo = fixedInfoList[index]; + + return ( + ({ + children, + props: { + colSpan, + rowSpan, + }, + })} + {...fixedInfo} + /> + ); +} diff --git a/src/Footer/Row.tsx b/src/Footer/Row.tsx new file mode 100644 index 000000000..e86a8b46e --- /dev/null +++ b/src/Footer/Row.tsx @@ -0,0 +1,11 @@ +import * as React from 'react'; + +export interface FooterRowProps { + children?: React.ReactNode; + className?: string; + style?: React.CSSProperties; +} + +export default function FooterRow(props: FooterRowProps) { + return ; +} diff --git a/src/Footer/index.tsx b/src/Footer/index.tsx index 22a9b6451..732ae5a0c 100644 --- a/src/Footer/index.tsx +++ b/src/Footer/index.tsx @@ -1,11 +1,20 @@ import * as React from 'react'; +import TableContext from '../context/TableContext'; +import Cell from './Cell'; +import Row from './Row'; -export interface FooterProps { +export interface FooterProps { children: React.ReactNode; } -function Footer({ children }: FooterProps) { - return {children}; +function Footer({ children }: FooterProps) { + const { prefixCls } = React.useContext(TableContext); + return {children}; } export default Footer; + +export const FooterComponents = { + Cell, + Row, +}; diff --git a/src/Table.tsx b/src/Table.tsx index e59c267eb..b0cb746aa 100644 --- a/src/Table.tsx +++ b/src/Table.tsx @@ -64,8 +64,9 @@ import useStickyOffsets from './hooks/useStickyOffsets'; import ColGroup from './ColGroup'; import { getExpandableProps, getDataAndAriaProps } from './utils/legacyUtil'; import Panel from './Panel'; -import Footer from './Footer'; +import Footer, { FooterComponents } from './Footer'; import { findAllChildrenKeys, renderExpandIcon } from './utils/expandUtil'; +import { getCellFixedInfo } from './utils/fixUtil'; // Used for conditions cache const EMPTY_DATA = []; @@ -503,7 +504,6 @@ function Table(props: TableProps(props: TableProps + getCellFixedInfo(colIndex, colIndex, flattenColumns, stickyOffsets, direction), + ), }), - [prefixCls, getComponent, scrollbarSize, direction], + [prefixCls, getComponent, scrollbarSize, direction, flattenColumns, stickyOffsets, direction], ); const BodyContextValue = React.useMemo( @@ -717,6 +720,8 @@ Table.Column = Column; Table.ColumnGroup = ColumnGroup; +Table.Summary = FooterComponents; + Table.defaultProps = { rowKey: 'key', prefixCls: 'rc-table', diff --git a/src/context/TableContext.tsx b/src/context/TableContext.tsx index e089f4e98..cf9a9ee7a 100644 --- a/src/context/TableContext.tsx +++ b/src/context/TableContext.tsx @@ -1,14 +1,18 @@ import * as React from 'react'; import { GetComponent } from '../interface'; +import { FixedInfo } from '../utils/fixUtil'; export interface TableContextProps { // Table context prefixCls: string; + getComponent: GetComponent; scrollbarSize: number; direction: 'ltr' | 'rtl'; + + fixedInfoList: FixedInfo[]; } const TableContext = React.createContext(null); diff --git a/src/index.ts b/src/index.ts index 5a87a23e8..f094e67c4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,8 +1,9 @@ import Table from './Table'; +import { FooterComponents as Summary } from './Footer'; import Column from './sugar/Column'; import ColumnGroup from './sugar/ColumnGroup'; import { INTERNAL_COL_DEFINE } from './utils/legacyUtil'; -export { Column, ColumnGroup, INTERNAL_COL_DEFINE }; +export { Summary, Column, ColumnGroup, INTERNAL_COL_DEFINE }; export default Table; diff --git a/tests/Table.spec.js b/tests/Table.spec.js index 1f9335aa2..8d9633e64 100644 --- a/tests/Table.spec.js +++ b/tests/Table.spec.js @@ -144,18 +144,43 @@ describe('Table.Basic', () => { ).toEqual('footer'); }); - it('render summary correctly', () => { - const wrapper = mount( - createTable({ - summary: () => ( - - Good - - ), - }), - ); + describe('summary', () => { + it('render correctly', () => { + const wrapper = mount( + createTable({ + summary: () => ( + + Good + + ), + }), + ); + + expect(wrapper.find('tfoot').text()).toEqual('Good'); + }); - expect(wrapper.find('tfoot').text()).toEqual('Good'); + it('support data type', () => { + const wrapper = mount( + ( + + + Light + + Bamboo + + )} + />, + ); + + expect(wrapper.find('tfoot').render()).toMatchSnapshot(); + }); }); it('renders with id correctly', () => { diff --git a/tests/__snapshots__/Table.spec.js.snap b/tests/__snapshots__/Table.spec.js.snap index 34bcaa619..a1e6c12d7 100644 --- a/tests/__snapshots__/Table.spec.js.snap +++ b/tests/__snapshots__/Table.spec.js.snap @@ -663,6 +663,27 @@ exports[`Table.Basic renders rowSpan correctly 1`] = ` `; +exports[`Table.Basic summary support data type 1`] = ` + + + + + + +`; + exports[`Table.Basic syntactic sugar 1`] = `
+ Light + + Bamboo +