Skip to content

Commit

Permalink
fix: solve fixed column's shadow display unexpected issue (#1081)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
kiner-tang authored Feb 21, 2024
1 parent 886671b commit 0b0211c
Show file tree
Hide file tree
Showing 14 changed files with 6,671 additions and 40 deletions.
8 changes: 8 additions & 0 deletions docs/demo/shadow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: shadow
nav:
title: Demo
path: /demo
---

<code src="../examples/shadow.tsx"></code>
191 changes: 191 additions & 0 deletions docs/examples/shadow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
import React from 'react';
import Table from 'rc-table';
import '../../assets/index.less';
import type { ColumnsType } from '@/interface';

interface DataType {
key: React.Key;
name: string;
age: number;
street: string;
building: string;
number: number;
companyAddress: string;
companyName: string;
gender: string;
}

const columns: TableColumnsType<DataType> = [
{
title: 'Other',
fixed: 'left',
ellipsis: true,
children: [
{
title: 'Age',
dataIndex: 'age',
key: 'age',
width: 150,
fixed: 'left',
ellipsis: true,
sorter: (a, b) => a.age - b.age,
},
{
title: 'Address',
children: [
{
title: 'Street',
dataIndex: 'street',
key: 'street',
width: 150,
fixed: 'left',
ellipsis: true,
},
{
title: 'Block',
children: [
{
title: 'Door No.',
dataIndex: 'number',
key: 'number',
width: 100,
fixed: 'left',
ellipsis: true,
},
{
title: 'Building',
dataIndex: 'building',
key: 'building',
width: 100,
fixed: 'left',
ellipsis: true,
},
],
},
],
},
],
},
{
title: 'Name',
dataIndex: 'name',
key: 'name',
width: 100,
filters: [
{
text: 'Joe',
value: 'Joe',
},
{
text: 'John',
value: 'John',
},
],
onFilter: (value: string, record) => record.name.indexOf(value) === 0,
},
{
title: 'Company',
children: [
{
title: 'Company Address',
dataIndex: 'companyAddress',
key: 'companyAddress',
width: 200,
},
{
title: 'Company Name',
dataIndex: 'companyName',
key: 'companyName',
},
],
},
{
title: 'Gender',
dataIndex: 'gender',
key: 'gender',
width: 80,
fixed: 'right',
},
];

const data: DataType[] = [];
for (let i = 0; i < 100; i++) {
data.push({
key: i,
name: 'John Brown',
age: i + 1,
street: 'Lake Park',
building: 'C',
number: 2035,
companyAddress: 'Lake Street 42',
companyName: 'SoftLake Co',
gender: 'M',
});
}

interface User {
key: number;
name: string;
}

const columns2: ColumnsType<User> = [
{
title: '父表头右侧的阴影导致整个表格最右侧有空隙',
key: 'title',
children: [
{
key: 'name0',
title: 'Name0',
fixed: 'left',
dataIndex: 'name0',
width: 100,
},
{
key: 'name1',
title: 'Name1',
fixed: 'left',
dataIndex: 'name1',
width: 100,
},
{
key: 'name2',
title: 'Name2',
dataIndex: 'name2',
width: 500,
},
{
key: 'name3',
title: 'Name3',
fixed: 'right',
dataIndex: 'name3',
width: 100,
},
],
},
];

const data2: User[] = [
{
key: 0,
name: 'Jack',
},
{
key: 1,
name: 'Jack1',
},
{
key: 2,
name: 'Jack1',
},
];

const Demo = () => (
<div>
<h2>colSpan & rowSpan</h2>
<Table columns={columns} data={data} className="table" scroll={{ x: 1500, y: 500 }} />
<hr />
<Table columns={columns2} data={data2} className="table" scroll={{ x: 1500, y: 500 }} />
</div>
);

export default Demo;
3 changes: 1 addition & 2 deletions src/Footer/Cell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default function SummaryCell({
align,
}: SummaryCellProps) {
const { prefixCls, direction } = useContext(TableContext, ['prefixCls', 'direction']);
const { scrollColumnIndex, stickyOffsets, flattenColumns, columns } = React.useContext(SummaryContext);
const { scrollColumnIndex, stickyOffsets, flattenColumns } = React.useContext(SummaryContext);
const lastIndex = index + colSpan - 1;
const mergedColSpan = lastIndex + 1 === scrollColumnIndex ? colSpan + 1 : colSpan;

Expand All @@ -34,7 +34,6 @@ export default function SummaryCell({
flattenColumns,
stickyOffsets,
direction,
columns?.[index]
);

return (
Expand Down
3 changes: 1 addition & 2 deletions src/Footer/SummaryContext.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import * as React from 'react';
import type { ColumnsType, ColumnType, StickyOffsets } from '../interface';
import type { ColumnType, StickyOffsets } from '../interface';

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

const SummaryContext = React.createContext<{
stickyOffsets?: StickyOffsets;
scrollColumnIndex?: number;
flattenColumns?: FlattenColumns<any>;
columns?: ColumnsType<any>;
}>({});

export default SummaryContext;
8 changes: 3 additions & 5 deletions src/Footer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useContext } from '@rc-component/context';
import * as React from 'react';
import TableContext, { responseImmutable } from '../context/TableContext';
import devRenderTimes from '../hooks/useRenderTimes';
import type { ColumnsType, ColumnType, StickyOffsets } from '../interface';
import type { ColumnType, StickyOffsets } from '../interface';
import Summary from './Summary';
import SummaryContext from './SummaryContext';

Expand All @@ -12,15 +12,14 @@ export interface FooterProps<RecordType> {
children: React.ReactNode;
stickyOffsets: StickyOffsets;
flattenColumns: FlattenColumns<RecordType>;
columns: ColumnsType<RecordType>;
}

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

const { children, stickyOffsets, flattenColumns, columns } = props;
const { children, stickyOffsets, flattenColumns } = props;

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

Expand All @@ -32,9 +31,8 @@ function Footer<RecordType>(props: FooterProps<RecordType>) {
stickyOffsets,
flattenColumns,
scrollColumnIndex: scrollColumn?.scrollbar ? lastColumnIndex : null,
columns,
}),
[scrollColumn, flattenColumns, lastColumnIndex, stickyOffsets, columns],
[scrollColumn, flattenColumns, lastColumnIndex, stickyOffsets],
);

