Skip to content
Merged
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
47 changes: 47 additions & 0 deletions docs/examples/measureRowRender.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react';
import Table from 'rc-table';

// 示例:使用 measureRowRender 来隐藏 MeasureRow 中的弹层
const MeasureRowRenderExample = () => {
const columns = [
{
title: (
<div>
Name
<div className="filter-dropdown" style={{ display: 'none' }}>
Filter Content
</div>
</div>
),
dataIndex: 'name',
key: 'name',
width: 100,
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
width: 80,
},
];

const data = [
{ key: 1, name: 'John', age: 25 },
{ key: 2, name: 'Jane', age: 30 },
];

// 自定义 MeasureRow 渲染,隐藏弹层内容
const measureRowRender = measureRow => <div style={{ display: 'none' }}>{measureRow}</div>;

return (
<Table
columns={columns}
data={data}
sticky
scroll={{ x: true }}
measureRowRender={measureRowRender}
/>
);
};

export default MeasureRowRenderExample;
7 changes: 6 additions & 1 deletion src/Body/MeasureRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import * as React from 'react';
import ResizeObserver from 'rc-resize-observer';
import MeasureCell from './MeasureCell';
import isVisible from 'rc-util/lib/Dom/isVisible';
import { useContext } from '@rc-component/context';
import TableContext from '../context/TableContext';
import type { ColumnType } from '../interface';

export interface MeasureRowProps {
Expand All @@ -18,8 +20,9 @@ export default function MeasureRow({
columns,
}: MeasureRowProps) {
const ref = React.useRef<HTMLTableRowElement>(null);
const { measureRowRender } = useContext(TableContext, ['measureRowRender']);

return (
const measureRow = (
<tr aria-hidden="true" className={`${prefixCls}-measure-row`} style={{ height: 0 }} ref={ref}>
<ResizeObserver.Collection
onBatchResize={infoList => {
Expand All @@ -44,4 +47,6 @@ export default function MeasureRow({
</ResizeObserver.Collection>
</tr>
);

return measureRowRender ? measureRowRender(measureRow) : measureRow;
}
14 changes: 14 additions & 0 deletions src/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,12 @@ export interface TableProps<RecordType = any>
internalRefs?: {
body: React.MutableRefObject<HTMLDivElement>;
};
/**
* @private Internal usage, may remove by refactor.
*
* !!! DO NOT USE IN PRODUCTION ENVIRONMENT !!!
*/
measureRowRender?: (measureRow: React.ReactNode) => React.ReactNode;
}

function defaultEmpty() {
Expand Down Expand Up @@ -210,6 +216,9 @@ function Table<RecordType extends DefaultRecordType>(
onRow,
onHeaderRow,

// Measure Row
measureRowRender,

// Events
onScroll,

Expand Down Expand Up @@ -850,6 +859,9 @@ function Table<RecordType extends DefaultRecordType>(
childrenColumnName: mergedChildrenColumnName,

rowHoverable,

// Measure Row
measureRowRender,
}),
[
// Scroll
Expand Down Expand Up @@ -901,6 +913,8 @@ function Table<RecordType extends DefaultRecordType>(
mergedChildrenColumnName,

rowHoverable,

measureRowRender,
],
);

Expand Down
3 changes: 3 additions & 0 deletions src/context/TableContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ export interface TableContextProps<RecordType = any> {
rowHoverable?: boolean;

expandedRowOffset: ExpandableConfig<RecordType>['expandedRowOffset'];

// Measure Row
measureRowRender?: (measureRow: React.ReactNode) => React.ReactNode;
}

const TableContext = createContext<TableContextProps>();
Expand Down
58 changes: 58 additions & 0 deletions tests/FixedHeader.spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -265,4 +265,62 @@ describe('Table.FixedHeader', () => {
'rc-table-cell-fix-left-last',
);
});

it('should support measureRowRender to wrap MeasureRow with custom provider', async () => {
const FilterDropdown = ({ visible, onVisibleChange }) => (
<div className="test-filter-dropdown" style={{ display: visible ? 'block' : 'none' }}>
Filter Content
<button onClick={() => onVisibleChange && onVisibleChange(!visible)}>Toggle</button>
</div>
);

const columns = [
{
title: (
<div>
Name
<FilterDropdown visible={true} onVisibleChange={() => {}} />
</div>
),
dataIndex: 'name',
key: 'name',
width: 100,
},
];

const data = [
{
key: 1,
name: 'Jack',
},
];

// Mock ConfigProvider-like wrapper
const measureRowRender = measureRow => (
<div data-testid="measure-row-wrapper" style={{ display: 'none' }}>
{measureRow}
</div>
);

const wrapper = mount(
<Table
columns={columns}
data={data}
sticky
scroll={{ x: true }}
measureRowRender={measureRowRender}
/>,
);

await safeAct(wrapper);

// Check that measureRowRender wrapper is applied
const measureRowWrapper = wrapper.find('[data-testid="measure-row-wrapper"]');
expect(measureRowWrapper).toHaveLength(1);
expect(measureRowWrapper.prop('style').display).toBe('none');

// Check that MeasureRow is inside the wrapper
const measureRowInWrapper = measureRowWrapper.find('.rc-table-measure-row');
expect(measureRowInWrapper).toHaveLength(1);
});
});