Skip to content

Commit b10f4d4

Browse files
authored
feat: support classNames and styles (#1261)
* feat: support classNames and styles * fix test * support components * opt * rm * opt * fix ts type * rm
1 parent 92dbe91 commit b10f4d4

File tree

12 files changed

+256
-22
lines changed

12 files changed

+256
-22
lines changed

docs/examples/className.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,20 @@ const Demo = () => (
5252
expandedRowClassName={(record, i) => `ex-row-${i}`}
5353
data={data}
5454
className="table"
55+
title={() => <span>title</span>}
56+
footer={() => <span>footer</span>}
57+
/>
58+
<h2>scroll</h2>
59+
<Table
60+
columns={columns}
61+
rowClassName={(record, i) => `row-${i}`}
62+
expandedRowRender={record => <p>extra: {record.a}</p>}
63+
expandedRowClassName={(record, i) => `ex-row-${i}`}
64+
data={Array(5).fill(data)}
65+
className="table"
66+
scroll={{ x: 'calc(700px + 50%)', y: 47 * 5 }}
67+
title={() => <span>title</span>}
68+
footer={() => <span>footer</span>}
5569
/>
5670
</div>
5771
);

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: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import classNames from 'classnames';
1+
import cls from 'classnames';
22
import * as React from 'react';
33
import Cell from '../Cell';
44
import { responseImmutable } from '../context/TableContext';
@@ -7,13 +7,16 @@ import useRowInfo from '../hooks/useRowInfo';
77
import type { ColumnType, CustomizeComponent } from '../interface';
88
import ExpandedRow from './ExpandedRow';
99
import { computedExpandedClassName } from '../utils/expandUtil';
10+
import { TableProps } from '..';
1011

1112
export interface BodyRowProps<RecordType> {
1213
record: RecordType;
1314
index: number;
1415
renderIndex: number;
1516
className?: string;
1617
style?: React.CSSProperties;
18+
classNames: TableProps['classNames']['body'];
19+
styles: TableProps['styles']['body'];
1720
rowComponent: CustomizeComponent;
1821
cellComponent: CustomizeComponent;
1922
scopeCellComponent: CustomizeComponent;
@@ -94,6 +97,8 @@ function BodyRow<RecordType extends { children?: readonly RecordType[] }>(
9497
const {
9598
className,
9699
style,
100+
classNames,
101+
styles,
97102
record,
98103
index,
99104
renderIndex,
@@ -103,6 +108,7 @@ function BodyRow<RecordType extends { children?: readonly RecordType[] }>(
103108
cellComponent,
104109
scopeCellComponent,
105110
} = props;
111+
106112
const rowInfo = useRowInfo(record, rowKey, index, indent);
107113
const {
108114
prefixCls,
@@ -133,16 +139,21 @@ function BodyRow<RecordType extends { children?: readonly RecordType[] }>(
133139
<RowComponent
134140
{...rowProps}
135141
data-row-key={rowKey}
136-
className={classNames(
142+
className={cls(
137143
className,
138144
`${prefixCls}-row`,
139145
`${prefixCls}-row-level-${indent}`,
140146
rowProps?.className,
147+
classNames.row,
141148
{
142149
[expandedClsName]: indent >= 1,
143150
},
144151
)}
145-
style={{ ...style, ...rowProps?.style }}
152+
style={{
153+
...style,
154+
...rowProps?.style,
155+
...styles.row,
156+
}}
146157
>
147158
{flattenColumns.map((column: ColumnType<RecordType>, colIndex) => {
148159
const { render, dataIndex, className: columnClassName } = column;
@@ -157,7 +168,8 @@ function BodyRow<RecordType extends { children?: readonly RecordType[] }>(
157168

158169
return (
159170
<Cell<RecordType>
160-
className={columnClassName}
171+
className={cls(columnClassName, classNames.cell)}
172+
style={styles.cell}
161173
ellipsis={column.ellipsis}
162174
align={column.align}
163175
scope={column.rowScope}
@@ -187,7 +199,7 @@ function BodyRow<RecordType extends { children?: readonly RecordType[] }>(
187199
expandRowNode = (
188200
<ExpandedRow
189201
expanded={expanded}
190-
className={classNames(
202+
className={cls(
191203
`${prefixCls}-expanded-row`,
192204
`${prefixCls}-expanded-row-level-${indent + 1}`,
193205
expandedClsName,

src/Body/index.tsx

Lines changed: 13 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);
@@ -65,6 +72,8 @@ function Body<RecordType>(props: BodyProps<RecordType>) {
6572

6673
return (
6774
<BodyRow
75+
classNames={bodyCls}
76+
styles={bodyStyles}
6877
key={key}
6978
rowKey={key}
7079
record={record}
@@ -97,7 +106,10 @@ function Body<RecordType>(props: BodyProps<RecordType>) {
97106

98107
return (
99108
<PerfContext.Provider value={perfRef.current}>
100-
<WrapperComponent className={`${prefixCls}-tbody`}>
109+
<WrapperComponent
110+
className={cls(`${prefixCls}-tbody`, bodyCls.wrapper)}
111+
style={bodyStyles.wrapper}
112+
>
101113
{/* Measure body column width with additional hidden col */}
102114
{measureColumnWidth && (
103115
<MeasureRow

src/Cell/index.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useContext } from '@rc-component/context';
2-
import classNames from 'classnames';
2+
import cls from 'classnames';
33
import * as React from 'react';
44
import TableContext from '../context/TableContext';
55
import devRenderTimes from '../hooks/useRenderTimes';
@@ -19,6 +19,7 @@ import { useEvent } from '@rc-component/util';
1919
export interface CellProps<RecordType extends DefaultRecordType> {
2020
prefixCls?: string;
2121
className?: string;
22+
style?: React.CSSProperties;
2223
record?: RecordType;
2324
/** `column` index is the real show rowIndex */
2425
index?: number;
@@ -88,6 +89,7 @@ function Cell<RecordType>(props: CellProps<RecordType>) {
8889
// Style
8990
prefixCls,
9091
className,
92+
style,
9193
align,
9294

9395
// Value
@@ -122,6 +124,7 @@ function Cell<RecordType>(props: CellProps<RecordType>) {
122124
} = props;
123125

124126
const cellPrefixCls = `${prefixCls}-cell`;
127+
125128
const { allColumnsFixedLeft, rowHoverable } = useContext(TableContext, [
126129
'allColumnsFixedLeft',
127130
'rowHoverable',
@@ -212,7 +215,7 @@ function Cell<RecordType>(props: CellProps<RecordType>) {
212215
});
213216

214217
// >>>>> ClassName
215-
const mergedClassName = classNames(
218+
const mergedClassName = cls(
216219
cellPrefixCls,
217220
className,
218221
{
@@ -249,6 +252,7 @@ function Cell<RecordType>(props: CellProps<RecordType>) {
249252
...fixedStyle,
250253
...alignStyle,
251254
...additionalProps.style,
255+
...style,
252256
};
253257

254258
// >>>>> Children Node

src/FixedHolder/index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ function useColumnWidth(colWidths: readonly number[], columCount: number) {
2626

2727
export interface FixedHeaderProps<RecordType> extends HeaderProps<RecordType> {
2828
className: string;
29+
style?: React.CSSProperties;
2930
noData: boolean;
3031
maxContentScroll: boolean;
3132
colWidths: readonly number[];
@@ -46,6 +47,7 @@ const FixedHolder = React.forwardRef<HTMLDivElement, FixedHeaderProps<any>>((pro
4647

4748
const {
4849
className,
50+
style,
4951
noData,
5052
columns,
5153
flattenColumns,
@@ -159,6 +161,7 @@ const FixedHolder = React.forwardRef<HTMLDivElement, FixedHeaderProps<any>>((pro
159161
style={{
160162
overflow: 'hidden',
161163
...(isSticky ? { top: stickyTopOffset, bottom: stickyBottomOffset } : {}),
164+
...style,
162165
}}
163166
ref={setScrollRef}
164167
className={classNames(className, {

src/Header/Header.tsx

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,13 @@ import type {
1111
StickyOffsets,
1212
} from '../interface';
1313
import HeaderRow from './HeaderRow';
14+
import cls from 'classnames';
15+
import { TableProps } from '..';
1416

1517
function parseHeaderRows<RecordType>(
1618
rootColumns: ColumnsType<RecordType>,
19+
classNames: TableProps['classNames']['header'],
20+
styles: TableProps['styles']['header'],
1721
): CellType<RecordType>[][] {
1822
const rows: CellType<RecordType>[][] = [];
1923

@@ -29,7 +33,8 @@ function parseHeaderRows<RecordType>(
2933
const colSpans: number[] = columns.filter(Boolean).map(column => {
3034
const cell: CellType<RecordType> = {
3135
key: column.key,
32-
className: column.className || '',
36+
className: cls(column.className, classNames.cell) || '',
37+
style: styles.cell,
3338
children: column.title,
3439
column,
3540
colStart: currentColIndex,
@@ -97,18 +102,33 @@ const Header = <RecordType extends any>(props: HeaderProps<RecordType>) => {
97102

98103
const { stickyOffsets, columns, flattenColumns, onHeaderRow } = props;
99104

100-
const { prefixCls, getComponent } = useContext(TableContext, ['prefixCls', 'getComponent']);
101-
const rows = React.useMemo<CellType<RecordType>[][]>(() => parseHeaderRows(columns), [columns]);
105+
const { prefixCls, getComponent, classNames, styles } = useContext(TableContext, [
106+
'prefixCls',
107+
'getComponent',
108+
'classNames',
109+
'styles',
110+
]);
111+
const { header: headerCls = {} } = classNames || {};
112+
const { header: headerStyles = {} } = styles || {};
113+
const rows = React.useMemo<CellType<RecordType>[][]>(
114+
() => parseHeaderRows(columns, headerCls, headerStyles),
115+
[columns, headerCls, headerStyles],
116+
);
102117

103118
const WrapperComponent = getComponent(['header', 'wrapper'], 'thead');
104119
const trComponent = getComponent(['header', 'row'], 'tr');
105120
const thComponent = getComponent(['header', 'cell'], 'th');
106121

107122
return (
108-
<WrapperComponent className={`${prefixCls}-thead`}>
123+
<WrapperComponent
124+
className={cls(`${prefixCls}-thead`, headerCls.wrapper)}
125+
style={headerStyles.wrapper}
126+
>
109127
{rows.map((row, rowIndex) => {
110128
const rowNode = (
111129
<HeaderRow
130+
classNames={headerCls}
131+
styles={headerStyles}
112132
key={rowIndex}
113133
flattenColumns={flattenColumns}
114134
cells={row}

src/Header/HeaderRow.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type {
1111
} from '../interface';
1212
import { getCellFixedInfo } from '../utils/fixUtil';
1313
import { getColumnsKey } from '../utils/valueUtil';
14+
import { TableProps } from '..';
1415

1516
export interface RowProps<RecordType> {
1617
cells: readonly CellType<RecordType>[];
@@ -20,6 +21,8 @@ export interface RowProps<RecordType> {
2021
cellComponent: CustomizeComponent;
2122
onHeaderRow: GetComponentProps<readonly ColumnType<RecordType>[]>;
2223
index: number;
24+
classNames: TableProps['classNames']['header'];
25+
styles: TableProps['styles']['header'];
2326
}
2427

2528
const HeaderRow = <RecordType extends any>(props: RowProps<RecordType>) => {
@@ -31,6 +34,8 @@ const HeaderRow = <RecordType extends any>(props: RowProps<RecordType>) => {
3134
cellComponent: CellComponent,
3235
onHeaderRow,
3336
index,
37+
classNames,
38+
styles,
3439
} = props;
3540
const { prefixCls } = useContext(TableContext, ['prefixCls']);
3641
let rowProps: React.HTMLAttributes<HTMLElement>;
@@ -44,7 +49,7 @@ const HeaderRow = <RecordType extends any>(props: RowProps<RecordType>) => {
4449
const columnsKey = getColumnsKey(cells.map(cell => cell.column));
4550

4651
return (
47-
<RowComponent {...rowProps}>
52+
<RowComponent {...rowProps} className={classNames.row} style={styles.row}>
4853
{cells.map((cell: CellType<RecordType>, cellIndex) => {
4954
const { column } = cell;
5055
const fixedInfo = getCellFixedInfo(

src/Panel/index.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ import * as React from 'react';
33
export interface TitleProps {
44
className: string;
55
children: React.ReactNode;
6+
style: React.CSSProperties;
67
}
78

8-
function Panel({ className, children }: TitleProps) {
9-
return <div className={className}>{children}</div>;
9+
function Panel({ className, style, children }: TitleProps) {
10+
return <div className={className} style={style}>{children}</div>;
1011
}
1112

1213
export default Panel;

0 commit comments

Comments
 (0)