| | |
| | | |
| | | import React, { useMemo } from 'react'; |
| | | import React, { useMemo, useRef, useEffect } from 'react'; |
| | | import { DataTable, useDataTableDataContext, useTranslate } from 'react-admin'; |
| | | import { TableFooter, TableRow, TableCell } from '@mui/material'; |
| | | |
| | |
| | | * DataTable 样式常量 |
| | | */ |
| | | const tableStyles = { |
| | | '& .RaBulkActionsToolbar-toolbar': { |
| | | top: 0, |
| | | zIndex: 6, |
| | | }, |
| | | '& .MuiTableCell-head': { |
| | | zIndex: 4, |
| | | borderBottom: 'none' |
| | |
| | | * - label: 显示的标签,支持翻译 key 或直接显示的文本 |
| | | * - render: 可选,自定义渲染函数 (value, data) => ReactNode |
| | | * @param {string} props.footerLabel - footer 第一列标签,默认'合计' |
| | | * @param {number} props.bulkActionsOffsetY - 批量操作栏展开时向下偏移(px) |
| | | */ |
| | | export const StickyDataTable = ({ |
| | | stickyLeft = [], |
| | | stickyRight = [], |
| | | footerConfig, |
| | | footerLabel = '合计', |
| | | bulkActionsOffsetY = 0, |
| | | children, |
| | | ...props |
| | | }) => { |
| | |
| | | return () => <StickyTableFooter footerConfig={footerConfig} footerLabel={footerLabel} />; |
| | | }, [footerConfig, footerLabel]); |
| | | |
| | | const dataTableStyles = useMemo(() => { |
| | | return { |
| | | ...tableStyles, |
| | | '& .RaBulkActionsToolbar-toolbar:not(.RaBulkActionsToolbar-collapsed)': { |
| | | transform: `translateY(${bulkActionsOffsetY}px)`, |
| | | zIndex: 10, |
| | | opacity: 1, |
| | | }, |
| | | '& .RaBulkActionsToolbar-toolbar.RaBulkActionsToolbar-collapsed': { |
| | | zIndex: 10, |
| | | opacity: 1, |
| | | }, |
| | | }; |
| | | }, [bulkActionsOffsetY]); |
| | | |
| | | const containerRef = useRef(null); |
| | | useEffect(() => { |
| | | const el = containerRef.current; |
| | | if (!el) return; |
| | | const clearExpandIconAriaHidden = () => { |
| | | el.querySelectorAll('.RaDataTable-expandIcon').forEach((btn) => btn.removeAttribute('aria-hidden')); |
| | | }; |
| | | clearExpandIconAriaHidden(); |
| | | const mo = new MutationObserver(clearExpandIconAriaHidden); |
| | | mo.observe(el, { attributes: true, attributeFilter: ['aria-hidden'], subtree: true }); |
| | | return () => mo.disconnect(); |
| | | }, []); |
| | | |
| | | return ( |
| | | <DataTable {...props} foot={footerComponent} sx={tableStyles}> |
| | | <span ref={containerRef} style={{ display: 'contents' }}> |
| | | <DataTable {...props} foot={footerComponent} sx={dataTableStyles}> |
| | | {/* {processedChildren} */} |
| | | {processedChildren |
| | | .map((column) => ( |
| | |
| | | )) |
| | | } |
| | | </DataTable> |
| | | </span> |
| | | ); |
| | | }; |
| | | |