Explorar el Código

feat: table实现超出隐藏

xyh hace 2 años
padre
commit
6f0b8ac973

+ 7 - 1
packages/app/src/components/table/Body.tsx

@@ -40,6 +40,8 @@ type Props = {
   setData: Dispatch<SetStateAction<any[]>>,
   isSecondLevel?: boolean,
   renderSubComponent?: (row: Row<Record<string, any>>) => ReactNode,
+  ellipsis?: boolean,
+  hasEllipsis: boolean,
 };
 
 type ActiveState = {
@@ -60,6 +62,8 @@ export default forwardRef<HTMLDivElement, Props>(function TableBody(
     setData,
     isSecondLevel,
     renderSubComponent,
+    ellipsis,
+    hasEllipsis,
   },
   ref,
 ) {
@@ -125,6 +129,7 @@ export default forwardRef<HTMLDivElement, Props>(function TableBody(
             className={classNames('ld-table', {
               'ld-table-enabled-right-fixed-shadow': scrollProgess !== 'end',
               'ld-table-enabled-left-fixed-shadow': scrollProgess !== 'start',
+              'ld-fixed-table': ellipsis || hasEllipsis,
             })}
             style={{width: getCenterTotalSize()}}
           >
@@ -133,6 +138,7 @@ export default forwardRef<HTMLDivElement, Props>(function TableBody(
                 getRowModel().rows.map(function(row) {
                   return (
                     <BodyTr
+                      enableEllipsis={ellipsis}
                       key={row.id}
                       highlight={row.original[hightlightKey as string ?? 'id'] === highlightValue}
                       enableDnd={enableDnd}
@@ -181,7 +187,7 @@ export default forwardRef<HTMLDivElement, Props>(function TableBody(
                 style={{width: getCenterTotalSize()}}
               >
                 <tbody>
-                  <BodyTr {...active} preview />
+                  <BodyTr {...active} preview enableEllipsis={ellipsis} />
                 </tbody>
               </table>
             </div>

+ 12 - 1
packages/app/src/components/table/BodyTr.tsx

@@ -9,6 +9,7 @@ type Props = {
   preview?: boolean,
   row: Row<Record<string, any>>,
   renderSubComponent?: (row: Row<Record<string, any>>) => ReactNode;
+  enableEllipsis?: boolean;
 };
 
 const BodyTr: FC<Props> = function({
@@ -17,6 +18,7 @@ const BodyTr: FC<Props> = function({
   enableDnd,
   preview,
   renderSubComponent,
+  enableEllipsis,
 }) {
   const trList = row.getVisibleCells();
   const {setNodeRef, listeners, attributes} = useSortable({
@@ -44,17 +46,26 @@ const BodyTr: FC<Props> = function({
           column,
           getContext,
         }) {
-          const {align, fixed, fixedStyle} = column.columnDef.meta as {
+          const {
+            align,
+            fixed,
+            fixedStyle,
+            ellipsis,
+          } = column.columnDef.meta as {
             align?: 'left' | 'center' | 'right';
             fixed?: 'right' | 'left';
             fixedStyle: CSSProperties,
+            ellipsis?: boolean,
           };
+
           return (
             <td
+              title={getContext().getValue() as string}
               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',
+                'ld-table-ellipsis': !fixed && ((enableEllipsis && ellipsis !== false) || ellipsis),
               })}
               style={{
                 width: column.getSize(),

+ 7 - 0
packages/app/src/components/table/Header.tsx

@@ -28,6 +28,8 @@ type Props = {
   disabledHeadSort?: boolean,
   isSecondLevel?: boolean,
   active: Header<Record<string, any>, unknown> | null,
+  ellipsis?: boolean,
+  hasEllipsis: boolean,
 };
 
 export default forwardRef<HTMLDivElement, Props>(function TableHead(
@@ -42,6 +44,8 @@ export default forwardRef<HTMLDivElement, Props>(function TableHead(
     disabledHeadSort,
     isSecondLevel,
     active,
+    ellipsis,
+    hasEllipsis,
   },
   ref,
 ) {
@@ -63,6 +67,7 @@ export default forwardRef<HTMLDivElement, Props>(function TableHead(
             className={classNames('ld-table', {
               'ld-table-enabled-right-fixed-shadow': scrollProgess !== 'end',
               'ld-table-enabled-left-fixed-shadow': scrollProgess !== 'start',
+              'ld-fixed-table': ellipsis || hasEllipsis,
             })}
             style={{width: getCenterTotalSize()}}
           >
@@ -72,6 +77,7 @@ export default forwardRef<HTMLDivElement, Props>(function TableHead(
                   <tr key={id}>
                     {headers.map(header => (
                       <HeaderTh
+                        enableEllipsis={ellipsis}
                         key={header.id}
                         header={header}
                         disabledSizeChange={disabledSizeChange}
@@ -94,6 +100,7 @@ export default forwardRef<HTMLDivElement, Props>(function TableHead(
               <thead className="width-full height-full">
                 <tr className="width-full height-full">
                   <HeaderTh
+                    enableEllipsis={ellipsis}
                     header={active}
                     preview
                   />

+ 12 - 1
packages/app/src/components/table/HeaderTh.tsx

@@ -10,6 +10,7 @@ type Props = {
   preview?: boolean;
   disabledSizeChange?: boolean;
   disabledHeadSort?: boolean;
+  enableEllipsis?: boolean;
 };
 
 const HeaderTh: FC<Props> = function({
@@ -17,17 +18,20 @@ const HeaderTh: FC<Props> = function({
   preview,
   disabledSizeChange,
   disabledHeadSort,
+  enableEllipsis,
 }) {
   const {
     fixed,
     disabledSort: colDisabledSort,
     fixedStyle = {},
     sort: dataSort,
+    ellipsis,
   } = header.column.columnDef.meta as {
     fixed?: 'left' | 'right';
     disabledSort?: boolean;
     fixedStyle?: CSSProperties,
     sort?: boolean,
+    ellipsis?: boolean,
   } ?? {};
 
   const disabledSort = colDisabledSort || disabledHeadSort;
@@ -57,6 +61,7 @@ const HeaderTh: FC<Props> = function({
 
   return (
     <th
+      title={header.getContext().column.columnDef.header as string}
       colSpan={header.colSpan}
       key={header.id}
       style={{...style, ...fixedStyle}}
@@ -66,13 +71,19 @@ const HeaderTh: FC<Props> = function({
       className={classNames('ld-table-head-th', {
         'ld-table-fixed-right ld-table-right-fixed-shadow': fixed === 'right',
         'ld-table-fixed-left ld-table-left-fixed-shadow': fixed === 'left',
+        'ld-table-ellipsis': !fixed && ((enableEllipsis && ellipsis !== false) || ellipsis),
       })}
     >
       {header.isPlaceholder
         ? null
         : <>
           <div className="ld-table-head-th-info">
-            {flexRender(header.column.columnDef.header, header.getContext())}
+            <span>
+              {flexRender(
+                header.column.columnDef.header,
+                header.getContext(),
+              )}
+            </span>
 
             {dataSort
               ? (

+ 19 - 9
packages/app/src/components/table/hooks.tsx

@@ -29,11 +29,15 @@ import {useLatest} from 'ahooks';
 
 function parseColumn<T extends Record<string, unknown>>(
   columns: LDColumnsType<T>[],
-  enableSelect?: boolean,
-  enableNo?: boolean,
+  options: {
+    enableSelect: boolean,
+    enableNo: boolean,
+  },
 ) {
+  const {enableSelect, enableNo} = options;
+
   const helper = createColumnHelper<Record<string, any>>();
-  let hasSort = false, hasGroup = false;
+  let hasSort = false, hasGroup = false, hasEllipsis = false;
 
   const parseColumns: LDColumnsType<T>[] = [...columns];
   if (enableNo) {
@@ -65,7 +69,9 @@ function parseColumn<T extends Record<string, unknown>>(
       width = TABLE_CELL_WIDTH.normal,
       sort,
       children,
+      ellipsis,
     } = val;
+    if (ellipsis && !hasEllipsis) hasEllipsis = true;
 
     let fixedStyle: CSSProperties = {};
 
@@ -85,6 +91,7 @@ function parseColumn<T extends Record<string, unknown>>(
       fixedStyle,
       disabledSort: Boolean(fixed) || dataIndex === 'no',
       sort,
+      ellipsis,
     };
 
     if (children && children.length) {
@@ -92,8 +99,7 @@ function parseColumn<T extends Record<string, unknown>>(
 
       const {columnList: columns} = parseColumn(
         children,
-        false,
-        false,
+        {enableNo: false, enableSelect: false},
       );
 
       const group = helper.group({
@@ -174,6 +180,7 @@ function parseColumn<T extends Record<string, unknown>>(
     columnList,
     hasSort,
     hasGroup,
+    hasEllipsis,
   };
 }
 
@@ -201,12 +208,13 @@ export function useTable<T extends Record<string, any>>(
   } = options;
 
   const [
-    {columnList, hasGroup, hasSort},
+    {columnList, hasGroup, hasSort, hasEllipsis},
     setColumns,
   ] = useState<ReturnType<typeof parseColumn>>({
     columnList: [],
     hasSort: false,
     hasGroup: false,
+    hasEllipsis: false,
   });
 
   // 这里不能用useMemo优化 useMemo可能会在useEffect前调用
@@ -214,8 +222,10 @@ export function useTable<T extends Record<string, any>>(
   useLayoutEffect(function() {
     setColumns(parseColumn(
       columns,
-      Boolean(setRowSelection),
-      true,
+      {
+        enableNo: true,
+        enableSelect: Boolean(setRowSelection),
+      },
     ));
   }, [columns, setRowSelection]);
 
@@ -297,7 +307,7 @@ export function useTable<T extends Record<string, any>>(
   }
 
   return [
-    {...table, active, hasSort, hasGroup},
+    {...table, active, hasSort, hasGroup, hasEllipsis},
     {onDragStart, onDragEnd},
   ] as const;
 }

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

@@ -24,6 +24,23 @@
   border-radius: var(--border-radius) var(--border-radius) 0 0;
 }
 
+.ld-fixed-table {
+  table-layout: fixed;
+}
+
+.ld-table-ellipsis {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+
+  & .ld-table-head-th-info span {
+    display: block;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+}
+
 & .ld-table-right-fixed-shadow,
 & .ld-table-left-fixed-shadow {
   &::before {
@@ -215,3 +232,17 @@
 .ld-table-resizing {
   opacity: 0.4;
 }
+
+.ld-table-tr-preview {
+  & td {
+    &:first-child {
+      border-left: 1px solid var(--border-color) !important;
+    }
+  }
+
+  &:hover {
+    & td {
+      background-color: var(--layout-background-color);
+    }
+  }
+}

+ 8 - 1
packages/app/src/components/table/index.tsx

@@ -36,6 +36,7 @@ export type LDColumnsType<T extends Record<string, unknown>> = {
   fixed?: 'left' | 'right',
   sort?: boolean,
   children?: LDColumnsType<T>[],
+  ellipsis?: boolean,
 };
 
 type Props<T extends Record<string, unknown>> = {
@@ -59,6 +60,7 @@ type Props<T extends Record<string, unknown>> = {
   onSortingChange?: (state: ColumnSort | null) => void;
   subRowKey?: keyof T;
   renderSubComponent?: (row: Row<Record<string, any>>) => ReactNode;
+  ellipsis?: boolean;
 };
 
 function LDTable<T extends Record<string, any>>(props: Props<T>): ReactElement {
@@ -82,6 +84,7 @@ function LDTable<T extends Record<string, any>>(props: Props<T>): ReactElement {
     onSortingChange,
     subRowKey,
     renderSubComponent,
+    ellipsis,
   } = props;
   const [klonaData, setKlonaData] = useState(klona(data));
   const [{page, pageSize}, {setPageContext}] = useTablePageContext(pageContext);
@@ -94,7 +97,7 @@ function LDTable<T extends Record<string, any>>(props: Props<T>): ReactElement {
   const [
     {
       getHeaderGroups, getRowModel, getCenterTotalSize,
-      active, hasSort, hasGroup,
+      active, hasSort, hasGroup, hasEllipsis,
     },
     {onDragEnd, onDragStart},
   ] = useTable(
@@ -136,6 +139,8 @@ function LDTable<T extends Record<string, any>>(props: Props<T>): ReactElement {
           columns={columns}
           scrollProgess={scrollProgess}
           getCenterTotalSize={getCenterTotalSize}
+          hasEllipsis={hasEllipsis}
+          ellipsis={ellipsis}
         />
 
         <TableBody
@@ -152,6 +157,8 @@ function LDTable<T extends Record<string, any>>(props: Props<T>): ReactElement {
           setData={setKlonaData}
           isSecondLevel={isSecondLevel}
           renderSubComponent={renderSubComponent}
+          ellipsis={ellipsis}
+          hasEllipsis={hasEllipsis}
         />
       </div>
       <Pagination