zhou zhou
18 小时以前 10776dd6f7f9ef9e47419427fcb1b692ed73d54d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
 
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;