From 70e42aa88406114cc46542361ea885320747dcc4 Mon Sep 17 00:00:00 2001 From: FatahChan Date: Wed, 19 Nov 2025 23:58:46 +0200 Subject: [PATCH 1/5] refactor: convert Demo component to functional component and optimize column resizing logic --- docs/examples/column-resize.tsx | 116 +++++++++++++------------------- 1 file changed, 46 insertions(+), 70 deletions(-) diff --git a/docs/examples/column-resize.tsx b/docs/examples/column-resize.tsx index a3f15cbbc..73b70aef3 100644 --- a/docs/examples/column-resize.tsx +++ b/docs/examples/column-resize.tsx @@ -1,95 +1,71 @@ -import React from 'react'; -import { Resizable } from 'react-resizable'; +import React, { useMemo, useState } from 'react'; +import type { ColumnType, ColumnsType } from 'rc-table'; import Table from 'rc-table'; +import { Resizable } from 'react-resizable'; import '../../assets/index.less'; import 'react-resizable/css/styles.css'; -import type { ColumnType } from '@/interface'; - const ResizableTitle = props => { const { onResize, width, ...restProps } = props; if (!width) { return ; } - return ( - + ); }; -interface RecordType { - a: string; - b?: string; - c?: string; - d?: number; - key: string; -} +const data = [ + { a: '123', key: '1' }, + { a: 'cdd', b: 'edd', key: '2' }, + { a: '1333', c: 'eee', d: 2, key: '3' }, +] as const; -interface DemoState { - columns: ColumnType[]; -} +type RecordType = (typeof data)[number]; -class Demo extends React.Component<{}, DemoState> { - state: DemoState = { - columns: [ - { title: 'title1', dataIndex: 'a', key: 'a', width: 100 }, - { title: 'title2', dataIndex: 'b', key: 'b', width: 100 }, - { title: 'title3', dataIndex: 'c', key: 'c', width: 200 }, - { - title: 'Operations', - dataIndex: '', - key: 'd', - render() { - return Operations; - }, +const Demo = () => { + const [columns, setColumns] = useState>([ + { title: 'title1', dataIndex: 'a', key: 'a', width: 100 }, + { title: 'title2', dataIndex: 'b', key: 'b', width: 100 }, + { title: 'title3', dataIndex: 'c', key: 'c', width: 200 }, + { + title: 'Operations', + dataIndex: '', + key: 'd', + render() { + return Operations; }, - ], - }; - - components = { - header: { - cell: ResizableTitle, }, - }; - - data = [ - { a: '123', key: '1' }, - { a: 'cdd', b: 'edd', key: '2' }, - { a: '1333', c: 'eee', d: 2, key: '3' }, - ]; - - handleResize = - index => - (e, { size }) => { - this.setState(({ columns }) => { - const nextColumns = [...columns]; - nextColumns[index] = { - ...nextColumns[index], - width: size.width, - }; - return { columns: nextColumns }; - }); + ]); + const handleResize = useMemo(() => { + return (index: number) => { + return (_: React.MouseEvent, { size }: { size: { width: number } }) => { + setColumns(prevColumns => + prevColumns.map((col, i) => (i === index ? { ...col, width: size.width } : col)), + ); + }; }; - - render() { - const columns = this.state.columns.map((col, index) => ({ + }, []); + const columnsWithResizable = useMemo(() => { + return columns.map((col, index) => ({ ...col, - onHeaderCell: (column: ColumnType) => - ({ - width: column.width, - onResize: this.handleResize(index), - }) as any, + onHeaderCell: (column: ColumnType) => ({ + width: column.width, + onResize: handleResize(index), + }), })); + }, [columns, handleResize]); - return ( -
-

Integrate with react-resizable

- - - ); - } -} + const tableProps = useMemo(() => { + return { + components: { header: { cell: ResizableTitle } }, + columns: columnsWithResizable, + data, + }; + }, [columnsWithResizable]); + return
; +}; export default Demo; From 3a5240eb310616e9a5a9bf16a17ebc19dd6623e5 Mon Sep 17 00:00:00 2001 From: FatahChan Date: Thu, 20 Nov 2025 09:25:06 +0200 Subject: [PATCH 2/5] feat: add sortable column demo with DnD functionality and update dependencies --- docs/demo/column-sortable.md | 8 +++ docs/examples/column-sortable.tsx | 97 +++++++++++++++++++++++++++++++ package.json | 3 + 3 files changed, 108 insertions(+) create mode 100644 docs/demo/column-sortable.md create mode 100644 docs/examples/column-sortable.tsx diff --git a/docs/demo/column-sortable.md b/docs/demo/column-sortable.md new file mode 100644 index 000000000..162c218c1 --- /dev/null +++ b/docs/demo/column-sortable.md @@ -0,0 +1,8 @@ +--- +title: column-sortable +nav: + title: Demo + path: /demo +--- + + diff --git a/docs/examples/column-sortable.tsx b/docs/examples/column-sortable.tsx new file mode 100644 index 000000000..c483666fe --- /dev/null +++ b/docs/examples/column-sortable.tsx @@ -0,0 +1,97 @@ +import type { DragEndEvent } from '@dnd-kit/core'; +import { DndContext, closestCenter } from '@dnd-kit/core'; +import { SortableContext, arrayMove, useSortable, rectSwappingStrategy } from '@dnd-kit/sortable'; +import { CSS } from '@dnd-kit/utilities'; +import type { ColumnType } from 'rc-table'; +import Table from 'rc-table'; +import React, { useCallback, useMemo, useState } from 'react'; +import 'react-resizable/css/styles.css'; +import '../../assets/index.less'; +import { restrictToHorizontalAxis } from '@dnd-kit/modifiers'; +const SortableHeaderCell = props => { + const { width, style: styleProps, ...restProps } = props; + + const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ + id: props.id as string, + }); + + const style = { + ...styleProps, + transform: CSS.Transform.toString(transform), + transition, + cursor: 'move', + }; + + return
; +}; + +const data = [ + { a: '123', key: '1' }, + { a: 'cdd', b: 'edd', key: '2' }, + { a: '1333', c: 'eee', d: 2, key: '3' }, +] as const; + +const Demo = () => { + const [columns, setColumns] = useState([ + { title: 'title1', dataIndex: 'a', key: 'a', width: 100 }, + { title: 'title2', dataIndex: 'b', key: 'b', width: 100 }, + { title: 'title3', dataIndex: 'c', key: 'c', width: 200 }, + { + title: 'Operations', + dataIndex: 's', + key: 'd', + render() { + return Operations; + }, + }, + ]); + + const columnsWithSortable = useMemo(() => { + return columns.map(col => ({ + ...col, + onHeaderCell: () => ({ + id: col.dataIndex?.toString(), + }), + onCell: () => ({ + id: col.dataIndex?.toString(), + }), + })); + }, [columns]); + + const tableProps = useMemo(() => { + return { + components: { header: { cell: SortableHeaderCell } }, + columns: columnsWithSortable, + data, + }; + }, [columnsWithSortable]); + const handleDragEnd = useCallback((e: DragEndEvent) => { + const { active, over } = e; + if (over) { + setColumns(prevColumns => { + const activeIndex = prevColumns.findIndex(col => col.key === active.id); + const overIndex = prevColumns.findIndex(col => col.key === over.id); + if (activeIndex === -1 || overIndex === -1) { + return prevColumns; + } + return arrayMove([...prevColumns], activeIndex, overIndex); + }); + } + }, []); + return ( + + col.dataIndex?.toString())} + strategy={rectSwappingStrategy} + > + ; + + + ); +}; + +export default Demo; diff --git a/package.json b/package.json index 99e7574de..d68790a7d 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,9 @@ "rc-virtual-list": "^3.14.2" }, "devDependencies": { + "@dnd-kit/core": "^6.3.1", + "@dnd-kit/modifiers": "^9.0.0", + "@dnd-kit/sortable": "^10.0.0", "@rc-component/father-plugin": "^2.0.1", "@rc-component/np": "^1.0.3", "@testing-library/dom": "^10.4.1", From e3fe7849380fae439e8d7c9f0463e1fed50e7895 Mon Sep 17 00:00:00 2001 From: FatahChan Date: Thu, 20 Nov 2025 09:34:03 +0200 Subject: [PATCH 3/5] fix: update column sorting logic to use dataIndex instead of key for improved functionality --- docs/examples/column-sortable.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/examples/column-sortable.tsx b/docs/examples/column-sortable.tsx index c483666fe..9a19ab02b 100644 --- a/docs/examples/column-sortable.tsx +++ b/docs/examples/column-sortable.tsx @@ -69,8 +69,8 @@ const Demo = () => { const { active, over } = e; if (over) { setColumns(prevColumns => { - const activeIndex = prevColumns.findIndex(col => col.key === active.id); - const overIndex = prevColumns.findIndex(col => col.key === over.id); + const activeIndex = prevColumns.findIndex(col => col.dataIndex === active.id); + const overIndex = prevColumns.findIndex(col => col.dataIndex === over.id); if (activeIndex === -1 || overIndex === -1) { return prevColumns; } From acc7f7ac67d213b4b2bbf25d026b16c7849c6b2e Mon Sep 17 00:00:00 2001 From: FatahChan Date: Thu, 20 Nov 2025 09:36:42 +0200 Subject: [PATCH 4/5] fix: update column resizing and sortable demo to correctly use dataIndex for operations column --- docs/examples/column-resize.tsx | 4 ++-- docs/examples/column-sortable.tsx | 12 ++++-------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/docs/examples/column-resize.tsx b/docs/examples/column-resize.tsx index 73b70aef3..df0e21623 100644 --- a/docs/examples/column-resize.tsx +++ b/docs/examples/column-resize.tsx @@ -11,7 +11,7 @@ const ResizableTitle = props => { return
; } return ( - + ); @@ -32,7 +32,7 @@ const Demo = () => { { title: 'title3', dataIndex: 'c', key: 'c', width: 200 }, { title: 'Operations', - dataIndex: '', + dataIndex: 'd', key: 'd', render() { return Operations; diff --git a/docs/examples/column-sortable.tsx b/docs/examples/column-sortable.tsx index 9a19ab02b..9abce26de 100644 --- a/docs/examples/column-sortable.tsx +++ b/docs/examples/column-sortable.tsx @@ -1,15 +1,14 @@ import type { DragEndEvent } from '@dnd-kit/core'; import { DndContext, closestCenter } from '@dnd-kit/core'; -import { SortableContext, arrayMove, useSortable, rectSwappingStrategy } from '@dnd-kit/sortable'; +import { restrictToHorizontalAxis } from '@dnd-kit/modifiers'; +import { SortableContext, arrayMove, rectSwappingStrategy, useSortable } from '@dnd-kit/sortable'; import { CSS } from '@dnd-kit/utilities'; -import type { ColumnType } from 'rc-table'; import Table from 'rc-table'; import React, { useCallback, useMemo, useState } from 'react'; import 'react-resizable/css/styles.css'; import '../../assets/index.less'; -import { restrictToHorizontalAxis } from '@dnd-kit/modifiers'; const SortableHeaderCell = props => { - const { width, style: styleProps, ...restProps } = props; + const { style: styleProps, ...restProps } = props; const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id: props.id as string, @@ -38,7 +37,7 @@ const Demo = () => { { title: 'title3', dataIndex: 'c', key: 'c', width: 200 }, { title: 'Operations', - dataIndex: 's', + dataIndex: 'd', key: 'd', render() { return Operations; @@ -52,9 +51,6 @@ const Demo = () => { onHeaderCell: () => ({ id: col.dataIndex?.toString(), }), - onCell: () => ({ - id: col.dataIndex?.toString(), - }), })); }, [columns]); From 71e3873c939381bbb41fc33d92610b3dd898549c Mon Sep 17 00:00:00 2001 From: FatahChan Date: Thu, 20 Nov 2025 18:29:55 +0200 Subject: [PATCH 5/5] fix: update column sortable demo to directly use dataIndex for header cell IDs and sortable items --- docs/examples/column-sortable.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/docs/examples/column-sortable.tsx b/docs/examples/column-sortable.tsx index 9abce26de..873d3eb83 100644 --- a/docs/examples/column-sortable.tsx +++ b/docs/examples/column-sortable.tsx @@ -49,7 +49,7 @@ const Demo = () => { return columns.map(col => ({ ...col, onHeaderCell: () => ({ - id: col.dataIndex?.toString(), + id: col.dataIndex, }), })); }, [columns]); @@ -80,10 +80,7 @@ const Demo = () => { onDragEnd={handleDragEnd} modifiers={[restrictToHorizontalAxis]} > - col.dataIndex?.toString())} - strategy={rectSwappingStrategy} - > + col.dataIndex)} strategy={rectSwappingStrategy}> ;