return (
Expand Down
3 changes: 1 addition & 2 deletions src/Header/HeaderRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,12 @@ const HeaderRow = <RecordType extends any>(props: RowProps<RecordType>) => {
<RowComponent {...rowProps}>
{cells.map((cell: CellType<RecordType>, cellIndex) => {
const { column } = cell;
const fixedInfo = getCellFixedInfo<RecordType>(
const fixedInfo = getCellFixedInfo(
cell.colStart,
cell.colEnd,
flattenColumns,
stickyOffsets,
direction,
column,
);

let additionalProps: React.HTMLAttributes<HTMLElement>;
Expand Down
10 changes: 3 additions & 7 deletions src/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -646,11 +646,7 @@ function Table<RecordType extends DefaultRecordType>(
{bodyColGroup}
{bodyTable}
{!fixFooter && summaryNode && (
<Footer
stickyOffsets={stickyOffsets}
flattenColumns={flattenColumns}
columns={columns}
>
<Footer stickyOffsets={stickyOffsets} flattenColumns={flattenColumns}>
{summaryNode}
</Footer>
)}
Expand Down Expand Up @@ -732,7 +728,7 @@ function Table<RecordType extends DefaultRecordType>(
{showHeader !== false && <Header {...headerProps} {...columnContext} />}
{bodyTable}
{summaryNode && (
<Footer stickyOffsets={stickyOffsets} flattenColumns={flattenColumns} columns={columns}>
<Footer stickyOffsets={stickyOffsets} flattenColumns={flattenColumns}>
{summaryNode}
</Footer>
)}
Expand Down Expand Up @@ -775,7 +771,7 @@ function Table<RecordType extends DefaultRecordType>(
fullTable = <ResizeObserver onResize={onFullTableResize}>{fullTable}</ResizeObserver>;
}

const fixedInfoList = useFixedInfo(flattenColumns, stickyOffsets, direction, columns);
const fixedInfoList = useFixedInfo(flattenColumns, stickyOffsets, direction);

const TableContextValue = React.useMemo(
() => ({
Expand Down
12 changes: 2 additions & 10 deletions src/hooks/useFixedInfo.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
import useMemo from 'rc-util/lib/hooks/useMemo';
import isEqual from 'rc-util/lib/isEqual';
import type { ColumnsType, ColumnType, Direction, StickyOffsets } from '../interface';
import type { ColumnType, Direction, StickyOffsets } from '../interface';
import { getCellFixedInfo } from '../utils/fixUtil';

export default function useFixedInfo<RecordType>(
flattenColumns: readonly ColumnType<RecordType>[],
stickyOffsets: StickyOffsets,
direction: Direction,
columns: ColumnsType<RecordType>,
) {
const fixedInfoList = flattenColumns.map((_, colIndex) =>
getCellFixedInfo(
colIndex,
colIndex,
flattenColumns,
stickyOffsets,
direction,
columns?.[colIndex],
),
getCellFixedInfo(colIndex, colIndex, flattenColumns, stickyOffsets, direction),
);

return useMemo(
Expand Down
18 changes: 7 additions & 11 deletions src/utils/fixUtil.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
import type {
ColumnGroupType,
ColumnType,
Direction,
FixedType,
StickyOffsets,
} from '../interface';
import type { Direction, FixedType, StickyOffsets } from '../interface';

export interface FixedInfo {
fixLeft: number | false;
Expand All @@ -19,13 +13,12 @@ export interface FixedInfo {
isSticky: boolean;
}

export function getCellFixedInfo<RecordType = any>(
export function getCellFixedInfo(
colStart: number,
colEnd: number,
columns: readonly { fixed?: FixedType }[],
stickyOffsets: StickyOffsets,
direction: Direction,
curColumns?: ColumnType<RecordType> | ColumnGroupType<RecordType>,
): FixedInfo {
const startColumn = columns[colStart] || {};
const endColumn = columns[colEnd] || {};
Expand All @@ -48,8 +41,11 @@ export function getCellFixedInfo<RecordType = any>(
const nextColumn = columns[colEnd + 1];
const prevColumn = columns[colStart - 1];

// no children only
const canLastFix = !(curColumns as ColumnGroupType<RecordType>)?.children;
// need show shadow only when canLastFix is true
const canLastFix =
(nextColumn && nextColumn.fixed === undefined) ||
(prevColumn && prevColumn.fixed === undefined) ||
columns.every(col => col.fixed === 'left');

if (direction === 'rtl') {
if (fixLeft !== undefined) {
Expand Down
Loading

0 comments on commit 0b0211c

Please sign in to comment.