Kaynağa Gözat

feat: ui调整完成

xyh 2 yıl önce
ebeveyn
işleme
fd366aa273

+ 1 - 0
packages/app/package.json

@@ -18,6 +18,7 @@
     "@hookform/resolvers": "^2.9.10",
     "@icon-park/react": "^1.4.2",
     "@tanstack/react-query": "^4.23.0",
+    "@tanstack/react-table": "^8.8.5",
     "ahooks": "^3.7.4",
     "antd": "^5.2.0",
     "axios": "^1.2.6",

+ 53 - 0
packages/app/src/components/table/hooks.ts

@@ -0,0 +1,53 @@
+import {
+  createColumnHelper,
+  useReactTable,
+  getCoreRowModel,
+} from '@tanstack/react-table';
+import {ColumnType} from 'antd/es/table';
+import {useMemo} from 'react';
+
+export function useTable<T extends Record<string, any>>(
+  columns: ColumnType<T>[],
+  data: T[],
+) {
+  const columnList = useMemo(function () {
+    const hepler = createColumnHelper<Record<string, any>>();
+
+    const tableColumns = columns.map(function ({dataIndex, title, render}) {
+      if (render) {
+        return hepler.display({
+          id: dataIndex!.toString(),
+          header: title?.toString(),
+          cell(props) {
+            return render(
+              props.getValue(),
+              props.row.original as T,
+              props.row.index,
+            );
+          },
+        });
+      }
+      return hepler.accessor(dataIndex!.toString(), {
+        header: title?.toString(),
+        cell: props => props.getValue(),
+      });
+    });
+
+    tableColumns.unshift(
+      hepler.display({
+        header: '序号',
+        cell({row}) {
+          return row.index;
+        },
+      }),
+    );
+
+    return tableColumns;
+  }, []);
+
+  return useReactTable({
+    data,
+    columns: columnList,
+    getCoreRowModel: getCoreRowModel(),
+  });
+}

+ 60 - 0
packages/app/src/components/table/index.module.css

@@ -0,0 +1,60 @@
+.table-wrapper {
+  width: 100%;
+  overflow: auto;
+  border-inline-start: 1px solid #f0f0f0;
+  border-start-start-radius: 8px;
+  border-start-end-radius: 8px;
+}
+
+.table {
+  box-sizing: border-box;
+  min-width: 100%;
+  padding: 0;
+  margin: 0;
+  font-size: 14px;
+  line-height: 1.5714;
+  color: rgb(0 0 0 / 88%);
+  text-align: start;
+  list-style: none;
+  table-layout: auto;
+  border-spacing: 0;
+  border-collapse: separate;
+  background: #fff;
+  border-top: 1px solid #f0f0f0;
+  border-radius: 8px 8px 0 0;
+}
+
+.table-head {
+  text-align: center;
+
+  & th {
+    position: relative;
+    padding: 16px;
+    margin: 0;
+    font-weight: 600;
+    color: rgb(0 0 0 / 88%);
+    text-align: center;
+    overflow-wrap: break-word;
+    list-style: none;
+    background: #fafafa;
+    border-inline-end: 1px solid #f0f0f0;
+    border-bottom: 1px solid #f0f0f0;
+    border-start-start-radius: 8px;
+    transition: background 0.2s ease;
+
+    &:last-child {
+      border-start-end-radius: 8px;
+    }
+  }
+}
+
+.table-body {
+  & td {
+    position: relative;
+    padding: 16px;
+    overflow-wrap: break-word;
+    border-inline-end: 1px solid #f0f0f0;
+    border-bottom: 1px solid #f0f0f0;
+    transition: background 0.2s, border-color 0.2s;
+  }
+}

+ 45 - 22
packages/app/src/components/table/index.tsx

