Skip to content

Commit 81fedad

Browse files
authored
Merge branch 'master' into fix-shadow
2 parents 53d664e + 886671b commit 81fedad

22 files changed

+3389
-187
lines changed

.github/workflows/main.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
key: lock-${{ github.sha }}
2525

2626
- name: create package-lock.json
27-
run: npm i --package-lock-only --ignore-scripts
27+
run: npm i --package-lock-only --ignore-scripts --legacy-peer-deps
2828

2929
- name: hack for singe file
3030
run: |
@@ -41,7 +41,7 @@ jobs:
4141

4242
- name: install
4343
if: steps.node_modules_cache_id.outputs.cache-hit != 'true'
44-
run: npm ci
44+
run: npm ci --legacy-peer-deps
4545

4646
lint:
4747
runs-on: ubuntu-latest

assets/index.less

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@
5656
}
5757

5858
// ================== Cell ==================
59+
&-fixed-column-gapped {
60+
.@{tablePrefixCls}-cell-fix-left-last::after,
61+
.@{tablePrefixCls}-cell-fix-right-first::after {
62+
display: none !important;
63+
}
64+
}
65+
5966
&-cell {
6067
background: #f4f4f4;
6168

docs/demo/components.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
title: components
3+
nav:
4+
title: Demo
5+
path: /demo
6+
---
7+
8+
<code src="../examples/components.tsx"></code>

docs/examples/components.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import React from 'react';
2+
import Table from 'rc-table';
3+
4+
const data = [];
5+
for (let i = 0; i < 100; i += 1) {
6+
data.push({
7+
key: i,
8+
a: `a${i}`,
9+
b: `b${i}`,
10+
c: `c${i}`,
11+
});
12+
}
13+
14+
const table = (props: any) => {
15+
return (
16+
<>
17+
<div style={{ background: '#fff' }}>header table</div>
18+
<table className={props.className}>{props.children}</table>
19+
</>
20+
);
21+
};
22+
23+
const Demo = () => {
24+
return (
25+
<div>
26+
<Table
27+
components={{ header: { table } }}
28+
sticky
29+
columns={[
30+
{ title: 'title1', dataIndex: 'a', key: 'a', width: 100 },
31+
{ title: 'title2', dataIndex: 'b', key: 'b', width: 100 },
32+
{ title: 'title3', dataIndex: 'c', key: 'c', width: 200 },
33+
]}
34+
data={data}
35+
/>
36+
</div>
37+
);
38+
};
39+
40+
export default Demo;

docs/examples/fixedColumns.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const columns: ColumnType<RecordType>[] = [
3434
{ title: 'title8', dataIndex: 'b', key: 'h' },
3535
{ title: 'title9', dataIndex: 'b', key: 'i' },
3636
{ title: 'title10', dataIndex: 'b', key: 'j' },
37-
{ title: 'title11', dataIndex: 'b', key: 'k', width: 50, fixed: 'right' },
37+
{ title: 'title11', dataIndex: 'b', key: 'k', width: 50 },
3838
{ title: 'title12', dataIndex: 'b', key: 'l', width: 100, fixed: 'right' },
3939
];
4040

@@ -65,6 +65,7 @@ const Demo = () => {
6565
Scroll Y
6666
</label>
6767
<Table
68+
// direction="rtl"
6869
columns={columns}
6970
expandedRowRender={({ b, c }) => b || c}
7071
scroll={{ x: 1200, y: scrollY ? 200 : null }}

package.json

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "rc-table",
3-
"version": "7.38.1",
3+
"version": "7.40.0",
44
"description": "table ui component for react",
55
"engines": {
66
"node": ">=8.x"
@@ -62,17 +62,16 @@
6262
},
6363
"devDependencies": {
6464
"@rc-component/father-plugin": "^1.0.2",
65-
"@testing-library/jest-dom": "^5.16.5",
65+
"@testing-library/jest-dom": "^6.4.0",
6666
"@testing-library/react": "^12.1.5",
6767
"@types/enzyme": "^3.10.5",
68-
"@types/react": "^18.0.28",
6968
"@types/jest": "^29.5.0",
69+
"@types/react": "^18.0.28",
7070
"@types/react-dom": "^18.0.5",
7171
"@types/responselike": "^1.0.0",
7272
"@types/styled-components": "^5.1.32",
73-
"@types/testing-library__jest-dom": "^6.0.0",
7473
"@umijs/fabric": "^4.0.1",
75-
"@vitest/coverage-c8": "^0.31.0",
74+
"@vitest/coverage-v8": "^1.2.2",
7675
"cross-env": "^7.0.0",
7776
"dumi": "^2.1.3",
7877
"enzyme": "^3.1.0",
@@ -105,7 +104,7 @@
105104
"regenerator-runtime": "^0.14.0",
106105
"styled-components": "^6.1.1",
107106
"typescript": "~5.3.0",
108-
"vitest": "^0.31.0"
107+
"vitest": "^1.2.2"
109108
},
110109
"lint-staged": {
111110
"**/*.{js,jsx,tsx,ts,md,json}": [

src/FixedHolder/index.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,13 @@ const FixedHolder = React.forwardRef<HTMLDivElement, FixedHeaderProps<unknown>>(
6363
...restProps
6464
} = props;
6565

66-
const { prefixCls, scrollbarSize, isSticky } = useContext(TableContext, [
66+
const { prefixCls, scrollbarSize, isSticky, getComponent } = useContext(TableContext, [
6767
'prefixCls',
6868
'scrollbarSize',
6969
'isSticky',
70+
'getComponent',
7071
]);
72+
const TableComponent = getComponent(['header', 'table'], 'table');
7173

7274
const combinationScrollBarSize = isSticky && !fixHeader ? 0 : scrollbarSize;
7375

@@ -146,7 +148,7 @@ const FixedHolder = React.forwardRef<HTMLDivElement, FixedHeaderProps<unknown>>(
146148
[stickyClassName]: !!stickyClassName,
147149
})}
148150
>
149-
<table
151+
<TableComponent
150152
style={{
151153
tableLayout: 'fixed',
152154
visibility: noData || mergedColumnWidth ? null : 'hidden',
@@ -165,7 +167,7 @@ const FixedHolder = React.forwardRef<HTMLDivElement, FixedHeaderProps<unknown>>(
165167
columns: columnsWithScrollbar,
166168
flattenColumns: flattenColumnsWithScrollbar,
167169
})}
168-
</table>
170+
</TableComponent>
169171
</div>
170172
);
171173
});

src/Header/Header.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,20 +90,19 @@ export interface HeaderProps<RecordType> {
9090
onHeaderRow: GetComponentProps<readonly ColumnType<RecordType>[]>;
9191
}
9292

93-
function Header<RecordType>(props: HeaderProps<RecordType>): React.ReactElement {
93+
const Header = <RecordType extends any>(props: HeaderProps<RecordType>) => {
9494
if (process.env.NODE_ENV !== 'production') {
9595
devRenderTimes(props);
9696
}
9797

9898
const { stickyOffsets, columns, flattenColumns, onHeaderRow } = props;
9999

100100
const { prefixCls, getComponent } = useContext(TableContext, ['prefixCls', 'getComponent']);
101-
const rows: CellType<RecordType>[][] = React.useMemo(() => parseHeaderRows(columns), [columns]);
101+
const rows = React.useMemo<CellType<RecordType>[][]>(() => parseHeaderRows(columns), [columns]);
102102

103103
const WrapperComponent = getComponent(['header', 'wrapper'], 'thead');
104104
const trComponent = getComponent(['header', 'row'], 'tr');
105105
const thComponent = getComponent(['header', 'cell'], 'th');
106-
const tdComponent = getComponent(['header', 'cell'], 'td');
107106

108107
return (
109108
<WrapperComponent className={`${prefixCls}-thead`}>
@@ -116,16 +115,14 @@ function Header<RecordType>(props: HeaderProps<RecordType>): React.ReactElement
116115
stickyOffsets={stickyOffsets}
117116
rowComponent={trComponent}
118117
cellComponent={thComponent}
119-
tdCellComponent={tdComponent}
120118
onHeaderRow={onHeaderRow}
121119
index={rowIndex}
122120
/>
123121
);
124-
125122
return rowNode;
126123
})}
127124
</WrapperComponent>
128125
);
129-
}
126+
};
130127

