Skip to content

Commit 0b0211c

Browse files
authored
fix: solve fixed column's shadow display unexpected issue (#1081)
* fix: solve fixed column's shadow display unexpected issue * fix: solve fixed column's shadow display unexpected issue * fix: solve fixed column's shadow display unexpected issue * fix: solve fixed column's shadow display unexpected issue * fix: solve fixed column's shadow display unexpected issue * feat: add test case * feat: optimize code * feat: optimize code
1 parent 886671b commit 0b0211c

File tree

14 files changed

+6671
-40
lines changed

14 files changed

+6671
-40
lines changed

docs/demo/shadow.md

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

docs/examples/shadow.tsx

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
import React from 'react';
2+
import Table from 'rc-table';
3+
import '../../assets/index.less';
4+
import type { ColumnsType } from '@/interface';
5+
6+
interface DataType {
7+
key: React.Key;
8+
name: string;
9+
age: number;
10+
street: string;
11+
building: string;
12+
number: number;
13+
companyAddress: string;
14+
companyName: string;
15+
gender: string;
16+
}
17+
18+
const columns: TableColumnsType<DataType> = [
19+
{
20+
title: 'Other',
21+
fixed: 'left',
22+
ellipsis: true,
23+
children: [
24+
{
25+
title: 'Age',
26+
dataIndex: 'age',
27+
key: 'age',
28+
width: 150,
29+
fixed: 'left',
30+
ellipsis: true,
31+
sorter: (a, b) => a.age - b.age,
32+
},
33+
{
34+
title: 'Address',
35+
children: [
36+
{
37+
title: 'Street',
38+
dataIndex: 'street',
39+
key: 'street',
40+
width: 150,
41+
fixed: 'left',
42+
ellipsis: true,
43+
},
44+
{
45+
title: 'Block',
46+
children: [
47+
{
48+
title: 'Door No.',
49+
dataIndex: 'number',
50+
key: 'number',
51+
width: 100,
52+
fixed: 'left',
53+
ellipsis: true,
54+
},
55+
{
56+
title: 'Building',
57+
dataIndex: 'building',
58+
key: 'building',
59+
width: 100,
60+
fixed: 'left',
61+
ellipsis: true,
62+
},
63+
],
64+
},
65+
],
66+
},
67+
],
68+
},
69+
{
70+
title: 'Name',
71+
dataIndex: 'name',
72+
key: 'name',
73+
width: 100,
74+
filters: [
75+
{
76+
text: 'Joe',
77+
value: 'Joe',
78+
},
79+
{
80+
text: 'John',
81+
value: 'John',
82+
},
83+
],
84+
onFilter: (value: string, record) => record.name.indexOf(value) === 0,
85+
},
86+
{
87+
title: 'Company',
88+
children: [
89+
{
90+
title: 'Company Address',
91+
dataIndex: 'companyAddress',
92+
key: 'companyAddress',
93+
width: 200,
94+
},
95+
{
96+
title: 'Company Name',
97+
dataIndex: 'companyName',
98+
key: 'companyName',
99+
},
100+
],
101+
},
102+
{
103+
title: 'Gender',
104+
dataIndex: 'gender',
105+
key: 'gender',
106+
width: 80,
107+
fixed: 'right',
108+
},
109+
];
110+
111+
const data: DataType[] = [];
112+
for (let i = 0; i < 100; i++) {
113+
data.push({
114+
key: i,
115+
name: 'John Brown',
116+
age: i + 1,
117+
street: 'Lake Park',
118+
building: 'C',
119+
number: 2035,
120+
companyAddress: 'Lake Street 42',
121+
companyName: 'SoftLake Co',
122+
gender: 'M',
123+
});
124+
}
125+
126+
interface User {
127+
key: number;
128+
name: string;
129+
}
130+
131+
const columns2: ColumnsType<User> = [
132+
{
133+
title: '父表头右侧的阴影导致整个表格最右侧有空隙',
134+
key: 'title',
135+
children: [
136+
{
137+
key: 'name0',
138+
title: 'Name0',
139+
fixed: 'left',
140+
dataIndex: 'name0',
141+
width: 100,
142+
},
143+
{
144+
key: 'name1',
145+
title: 'Name1',
146+
fixed: 'left',
147+
dataIndex: 'name1',
148+
width: 100,
149+
},
150+
{
151+
key: 'name2',
152+
title: 'Name2',
153+
dataIndex: 'name2',
154+
width: 500,
155+
},
156+
{
157+
key: 'name3',
158+
title: 'Name3',
159+
fixed: 'right',
160+
dataIndex: 'name3',
161+
width: 100,
162+
},
163+
],
164+
},
165+
];
166+
167+
const data2: User[] = [
168+
{
169+
key: 0,
170+
name: 'Jack',
171+
},
172+
{
173+
key: 1,
174+
name: 'Jack1',
175+
},
176+
{
177+
key: 2,
178+
name: 'Jack1',
179+
},
180+
];
181+
182+
const Demo = () => (
183+
<div>
184+
<h2>colSpan & rowSpan</h2>
185+
<Table columns={columns} data={data} className="table" scroll={{ x: 1500, y: 500 }} />
186+
<hr />
187+
<Table columns={columns2} data={data2} className="table" scroll={{ x: 1500, y: 500 }} />
188+
</div>
189+
);
190+
191+
export default Demo;