@@ -1,4 +1,5 @@
-import {Table as OriTable} from 'antd';
+import {Spin} from 'antd';
+import 'antd/lib/table/style';
 import {ColumnsType} from 'antd/es/table';
 import {
   createPageContext,
@@ -8,6 +9,9 @@ import {
 } from '@hooks';
 import {PAGE_SIZE_LIST, calcColumnsWidth} from '@utils';
 import {ReactElement, useMemo} from 'react';
+import {useTable} from './hooks';
+import {flexRender} from '@tanstack/react-table';
+import css from './index.module.css';
 
 type Props<T> = {
   columns: ColumnsType<T>;
@@ -34,6 +38,7 @@ function Table<T extends Record<string, any>>(props: Props<T>): ReactElement {
   const [isSearching] = useTableSearchState(searchContext);
   const colWidth = calcColumnsWidth(columns);
   const scrollX = colWidth > 0 ? {x: colWidth} : void 0;
+  const {getHeaderGroups, getRowModel} = useTable(columns, data);
 
   const tableColumns = useMemo(
     function () {
@@ -53,27 +58,45 @@ function Table<T extends Record<string, any>>(props: Props<T>): ReactElement {
   );
 
   return (
-    <OriTable
-      data-testid={props['data-testid']}
-      columns={tableColumns as ColumnsType<T>}
-      dataSource={data}
-      pagination={{
-        pageSize,
-        showQuickJumper: true,
-        pageSizeOptions: pageSizeList,
-        total: count,
-        showSizeChanger: true,
-        onChange: onPageChange,
-        current: page,
-        showTotal(total) {
-          return `共${total}条数据`;
-        },
-      }}
-      rowKey={rowKey ?? 'id'}
-      loading={isSearching}
-      scroll={scrollX}
-      bordered
-    />
+    <Spin spinning={isSearching}>
+      <div className={css.tableWrapper}>
+        <table className={css.table}>
+          <thead className={css.tableHead}>
+            {getHeaderGroups().map(function ({id, headers}) {
+              return (
+                <tr key={id}>
+                  {headers.map(header => (
+                    <th key={header.id}>
+                      {header.isPlaceholder
+                        ? null
+                        : flexRender(
+                            header.column.columnDef.header,
+                            header.getContext(),
+                          )}
+                    </th>
+                  ))}
+                </tr>
+              );
+            })}
+          </thead>
+          <tbody className={css.tableBody}>
+            {getRowModel().rows.map(function ({id, getVisibleCells}) {
+              return (
+                <tr key={id}>
+                  {getVisibleCells().map(function ({id, column, getContext}) {
+                    return (
+                      <td key={id}>
+                        {flexRender(column.columnDef.cell, getContext())}
+                      </td>
+                    );
+                  })}
+                </tr>
+              );
+            })}
+          </tbody>
+        </table>
+      </div>
+    </Spin>
   );
 }
 

+ 20 - 0
pnpm-lock.yaml

@@ -116,6 +116,9 @@ importers:
       '@tanstack/react-query':
         specifier: ^4.23.0
         version: 4.23.0(react-dom@18.2.0)(react@18.2.0)
+      '@tanstack/react-table':
+        specifier: ^8.8.5
+        version: 8.8.5(react-dom@18.2.0)(react@18.2.0)
       ahooks:
         specifier: ^3.7.4
         version: 3.7.4(react@18.2.0)
@@ -3043,6 +3046,23 @@ packages:
       react-dom: 18.2.0(react@18.2.0)
       use-sync-external-store: 1.2.0(react@18.2.0)
 
+  /@tanstack/react-table@8.8.5(react-dom@18.2.0)(react@18.2.0):
+    resolution: {integrity: sha512-g/t21E/ICHvaCOJOhsDNr5QaB/6aDQEHFbx/YliwwU/CJThMqG+dS28vnToIBV/5MBgpeXoGRi2waDJVJlZrtg==}
+    engines: {node: '>=12'}
+    peerDependencies:
+      react: '>=16'
+      react-dom: '>=16'
+    dependencies:
+      '@tanstack/table-core': 8.8.5
+      react: 18.2.0
+      react-dom: 18.2.0(react@18.2.0)
+    dev: false
+
+  /@tanstack/table-core@8.8.5:
+    resolution: {integrity: sha512-Xnwa1qxpgvSW7ozLiexmKp2PIYcLBiY/IizbdGriYCL6OOHuZ9baRhrrH51zjyz+61ly6K59rmt6AI/3RR+97Q==}
+    engines: {node: '>=12'}
+    dev: false
+
   /@testing-library/dom@8.19.0:
     resolution: {integrity: sha512-6YWYPPpxG3e/xOo6HIWwB/58HukkwIVTOaZ0VwdMVjhRUX/01E4FtQbck9GazOOj7MXHc5RBzMrU86iBJHbI+A==}
     engines: {node: '>=12'}