|
import React from 'react';
|
import { DataTable } from 'react-admin';
|
|
/**
|
* StickyDataTable Component
|
*
|
* 封装 react-admin 的 DataTable,实现传入列名即可固定列。
|
*
|
* @param {Object} props
|
* @param {string[]} props.stickyLeft - 需要固定在左侧的字段 source 列表
|
* @param {string[]} props.stickyRight - 需要固定在右侧的字段 source 列表
|
*/
|
export const StickyDataTable = ({ stickyLeft = [], stickyRight = [], children, ...props }) => {
|
|
// 递归处理 Children,确保即便是 Fragment 包裹的列也能被处理
|
const processChildren = (children) => {
|
return React.Children.map(children, (child) => {
|
if (!React.isValidElement(child)) return child;
|
|
// 如果是 Fragment,递归处理其 children
|
if (child.type === React.Fragment) {
|
return <React.Fragment>{processChildren(child.props.children)}</React.Fragment>;
|
}
|
|
const source = child.props.source;
|
let stickyStyle = {};
|
|
// 左侧固定
|
if (stickyLeft.includes(source)) {
|
stickyStyle = {
|
position: 'sticky',
|
left: 0,
|
zIndex: 2, // 比普通内容高
|
backgroundColor: '#FFFFFF',
|
'.MuiTableRow-root:not(.MuiTableRow-head):hover &': {
|
backgroundColor: '#f5f5f5'
|
}
|
};
|
}
|
|
// 右侧固定
|
if (stickyRight.includes(source)) {
|
stickyStyle = {
|
position: 'sticky',
|
right: 0,
|
zIndex: 2,
|
backgroundColor: '#FFFFFF',
|
'.MuiTableRow-root:not(.MuiTableRow-head):hover &': {
|
backgroundColor: '#f5f5f5'
|
}
|
};
|
}
|
|
if (Object.keys(stickyStyle).length > 0) {
|
// 合并 sx
|
return React.cloneElement(child, {
|
sx: { ...child.props.sx, ...stickyStyle }
|
});
|
}
|
|
return child;
|
});
|
};
|
|
return (
|
<DataTable {...props} sx={{
|
'& .MuiTableCell-head': {
|
zIndex: 4,
|
borderBottom: 'none' // 遵循之前的优化,去除表头下边框
|
},
|
}}>
|
{processChildren(children)}
|
</DataTable>
|
);
|
};
|
|
export default StickyDataTable;
|