diff --git a/docs/demo/fixedColumns-resize.md b/docs/demo/fixedColumns-resize.md new file mode 100644 index 000000000..4fc7cb6e5 --- /dev/null +++ b/docs/demo/fixedColumns-resize.md @@ -0,0 +1,3 @@ +## fixedColumns-resize + + diff --git a/docs/examples/fixedColumns-resize.tsx b/docs/examples/fixedColumns-resize.tsx new file mode 100644 index 000000000..c3a35b678 --- /dev/null +++ b/docs/examples/fixedColumns-resize.tsx @@ -0,0 +1,121 @@ +import React, { useState, useCallback } from 'react'; +import Table from 'rc-table'; +import '../../assets/index.less'; +import type { ColumnType } from '@/interface'; + +interface RecordType { + a: string; + b?: string; + c?: string; + d: number; + key: string; +} + +const defaultColumns: ColumnType[] = [ + { title: 'title1', dataIndex: 'a', key: 'a', width: 100, fixed: 'left' }, + { title: 'title2', dataIndex: 'b', key: 'b', width: 100, fixed: 'left', ellipsis: true }, + { title: 'title3', dataIndex: 'c', key: 'c' }, + { title: 'title4', dataIndex: 'b', key: 'd' }, + { title: 'title5', dataIndex: 'b', key: 'e' }, + { title: 'title6', dataIndex: 'b', key: 'f' }, + { title: 'title8', dataIndex: 'b', key: 'h' }, + { title: 'title9', dataIndex: 'b', key: 'i' }, + { title: 'title11', dataIndex: 'b', key: 'j' }, + { title: 'title12', dataIndex: 'b', key: 'j1' }, + { title: 'title13', dataIndex: 'b', key: 'j2' }, + { title: 'title14', dataIndex: 'b', key: 'j3' }, + { title: 'title15', dataIndex: 'b', key: 'j4' }, + { title: 'title16', dataIndex: 'b', key: 'j5' }, + { title: 'title17', dataIndex: 'b', key: 'j6' }, + { title: 'title18', dataIndex: 'b', key: 'j7' }, + { title: 'title19', dataIndex: 'b', key: 'k', width: 50, fixed: 'right' }, + { title: 'title20', dataIndex: 'b', key: 'l', width: 100, fixed: 'right' }, +]; + +const data: RecordType[] = Array.from(new Array(200).fill(1), (v, index) => { + return { + a: '123', + b: 'xxxxx', + d: 3, + key: index + '', + }; +}); + +const Demo = () => { + const [isShown, setIsShown] = useState(false); + const [renderTime, setRenderTime] = useState(0); + const [isFixed, setIsFixed] = useState(true); + const [columns, setColumns] = useState(defaultColumns); + const onToggleSideBar = useCallback(() => { + const s = window.performance.now(); + setIsShown(v => !v); + + setTimeout(() => { + setRenderTime(+(window.performance.now() - s).toFixed(2)); + }); + }, []); + + const onToggleFixed = useCallback(() => { + setIsFixed(v => !v); + }, []); + + const onRemoveColumn = useCallback(() => { + setColumns(state => { + const newState = [...state]; + newState.splice( + state.findIndex(({ fixed }) => !fixed), + 1, + ); + return newState; + }); + }, []); + + const onAddColumn = useCallback(() => { + setColumns(state => { + const newState = [...state]; + newState.splice( + state.findIndex(({ fixed }) => !fixed), + 0, + { title: 'new title', dataIndex: 'b', key: Math.random().toString(16).slice(2) }, + ); + return newState; + }); + }, []); + + const expandedRowRender = useCallback(({ b, c }) => b || c, []); + + return ( +
+
+ + + + +

更新用时:{renderTime} ms

