Skip to content

Commit 4040edf

Browse files
committed
support components
1 parent 8fd21ea commit 4040edf

File tree

9 files changed

+150
-59
lines changed

9 files changed

+150
-59
lines changed

docs/examples/components.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,18 @@ const Demo = () => {
2424
return (
2525
<div>
2626
<Table
27+
classNames={{
28+
body: {
29+
wrapper: 'test-body-wrapper',
30+
cell: 'test-body-cell',
31+
row: 'test-body-row',
32+
},
33+
header: {
34+
wrapper: 'test-header-wrapper',
35+
cell: 'test-header-cell',
36+
row: 'test-header-row',
37+
},
38+
}}
2739
components={{ header: { table } }}
2840
sticky
2941
columns={[

src/Body/BodyRow.tsx

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import classNames from 'classnames';
1+
import cls from 'classnames';
22
import * as React from 'react';
33
import Cell from '../Cell';
4-
import { responseImmutable } from '../context/TableContext';
4+
import { useContext } from '@rc-component/context';
5+
import TableContext, { responseImmutable } from '../context/TableContext';
56
import devRenderTimes from '../hooks/useRenderTimes';
67
import useRowInfo from '../hooks/useRowInfo';
78
import type { ColumnType, CustomizeComponent } from '../interface';
@@ -19,6 +20,7 @@ export interface BodyRowProps<RecordType> {
1920
scopeCellComponent: CustomizeComponent;
2021
indent?: number;
2122
rowKey: React.Key;
23+
rowType?: 'header' | 'body' | 'footer';
2224
}
2325

2426
// ==================================================================================
@@ -90,7 +92,6 @@ function BodyRow<RecordType extends { children?: readonly RecordType[] }>(
9092
if (process.env.NODE_ENV !== 'production') {
9193
devRenderTimes(props);
9294
}
93-
9495
const {
9596
className,
9697
style,
@@ -102,7 +103,11 @@ function BodyRow<RecordType extends { children?: readonly RecordType[] }>(
102103
rowComponent: RowComponent,
103104
cellComponent,
104105
scopeCellComponent,
106+
rowType,
105107
} = props;
108+
const { classNames, styles } = useContext(TableContext, ['classNames', 'styles']);
109+
const { body: bodyCls, header: headerCls } = classNames || {};
110+
const { body: bodyStyles, header: headerStyles } = styles || {};
106111
const rowInfo = useRowInfo(record, rowKey, index, indent);
107112
const {
108113
prefixCls,
@@ -133,16 +138,23 @@ function BodyRow<RecordType extends { children?: readonly RecordType[] }>(
133138
<RowComponent
134139
{...rowProps}
135140
data-row-key={rowKey}
136-
className={classNames(
141+
className={cls(
137142
className,
138143
`${prefixCls}-row`,
139144
`${prefixCls}-row-level-${indent}`,
140145
rowProps?.className,
141146
{
147+
[headerCls?.row]: headerCls?.row && rowType === 'header',
148+
[bodyCls?.row]: bodyCls?.row && rowType === 'body',
142149
[expandedClsName]: indent >= 1,
143150
},
144151
)}
145-
style={{ ...style, ...rowProps?.style }}
152+
style={{
153+
...style,
154+
...rowProps?.style,
155+
...(rowType === 'header' && headerStyles?.row),
156+
...(rowType === 'body' && bodyStyles?.row),
157+
}}
146158
>
147159
{flattenColumns.map((column: ColumnType<RecordType>, colIndex) => {
148160
const { render, dataIndex, className: columnClassName } = column;
@@ -157,6 +169,7 @@ function BodyRow<RecordType extends { children?: readonly RecordType[] }>(
157169

158170
return (
159171
<Cell<RecordType>
172+
rowType="body"
160173
className={columnClassName}
161174
ellipsis={column.ellipsis}
162175
align={column.align}
@@ -187,7 +200,7 @@ function BodyRow<RecordType extends { children?: readonly RecordType[] }>(
187200
expandRowNode = (
188201
<ExpandedRow
189202
expanded={expanded}
190-
className={classNames(
203+
className={cls(
191204
`${prefixCls}-expanded-row`,
192205
`${prefixCls}-expanded-row-level-${indent + 1}`,
193206
expandedClsName,

src/Body/index.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { getColumnsKey } from '../utils/valueUtil';
99
import BodyRow from './BodyRow';
1010
import ExpandedRow from './ExpandedRow';
1111
import MeasureRow from './MeasureRow';
12+
import cls from 'classnames';
1213

1314
export interface BodyProps<RecordType> {
1415
data: readonly RecordType[];
@@ -31,6 +32,8 @@ function Body<RecordType>(props: BodyProps<RecordType>) {
3132
expandedKeys,
3233
childrenColumnName,
3334
emptyNode,
35+
classNames,
36+
styles,
3437
} = useContext(TableContext, [
3538
'prefixCls',
3639
'getComponent',
@@ -40,7 +43,11 @@ function Body<RecordType>(props: BodyProps<RecordType>) {
4043
'expandedKeys',
4144
'childrenColumnName',
4245
'emptyNode',
46+
'classNames',
47+
'styles',
4348
]);
49+
const { body: bodyCls } = classNames || {};
50+
const { body: bodyStyles } = styles || {};
4451

4552
const flattenData: { record: RecordType; indent: number; index: number }[] =
4653
useFlattenRecords<RecordType>(data, childrenColumnName, expandedKeys, getRowKey);
@@ -66,6 +73,7 @@ function Body<RecordType>(props: BodyProps<RecordType>) {
6673
return (
6774
<BodyRow
6875
key={key}
76+
rowType="body"
6977
rowKey={key}
7078
record={record}
7179
index={idx}
@@ -97,7 +105,10 @@ function Body<RecordType>(props: BodyProps<RecordType>) {
97105

98106
return (
99107
<PerfContext.Provider value={perfRef.current}>
100-
<WrapperComponent className={`${prefixCls}-tbody`}>
108+
<WrapperComponent
109+
className={cls(`${prefixCls}-tbody`, bodyCls?.wrapper)}
110+
style={bodyStyles?.wrapper}
111+
>
101112
{/* Measure body column width with additional hidden col */}
102113
{measureColumnWidth && (
103114
<MeasureRow

src/Cell/index.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ function Cell<RecordType>(props: CellProps<RecordType>) {
129129
'classNames',
130130
'styles',
131131
]);
132+
const { body: bodyCls, header: headerCls } = classNames || {};
133+
const { body: bodyStyles, header: headerStyles } = styles || {};
132134

133135
// ====================== Value =======================
134136
const [childNode, legacyCellProps] = useCellRender(
@@ -220,6 +222,9 @@ function Cell<RecordType>(props: CellProps<RecordType>) {
220222
classNames?.item,
221223
className,
222224
{
225+
[headerCls?.cell]: headerCls?.cell && rowType === 'header',
226+
[bodyCls?.cell]: bodyCls?.cell && rowType === 'body',
227+
223228
// Fixed
224229
[`${cellPrefixCls}-fix`]: isFixStart || isFixEnd,
225230
[`${cellPrefixCls}-fix-start`]: isFixStart,
@@ -254,7 +259,10 @@ function Cell<RecordType>(props: CellProps<RecordType>) {
254259
...alignStyle,
255260
...additionalProps.style,
256261
...styles?.item,
262+
...(rowType === 'header' && headerStyles?.cell),
263+
...(rowType === 'body' && bodyStyles?.cell),
257264
};
265+
console.log('rowType', rowType);
258266

259267
// >>>>> Children Node
260268
let mergedChildNode = childNode;

src/Header/Header.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type {
1111
StickyOffsets,
1212
} from '../interface';
1313
import HeaderRow from './HeaderRow';
14+
import cls from 'classnames';
1415

1516
function parseHeaderRows<RecordType>(
1617
rootColumns: ColumnsType<RecordType>,
@@ -97,15 +98,25 @@ const Header = <RecordType extends any>(props: HeaderProps<RecordType>) => {
9798

9899
const { stickyOffsets, columns, flattenColumns, onHeaderRow } = props;
99100

100-
const { prefixCls, getComponent } = useContext(TableContext, ['prefixCls', 'getComponent']);
101+
const { prefixCls, getComponent, classNames, styles } = useContext(TableContext, [
102+
'prefixCls',
103+
'getComponent',
104+
'classNames',
105+
'styles',
106+
]);
107+
const { header: headerCls } = classNames || {};
108+
const { header: headerStyles } = styles || {};
101109
const rows = React.useMemo<CellType<RecordType>[][]>(() => parseHeaderRows(columns), [columns]);
102110

103111
const WrapperComponent = getComponent(['header', 'wrapper'], 'thead');
104112
const trComponent = getComponent(['header', 'row'], 'tr');
105113
const thComponent = getComponent(['header', 'cell'], 'th');
106114

107115
return (
108-
<WrapperComponent className={`${prefixCls}-thead`}>
116+
<WrapperComponent
117+
className={cls(`${prefixCls}-thead`, headerCls?.wrapper)}
118+
style={headerStyles?.wrapper}
119+
>
109120
{rows.map((row, rowIndex) => {
110121
const rowNode = (
111122
<HeaderRow

src/Header/HeaderRow.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,13 @@ const HeaderRow = <RecordType extends any>(props: RowProps<RecordType>) => {
3232
onHeaderRow,
3333
index,
3434
} = props;
35-
const { prefixCls } = useContext(TableContext, ['prefixCls']);
35+
const { prefixCls, styles, classNames } = useContext(TableContext, [
36+
'prefixCls',
37+
'styles',
38+
'classNames',
39+
]);
40+
const { header: headerCls } = classNames || {};
41+
const { header: headerStyles } = styles || {};
3642
let rowProps: React.HTMLAttributes<HTMLElement>;
3743
if (onHeaderRow) {
3844
rowProps = onHeaderRow(
@@ -44,7 +50,7 @@ const HeaderRow = <RecordType extends any>(props: RowProps<RecordType>) => {
4450
const columnsKey = getColumnsKey(cells.map(cell => cell.column));
4551

4652
return (
47-
<RowComponent {...rowProps}>
53+
<RowComponent {...rowProps} className={headerCls?.row} style={headerStyles?.row}>
4854
{cells.map((cell: CellType<RecordType>, cellIndex) => {
4955
const { column } = cell;
5056
const fixedInfo = getCellFixedInfo(

src/Table.tsx

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,21 @@ const EMPTY_DATA = [];
8585
// Used for customize scroll
8686
const EMPTY_SCROLL_TARGET = {};
8787

88-
export type SemanticName = 'section'| 'header' | 'title' | 'footer' | 'body' | 'content' | 'item';
88+
export type SemanticName = 'section' | 'title' | 'footer' | 'content' | 'item';
89+
export type ComponentsSemantic = 'wrapper' | 'cell' | 'row';
8990
export interface TableProps<RecordType = any>
9091
extends Omit<LegacyExpandableProps<RecordType>, 'showExpandColumn'> {
9192
prefixCls?: string;
9293
className?: string;
9394
style?: React.CSSProperties;
94-
classNames?: Partial<Record<SemanticName, string>>;
95-
styles?: Partial<Record<SemanticName, React.CSSProperties>>;
95+
classNames?: Partial<Record<SemanticName, string>> & {
96+
body?: Partial<Record<ComponentsSemantic, string>>;
97+
header?: Partial<Record<ComponentsSemantic, string>>;
98+
};
99+
styles?: Partial<Record<SemanticName, React.CSSProperties>> & {
100+
body?: Partial<Record<ComponentsSemantic, React.CSSProperties>>;
101+
header?: Partial<Record<ComponentsSemantic, React.CSSProperties>>;
102+
};
96103
children?: React.ReactNode;
97104
data?: readonly RecordType[];
98105
columns?: ColumnsType<RecordType>;
@@ -660,11 +667,10 @@ function Table<RecordType extends DefaultRecordType>(
660667
style={{
661668
...scrollXStyle,
662669
...scrollYStyle,
663-
...styles?.body,
664670
}}
665671
onScroll={onBodyScroll}
666672
ref={scrollBodyRef}
667-
className={cls(`${prefixCls}-body`, classNames?.body)}
673+
className={`${prefixCls}-body`}
668674
>
669675
<TableComponent
670676
style={{
@@ -704,8 +710,7 @@ function Table<RecordType extends DefaultRecordType>(
704710
<FixedHolder
705711
{...fixedHolderProps}
706712
stickyTopOffset={offsetHeader}
707-
className={cls(`${prefixCls}-header`, classNames?.header)}
708-
style={styles?.header}
713+
className={`${prefixCls}-header`}
709714
ref={scrollHeaderRef}
710715
>
711716
{renderFixedHeaderTable}
@@ -800,11 +805,23 @@ function Table<RecordType extends DefaultRecordType>(
800805
ref={fullTableRef}
801806
{...dataProps}
802807
>
803-
{title && <Panel className={cls(`${prefixCls}-title`, classNames?.title)} style={styles?.title}>{title(mergedData)}</Panel>}
804-
<div ref={scrollBodyContainerRef} className={cls(`${prefixCls}-container`, classNames?.section)} style={styles?.section}>
808+
{title && (
809+
<Panel className={cls(`${prefixCls}-title`, classNames?.title)} style={styles?.title}>
810+
{title(mergedData)}
811+
</Panel>
812+
)}
813+
<div
814+
ref={scrollBodyContainerRef}
815+
className={cls(`${prefixCls}-container`, classNames?.section)}
816+
style={styles?.section}
817+
>
805818
{groupTableNode}
806819
</div>
807-
{footer && <Panel className={cls(`${prefixCls}-footer`, classNames?.footer)} style={styles?.footer}>{footer(mergedData)}</Panel>}
820+
{footer && (
821+
<Panel className={cls(`${prefixCls}-footer`, classNames?.footer)} style={styles?.footer}>
822+
{footer(mergedData)}
823+
</Panel>
824+
)}
808825
</div>
809826
);
810827

src/context/TableContext.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import type {
1414
TriggerEventHandler,
1515
} from '../interface';
1616
import type { FixedInfo } from '../utils/fixUtil';
17-
import { SemanticName } from '../Table';
17+
import { TableProps } from '../Table';
1818

1919
const { makeImmutable, responseImmutable, useImmutableMark } = createImmutable();
2020
export { makeImmutable, responseImmutable, useImmutableMark };
@@ -24,8 +24,8 @@ export type ScrollInfoType = [scrollLeft: number, scrollRange: number];
2424
export interface TableContextProps<RecordType = any> {
2525
// Scroll
2626
scrollX: number | string | true;
27-
classNames?: Partial<Record<SemanticName, string>>;
28-
styles?: Partial<Record<SemanticName, React.CSSProperties>>;
27+
classNames?: TableProps['classNames'];
28+
styles?: TableProps['styles'];
2929

3030
// Table
3131
prefixCls: string;

0 commit comments

Comments
 (0)