Browse Source

feat: Table column add resize prop #1762

shijia.me 2 years ago
parent
commit
c83fb85de1

+ 7 - 4
packages/semi-ui/table/ResizableHeaderCell.tsx

@@ -6,14 +6,16 @@ export interface ResizableHeaderCellProps {
     onResize?: ResizeFn;
     onResize?: ResizeFn;
     onResizeStart?: ResizeFn;
     onResizeStart?: ResizeFn;
     onResizeStop?: ResizeFn;
     onResizeStop?: ResizeFn;
-    width?: number | string
+    width?: number | string;
+    /** For compatibility with previous versions, the default value is true. If you don't want to resize, set it to false */
+    resize?: boolean
 }
 }
 
 
 class ResizableHeaderCell extends React.PureComponent<ResizableHeaderCellProps> {
 class ResizableHeaderCell extends React.PureComponent<ResizableHeaderCellProps> {
     render() {
     render() {
-        const { onResize, onResizeStart, onResizeStop, width, ...restProps } = this.props;
+        const { onResize, onResizeStart, onResizeStop, width, resize, ...restProps } = this.props;
 
 
-        if (typeof width !== 'number') {
+        if (typeof width !== 'number' || resize === false) {
             return <th {...restProps} />;
             return <th {...restProps} />;
         }
         }
 
 
@@ -24,12 +26,13 @@ class ResizableHeaderCell extends React.PureComponent<ResizableHeaderCellProps>
 
 
         return (
         return (
             <Resizable
             <Resizable
-                width={width}
+                width={width as number}
                 height={0}
                 height={0}
                 onResize={onResize}
                 onResize={onResize}
                 onResizeStart={onResizeStart}
                 onResizeStart={onResizeStart}
                 onResizeStop={onResizeStop}
                 onResizeStop={onResizeStop}
                 draggableOpts={{ enableUserSelectHack: false }}
                 draggableOpts={{ enableUserSelectHack: false }}
+                axis='x'
             >
             >
                 <th {...restProps}>
                 <th {...restProps}>
                     {children}
                     {children}

+ 2 - 2
packages/semi-ui/table/TableHeader.tsx

@@ -6,7 +6,7 @@ import BaseComponent, { BaseProps } from '../_base/baseComponent';
 import { strings, cssClasses } from '@douyinfe/semi-foundation/table/constants';
 import { strings, cssClasses } from '@douyinfe/semi-foundation/table/constants';
 import { shouldShowEllipsisTitle } from '@douyinfe/semi-foundation/table/utils';
 import { shouldShowEllipsisTitle } from '@douyinfe/semi-foundation/table/utils';
 import TableHeaderRow from './TableHeaderRow';
 import TableHeaderRow from './TableHeaderRow';
-import { Fixed, TableComponents, OnHeaderRow } from './interface';
+import { Fixed, TableComponents, OnHeaderRow, ColumnProps } from './interface';
 
 
 function parseHeaderRows(columns: any[]) {
 function parseHeaderRows(columns: any[]) {
     const rows: any[] = [];
     const rows: any[] = [];
@@ -175,7 +175,7 @@ export interface TableHeaderCell {
     key: string | number;
     key: string | number;
     className: string;
     className: string;
     children: ReactNode;
     children: ReactNode;
-    column: any[];
+    column: ColumnProps;
     colStart: number;
     colStart: number;
     level: number;
     level: number;
     parents: any[];
     parents: any[];

+ 5 - 2
packages/semi-ui/table/TableHeaderRow.tsx

@@ -16,10 +16,11 @@ import {
 import BaseComponent from '../_base/baseComponent';
 import BaseComponent from '../_base/baseComponent';
 import TableContext, { TableContextProps } from './table-context';
 import TableContext, { TableContextProps } from './table-context';
 import { TableComponents, OnHeaderRow, Fixed } from './interface';
 import { TableComponents, OnHeaderRow, Fixed } from './interface';
+import type { TableHeaderCell } from './TableHeader';
 
 
 export interface TableHeaderRowProps {
 export interface TableHeaderRowProps {
     components?: TableComponents;
     components?: TableComponents;
-    row?: any[];
+    row?: TableHeaderCell[];
     prefixCls?: string;
     prefixCls?: string;
     onHeaderRow?: OnHeaderRow<any>;
     onHeaderRow?: OnHeaderRow<any>;
     index?: number;
     index?: number;
@@ -81,7 +82,7 @@ export default class TableHeaderRow extends BaseComponent<TableHeaderRowProps, R
             this.context.setHeadWidths(
             this.context.setHeadWidths(
                 map(heads, (head, headIndex) => {
                 map(heads, (head, headIndex) => {
                     let configWidth = get(row, [headIndex, 'column', 'width']);
                     let configWidth = get(row, [headIndex, 'column', 'width']);
-                    const key = get(row, [headIndex, 'column', 'key']);
+                    const key = get(row, [headIndex, 'column', 'key']) as any;
                     if (typeof configWidth !== 'number') {
                     if (typeof configWidth !== 'number') {
                         configWidth = (head && head.getBoundingClientRect().width) || 0;
                         configWidth = (head && head.getBoundingClientRect().width) || 0;
                     }
                     }
@@ -175,6 +176,8 @@ export default class TableHeaderRow extends BaseComponent<TableHeaderRowProps, R
                 }
                 }
             }
             }
 
 
+            Object.assign(cellProps, { resize: column.resize });
+
             const props = omit({ ...cellProps, ...customProps }, [
             const props = omit({ ...cellProps, ...customProps }, [
                 'colStart',
                 'colStart',
                 'colEnd',
                 'colEnd',

+ 2 - 1
packages/semi-ui/table/_story/table.stories.jsx

@@ -99,7 +99,8 @@ export {
     Fixed1556,
     Fixed1556,
     FixedColumnAlign,
     FixedColumnAlign,
     FixOnChange,
     FixOnChange,
-    FixedSticky
+    FixedSticky,
+    ColumnResize
 } from './v2';
 } from './v2';
 export { default as FixSelectAll325 } from './Demos/rowSelection';
 export { default as FixSelectAll325 } from './Demos/rowSelection';
 
 

+ 104 - 0
packages/semi-ui/table/_story/v2/ColumnResize/index.tsx

@@ -0,0 +1,104 @@
+import React, { useMemo } from 'react';
+import { Table, Avatar } from '@douyinfe/semi-ui';
+import * as dateFns from 'date-fns';
+import { ColumnProps } from '../../../interface';
+import { IconMore } from '@douyinfe/semi-icons';
+
+
+/**
+ * fixed columns with resizable
+ */
+function App() {
+    const DAY = 24 * 60 * 60 * 1000;
+    const figmaIconUrl = 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/figma-icon.png';
+    
+    const columns: ColumnProps[] = [
+        {
+            title: 'fixed + width',
+            dataIndex: 'name',
+            width: 300,
+            render: (text, record, index) => {
+                return (
+                    <div>
+                        <Avatar size="small" shape="square" src={figmaIconUrl} style={{ marginRight: 12 }}></Avatar>
+                        {text}
+                    </div>
+                );
+            },
+            filters: [
+                {
+                    text: 'Semi Design 设计稿',
+                    value: 'Semi Design 设计稿',
+                },
+                {
+                    text: 'Semi D2C 设计稿',
+                    value: 'Semi D2C 设计稿',
+                },
+            ],
+            fixed: true,
+            resize: false,
+            onFilter: (value, record) => record.name.includes(value),
+        },
+        {
+            title: '有固定宽度',
+            dataIndex: 'size',
+            width: 200,
+            sorter: (a, b) => (a.size - b.size > 0 ? 1 : -1),
+            render: text => `${text} KB`,
+        },
+        {
+            title: '有固定宽度',
+            width: 200,
+            dataIndex: 'owner',
+            render: (text, record, index) => {
+                return (
+                    <div>
+                        <Avatar size="small" color={record.avatarBg} style={{ marginRight: 4 }}>
+                            {typeof text === 'string' && text.slice(0, 1)}
+                        </Avatar>
+                        {text}
+                    </div>
+                );
+            },
+        },
+        {
+            title: '留一列自适应宽度',
+            dataIndex: 'updateTime',
+            sorter: (a, b) => (a.updateTime - b.updateTime > 0 ? 1 : -1),
+            render: value => {
+                return dateFns.format(new Date(value), 'yyyy-MM-dd');
+            },
+        },
+        {
+            title: 'fixed + width',
+            dataIndex: 'operate',
+            fixed: 'right',
+            width: 200,
+            resize: false,
+            render: () => {
+                return <IconMore />;
+            },
+        },
+    ];
+
+    const data = useMemo(() => {
+        const _data = [];
+        for (let i = 0; i < 46; i++) {
+            const isSemiDesign = i % 2 === 0;
+            const randomNumber = (i * 1000) % 199;
+            _data.push({
+                key: '' + i,
+                name: isSemiDesign ? `Semi Design 设计稿${i}.fig` : `Semi D2C 设计稿${i}.fig`,
+                owner: isSemiDesign ? '姜鹏志' : '郝宣',
+                size: randomNumber,
+                updateTime: new Date().valueOf() + randomNumber * DAY,
+                avatarBg: isSemiDesign ? 'grey' : 'red',
+            });
+        }
+        return _data;
+    }, []);
+
+    return <Table columns={columns} dataSource={data} resizable bordered />;
+}
+
+export default App;

+ 1 - 0
packages/semi-ui/table/_story/v2/index.js

@@ -21,3 +21,4 @@ export { default as Fixed1556 } from './Fixed1556';
 export { default as FixedColumnAlign } from './FixedColumnAlign';
 export { default as FixedColumnAlign } from './FixedColumnAlign';
 export { default as FixOnChange } from './FixOnChange';
 export { default as FixOnChange } from './FixOnChange';
 export { default as FixedSticky } from './FixedSticky';
 export { default as FixedSticky } from './FixedSticky';
+export { default as ColumnResize } from './ColumnResize';

+ 2 - 1
packages/semi-ui/table/interface.ts

@@ -105,7 +105,8 @@ export interface ColumnProps<RecordType extends Record<string, any> = any> {
     onFilter?: OnFilter<RecordType>;
     onFilter?: OnFilter<RecordType>;
     onFilterDropdownVisibleChange?: OnFilterDropdownVisibleChange;
     onFilterDropdownVisibleChange?: OnFilterDropdownVisibleChange;
     onHeaderCell?: OnHeaderCell<RecordType>;
     onHeaderCell?: OnHeaderCell<RecordType>;
-    ellipsis?: BaseEllipsis
+    ellipsis?: BaseEllipsis;
+    resize?: boolean
 }
 }
 
 
 export type Align = BaseAlign;
 export type Align = BaseAlign;