+
+
+
+
+ + + + + ); +}; + +export default Demo; diff --git a/src/Body/BodyRow.tsx b/src/Body/BodyRow.tsx index ac1177cc7..5f307cad6 100644 --- a/src/Body/BodyRow.tsx +++ b/src/Body/BodyRow.tsx @@ -49,10 +49,6 @@ function BodyRow( } = props; const { prefixCls, fixedInfoList } = React.useContext(TableContext); const { - fixHeader, - fixColumn, - horizonScroll, - componentWidth, flattenColumns, expandableType, expandRowByClick, @@ -197,11 +193,7 @@ function BodyRow( computedExpandedRowClassName, )} prefixCls={prefixCls} - fixHeader={fixHeader} - fixColumn={fixColumn} - horizonScroll={horizonScroll} component={RowComponent} - componentWidth={componentWidth} cellComponent={cellComponent} colSpan={flattenColumns.length} > diff --git a/src/Body/ExpandedRow.tsx b/src/Body/ExpandedRow.tsx index ebdd753fa..b3203e8b3 100644 --- a/src/Body/ExpandedRow.tsx +++ b/src/Body/ExpandedRow.tsx @@ -1,16 +1,13 @@ import * as React from 'react'; -import { CustomizeComponent } from '../interface'; +import type { CustomizeComponent } from '../interface'; import Cell from '../Cell'; import TableContext from '../context/TableContext'; +import ExpandedRowContext from '../context/ExpandedRowContext'; export interface ExpandedRowProps { prefixCls: string; component: CustomizeComponent; cellComponent: CustomizeComponent; - fixHeader: boolean; - fixColumn: boolean; - horizonScroll: boolean; - componentWidth: number; className: string; expanded: boolean; children: React.ReactNode; @@ -22,15 +19,12 @@ function ExpandedRow({ children, component: Component, cellComponent, - fixHeader, - fixColumn, - horizonScroll, className, expanded, - componentWidth, colSpan, }: ExpandedRowProps) { const { scrollbarSize } = React.useContext(TableContext); + const { fixHeader, fixColumn, componentWidth } = React.useContext(ExpandedRowContext); // Cache render node return React.useMemo(() => { @@ -67,13 +61,13 @@ function ExpandedRow({ }, [ children, Component, - fixHeader, - horizonScroll, className, expanded, - componentWidth, colSpan, scrollbarSize, + componentWidth, + fixColumn, + fixHeader, ]); } diff --git a/src/Body/index.tsx b/src/Body/index.tsx index 88c06f409..8aad33189 100644 --- a/src/Body/index.tsx +++ b/src/Body/index.tsx @@ -35,8 +35,7 @@ function Body({ const [endRow, setEndRow] = React.useState(-1); const { onColumnResize } = React.useContext(ResizeContext); const { prefixCls, getComponent } = React.useContext(TableContext); - const { fixHeader, horizonScroll, flattenColumns, componentWidth } = - React.useContext(BodyContext); + const { flattenColumns } = React.useContext(BodyContext); const flattenData: { record: RecordType; indent: number }[] = useFlattenRecords( data, @@ -91,11 +90,7 @@ function Body({ expanded className={`${prefixCls}-placeholder`} prefixCls={prefixCls} - fixHeader={fixHeader} - fixColumn={horizonScroll} - horizonScroll={horizonScroll} component={trComponent} - componentWidth={componentWidth} cellComponent={tdComponent} colSpan={flattenColumns.length} > @@ -138,12 +133,9 @@ function Body({ expandedKeys, getRowKey, getComponent, - componentWidth, emptyNode, flattenColumns, childrenColumnName, - fixHeader, - horizonScroll, onColumnResize, rowExpandable, flattenData, diff --git a/src/Table.tsx b/src/Table.tsx index ad1e623a0..322e7d41c 100644 --- a/src/Table.tsx +++ b/src/Table.tsx @@ -76,6 +76,7 @@ import FixedHolder from './FixedHolder'; import type { SummaryProps } from './Footer/Summary'; import Summary from './Footer/Summary'; import StickyContext from './context/StickyContext'; +import ExpandedRowContext from './context/ExpandedRowContext'; import { EXPAND_COLUMN } from './constant'; // Used for conditions cache @@ -807,10 +808,6 @@ function Table(props: TableProps(props: TableProps(props: TableProps ({ + componentWidth, + fixHeader, + fixColumn, + }), + [componentWidth, fixHeader, fixColumn], + ); + const ResizeContextValue = React.useMemo(() => ({ onColumnResize }), [onColumnResize]); return ( - {fullTable} + + {fullTable} + diff --git a/src/context/BodyContext.tsx b/src/context/BodyContext.tsx index bba1b2ac5..5f7233971 100644 --- a/src/context/BodyContext.tsx +++ b/src/context/BodyContext.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { +import type { ColumnType, DefaultRecordType, ColumnsType, @@ -18,11 +18,7 @@ export interface BodyContextProps { columns: ColumnsType; flattenColumns: readonly ColumnType[]; - componentWidth: number; tableLayout: TableLayout; - fixHeader: boolean; - fixColumn: boolean; - horizonScroll: boolean; indentSize: number; expandableType: ExpandableType; diff --git a/src/context/ExpandedRowContext.tsx b/src/context/ExpandedRowContext.tsx new file mode 100644 index 000000000..70d46fb20 --- /dev/null +++ b/src/context/ExpandedRowContext.tsx @@ -0,0 +1,11 @@ +import * as React from 'react'; + +export interface ExpandedRowProps { + componentWidth: number; + fixHeader: boolean; + fixColumn: boolean; +} + +const ExpandedRowContext = React.createContext(null); + +export default ExpandedRowContext;