index.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import {Spin} from 'antd';
  2. import 'antd/lib/table/style';
  3. import {ColumnsType} from 'antd/es/table';
  4. import {
  5. createPageContext,
  6. createSearchContext,
  7. usePage,
  8. useTableSearchState,
  9. } from '@hooks';
  10. import {PAGE_SIZE_LIST, calcColumnsWidth} from '@utils';
  11. import {ReactElement, useMemo} from 'react';
  12. import {useTable} from './hooks';
  13. import {flexRender} from '@tanstack/react-table';
  14. import css from './index.module.css';
  15. import classNames from 'classnames';
  16. type Props<T> = {
  17. columns: ColumnsType<T>;
  18. data: T[];
  19. pageContext: ReturnType<typeof createPageContext>;
  20. searchContext: ReturnType<typeof createSearchContext>;
  21. count: number;
  22. rowKey?: string;
  23. 'data-testid'?: string;
  24. pageSizeList?: string[];
  25. };
  26. function Table<T extends Record<string, any>>(props: Props<T>): ReactElement {
  27. const {
  28. columns,
  29. data,
  30. pageContext,
  31. searchContext,
  32. count,
  33. rowKey,
  34. pageSizeList = PAGE_SIZE_LIST,
  35. } = props;
  36. const [{page, pageSize}, {onPageChange}] = usePage(pageContext);
  37. const [isSearching] = useTableSearchState(searchContext);
  38. const colWidth = calcColumnsWidth(columns);
  39. const scrollX = colWidth > 0 ? {x: colWidth} : void 0;
  40. const tableColumns = useMemo(
  41. function () {
  42. return [
  43. {
  44. title: '序号',
  45. width: 64,
  46. render(_: any, __: any, idx: number) {
  47. return idx + 1;
  48. },
  49. align: 'center',
  50. },
  51. ...columns,
  52. ];
  53. },
  54. [columns],
  55. );
  56. const {getHeaderGroups, getRowModel, getCenterTotalSize} = useTable(
  57. columns,
  58. data,
  59. );
  60. return (
  61. <Spin spinning={isSearching}>
  62. <div className={css.tableWrapper}>
  63. <table className={css.table} style={{width: getCenterTotalSize()}}>
  64. <thead className={css.tableHead}>
  65. {getHeaderGroups().map(function ({id, headers}) {
  66. return (
  67. <tr key={id}>
  68. {headers.map(header => (
  69. <th key={header.id} style={{width: header.getSize()}}>
  70. {header.isPlaceholder
  71. ? null
  72. : flexRender(
  73. header.column.columnDef.header,
  74. header.getContext(),
  75. )}
  76. <div
  77. onMouseDown={header.getResizeHandler()}
  78. className={classNames(css.resizer, {
  79. [css.resizing]: header.column.getIsResizing(),
  80. })}
  81. />
  82. </th>
  83. ))}
  84. </tr>
  85. );
  86. })}
  87. </thead>
  88. <tbody className={css.tableBody}>
  89. {getRowModel().rows.map(function ({id, getVisibleCells}) {
  90. return (
  91. <tr key={id}>
  92. {getVisibleCells().map(function ({id, column, getContext}) {
  93. return (
  94. <td key={id} style={{width: column.getSize()}}>
  95. {flexRender(column.columnDef.cell, getContext())}
  96. </td>
  97. );
  98. })}
  99. </tr>
  100. );
  101. })}
  102. </tbody>
  103. </table>
  104. </div>
  105. </Spin>
  106. );
  107. }
  108. export default Table;