131128
export default responseImmutable(Header);

src/Header/HeaderRow.tsx

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,20 @@ export interface RowProps<RecordType> {
1818
flattenColumns: readonly ColumnType<RecordType>[];
1919
rowComponent: CustomizeComponent;
2020
cellComponent: CustomizeComponent;
21-
tdCellComponent: CustomizeComponent;
2221
onHeaderRow: GetComponentProps<readonly ColumnType<RecordType>[]>;
2322
index: number;
2423
}
2524

26-
function HeaderRow<RecordType>({
27-
cells,
28-
stickyOffsets,
29-
flattenColumns,
30-
rowComponent: RowComponent,
31-
cellComponent: CellComponent,
32-
tdCellComponent,
33-
onHeaderRow,
34-
index,
35-
}: RowProps<RecordType>) {
25+
const HeaderRow = <RecordType extends any>(props: RowProps<RecordType>) => {
26+
const {
27+
cells,
28+
stickyOffsets,
29+
flattenColumns,
30+
rowComponent: RowComponent,
31+
cellComponent: CellComponent,
32+
onHeaderRow,
33+
index,
34+
} = props;
3635
const { prefixCls, direction } = useContext(TableContext, ['prefixCls', 'direction']);
3736
let rowProps: React.HTMLAttributes<HTMLElement>;
3837
if (onHeaderRow) {
@@ -67,7 +66,7 @@ function HeaderRow<RecordType>({
6766
scope={column.title ? (cell.colSpan > 1 ? 'colgroup' : 'col') : null}
6867
ellipsis={column.ellipsis}
6968
align={column.align}
70-
component={column.title ? CellComponent : tdCellComponent}
69+
component={CellComponent}
7170
prefixCls={prefixCls}
7271
key={columnsKey[cellIndex]}
7372
{...fixedInfo}
@@ -78,7 +77,7 @@ function HeaderRow<RecordType>({
7877
})}
7978
</RowComponent>
8079
);
81-
}
80+
};
8281

8382
if (process.env.NODE_ENV !== 'production') {
8483
HeaderRow.displayName = 'HeaderRow';

src/Table.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ function Table<RecordType extends DefaultRecordType>(
280280
const scrollX = scroll?.x;
281281
const [componentWidth, setComponentWidth] = React.useState(0);
282282

283-
const [columns, flattenColumns, flattenScrollX] = useColumns(
283+
const [columns, flattenColumns, flattenScrollX, hasGapFixed] = useColumns(
284284
{
285285
...props,
286286
...expandableConfig,
@@ -348,7 +348,7 @@ function Table<RecordType extends DefaultRecordType>(
348348
const colsKeys = getColumnsKey(flattenColumns);
349349
const pureColWidths = colsKeys.map(columnKey => colsWidths.get(columnKey));
350350
const colWidths = React.useMemo(() => pureColWidths, [pureColWidths.join('_')]);
351-
const stickyOffsets = useStickyOffsets(colWidths, flattenColumns.length, direction);
351+
const stickyOffsets = useStickyOffsets(colWidths, flattenColumns, direction);
352352
const fixHeader = scroll && validateValue(scroll.y);
353353
const horizonScroll = (scroll && validateValue(mergedScrollX)) || Boolean(expandableConfig.fixed);
354354
const fixColumn = horizonScroll && flattenColumns.some(({ fixed }) => fixed);
@@ -706,6 +706,7 @@ function Table<RecordType extends DefaultRecordType>(
706706
scrollBodyRef={scrollBodyRef}
707707
onScroll={onScroll}
708708
container={container}
709+
data={data}
709710
/>
710711
)}
711712
</>
@@ -750,6 +751,7 @@ function Table<RecordType extends DefaultRecordType>(
750751
[`${prefixCls}-fixed-header`]: fixHeader,
751752
/** No used but for compatible */
752753
[`${prefixCls}-fixed-column`]: fixColumn,
754+
[`${prefixCls}-fixed-column-gapped`]: fixColumn && hasGapFixed,
753755
[`${prefixCls}-scroll-horizontal`]: horizonScroll,
754756
[`${prefixCls}-has-fix-left`]: flattenColumns[0] && flattenColumns[0].fixed,
755757
[`${prefixCls}-has-fix-right`]:

src/hooks/useColumns/index.tsx

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -88,30 +88,6 @@ function flatColumns<RecordType>(
8888
}, []);
8989
}
9090

91-
function warningFixed(flattenColumns: readonly { fixed?: FixedType }[]) {
92-
let allFixLeft = true;
93-
for (let i = 0; i < flattenColumns.length; i += 1) {
94-
const col = flattenColumns[i];
95-
if (allFixLeft && col.fixed !== 'left') {
96-
allFixLeft = false;
97-
} else if (!allFixLeft && col.fixed === 'left') {
98-
warning(false, `Index ${i - 1} of \`columns\` missing \`fixed='left'\` prop.`);
99-
break;
100-
}
101-
}
102-
103-
let allFixRight = true;
104-
for (let i = flattenColumns.length - 1; i >= 0; i -= 1) {
105-
const col = flattenColumns[i];
106-
if (allFixRight && col.fixed !== 'right') {
107-
allFixRight = false;
108-
} else if (!allFixRight && col.fixed === 'right') {
109-
warning(false, `Index ${i + 1} of \`columns\` missing \`fixed='right'\` prop.`);
110-
break;
111-
}
112-
}
113-
}
114-
11591
function revertForRtl<RecordType>(columns: ColumnsType<RecordType>): ColumnsType<RecordType> {
11692
return columns.map(column => {
11793
const { fixed, ...restProps } = column;
@@ -176,6 +152,7 @@ function useColumns<RecordType>(
176152
columns: ColumnsType<RecordType>,
177153
flattenColumns: readonly ColumnType<RecordType>[],
178154
realScrollWidth: undefined | number,
155+
hasGapFixed: boolean,
179156
] {
180157
const baseColumns = React.useMemo<ColumnsType<RecordType>>(() => {
181158
const newColumns = columns || convertChildrenToColumns(children) || [];
@@ -294,10 +271,40 @@ function useColumns<RecordType>(
294271
return flatColumns(mergedColumns);
295272
}, [mergedColumns, direction, scrollWidth]);
296273

297-
// Only check out of production since it's waste for each render
298-
if (process.env.NODE_ENV !== 'production') {
299-
warningFixed(direction === 'rtl' ? flattenColumns.slice().reverse() : flattenColumns);
300-
}
274+
// ========================= Gap Fixed ========================
275+
const hasGapFixed = React.useMemo(() => {
276+
// Fixed: left, since old browser not support `findLastIndex`, we should use reverse loop
277+
let lastLeftIndex = -1;
278+
for (let i = flattenColumns.length - 1; i >= 0; i -= 1) {
279+
const colFixed = flattenColumns[i].fixed;
280+
if (colFixed === 'left' || colFixed === true) {
281+
lastLeftIndex = i;
282+
break;
283+
}
284+
}
285+
286+
if (lastLeftIndex >= 0) {
287+
for (let i = 0; i <= lastLeftIndex; i += 1) {
288+
const colFixed = flattenColumns[i].fixed;
289+
if (colFixed !== 'left' && colFixed !== true) {
290+
return true;
291+
}
292+
}
293+
}
294+
295+
// Fixed: right
296+
const firstRightIndex = flattenColumns.findIndex(({ fixed: colFixed }) => colFixed === 'right');
297+
if (firstRightIndex >= 0) {
298+
for (let i = firstRightIndex; i < flattenColumns.length; i += 1) {
299+
const colFixed = flattenColumns[i].fixed;
300+
if (colFixed !== 'right') {
301+
return true;
302+
}
303+
}
304+
}
305+
306+
return false;
307+
}, [flattenColumns]);
301308

302309
// ========================= FillWidth ========================
303310
const [filledColumns, realScrollWidth] = useWidthColumns(
@@ -306,7 +313,7 @@ function useColumns<RecordType>(
306313
clientWidth,
307314
);
308315

309-
return [mergedColumns, filledColumns, realScrollWidth];
316+
return [mergedColumns, filledColumns, realScrollWidth, hasGapFixed];
310317
}
311318

312319
export default useColumns;

0 commit comments

Comments
 (0)