src/Footer/Cell.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export default function SummaryCell({
2424
align,
2525
}: SummaryCellProps) {
2626
const { prefixCls, direction } = useContext(TableContext, ['prefixCls', 'direction']);
27-
const { scrollColumnIndex, stickyOffsets, flattenColumns, columns } = React.useContext(SummaryContext);
27+
const { scrollColumnIndex, stickyOffsets, flattenColumns } = React.useContext(SummaryContext);
2828
const lastIndex = index + colSpan - 1;
2929
const mergedColSpan = lastIndex + 1 === scrollColumnIndex ? colSpan + 1 : colSpan;
3030

@@ -34,7 +34,6 @@ export default function SummaryCell({
3434
flattenColumns,
3535
stickyOffsets,
3636
direction,
37-
columns?.[index]
3837
);
3938

4039
return (

src/Footer/SummaryContext.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import * as React from 'react';
2-
import type { ColumnsType, ColumnType, StickyOffsets } from '../interface';
2+
import type { ColumnType, StickyOffsets } from '../interface';
33

44
type FlattenColumns<RecordType> = readonly (ColumnType<RecordType> & { scrollbar?: boolean })[];
55

66
const SummaryContext = React.createContext<{
77
stickyOffsets?: StickyOffsets;
88
scrollColumnIndex?: number;
99
flattenColumns?: FlattenColumns<any>;
10-
columns?: ColumnsType<any>;
1110
}>({});
1211

1312
export default SummaryContext;

src/Footer/index.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { useContext } from '@rc-component/context';
22
import * as React from 'react';
33
import TableContext, { responseImmutable } from '../context/TableContext';
44
import devRenderTimes from '../hooks/useRenderTimes';
5-
import type { ColumnsType, ColumnType, StickyOffsets } from '../interface';
5+
import type { ColumnType, StickyOffsets } from '../interface';
66
import Summary from './Summary';
77
import SummaryContext from './SummaryContext';
88

@@ -12,15 +12,14 @@ export interface FooterProps<RecordType> {
1212
children: React.ReactNode;
1313
stickyOffsets: StickyOffsets;
1414
flattenColumns: FlattenColumns<RecordType>;
15-
columns: ColumnsType<RecordType>;
1615
}
1716

1817
function Footer<RecordType>(props: FooterProps<RecordType>) {
1918
if (process.env.NODE_ENV !== 'production') {
2019
devRenderTimes(props);
2120
}
2221

23-
const { children, stickyOffsets, flattenColumns, columns } = props;
22+
const { children, stickyOffsets, flattenColumns } = props;
2423

2524
const prefixCls = useContext(TableContext, 'prefixCls');
2625

@@ -32,9 +31,8 @@ function Footer<RecordType>(props: FooterProps<RecordType>) {
3231
stickyOffsets,
3332
flattenColumns,
3433
scrollColumnIndex: scrollColumn?.scrollbar ? lastColumnIndex : null,
35-
columns,
3634
}),
37-
[scrollColumn, flattenColumns, lastColumnIndex, stickyOffsets, columns],
35+
[scrollColumn, flattenColumns, lastColumnIndex, stickyOffsets],
3836
);
3937

4038
return (

src/Header/HeaderRow.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,12 @@ const HeaderRow = <RecordType extends any>(props: RowProps<RecordType>) => {
4747
<RowComponent {...rowProps}>
4848
{cells.map((cell: CellType<RecordType>, cellIndex) => {
4949
const { column } = cell;
50-
const fixedInfo = getCellFixedInfo<RecordType>(
50+
const fixedInfo = getCellFixedInfo(
5151
cell.colStart,
5252
cell.colEnd,
5353
flattenColumns,
5454
stickyOffsets,
5555
direction,
56-
column,
5756
);
5857

5958
let additionalProps: React.HTMLAttributes<HTMLElement>;

src/Table.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -646,11 +646,7 @@ function Table<RecordType extends DefaultRecordType>(
646646
{bodyColGroup}
647647
{bodyTable}
648648
{!fixFooter && summaryNode && (
649-
<Footer
650-
stickyOffsets={stickyOffsets}
651-
flattenColumns={flattenColumns}
652-
columns={columns}
653-
>
649+
<Footer stickyOffsets={stickyOffsets} flattenColumns={flattenColumns}>
654650
{summaryNode}
655651
</Footer>
656652
)}
@@ -732,7 +728,7 @@ function Table<RecordType extends DefaultRecordType>(
732728
{showHeader !== false && <Header {...headerProps} {...columnContext} />}
733729
{bodyTable}
734730
{summaryNode && (
735-
<Footer stickyOffsets={stickyOffsets} flattenColumns={flattenColumns} columns={columns}>
731+
<Footer stickyOffsets={stickyOffsets} flattenColumns={flattenColumns}>
736732
{summaryNode}
737733
</Footer>
738734
)}
@@ -775,7 +771,7 @@ function Table<RecordType extends DefaultRecordType>(
775771
fullTable = <ResizeObserver onResize={onFullTableResize}>{fullTable}</ResizeObserver>;
776772
}
777773

778-
const fixedInfoList = useFixedInfo(flattenColumns, stickyOffsets, direction, columns);
774+
const fixedInfoList = useFixedInfo(flattenColumns, stickyOffsets, direction);
779775

780776
const TableContextValue = React.useMemo(
781777
() => ({

src/hooks/useFixedInfo.ts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,15 @@
11
import useMemo from 'rc-util/lib/hooks/useMemo';
22
import isEqual from 'rc-util/lib/isEqual';
3-
import type { ColumnsType, ColumnType, Direction, StickyOffsets } from '../interface';
3+
import type { ColumnType, Direction, StickyOffsets } from '../interface';
44
import { getCellFixedInfo } from '../utils/fixUtil';
55

66
export default function useFixedInfo<RecordType>(
77
flattenColumns: readonly ColumnType<RecordType>[],
88
stickyOffsets: StickyOffsets,
99
direction: Direction,
10-
columns: ColumnsType<RecordType>,
1110
) {
1211
const fixedInfoList = flattenColumns.map((_, colIndex) =>
13-
getCellFixedInfo(
14-
colIndex,
15-
colIndex,
16-
flattenColumns,
17-
stickyOffsets,
18-
direction,
19-
columns?.[colIndex],
20-
),
12+
getCellFixedInfo(colIndex, colIndex, flattenColumns, stickyOffsets, direction),
2113
);
2214

2315
return useMemo(

src/utils/fixUtil.ts

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
1-
import type {
2-
ColumnGroupType,
3-
ColumnType,
4-
Direction,
5-
FixedType,
6-
StickyOffsets,
7-
} from '../interface';
1+
import type { Direction, FixedType, StickyOffsets } from '../interface';
82

93
export interface FixedInfo {
104
fixLeft: number | false;
@@ -19,13 +13,12 @@ export interface FixedInfo {
1913
isSticky: boolean;
2014
}
2115

22-
export function getCellFixedInfo<RecordType = any>(
16+
export function getCellFixedInfo(
2317
colStart: number,
2418
colEnd: number,
2519
columns: readonly { fixed?: FixedType }[],
2620
stickyOffsets: StickyOffsets,
2721
direction: Direction,
28-
curColumns?: ColumnType<RecordType> | ColumnGroupType<RecordType>,
2922
): FixedInfo {
3023
const startColumn = columns[colStart] || {};
3124
const endColumn = columns[colEnd] || {};
@@ -48,8 +41,11 @@ export function getCellFixedInfo<RecordType = any>(
4841
const nextColumn = columns[colEnd + 1];
4942
const prevColumn = columns[colStart - 1];
5043

51-
// no children only
52-
const canLastFix = !(curColumns as ColumnGroupType<RecordType>)?.children;
44+
// need show shadow only when canLastFix is true
45+
const canLastFix =
46+
(nextColumn && nextColumn.fixed === undefined) ||
47+
(prevColumn && prevColumn.fixed === undefined) ||
48+
columns.every(col => col.fixed === 'left');
5349

5450
if (direction === 'rtl') {
5551
if (fixLeft !== undefined) {

0 commit comments

Comments
 (0)