Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions assets/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -281,4 +281,10 @@
border-top: 0;
padding: @cell-padding;
}

tfoot {
td {
background: #fff;
}
}
}
14 changes: 14 additions & 0 deletions examples/fixedColumns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,20 @@ const Demo = () => (
expandedRowRender={({ b, c }) => b || c}
scroll={{ x: 1200 }}
data={data}
summary={() => (
<>
<Table.Summary.Row>
<Table.Summary.Cell index={0} />
<Table.Summary.Cell index={1} colSpan={2}>
Summary
</Table.Summary.Cell>
<Table.Summary.Cell index={3} colSpan={9}>
Content
</Table.Summary.Cell>
<Table.Summary.Cell index={12}>Right</Table.Summary.Cell>
</Table.Summary.Row>
</>
)}
/>
</div>
);
Expand Down
25 changes: 6 additions & 19 deletions src/Body/BodyRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,14 @@ 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<RecordType> {
record: RecordType;
index: number;
className?: string;
style?: React.CSSProperties;
stickyOffsets: StickyOffsets;
recordKey: Key;
expandedKeys: Set<Key>;
rowComponent: CustomizeComponent;
Expand All @@ -37,19 +28,19 @@ function BodyRow<RecordType extends { children?: RecordType[] }>(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,
Expand All @@ -68,23 +59,19 @@ function BodyRow<RecordType extends { children?: RecordType[] }>(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) {
setExpandRended(true);
}
}, [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 ===========================
Expand Down
6 changes: 1 addition & 5 deletions src/Body/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -12,7 +12,6 @@ export interface BodyProps<RecordType> {
data: RecordType[];
getRowKey: GetRowKey<RecordType>;
measureColumnWidth: boolean;
stickyOffsets: StickyOffsets;
expandedKeys: Set<Key>;
onRow: GetComponentProps<RecordType>;
rowExpandable: (record: RecordType) => boolean;
Expand All @@ -24,7 +23,6 @@ function Body<RecordType>({
data,
getRowKey,
measureColumnWidth,
stickyOffsets,
expandedKeys,
onRow,
rowExpandable,
Expand Down Expand Up @@ -56,7 +54,6 @@ function Body<RecordType>({
index={index}
rowComponent={trComponent}
cellComponent={tdComponent}
stickyOffsets={stickyOffsets}
expandedKeys={expandedKeys}
onRow={onRow}
getRowKey={getRowKey}
Expand Down Expand Up @@ -112,7 +109,6 @@ function Body<RecordType>({
prefixCls,
onRow,
measureColumnWidth,
stickyOffsets,
expandedKeys,
getRowKey,
getComponent,
Expand Down
42 changes: 42 additions & 0 deletions src/Footer/Cell.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<Cell
className={className}
index={index}
component="td"
prefixCls={prefixCls}
record={null}
dataIndex={null}
render={() => ({
children,
props: {
colSpan,
rowSpan,
},
})}
{...fixedInfo}
/>
);
}
11 changes: 11 additions & 0 deletions src/Footer/Row.tsx
Original file line number Diff line number Diff line change
@@ -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 <tr {...props} />;
}
15 changes: 12 additions & 3 deletions src/Footer/index.tsx
Original file line number Diff line number Diff line change
@@ -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<RecordType> {
children: React.ReactNode;
}

function Footer({ children }: FooterProps) {
return <tfoot>{children}</tfoot>;
function Footer<RecordType>({ children }: FooterProps<RecordType>) {
const { prefixCls } = React.useContext(TableContext);
return <tfoot className={`${prefixCls}-summary`}>{children}</tfoot>;
}

export default Footer;

export const FooterComponents = {
Cell,
Row,
};
11 changes: 8 additions & 3 deletions src/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [];
Expand Down Expand Up @@ -503,7 +504,6 @@ function Table<RecordType extends DefaultRecordType>(props: TableProps<RecordTyp
<Body
data={mergedData}
measureColumnWidth={fixHeader || horizonScroll}
stickyOffsets={stickyOffsets}
expandedKeys={mergedExpandedKeys}
rowExpandable={rowExpandable}
getRowKey={getRowKey}
Expand Down Expand Up @@ -661,8 +661,11 @@ function Table<RecordType extends DefaultRecordType>(props: TableProps<RecordTyp
getComponent,
scrollbarSize,
direction,
fixedInfoList: flattenColumns.map((_, colIndex) =>
getCellFixedInfo(colIndex, colIndex, flattenColumns, stickyOffsets, direction),
),
}),
[prefixCls, getComponent, scrollbarSize, direction],
[prefixCls, getComponent, scrollbarSize, direction, flattenColumns, stickyOffsets, direction],
);

const BodyContextValue = React.useMemo(
Expand Down Expand Up @@ -717,6 +720,8 @@ Table.Column = Column;

Table.ColumnGroup = ColumnGroup;

Table.Summary = FooterComponents;

Table.defaultProps = {
rowKey: 'key',
prefixCls: 'rc-table',
Expand Down
4 changes: 4 additions & 0 deletions src/context/TableContext.tsx
Original file line number Diff line number Diff line change
@@ -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<TableContextProps>(null);
Expand Down
3 changes: 2 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -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;
47 changes: 36 additions & 11 deletions tests/Table.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,18 +144,43 @@ describe('Table.Basic', () => {
).toEqual('footer');
});

it('render summary correctly', () => {
const wrapper = mount(
createTable({
summary: () => (
<tr className="summary">
<td>Good</td>
</tr>
),
}),
);
describe('summary', () => {
it('render correctly', () => {
const wrapper = mount(
createTable({
summary: () => (
<tr className="summary">
<td>Good</td>
</tr>
),
}),
);

expect(wrapper.find('tfoot').text()).toEqual('Good');
});

expect(wrapper.find('tfoot').text()).toEqual('Good');
it('support data type', () => {
const wrapper = mount(
<Table
columns={[
{ dataIndex: 'a', fixed: 'left', width: 10 },
{ dataIndex: 'b', fixed: 'left', width: 20 },
{ dataIndex: 'c', width: 30 },
]}
data={[{ key: 1, a: 2, b: 3, c: 4 }]}
summary={() => (
<Table.Summary.Row>
<Table.Summary.Cell colSpan={2} index={0}>
Light
</Table.Summary.Cell>
<Table.Summary.Cell index={2}>Bamboo</Table.Summary.Cell>
</Table.Summary.Row>
)}
/>,
);

expect(wrapper.find('tfoot').render()).toMatchSnapshot();
});
});

it('renders with id correctly', () => {
Expand Down
21 changes: 21 additions & 0 deletions tests/__snapshots__/Table.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,27 @@ exports[`Table.Basic renders rowSpan correctly 1`] = `
</div>
`;

exports[`Table.Basic summary support data type 1`] = `
<tfoot
class="rc-table-summary"
>
<tr>
<td
class="rc-table-cell rc-table-cell-fix-left"
colspan="2"
style="position: sticky; left: 0px;"
>
Light
</td>
<td
class="rc-table-cell"
>
Bamboo
</td>
</tr>
</tfoot>
`;

exports[`Table.Basic syntactic sugar 1`] = `
<div
class="rc-table"
Expand Down