Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/gap fixed columns shadow #1202

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
45 changes: 36 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,19 @@ function Cell<RecordType>(props: CellProps<RecordType>) {
additionalProps?.onMouseLeave?.(event);
});

const mergedLastFixLeft = React.useMemo(() => {
const { current } = headerCellRefs;
const dom = current[colIndex];

if (lastFixLeft && dom && typeof fixLeft === 'number') {
const offsetLeft =
dom.getBoundingClientRect().x - dom.parentElement.getBoundingClientRect().x || 0;

// should not be tagged as lastFixLeft if cell is not stickying;
return offsetLeft === fixLeft + bodyScrollLeft;
}
return lastFixLeft;
}, [bodyScrollLeft, colIndex, fixLeft, headerCellRefs, lastFixLeft]);
// ====================== Render ======================
if (mergedColSpan === 0 || mergedRowSpan === 0) {
return null;
Expand All @@ -192,8 +216,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,
[`${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 +261,7 @@ function Cell<RecordType>(props: CellProps<RecordType>) {

return (
<Component
ref={ref}
{...legacyCellProps}
{...additionalProps}
className={mergedClassName}
Expand All @@ -257,4 +282,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;
13 changes: 12 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 All @@ -43,6 +47,11 @@ const HeaderRow = <RecordType extends any>(props: RowProps<RecordType>) => {

const columnsKey = getColumnsKey(cells.map(cell => cell.column));

const handleHeaderCellRef =
(cellIndex: number) => (headerCellRef: HTMLTableCellElement | null) => {
headerCellRefs.current[cellIndex] = headerCellRef;
};

return (
<RowComponent {...rowProps}>
{cells.map((cell: CellType<RecordType>, cellIndex) => {
Expand All @@ -62,6 +71,8 @@ const HeaderRow = <RecordType extends any>(props: RowProps<RecordType>) => {

return (
<Cell
colIndex={cellIndex}
ref={handleHeaderCellRef(cellIndex)}
{...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,
bbb169 marked this conversation as resolved.
Show resolved Hide resolved
}),
[
// Scroll
Expand Down Expand Up @@ -895,6 +900,8 @@ function Table<RecordType extends DefaultRecordType>(
mergedChildrenColumnName,

rowHoverable,
bodyScrollLeft,
headerCellRefs,
bbb169 marked this conversation as resolved.
Show resolved Hide resolved
],
);

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
Loading