Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions assets/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,6 @@
}

// ================== Cell ==================
&-fixed-column-gapped {
.@{tablePrefixCls}-cell-fix-left-last::after,
.@{tablePrefixCls}-cell-fix-right-first::after {
display: none !important;
}
}

&-cell {
background: #f4f4f4;
Expand Down
1 change: 1 addition & 0 deletions src/Body/BodyRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ function BodyRow<RecordType extends { children?: readonly RecordType[] }>(
key={key}
record={record}
index={index}
colIndex={colIndex}
renderIndex={renderIndex}
dataIndex={dataIndex}
render={render}
Expand Down
42 changes: 33 additions & 9 deletions src/Cell/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export interface CellProps<RecordType extends DefaultRecordType> {
record?: RecordType;
/** `column` index is the real show rowIndex */
index?: number;
/** the column index which cell in */
colIndex?: number;
/** the index of the record. For the render(value, record, renderIndex) */
renderIndex?: number;
dataIndex?: DataIndex<RecordType>;
Expand Down Expand Up @@ -72,7 +74,10 @@ const getTitleFromCellRenderChildren = ({
return title;
};

function Cell<RecordType>(props: CellProps<RecordType>) {
function Cell<RecordType>(
props: CellProps<RecordType>,
ref: React.ForwardedRef<HTMLTableCellElement>,
) {
if (process.env.NODE_ENV !== 'production') {
devRenderTimes(props);
}
Expand All @@ -99,6 +104,9 @@ function Cell<RecordType>(props: CellProps<RecordType>) {
index,
rowType,

// Col,
colIndex,

// Span
colSpan,
rowSpan,
Expand All @@ -118,11 +126,14 @@ function Cell<RecordType>(props: CellProps<RecordType>) {
} = props;

const cellPrefixCls = `${prefixCls}-cell`;
const { supportSticky, allColumnsFixedLeft, rowHoverable } = useContext(TableContext, [
'supportSticky',
'allColumnsFixedLeft',
'rowHoverable',
]);
const { supportSticky, allColumnsFixedLeft, rowHoverable, bodyScrollLeft, headerCellRefs } =
useContext(TableContext, [
'supportSticky',
'allColumnsFixedLeft',
'rowHoverable',
'bodyScrollLeft',
'headerCellRefs',
]);

// ====================== Value =======================
const [childNode, legacyCellProps] = useCellRender(
Expand Down Expand Up @@ -171,6 +182,16 @@ function Cell<RecordType>(props: CellProps<RecordType>) {
additionalProps?.onMouseLeave?.(event);
});

let mergedLastFixLeft = lastFixLeft;
const { current } = headerCellRefs;
const dom = current[colIndex];
if (lastFixLeft && dom) {
const offsetLeft =
dom.getBoundingClientRect().x - dom.parentElement.getBoundingClientRect().x || 0;

// should not be tagged as lastFixLeft if cell is not stickying;
mergedLastFixLeft = typeof fixLeft === 'number' && offsetLeft === fixLeft + bodyScrollLeft;
}
// ====================== Render ======================
if (mergedColSpan === 0 || mergedRowSpan === 0) {
return null;
Expand All @@ -192,8 +213,8 @@ function Cell<RecordType>(props: CellProps<RecordType>) {
{
[`${cellPrefixCls}-fix-left`]: isFixLeft && supportSticky,
[`${cellPrefixCls}-fix-left-first`]: firstFixLeft && supportSticky,
[`${cellPrefixCls}-fix-left-last`]: lastFixLeft && supportSticky,
[`${cellPrefixCls}-fix-left-all`]: lastFixLeft && allColumnsFixedLeft && supportSticky,
[`${cellPrefixCls}-fix-left-last`]: mergedLastFixLeft && supportSticky,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

直接拆解出来,多做一个 div holder 专门用来绘制阴影,也不用依赖 cell 了。

[`${cellPrefixCls}-fix-left-all`]: mergedLastFixLeft && allColumnsFixedLeft && supportSticky,
[`${cellPrefixCls}-fix-right`]: isFixRight && supportSticky,
[`${cellPrefixCls}-fix-right-first`]: firstFixRight && supportSticky,
[`${cellPrefixCls}-fix-right-last`]: lastFixRight && supportSticky,
Expand Down Expand Up @@ -237,6 +258,7 @@ function Cell<RecordType>(props: CellProps<RecordType>) {

return (
<Component
ref={ref}
{...legacyCellProps}
{...additionalProps}
className={mergedClassName}
Expand All @@ -257,4 +279,6 @@ function Cell<RecordType>(props: CellProps<RecordType>) {
);
}

export default React.memo(Cell) as typeof Cell;
export default React.memo(React.forwardRef(Cell)) as <RecordType>(
props: CellProps<RecordType> & { ref?: React.ForwardedRef<HTMLTableCellElement> },
) => React.JSX.Element;
8 changes: 7 additions & 1 deletion src/Header/HeaderRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ const HeaderRow = <RecordType extends any>(props: RowProps<RecordType>) => {
onHeaderRow,
index,
} = props;
const { prefixCls, direction } = useContext(TableContext, ['prefixCls', 'direction']);
const { prefixCls, direction, headerCellRefs } = useContext(TableContext, [
'prefixCls',
'direction',
'headerCellRefs',
]);
let rowProps: React.HTMLAttributes<HTMLElement>;
if (onHeaderRow) {
rowProps = onHeaderRow(
Expand Down Expand Up @@ -62,6 +66,8 @@ const HeaderRow = <RecordType extends any>(props: RowProps<RecordType>) => {

return (
<Cell
colIndex={cellIndex}
ref={headerCellRef => (headerCellRefs.current[cellIndex] = headerCellRef)}
{...cell}
scope={column.title ? (cell.colSpan > 1 ? 'colgroup' : 'col') : null}
ellipsis={column.ellipsis}
Expand Down
7 changes: 7 additions & 0 deletions src/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -435,12 +435,14 @@ function Table<RecordType extends DefaultRecordType>(
}
}
}
const [bodyScrollLeft, setBodyScrollLeft] = React.useState<number>(0);

const onInternalScroll = useEvent(
({ currentTarget, scrollLeft }: { currentTarget: HTMLElement; scrollLeft?: number }) => {
const isRTL = direction === 'rtl';
const mergedScrollLeft =
typeof scrollLeft === 'number' ? scrollLeft : currentTarget.scrollLeft;
setBodyScrollLeft(mergedScrollLeft);

const compareTarget = currentTarget || EMPTY_SCROLL_TARGET;
if (!getScrollTarget() || getScrollTarget() === compareTarget) {
Expand Down Expand Up @@ -796,6 +798,7 @@ function Table<RecordType extends DefaultRecordType>(

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

const headerCellRefs = React.useRef<HTMLTableCellElement[]>([]);
const TableContextValue = React.useMemo(
() => ({
// Scroll
Expand Down Expand Up @@ -846,6 +849,8 @@ function Table<RecordType extends DefaultRecordType>(
childrenColumnName: mergedChildrenColumnName,

rowHoverable,
bodyScrollLeft,
headerCellRefs,
}),
[
// Scroll
Expand Down Expand Up @@ -895,6 +900,8 @@ function Table<RecordType extends DefaultRecordType>(
mergedChildrenColumnName,

rowHoverable,
bodyScrollLeft,
headerCellRefs,
],
);

Expand Down
3 changes: 2 additions & 1 deletion src/context/TableContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,9 @@ export interface TableContextProps<RecordType = any> {
expandedKeys: Set<React.Key>;
getRowKey: GetRowKey<RecordType>;
childrenColumnName: string;

headerCellRefs: React.MutableRefObject<HTMLTableCellElement[]>;
rowHoverable?: boolean;
bodyScrollLeft?: number;
}

const TableContext = createContext<TableContextProps>();
Expand Down
39 changes: 39 additions & 0 deletions tests/FixedColumn.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,31 @@ describe('Table.FixedColumn', () => {
offsetWidth: {
get: () => 1000,
},
getBoundingClientRect() {
if (this.tagName === 'TR') {
return {
x: 0,
y: 0,
width: 1000,
height: 105,
};
}
if (this.textContent === 'title2') {
return {
x: 93,
y: 0,
width: 93,
height: 105,
};
}

return {
x: 0,
y: 0,
width: 100,
height: 100,
};
},
});
});

Expand Down Expand Up @@ -249,6 +274,20 @@ describe('Table.FixedColumn', () => {

it('when all columns fixed left,cell should has classname rc-table-cell-fix-left-all', async () => {
const wrapper = mount(<Table columns={columns.slice(0, 2)} data={data} scroll={{ x: 1000 }} />);

// make `mergedLastFixLeft`'s calculation work.
act(() => {
wrapper
.find(RcResizeObserver.Collection)
.first()
.props()
.onBatchResize([
{
data: wrapper.find('table ResizeObserver').first().props().data,
size: { width: 93, offsetWidth: 93 },
} as any,
]);
});
await safeAct(wrapper);
expect(wrapper.find('.rc-table-cell-fix-left-all')).toHaveLength(10);
});
Expand Down