Selaa lähdekoodia

feat: table增加renderSubComponent

xyh 2 vuotta sitten
vanhempi
commit
8805c67564

+ 10 - 12
packages/app/src/components/table/Body.tsx

@@ -2,6 +2,7 @@ import classNames from 'classnames';
 import {
   Dispatch,
   MutableRefObject,
+  ReactNode,
   SetStateAction,
   forwardRef,
   useEffect,
@@ -9,7 +10,7 @@ import {
 } from 'react';
 import BodyTr from './BodyTr';
 import {Empty} from 'antd';
-import {Cell, HeaderGroup, RowModel} from '@tanstack/react-table';
+import {HeaderGroup, Row, RowModel} from '@tanstack/react-table';
 import {
   DndContext,
   DragEndEvent,
@@ -38,11 +39,11 @@ type Props = {
   data: any[],
   setData: Dispatch<SetStateAction<any[]>>,
   isSecondLevel?: boolean,
+  renderSubComponent?: (row: Row<Record<string, any>>) => ReactNode,
 };
 
 type ActiveState = {
-  getVisibleCells: () => Cell<Record<string, any>, unknown>[],
-  id: string,
+  row: Row<Record<string, any>>,
 } | null;
 
 export default forwardRef<HTMLDivElement, Props>(function TableBody(
@@ -58,6 +59,7 @@ export default forwardRef<HTMLDivElement, Props>(function TableBody(
     rawKey,
     setData,
     isSecondLevel,
+    renderSubComponent,
   },
   ref,
 ) {
@@ -128,18 +130,14 @@ export default forwardRef<HTMLDivElement, Props>(function TableBody(
           >
             <tbody className="ld-table-body">
               {getRowModel().rows.length > 0 ? (
-                getRowModel().rows.map(function({
-                  id,
-                  getVisibleCells,
-                  original,
-                }) {
+                getRowModel().rows.map(function(row) {
                   return (
                     <BodyTr
-                      id={id}
-                      getVisibleCells={getVisibleCells}
-                      key={id}
-                      highlight={original[hightlightKey as string ?? 'id'] === highlightValue}
+                      key={row.id}
+                      highlight={row.original[hightlightKey as string ?? 'id'] === highlightValue}
                       enableDnd={enableDnd}
+                      row={row}
+                      renderSubComponent={renderSubComponent}
                     />
                   );
                 })

+ 62 - 51
packages/app/src/components/table/BodyTr.tsx

@@ -1,75 +1,86 @@
 import {useSortable} from '@dnd-kit/sortable';
-import {Cell, flexRender} from '@tanstack/react-table';
+import {Row, flexRender} from '@tanstack/react-table';
 import classNames from 'classnames';
-import {CSSProperties, FC} from 'react';
+import {CSSProperties, FC, ReactNode} from 'react';
 
 type Props = {
-  getVisibleCells: () => Cell<Record<string, any>, unknown>[],
-  id: string,
   highlight?: boolean,
   enableDnd?: boolean,
   preview?: boolean,
+  row: Row<Record<string, any>>,
+  renderSubComponent?: (row: Row<Record<string, any>>) => ReactNode;
 };
 
 const BodyTr: FC<Props> = function({
-  getVisibleCells,
+  row,
   highlight,
-  id,
   enableDnd,
   preview,
+  renderSubComponent,
 }) {
-  const trList = getVisibleCells();
+  const trList = row.getVisibleCells();
   const {setNodeRef, listeners, attributes} = useSortable({
-    id,
+    id: row.id,
     disabled: !enableDnd,
     data: {
-      getVisibleCells,
-      id,
+      row,
     },
   });
 
   return (
-    <tr
-      ref={setNodeRef}
-      {...listeners}
-      {...attributes}
-      style={{cursor: enableDnd || preview ? 'move' : 'auto'}}
-      className={classNames('ld-table-body-tr ', {
-        'ld-table-tr-highlight': highlight,
-        'ld-table-tr-preview': preview,
-      })}
-    >
-      {trList.map(function({
-        id,
-        column,
-        getContext,
-      }) {
-        const {align, fixed, fixedStyle} = column.columnDef.meta as {
-          align?: 'left' | 'center' | 'right';
-          fixed?: 'right' | 'left';
-          fixedStyle: CSSProperties,
-        };
-        return (
-          <td
-            key={id}
-            className={classNames({
-              'ld-table-fixed-right ld-table-right-fixed-shadow': fixed === 'right',
-              'ld-table-fixed-left ld-table-left-fixed-shadow': fixed === 'left',
-            })}
-            style={{
-              width: column.getSize(),
-              textAlign: align ?? 'left',
-              ...fixedStyle,
-            }}
-          >
-            {flexRender(
-              column.columnDef.cell,
-              getContext(),
-            )}
-          </td>
-        );
-      })}
-    </tr>
+    <>
+      <tr
+        ref={setNodeRef}
+        {...listeners}
+        {...attributes}
+        style={{cursor: enableDnd || preview ? 'move' : 'auto'}}
+        className={classNames('ld-table-body-tr ', {
+          'ld-table-tr-highlight': highlight,
+          'ld-table-tr-preview': preview,
+        })}
+      >
+        {trList.map(function({
+          id,
+          column,
+          getContext,
+        }) {
+          const {align, fixed, fixedStyle} = column.columnDef.meta as {
+            align?: 'left' | 'center' | 'right';
+            fixed?: 'right' | 'left';
+            fixedStyle: CSSProperties,
+          };
+          return (
+            <td
+              key={id}
+              className={classNames({
+                'ld-table-fixed-right ld-table-right-fixed-shadow': fixed === 'right',
+                'ld-table-fixed-left ld-table-left-fixed-shadow': fixed === 'left',
+              })}
+              style={{
+                width: column.getSize(),
+                textAlign: align ?? 'left',
+                ...fixedStyle,
+              }}
+            >
+              {flexRender(
+                column.columnDef.cell,
+                getContext(),
+              )}
+            </td>
+          );
+        })}
+      </tr>
+
+      {row.getIsExpanded() && Boolean(renderSubComponent)
+        ? (
+          <tr className="ld-table-body-tr">
+            <td colSpan={row.getVisibleCells().length}>
+              {renderSubComponent?.(row)}
+            </td>
+          </tr>
+        )
+        : null}
+    </>
   );
 };
 

+ 5 - 1
packages/app/src/components/table/hooks.tsx

@@ -173,6 +173,7 @@ export function useTable<T extends Record<string, any>>(
     rawKey?: keyof T;
     onSortingChange?: (state: ColumnSort | null) => void;
     subRowKey?: keyof T;
+    hasRenderSubComponent: boolean;
   },
 ) {
   const {
@@ -182,6 +183,7 @@ export function useTable<T extends Record<string, any>>(
     rawKey,
     onSortingChange,
     subRowKey,
+    hasRenderSubComponent,
   } = options;
 
   const {columnList, hasSort, hasGroup} = useMemo(
@@ -237,7 +239,9 @@ export function useTable<T extends Record<string, any>>(
     getRowId: row => row[rawKey as string | undefined ?? 'id'],
     onSortingChange: setSorting,
     getSubRows: subRowKey ? row => row[subRowKey as string] : void 0,
-    getExpandedRowModel: subRowKey ? getExpandedRowModel() : void 0,
+    getExpandedRowModel: subRowKey && !hasRenderSubComponent
+      ? getExpandedRowModel()
+      : void 0,
     onExpandedChange: setExpanded,
   });
 

+ 4 - 0
packages/app/src/components/table/index.tsx

@@ -58,6 +58,7 @@ type Props<T extends Record<string, unknown>> = {
   rawKey?: keyof T;
   onSortingChange?: (state: ColumnSort | null) => void;
   subRowKey?: keyof T;
+  renderSubComponent?: (row: Row<Record<string, any>>) => ReactNode;
 };
 
 function LDTable<T extends Record<string, any>>(props: Props<T>): ReactElement {
@@ -80,6 +81,7 @@ function LDTable<T extends Record<string, any>>(props: Props<T>): ReactElement {
     enableRowDnd,
     onSortingChange,
     subRowKey,
+    renderSubComponent,
   } = props;
   const [klonaData, setKlonaData] = useState(klona(data));
   const [{page, pageSize}, {setPageContext}] = useTablePageContext(pageContext);
@@ -105,6 +107,7 @@ function LDTable<T extends Record<string, any>>(props: Props<T>): ReactElement {
       rawKey,
       onSortingChange,
       subRowKey,
+      hasRenderSubComponent: Boolean(renderSubComponent),
     },
   );
 
@@ -148,6 +151,7 @@ function LDTable<T extends Record<string, any>>(props: Props<T>): ReactElement {
           enableDnd={enableRowDnd && (!hasSort || Boolean(onSortingChange))}
           setData={setKlonaData}
           isSecondLevel={isSecondLevel}
+          renderSubComponent={renderSubComponent}
         />
       </div>
       <Pagination